The plan carries the objective, current mechanism, and cut line; the map's mission, boundaries, and subgoals speak the live admission vocabulary; the session-zero document is teardown evidence; the draft answer variant is marked representable but uninhabited. Steward folded the task opening into the handoff and map. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
333 lines
20 KiB
Markdown
333 lines
20 KiB
Markdown
# Ghostlight Dungeon Session Zero and Bounded Co-op
|
|
|
|
## Status
|
|
|
|
Teardown evidence, not a live authority map. The `SessionZeroKernel`, the
|
|
compiler, the preview and contract-review organs described below exist in no
|
|
committed source. World creation is `world.create` on the sealed kernel; seed
|
|
authoring is plan step 8, the seed producer: a Draft-phase authoring session
|
|
that admits `AdmitPatch` seeds as the owner for approval before activation
|
|
(`notes/ghostlight-implementation-plan.md`). Read this document only for the
|
|
co-op intent and the rejected compiler shape.
|
|
|
|
## Owners
|
|
|
|
### SessionZeroKernel
|
|
|
|
`SessionZeroKernel` owns one persistent draft mailbox and its revisions. Its
|
|
MessagePack CultCache store contains the roster, single-use invitations,
|
|
shared/private channels, messages, contract, private character drafts,
|
|
boundaries, decisions, approvals, DM Persona, evidence coverage, compilation
|
|
preview, and publication receipt.
|
|
|
|
The store keeps two deliberately different model-receipt collections. The
|
|
inference audit contains every committed invocation, including two calls whose
|
|
semantic receipt hashes match but whose latency or provider-attempt telemetry
|
|
differs. The active-preview proof set contains only the compiler transaction
|
|
that produced the currently retained preview. Replacing or retiring a preview
|
|
clears that proof set without erasing the audit. A campaign publication carries
|
|
only the active proof set; historical DM turns and superseded compiler runs do
|
|
not become evidence for a seed they did not produce.
|
|
|
|
Player messages are durable conversation, not campaign facts. Projector, DM
|
|
Persona, Interpreter, retrieval, and compilation stages return proposals. Only
|
|
the kernel may change the draft.
|
|
|
|
Private DM channels use character-component and channel epochs. Independent
|
|
private turns can finish in parallel even if an unrelated private component
|
|
commits first. Shared changes serialize through the shared epoch. No output is
|
|
rebased.
|
|
|
|
### WorldKernel
|
|
|
|
`WorldKernel` receives nothing while Session Zero is drafting. Publication
|
|
builds a new campaign store in a private staging directory. Campaign seed,
|
|
membership, contract, governance, DM Persona, approved brief, approval digests,
|
|
Vault evidence, and model receipts enter one empty CultCache batch. The
|
|
directory becomes discoverable only after the batch succeeds.
|
|
|
|
Publication is idempotent by the approved seed digest. Repeating the same
|
|
publication recovers the campaign. Reusing the campaign ID for a different
|
|
digest is rejected.
|
|
|
|
## Privacy membrane
|
|
|
|
Shared DM inference receives the shared contract, aggregate boundary policy,
|
|
public party cards, shared decisions, evidence coverage, and recent shared
|
|
messages. It cannot receive raw boundaries, another player's private draft, or
|
|
private messages.
|
|
|
|
Private DM inference receives the shared contract, aggregate policy, public
|
|
party cards, that player's character draft, that player's attributed
|
|
boundaries, visible decisions, and recent messages from that private channel.
|
|
It cannot receive another player's private state.
|
|
|
|
Account hashes and invite-token hashes remain private persistence fields. They
|
|
are absent from JSON Schemas, browser projections, CultMesh surfaces, and model
|
|
contexts. Actor-specific campaign surfaces use random campaign member IDs and
|
|
the exact assigned actor.
|
|
|
|
The structured Projector and Interpreter receive their exact stable JSON
|
|
Schema before any dynamic context. OpenAI-compatible JSON-object modes
|
|
constrain syntax but do not communicate the application schema by themselves.
|
|
The DM Persona owns the natural utterance. The Interpreter's model-facing
|
|
schema has no speech field: it emits only new typed proposals and reply
|
|
affordances, after which the runtime binds the Persona output losslessly into
|
|
the proposed kernel delta. It cannot rewrite, summarize, or truncate the
|
|
Persona while extracting state. The kernel still treats the three stages as
|
|
one atomic proposal; an invalid Interpreter commits neither speech nor state.
|
|
|
|
The Interpreter receives only the current contract, its channel and member
|
|
scope, the entitled private character when applicable, unresolved material
|
|
decisions, and the exact Persona response. Non-material opening and role cards
|
|
remain renderer-visible suggestions but never enter Projector or Interpreter
|
|
cognition unless the player explicitly selects or discusses one. Transcript windows, evidence coverage,
|
|
boundaries, and public-party narrative already served their purpose in the
|
|
Projector and are not replayed into extraction. It cannot restate existing
|
|
draft fields or unresolved decisions as new proposals. Stable schema-first
|
|
prefixes preserve provider cache reuse. Empty, malformed, schema-invalid, or
|
|
stale outputs cannot change the typed draft. If both same-snapshot attempts
|
|
fail, the kernel may append a fixed local DM notice to the conversation while
|
|
leaving contract, characters, decisions, boundaries, approvals, and model
|
|
receipts unchanged.
|
|
|
|
Every player-triggered Session Zero model task enters the same live-inference
|
|
priority gate as campaign play. This includes opening and role suggestions, DM
|
|
turns, counter replacements, and world compilation. Entering the gate cancels
|
|
an in-flight strategic model wave before it can commit and prevents new
|
|
background inference from launching until the interactive task leaves. A quiet
|
|
campaign cannot consume provider concurrency while a player is waiting at the
|
|
table.
|
|
|
|
One Interpreter turn has one owner per typed lane. A shared turn may directly
|
|
edit the draft contract or offer a contract decision, never both; a private turn
|
|
may directly edit the ordinary character draft or offer a character-patch
|
|
decision, never both. An extraordinary-permission bargain is a separate consent
|
|
lane, so it may accompany a direct mundane character patch without being
|
|
silently granted. The model-facing schema requests a same-snapshot correction for a
|
|
split-lane output, and the kernel repeats the invariant before mutation.
|
|
|
|
Decision metadata is not part of the general Interpreter's ontology. Its
|
|
schema carries only the prompt, proposed resolution, and one or more typed
|
|
semantic payloads. The Director assigns a fresh durable decision ID, exact
|
|
private-channel owner (or shared ownership), material status, and clean
|
|
lifecycle state. Extraordinary-permission proposals similarly contain terms
|
|
only; Ghostlight assigns the permission ID and binds the exact entitled actor.
|
|
Model output cannot reuse a decision ID, target another actor, replace an
|
|
existing permission by guessing its ID, or claim evidence custody. Focused
|
|
counter replacement preserves the already committed permission identity while
|
|
allowing only its negotiated terms to change.
|
|
|
|
Generated opening and role suggestions are non-material decisions: the player
|
|
may accept, counter, discuss, or ignore them without blocking a fully custom
|
|
draft. They are UI affordances, not implicit DM memory. On daemon load, the registry demotes pre-cut payloadless questions and
|
|
generated opening records whose old `material` flags would otherwise veto a
|
|
custom draft. A payloadless question cannot own compilation readiness because
|
|
it has no typed change to accept. This migration uses an exact CultCache
|
|
replacement and does not advance the Session Zero revision or shared epoch.
|
|
Material decisions preserve the distinction between discussion and consent.
|
|
Every acceptable decision carries at least one non-empty typed contract,
|
|
character, or extraordinary-permission payload. A question or a prose promise
|
|
without an exact state change remains DM speech or a suggested reply; it cannot
|
|
render an Accept control, advance the draft through acceptance, or claim that
|
|
the promised materialization occurred. The Interpreter schema enforces the
|
|
payload before correction/retry, and the kernel rejects any legacy payloadless
|
|
decision that reaches acceptance.
|
|
The actor-filtered Eve projection shows that exact payload beside the DM's
|
|
explanation before exposing Accept. Its private character ledger projects every
|
|
player-entitled draft field, including history, secrets, knowledge, equipment,
|
|
relationships, goals, and the complete terms of extraordinary permissions.
|
|
Prose explains a bargain; the visible typed payload is the state the player is
|
|
actually consenting to.
|
|
Character patches are reversible during negotiation. Every list supports exact
|
|
removals before additions, and relationship keys support exact removal before a
|
|
replacement is installed. This permits spelling, identity, and mistaken-ledger
|
|
corrections without duplicate private subjects or transcript replay.
|
|
Accept applies only the exact typed payload currently stored in the decision.
|
|
Counter preserves that payload as an inert, visible audit and replacement
|
|
basis, records the player's text in the decision's durable channel, marks the
|
|
unresolved decision as awaiting a DM replacement, and invalidates the affected
|
|
projection epoch. `pending_counter` removes the Accept surface and makes the
|
|
retired payload uncommittable. The DM response
|
|
must produce a fresh material decision against that same channel and component
|
|
epoch; installing it and retiring the pending counter is one kernel commit.
|
|
Until then the old decision has no Accept surface and forged acceptance fails.
|
|
Inference failure, an irrelevant response, or a stale response leaves the
|
|
counter unresolved and compilation blocked.
|
|
Retry relaunches the membrane from that already persisted counter and unchanged
|
|
Session Zero snapshot. It does not ask the player to retype the counter, append
|
|
a duplicate message, or advance revision merely to try inference again; only a
|
|
later kernel-validated replacement changes state.
|
|
The countered decision ID is also part of the model snapshot binding and
|
|
permitted turn context. A deterministic Ghostlight Projector renders that one
|
|
pending decision, its retired typed payload, exact counter, and aggregate safety
|
|
policy into the Persona's narrative stream. This exact projection needs no
|
|
model call or model receipt; the focused turn records only Persona and
|
|
Interpreter inference. The Interpreter separately receives the same bounded
|
|
typed basis. When the retired proposal still has one exact typed lane, the
|
|
Interpreter emits only that replacement payload: character patch, contract
|
|
patch, or permission terms. Ghostlight binds the fresh decision ID, owner,
|
|
materiality, evidence, prompt, and persisted counter locally. Permission IDs,
|
|
actor bindings, and evidence receipts are preserved from the retired proposal
|
|
and are absent from the model's output authority. The larger union Interpreter
|
|
remains only for ordinary conversation and pre-cut payloadless migration.
|
|
Conversation history, party
|
|
cards, the contract, unrelated decisions, and unrelated private character state
|
|
are not part of the focused retry. Pre-cut decisions whose typed payload was
|
|
erased receive one bounded current-state basis for migration only. The kernel
|
|
accepts exactly one same-lane replacement with stable extraordinary-permission
|
|
identity; direct patches or unrelated decisions cannot retire the counter.
|
|
|
|
## Approval and publication
|
|
|
|
The host locks the roster before compilation. Material unresolved decisions
|
|
block compilation. The kernel also refuses a conversation-only draft: the
|
|
typed contract must identify premise, canon horizon, start, pressure, goal,
|
|
tone, pacing, consequences, narrative focus, and DM style; every active
|
|
character must have a public premise, capability, goal, and at least one
|
|
obligation or vulnerability. Group drafts additionally require a party bond.
|
|
The compiler receives an `approved_campaign_brief.v1`, not
|
|
the transcript. Private character history and secrets are withheld from world
|
|
generation; after the grounded seed validates, Ghostlight locally replaces the
|
|
provisional compiler player with the exact approved actors at one shared start.
|
|
Approved relationships cross that membrane by identity, not by free-form map
|
|
key. A relationship naming another approved player resolves to that player's
|
|
exact actor ID. An otherwise unresolved named person receives a stable,
|
|
server-generated relationship-anchor actor ID; the compiler must materialize
|
|
that exact actor and name in the seed, but it never receives the private
|
|
relationship description and may not reveal the anchor in opening narration
|
|
merely because the private ledger requires their existence. The owning player
|
|
sees the compiled subject, placement, and relationship during private review.
|
|
Their final approval therefore covers the compiler's placement without
|
|
exposing it to the table. Actors may also hold directional relationships to an
|
|
exact institution, Gestalt, or named Gestalt member. Such a relationship grants
|
|
no knowledge, resource, membership, or collective authority.
|
|
If compilation fails before a preview is installed, the roster remains locked
|
|
and the typed brief remains authoritative. A host whose current brief still
|
|
passes the readiness gate receives the Compile action again; retrying uses the
|
|
new revision and never replays or accepts transcript prose.
|
|
|
|
Evidence gaps return the draft to conversation with explicit questions. A
|
|
gap-bearing compiler result is retained as an exact non-canonical preview while
|
|
the session remains in `drafting`. The host may move that exact digest into
|
|
review, or the table may revise typed state and retire it before another
|
|
compile. Moving it to review is not approval. Every active player must approve
|
|
the current shared digest, their current private character digest, and the
|
|
exact world-preview digest containing topology, cast, institutions,
|
|
populations, clocks, evidence lanes, gaps, and branch-local assumptions.
|
|
Publication persists the approved preview digest and exact accepted gap and
|
|
assumption lists beside the campaign seed. Substituting any preview makes every
|
|
prior approval stale. Relevant edits retire the preview and invalidate the
|
|
affected approvals. The host has no override.
|
|
|
|
Pre-cut Session Zero stores used one receipt list for both meanings. Registry
|
|
load migrates that list without advancing Session Zero revision or fictional
|
|
time: all entries become audit history, while an extant world-seed preview
|
|
receives the bounded final compiler transaction from its last
|
|
`custom_retrieval_plan` through `agency_compile` as its exact proof set. Later
|
|
conversation receipts and Contract Review previews are excluded. The migration
|
|
is an atomic CultCache replacement and is idempotent on restart.
|
|
|
|
Accepted extraordinary bargains become typed permissions. Later assessment
|
|
receives their exact scope, prerequisites, costs, limits, exposure, evidence,
|
|
and effect ceiling.
|
|
|
|
## Bounded co-op
|
|
|
|
`campaign_membership.v1` binds authenticated account hashes to random member
|
|
IDs and exact actor IDs. HTTP admission derives the acting actor from this
|
|
record. Assessment confirmation includes that actor ID and cannot consume
|
|
another actor's assessment.
|
|
|
|
The first co-op mode deliberately permits one shared scene and sequential
|
|
public actions. It rejects player-versus-player state mutation, movement that
|
|
would split the party, raw unilateral waits, and unilateral resolution-budget
|
|
changes. Time, group travel, and pooled Persona-cell budget changes use
|
|
revision-bound proposals; the final approval and campaign transition commit
|
|
atomically. Group travel revalidates the shared origin and exact route, moves
|
|
every assigned actor, and advances time in one world commit.
|
|
|
|
Every human-controlled actor has a non-simulatable agency profile. Live NPC
|
|
appraisal, multiresolution cells, strategic outcomes, migration, scheduler
|
|
ticks, and away-time work all exclude those actors from Persona control and
|
|
direct mutation. Disconnection grants no proxy authority.
|
|
|
|
Each active member contributes their entitlement-provided cell allowance. Test
|
|
accounts currently contribute eight. The campaign starts at the pooled total,
|
|
capped at 240; physical provider concurrency remains independent.
|
|
|
|
## Realtime and interface
|
|
|
|
Ghostlight publishes an actor-filtered Eve surface for each Session Zero member
|
|
and campaign member. Server-sent events contain revision notifications only.
|
|
The browser refetches the authoritative Eve document after a notice; the
|
|
transport owns no messages, drafts, ledgers, approvals, or world state.
|
|
|
|
The browser exposes keyboard-operable shared/private channel tabs, live status,
|
|
public party cards, private ledgers and boundaries, unresolved decisions,
|
|
roster readiness, and explicit compile/review/approve/publish actions. The Eve
|
|
review tree visibly renders topology, non-private cast, institutions without
|
|
private goals or resources, populations, clocks, evidence-use rationales,
|
|
gaps, and branch assumptions. Relationship-anchor people remain absent from
|
|
the shared cast and appear only in their owner's private relationship card.
|
|
Privacy is labeled in text and never conveyed only by color.
|
|
The host may discard any non-canonical preview through a typed Session Zero
|
|
command and continue drafting without changing the contract, characters, or
|
|
fictional time. A retained preview never traps the table into reviewing it.
|
|
|
|
Session Zero also remains the sole owner of every human-controlled character.
|
|
The shared compiler may use player-approved public names and premises as world
|
|
context, but those names are reserved: neither ordinary cast nor Gestalt member
|
|
output may materialize them. Its singular player document is only a provisional
|
|
starting-position marker. After compilation, Ghostlight removes that marker and
|
|
installs the approved typed characters. A candidate that duplicates a reserved
|
|
player identity is corrected against the same snapshot or rejected atomically.
|
|
|
|
An approved unresolved relationship person crosses world compilation as a
|
|
server-owned identity anchor. The shared world compiler never receives that
|
|
person's name, identity handle, or relationship. After the public topology is
|
|
validated, a separate private stage receives the approved name and exact
|
|
available locations and must synthesize exactly one ordinary actor candidate.
|
|
It remains responsible for that person's location, capabilities, knowledge,
|
|
equipment, obligations, and goals, but cannot emit IDs, relationships,
|
|
narration, facts, gaps, assumptions, or public-world changes. The compiler then
|
|
attaches the opaque canonical ID locally and the approved relationship is added
|
|
only to its owner's actor. Omission, ambiguity, unknown placement, or ID
|
|
collision rejects the whole candidate. Shared output cannot leak private input
|
|
that its owning model never received.
|
|
|
|
## Inline grounded suggestions
|
|
|
|
Opening and role generation is no longer a browser-owned creation flow. On a
|
|
new draft, the compiler retrieves three distinct Vault-grounded opening
|
|
suggestions and installs them as shared typed decisions. Accepting one amends
|
|
the draft for further discussion; it does not publish a world. Ghostlight then
|
|
retrieves three grounded role suggestions and installs separate typed decisions
|
|
in each player's private channel. A custom premise uses the same conversation,
|
|
draft, approval, and compiler path.
|
|
|
|
## Contract Review
|
|
|
|
A launched campaign can enter a focused Contract Review backed by the same
|
|
Session Zero kernel and privacy projections. The review is bound to the exact
|
|
world revision at which it began. Any intervening world commit makes it stale.
|
|
Every active member approves the revised shared digest and their own character
|
|
digest before the host can publish.
|
|
|
|
Publication updates the existing campaign, contract, membership permissions,
|
|
DM Persona, approved brief, governance epoch, actors' approved forward-looking
|
|
ledger fields, event, and receipt in one CultCache batch. It cannot change
|
|
membership custody, locations, topology, knowledge, memories, historical
|
|
events, Vault, canon horizon, or established starting geometry. Tightened
|
|
private boundaries publish immediately as an anonymous strictest campaign
|
|
policy; relaxation waits for unanimous review publication. Narration, action
|
|
assessment, resolution demand, cell Projectors, Interpreters, and semantic
|
|
verification receive the approved contract and aggregate policy. Actor Personas
|
|
still receive only lived narrative, not policy schemas or attributed safety
|
|
records.
|
|
|
|
## Deferred governance
|
|
|
|
Split parties, private in-play actions, simultaneous declarations, PvP,
|
|
delegation, late joining, permanent post-publication departure, group
|
|
fork/reset/export, and voice remain unsupported.
|