Ghostlight/state/evidence.jsonl
Meta Vens 5d3f296747 Record the pass close-out in evidence and drop the compaction scratch
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-23 11:54:16 +02:00

25 lines
34 KiB
JSON

{"note": "Delvehold boundary, merged from four records of 2026-08-26. Delvehold is the first proving consumer of Ghostlight's generic world-simulation API, not an integration organ; adversarial single-player Dungeon play remains a regression and context-discovery path. Ghostlight adds only generic capability: one seed admission path shared by produced and consumer seeds, generic externally owned subject authority that admits institution and population-scale subjects through one tagged projection, consumer-supplied effect schemas, and typed proposals and receipts. Delvehold retains quantitative economy authority (quantities, prices, recipes, capacity, inventories, orders, contracts, conservation); Ghostlight resource handles never impersonate them. A forced ontology may bypass world generation but never kernel validation. The greathold ID and every delvehold.* binding stay Delvehold-owned; no cell or kernel switches on a consumer name. The legacy implementation those records described (WorldSeed transaction, ExternalSubjectAuthority, loopback RUDP operations) was torn down; the live implementation is the pass-10 confined consumer ingress in docs/architecture/ghostlight-world-consumer-api.md.", "status": "accepted", "ts": "2026-08-26T17:12:55+00:00", "type": "architecture"}
{"note": "Standing pre-rebuild decisions, merged from seven records dated 2026-05-02 to 2026-08-29; map.yaml hard_boundaries and mission own the binding text. (1) VoidBot appraisal: appraiser and relationship/perception training must support human-facing reads, grounded opinions, uncertainty, repair signals, and opinion updates over repeated contact, not only fictional scene mutation. (2) Generated environment images are concept and material reference only; multi-angle or branch-consistent replay needs a durable scene-set source with named cameras and staging slots. (3) Coordinator turns are a sandboxed promptable organ with exact visible input, raw output, and labeled interventions; the meta-coordinator never collapses them into omniscient chat steering. (4) Character cognition is modeled state: the machinery is maximally smart, characters reason and maneuver only to the level their modeled state supports, and narrator prose may explain tactics for the reader without granting that explanation to characters. (5) ghostlight.agent_state.v0 is the shared cross-runtime payload contract, carried unchanged inside typed CultNet envelopes. (6) Multiplayer extends the one-WorldKernel, many-actor authority model: humans control distinct canonical actors through the same commit path, with no party prompt or room-state authority. (7) A newspaper is a persistent political/editorial Persona owning audience, remembered beats, framing, selective pickup, throughlines, and rivals; grounding constrains factual assertion and provenance while preserving legible interpretation; only the economic layer supplies advertisers.", "status": "accepted", "ts": "2026-08-29T05:15:35+00:00", "type": "architecture"}
{"note": "Sealing the replacement kernel, 2026-09-01, four records merged; git owns the commits (b53251f, d49b907, 12ee9f4, 66ed2ec). The first uncommitted world.rs foundation passed its focused tests and was deleted anyway: it exposed mutable WorldState and ID issuance, let translation-gap inference become canonical mutation, let empty batches advance revision, left controller commands without consumed opportunity, readiness, and affordance binding, and made batch self-digests unverifiable. The rule that came out of it: seal private WorldKernel, aggregate, and journal ownership first, then reintroduce a minimal reducer behind it; never publish mutable world types or an ID issuer for test or adapter convenience. The Persona interpretation contract is structurally total: source prose is immutable noncanonical evidence bound to typed receipts, only exact typed captures propose state, actual quoted dialogue is required for speech, malformed spans and step exhaustion become whole-source gaps, and infrastructure interruption returns the source pending. Legacy ingresses were deleted without a compatibility writer.", "status": "ok", "ts": "2026-09-01T17:40:32+00:00", "type": "implementation"}
{"note": "Deployment authority, merged from a four-record supersession chain, 2026-09-02 to 2026-09-03; map.yaml live_architecture.deployment_authority owns the full current rule. The read-only cutover audit found the old Idunn path structurally unfit: source, ref, and floor policy duplicated across compiled Rust, raw executable command records, a privileged shell dispatcher, and gamecult-ops target programs; root Git unable to inspect idunn-owned mirrors; world-v2 purity checks ignoring most legacy state; fixed-port activation stopping the incumbent before the candidate was green. Adopted: target-owned visible recipes with constrained launch declarations (raw unit and container templates rejected; the operator-selected workload driver lowers them), Idunn-configured refs, runner, and host bindings, Git and recipe materialization as the Idunn identity, Expected published by plan, service-signed Present, a process write lease before writable state, Odin-derived Ready, route membership only after Ready, and deployment separate from continuity. The owner is exactly DeploymentCommand, DeploymentTransaction, and AdmittedGeneration with nine persisted phases before effects (Odin 65cf2b2; contracts on CultLib 85f7024; provider sides Ghostlight 6a79cb0 and CodexConnector ede3c30). Live admission remains absent. The Nginx route receipt proves configuration plus nginx -T visibility only, so an independently persisted data-plane observation is required before fence clearance, drain, or cutover acceptance. Do not issue the old Connector or Ghostlight redeploy helpers.", "status": "accepted", "ts": "2026-09-03T06:13:20+00:00", "type": "research"}
{"note": "Core-stack consolidation, merged from ten records, 2026-09-03 to 2026-09-04. CultLib is the canonical home for CultCache, CultNet, and CultMesh across every runtime because wire-parity conformance lives only there; Ghostlight consumes all three by pinned rev 85f7024 (d0510ac), a permanent ancestor of CultLib main, and its vendored fork charter is deleted. Resolution key for older records: CultNet e542225 and f4ab237 and Odin d527d72 and 65cf2b2 were never on their repos' main branches; their content is on CultLib 85f7024 and Odin branch codex/ygg-idunn-independent-bootstrap, ported forward rather than merged, so those SHAs are dated history and GameCult/cultnet-rs may be retired. A whole-file symbol comparison, not a diff of recent changes, found four real capabilities in the forks (reliable send expiry owned by the transport profile, snapshot and per-entry compare-exchange, a framed-length check before allocation), all ported with tests; every other fork under F:/Projects held reach rather than divergence, and each consumer pinning a different branch was the combinatorial reason separate repos failed. CultLib main landed by fast-forward at 8cb3b72, so every consumer pin (Ghostlight 85f7024, Epiphany and CodexConnector e171eca, Odin cbde940) resolves from a fresh clone; a squash would have orphaned all of them. Odin eedce4f consumes CultLib, its recipe no longer requires gitlinks, and gamecult-ops 8f7ae2a drops the phantom gitlinks Idunn would have refused; odin-daemon reads systemd file descriptors and compiles only on Linux. Non-Rust forks persist for distribution, not divergence: npm and pip cannot consume a package from a git subdirectory, so CultLib 8cb3b72 adds tag-triggered publishing (@gamecult/cultcache-ts, cultcache-py on PyPI, MIT confirmed by the operator). Ghostlight keeps vendor/cultcache-py on sys.path deliberately so the state tooling runs from a bare clone; replacing it means session bootstrap must install.", "status": "accepted", "ts": "2026-09-04T13:17:04+00:00", "type": "architecture"}
{"note": "Why the whole-machine rebuild, merged from three records, 2026-09-01 to 2026-09-04. Run 108 inspection: 2,400 active leaves across five realms with strong authored crisis theater, but repeated fission substituted taxonomy for novelty (557 other-unknown records, 780 residual, inherited identical goals, eight distinct Actors named Mara Venn); counting active leaves measured nothing about world shape. Run 115 terminated at revision 2, regions 2/8, waves 0/1, after an SSE timeout and a dangling institution location exhausted four reconciliation steps; the qualification, verifier, reconciliation, timeout, and routing patch sequence through 8964a92 never established ownership, and the operator ordered one WorldKernel, one typed reducer, one CommandEnvelope/CultCache commit path. The root cause was vocabulary-shaped, not model-shaped: caller-supplied string SubjectRefs, two-phase entity admission, and a flat mutation list made a dangling reference a runtime discovery rather than an unrepresentable input, and depth lived in free strings, so the model tribunals (WorldComplexity qualification and verification, the titled semantic verifier that judged whether a proposal satisfied its titled assignment, and fixed titled quotas) were compensators for an ontology with nowhere to hold depth. The eight titles themselves were lenses, not tribunals; see the 2026-09-15 correction. Adopted cut: reducer-issued typed ID namespaces, draft handles resolved inside one closed WorldPatch before any ID allocates, twelve decision-constraining components, and elaboration that answers a derived CausalBoundary instead of running waves and quotas. Counts, cover ratios, interest, and diversity are evaluation evidence, never admission or completeness authority. Run 115's root at /var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-0a83034-115 and invocation d9254cd9b77946aebcf7a7fdae821402 stay immutable; do not resume it.", "status": "accepted", "ts": "2026-09-04T13:39:08+00:00", "type": "research"}
{"note": "Ontology v2 decisions and the scale directive, 2026-09-04, two records merged; docs/architecture/ghostlight-world-ontology.md owns the vocabulary. Elaboration and character action lower under one WorldPatch and one deterministic verifier. Affordances are world-authored data (preconditions, effect slots, weighted outcome bands) over a closed operation set, so genre lives in the seed and the kernel never learns one; uncertainty resolves by kernel entropy seeded from world, revision, and command, so no model ever chooses success; proposals bind to a scope digest of the components their verification reads rather than the whole state digest, so many subjects and elaborators do not serialize on one revision. Elaborator tools are a derived projection of the operation set and cannot drift. Operator correction, preserve in intent: the 2,400-subject / 240-cell / 10% cover profile is deliberate design, not a load fixture; a world feels alive only when actors at every level pursue their own goals, so that detail is generated first and multiresolution simulation is then choked so attention is scarce and selection is forced. The seed carries a WorldScaleIntent whose structurally counted deficit (an active subject with one controller, one Goal commitment, one affordance) the elaborators pursue after boundaries; a budgeted connected cover runs every tick with singleton detail cells and grouped coarse cells. Deleted for good: gestalt as canonical identity, arena knowledge union, semantic qualification and verification models, fission quotas as mutation, string identifiers.", "status": "accepted", "ts": "2026-09-04T14:14:10+00:00", "type": "research"}
{"note": "Codex CLI fan-out cannot commit. A linked git worktree fails because its .git file points outside the sandbox's writable roots, and a full clone fails too: the Codex workspace-write sandbox keeps .git read-only even under the writable root, so a Codex worker can never commit or push regardless of clone layout or network grant. Rule for any Codex fan-out that must produce committed work: the worker writes files only; a supervisor outside the sandbox commits and pushes the clone after the worker exits. The elaborator scheduler (C:/Users/Meta/.claude/worlds) does this per slot to slot/<world>/<title>/<stamp> branches in the Ghostlight world clone and the lore clone; integration into codex/world-<world> and codex/ghostlight-worlds is a separate deliberate pass, still owed. Clones live at F:/Projects/Ghostlight-worlds/<world> and F:/Projects/<Lore>-worktrees/ghostlight-worlds (full clones despite the name).", "status": "ok", "ts": "2026-09-04T15:04:24+00:00", "type": "verification"}
{"note": "Plan step 6, the ontology widening, is complete: ten passes landed on codex/ghostlight-dungeon-mvp, 2026-09-04 to 2026-09-05, each a Hands cut in an isolation worktree, a Soul falsification in the same tree, and a gated integration (pass tips are in git history and the handoff). The kernel holds twelve decision-constraining component kinds over a pinned operation catalog under one WorldPatch, one reducer, one CAS commit, one decode bound for both authoring lanes, and three confined SystemCapability arms (Clock, Elaborator, Consumer). Soul's series verdict: the eleven plan invariants hold structurally (one reducer and atomic commit; kernel-derived authority; one controller per scope with no fallback or double action; total interpretation with exact gaps; deterministic structural rejection without a model verifier; scoped knowledge until explicit communication; external-consumer sovereignty; sparse causal sufficiency with counts as evidence only; restart reconstructs the exact world; IDs allocated only inside an admitted reduction; opportunities bound to a scope digest rather than a revision); the pairing invariant is re-decided at three gates by doctrine, not by a repair loop. The budgeted cover verified 22 ticks at the 2,400/240 profile with fairness ceil(N/R), R being cells minus urgency slots. Two decisions stay with the operator and are recorded nowhere else durable: whether a refused coupled constituent may re-submit once inside the same tick, decided with the submitted-versus-committed number in hand; and the authority for an owner-only Eve world.run_tick command.", "status": "ok", "ts": "2026-09-05T02:13:22+00:00", "type": "implementation"}
{"note": "The rebuilt kernel runs on the road, 2026-09-05; runbook notes/local-live-smoke.md. Genesis smoke: tick driver, cover, Persona membrane, operational lane, clock, and elaboration sweep ran three ticks against a real CodexConnector; the road worked and the prose was thin because genesis is three subjects in one room, which made the seed producer an evidenced gap rather than an argued one. Seeded smoke: from the Kalsa Public vault one seed session authored six qualified persons into Low Sere in one round, deficit 6 to 0, and three ticks of eight singleton cells had the seeded people speaking to each other by name. Twelve runs were needed; every failure was on the road, not in the kernel, and each is now a rule in the tree: one credential family (the operator's real codex home), strict schemas (anyOf, typed tags, an offline totality test over both lanes), a Persona model the account supports, connector expiry skew below the response timeout, canonical ids printed beside labels, a seed round budget with parallel calls and budget-end submit, content-addressed provider request ids, the commitment shape rule in the tool description, and the placement rule. The harness fails on an empty seed or a silent world. The Codex subscription lapsed during this series and the runs consumed half the monthly free quota; no Codex road run is possible until it is renewed.", "status": "ok", "ts": "2026-09-05T17:36:41+00:00", "type": "verification"}
{"note": "Claude SDK inference port, plan step 11, 2026-09-06, two records merged. Research: the Agent SDK's system prompt is fully replaceable, built-ins strippable, CLAUDE.md loading stoppable, and assistant tool_use blocks come back verbatim with usage; but there is no silent capture, no replayable input list, no request id, and each query is one subprocess. Rejected: a Messages-API backend (no API budget) and a backend inside CodexConnector (a deliberately isolated Codex fork; nothing goes into it). Landed: a second InferencePort over a Node sidecar, routed per lane by model prefix, execute-through: the sidecar computes no tool result and Rust answers every call through a per-lane ToolResultOracle that is the evaluator's own fold, so divergence is impossible by construction; both ports share one prepare_invocation. Lesson that changes how any future transport is judged: a transport-side validator is a second semantics. The SDK's Zod layer stripped unknown keys and refused missing fields before the handler ran, so a claude lane silently admitted what the connector refused; the fix is one validator on both transports, the Rust decoder, with the sidecar handing arguments through unvalidated. Residual liability: a wrong-typed property reaches Rust as absent. The receipt is the SDK message, a named stopgap; the exit is a Messages-API port when API budget exists, deleting the sidecar whole. Not yet run on the road: the operator must install the Claude Code CLI and log in first; Ghostlight never holds the credential.", "status": "ok", "ts": "2026-09-06T00:35:37+00:00", "type": "implementation"}
{"note": "Evidence ledger distilled 2026-09-06: 44 records to 12. Supersession chains collapsed to their survivors, per-commit implementation receipts folded into the decision they served, and the pre-rebuild standing decisions merged into one record because map.yaml owns their binding text. Every removed record is appended verbatim to state/evidence.archive.jsonl. The compaction ran through tools/ghostlight_state.py compact-evidence, now the one durable path: evidence.jsonl is a regenerated export, so a store-only replacement is the only deletion that sticks.", "status": "ok", "ts": "2026-09-06T13:03:22+00:00", "type": "maintenance"}
{"note": "First SDK-backed seeded road runs, 2026-09-10 (936aa71, 4f7513b; runbook \"SDK runs, 2026-09-10\"; plan \"Road follow-ups\"). Transport verified: every lane on claude-sonnet-5 through the Node sidecar, no connector bound, seed sessions and ticks committed end to end (run 2: revision 3 to 24; run 3: revision 3 to 15, no quarantine). Belief-changing findings: (1) the sidecar's schema conversion dropped every field description, so the claude lane authored against bare types; descriptions now carry through. (2) The model wrote twelve commitments due at or before a clock it was never shown; due now describes itself as a clock reading and both authoring prompts print the clock. (3) A kernel refusal now continues the same authoring conversation (Refusal rows, controller_work.v12, prior rows refused not migrated) instead of a fresh-draft repair whose sites named a draft the model could not see. (4) Interpreter speak and record_gap cite prose by quote (source_quote) and the harness derives the span; model-counted byte offsets cut three of eight utterances mid-word, and run 3 shows every utterance whole. (5) The tick-3 quarantine in run 2 was a mis-spanned utterance failing the canonical-text rule: a translation gap, not an infrastructure fault; a bad quote is now a gap at capture. (6) Cost shape: singleton cells run in sequence at 15 to 50 s each on this lane, so a nine-cell tick is 2 to 8 min. Still owed: the live interrupted cell and its log line.", "status": "ok", "ts": "2026-09-10T22:06:08+00:00", "type": "verification"}
{"note": "The membrane read end to end, 2026-09-11 (runs 4 to 6 of the SDK route, traced with GHOSTLIGHT_SMOKE_TRACE; plan 'Proposed step 12'). Findings that change belief: (1) The Projector context carried a name, a clock, and permission to speak, none of the life the seed authored; it now renders the subject's own state by label, never by id, and a seeded person went from saying 'hello' to speaking about its debt. (2) The pathos in run 5 was the model's default voice, not the character's: the prompts asked for what the person remembers, wants, and fears with no component to ground it, violating the hard boundary that character intelligence is modeled state. Flattened prompts render only what the context carries; run 6 is correctly silent. (3) A Commitment carries no statement of what is promised, so due 1000 read as money and due 20160 as fourteen days; due now renders as minutes from now, and the statement is proposed step 12. (4) PersonaMaterial is named in the ontology doc as a component with a set operation and exists nowhere in the kernel; the seed can only author identical people. (5) The Projector says 'no one before me' for two people in one house: own place is carried, co-presence is not. (6) The Interpreter, given quoted-speech capture, records honest gaps that double as a survey of missing primitives: posture, private priority, provisional belief.", "status": "ok", "ts": "2026-09-10T23:31:00+00:00", "type": "verification"}
{"note": "Plan step 12 on the road, 2026-09-11 (c31f254, a9d6a1c; runs 7 and 8; runbook 'SDK runs'). PersonaMaterial (values, voice, memories, reads) is the thirteenth component, a Commitment carries a required statement, the Projector sees who else stands in its place, and the Persona identity is label, voice, values; material is outside every scope digest by test. Run 8: six seeded people with six voices, 43 speech captures to 9 gaps across two ticks (run 5 was 3 to 25), and the lines reference each other's promises by content. Beliefs that changed: (1) with a vocabulary for meaning, the seed lane authors real people unprompted by anything but the tool and one sentence of instruction; (2) run 7 lost the best patch yet to an undescribed variant field and a tool result that said only 'recorded as a gap', so every decode failure now returns its reason to the model and the controller variant describes its shapes; (3) the SDK transport takes one user prompt, so a refusal continuation must ride in the transcript, and now does; (4) the world title and brief are authored facts the machine lacks: 'Cover Tick Fixture' and the brief's boundary language leaked into a vow, so world_create.v3 is the next cut.", "status": "ok", "ts": "2026-09-11T00:35:37+00:00", "type": "verification"}
{"note": "Plan step 13, the world brief, on the road 2026-09-11 (d4d7bc3; run 9). world_create.v3 carries a required brief, trimmed at ingress, held on WorldState and its snapshot, replayed identically, and projected as the guidance of every lane and both authoring prompts; the narrative stages that rebuild prompts on resume carry it (controller_work.v13). Belief that changed: guidance is world truth, not a prompt constant. With an empty slot every lane reasoned about a world named Cover Tick Fixture and run 8 put that name into a vow; with the brief, run 9's trace holds no fixture name, its promises are about hearths, ration boards, and the kiln, and its people speak in the world's terms. The smoke titles its world by the seed root label and gives its brief to the world once, not to each seed session. Speak-to-gap ratio moved from 43:9 (run 8) to 20:24 (run 9) on the same prompts: that is sampling, not a regression, and the runbook records both.", "status": "ok", "ts": "2026-09-11T01:13:50+00:00", "type": "verification"}
{"note": "Plan step 14 landed and proven by SDK run 10 (2026-09-11): a visible act is a display, speech's twin. The kernel lowers an invocation's display beside its utterance into AssertClaim plus Display, landing Seen { by } on the co-located only, never over a channel; a display alone on the speak entry is an address, not SpeechRequired; the Interpreter quotes the visible clause alone by a display tool, one per turn. Run 10: 29 speak, 18 display, 10 gaps, every gap private reasoning, no quarantine; the first live interrupted cell re-lowered Maro's prose against Sera's line as said and her act as seen. Belief change: a false binary (record intent vs record posture) resolved by the display, the public act at the grain a witness perceives it; intent stays a gap on purpose. Follow-ups, not rules: verbatim-substring quoting admits fragments (I don't, Nod); one display per turn drops a turn's second and third acts to ambiguity gaps; the harness emits no per-cell interrupted line, which is the remaining half of item (a).", "status": "ok", "ts": "2026-09-11T11:32:03+00:00", "type": "verification"}
{"note": "Item (a) closed 2026-09-11: the interrupted cell is exercised live and reported. Commit 81a1f53 reads the bound and renewed scope digests from the committed turn's own receipt (NarrativeDecision::re_lowering), carries them on the cover tick summary, logs one tracing line per re-lowered cell, and the smoke harness prints one 'interrupted cell subject= bound= renewed=' line per cell after the tick line. SDK run 11 passed (27 speak, 24 display, 14 gaps) with three interrupted cells, three lines, three re-lowerings in the trace, and each act once in the operator feed. Belief: the runbook's three conditions for this section hold on a live provider; the record and the receipt cannot disagree because the line is derived from the receipt.", "status": "ok", "ts": "2026-09-11T12:11:53+00:00", "type": "verification"}
{"note": "Fragment fault diagnosed and cut 2026-09-11 (commit 855727f, controller_work.v15): the Interpreter was citing correctly (So, then the rest of the sentence; four visible acts as four calls) and the fold was discarding everything after the first span per kind as ambiguity gaps. A turn's utterance and display are now every span cited for them, joined in prose order; only an overlapping span is an ambiguity. SDK run 12 passed: 39 speak, 6 display, 10 gaps, zero overlap gaps, every cited span landed, two interrupted cells reported. Belief: when a capture looks fragmentary, check what the harness dropped before what the model quoted. Seed lane note: run 12 round 1 was rejected because the seed model wrote kind for type and omitted the over tag against an explicit schema, then narrated tool bugs; round 2 committed. Sampling, not a schema fault.", "status": "ok", "ts": "2026-09-11T12:34:04+00:00", "type": "verification"}
{"note": "The titled elaborators were never an operator-approved cut, 2026-09-15. Patina, Charter, Ledger, Hearth, Tangle, Veil, Ember, and Numen fell in three steps: 4aebe17 (2026-09-01) listed titled elaborator quotas for deletion under the operator's whole-machine order; 6bb6869 deleted elaboration.rs and the titles with it; 9c662bd (2026-09-04) classed ElaboratorTitle as a model tribunal and reused 'eight elaborators' for per-jurisdiction loop instances without flagging the change. No record holds operator approval of the titles' removal. The tribunal was the titled semantic verifier and the fixed quotas, not the title: the Run 108 inspection called the titles excellent distinct lanes, and the 2026-09-04 elaborator swarm kept them. Operator direction: titles return as lenses over the typed ontology. A swarm of elaborators draws a title per session by the world's weights (world data, which Dungeon's Session Zero lets the player set); any title may add any structure, the title shapes what kind, and the weights set the world's flavor. No title gates admission, holds authority, or fills a quota. Landed as L1; target docs/architecture/ghostlight-stock-lenses.md. Lesson: when cutting a compensator, separate the judging machinery from the capability it judged, and put a named, operator-visible feature before the operator before deleting it.", "status": "accepted", "ts": "2026-09-15T20:31:32+00:00", "type": "correction"}
{"note": "Library and consumer boundary, merged from two records, 2026-09-15. Ghostlight Dungeon is a consumer of the Ghostlight library, which serves all GameCult narrative simulation. Session Zero, Vault choice, players, sliders, and starting locations are Dungeon authority and never shape the library. Operator decisions: (1) extract the world kernel into a library crate before any library pass (executed as L0; see the L0 record). (2) The eight titles ship as the library's stock lens set. (3) Each world will carry a typed detail rule (plan step 15 L3, not landed), a function from place to detail level that the library evaluates; consumers choose the rule (Dungeon ByDistance anchored on important subjects, the player first; Delvehold Uniform). It must be typed data, not consumer code, because the deficit it produces is an admission input and journal replay re-runs reduce. WorldScaleIntent per-kind targets remain the ceiling the rule distributes. Lesson: name the owner, library or consumer, before designing a feature; a player-facing flow placed on the kernel quietly makes one consumer's policy library vocabulary.", "status": "accepted", "ts": "2026-09-15T20:55:07+00:00", "type": "architecture"}
{"note": "L0 closed, 2026-09-16 (Ghostlight 108b691..ab95d78, gamecult-ops 6aba281..803f2c7; postmortem docs/architecture/ghostlight-library-extraction-postmortem.md). The world kernel is the ghostlight library crate and ghostlight-dungeon consumes it. Belief-changing findings: (1) private constructors do not seal a public type that derives Deserialize, and Dungeon's Eve payloads need those derives, so ruling Q1-9 defines sealing as unforgeable admission: external code may hold a syntactically valid ID, digest or opportunity, and the kernel rejects every one it did not issue, proven by crates/ghostlight/tests/external_admission.rs. (2) compile_fail doc-tests pin names and, on stable rustc, not even error codes; they prove 'does not compile', not privacy. (3) Rejection tests need forgeries shaped like real values: short fake digests passed against kernels comparing only length, a prefix, all but the last character, case-insensitively, or only the hex after the label. (4) Every text scanner written in L0 lost to a short evasion (the minter count, the gamecult-ops wiring test and its fix); treat such checks as tripwires with stated limits, and use a semantic tool for semantic properties. The minter scanner stays as a tripwire (Q1-10 defaulted); Clippy disallowed-methods is the recorded fix.", "status": "accepted", "ts": "2026-09-16T00:27:09+00:00", "type": "architecture"}
{"note": "L1 closed, 2026-09-16 (Ghostlight 835ea4d..872ba35 plus Cut 5 docs; postmortem docs/architecture/ghostlight-stock-lenses-postmortem.md). The ghostlight library ships eight stock lenses; lens weights are world data (consumer.v5), required at creation with no library default, replaced by the owner's SetLensWeights in any phase; a set that draws the same as the current one is refused as NoCanonicalChange. Each elaborator session draws its lens replayably from world id and command id and records the lens and its instruction text on the session (controller_work.v16); the lens never enters the command id, which stays the idempotency key. Belief-changing findings: (1) before L1 the elaborator repair loop never worked across sweeps: a deficit session's key moved on any commit (orphan plus repeated inference) and a boundary session was Superseded forever after any commit; resume now reads in-flight rows from the store by what they answer (L1-Q9), and rows ready to submit are excluded because adopting a committed row stalls the deficit (L1-Q10). (2) Concurrent sessions are distinct through a per-sweep in-memory claim set; elaboration has its own permit ceiling separate from the simulation budget. (3) A panicking session task used to kill the runtime elaboration driver silently; it is now an error returned after siblings finish. (4) Agents told to wait for long jobs still ended their turns mid-build until briefs named the mechanism: block inside a tool call. Open for the operator: L1.f1 quarantine handling, L1.f13 seed-lane orphans, L1.f14 row retirement, L1.f16 consumer lens sets.", "status": "accepted", "ts": "2026-09-16T18:08:25+00:00", "type": "architecture"}
{"note": "Playtest gate redirected, 2026-09-22 (operator; target docs/architecture/ghostlight-play-agent.md, plan step 16). (1) The controller machinery (cover, grouped cells, action catalogs, Interpreter pass, owner-click dispatch) suits offline generation and simulation, not interactive role-play; on Dungeon's play path one operational play agent replaces it and the library keeps it. (2) Projector -> Persona is unchanged and a Persona never sees structured state; the player's view is rendered by the same Projector. Rejected: Personas reading their own state, the structured-state dump the projector/interpreter sandwich prevents. (3) The agent holds a named kernel authority (declare in Active without answering elaboration demand, whole-world reach, advance time); an actor's act commits only through that actor's affordance; raw ops are the agent's rulings; the agent is Dungeon's detail demand. (4) L2-L4, Session Zero D1-D3, L1.f16/f1/f13/f14 deferred by ruling, not dropped. (5) Source check: inference routes per lane by model name to the SDK sidecar (prefix claude) or CodexConnector, no runtime fallback, no local-model transport; the sidecar is a private msgpack child-process pipe behind InferencePort, not the CultNet connector API.", "status": "accepted", "ts": "2026-09-21T22:53:11+00:00", "type": "architecture"}
{"ts": "2026-09-23T09:54:03+00:00", "type": "implementation", "status": "ok", "note": "Play agent pass closed 2026-09-23: 17 cuts, ~10 fix batches, 195 findings, Soul verdict \"bar met\". Ghostlight Dungeon now runs on one operational agent through world.play; world.speak and the story card are deleted. Postmortem: docs/architecture/ghostlight-play-agent-postmortem.md. About 150 of 195 findings were introduced by the pass own earlier steps, not inherited. One defect shape recurred five times: a true statement about a narrow mechanism standing in for a false one about the whole path (a committed file exists therefore the client works; git exited zero therefore this is a checkout; cargo printed ok therefore the fixture is live). The Eve client round trip had never been exercised before this pass and no client could ever have created a world. Unproven: seeding past its config check, and any model behind the local inference port. Not built and gating a wider share: fiction-first risk resolution and gestalt agency."}