The kernel extraction is finished. The world kernel is the ghostlight library crate; Dungeon consumes it across a boundary sealed by admission, proven from outside the crate. The cut map records the last two fix batches and Q1-10, defaulted: the minter scanner stays a tripwire, with Clippy recorded as the fix. The subtraction ledger missed its estimate, +210 net source lines against about +65. The reasons: the scanner grew chasing evasions, the boundary needed about 90 more public items than planned, and the rejection tests buy a ruling made after the estimate. The postmortem lists what Soul caught, the operator corrections, the incidents, and the open follow-ups. The target states which invariants hold and how. The plan, map.yaml and the handoff point at L1. The L0 evidence record is rewritten as its distilled lessons; the previous text is archived. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
4.5 KiB
Ghostlight library extraction (plan step 15, L0)
Status: closed 2026-09-16. Landed in Ghostlight 108b691..ab95d78 and
gamecult-ops 6aba281..803f2c7; the means and every Soul verdict are in
ghostlight-library-extraction-cut.md, the scars in
ghostlight-library-extraction-postmortem.md.
Reconciled with the Body. Invariant 1 holds as restated by Q1-9 and is
proven by crates/ghostlight/tests/external_admission.rs; the compile_fail
doc-tests prove "does not compile", not privacy, because stable rustc does
not enforce their error codes. Invariants 2, 4, 6 and 7 hold as written.
Invariant 3 holds for library source and tests: no Eve, Heimdall, AppSession
or player vocabulary remains. Invariant 5 holds on Windows; the Linux release
is unexercised until Idunn builds it. The open questions below were all
ruled (Q1-1 through Q1-10 in the cut map) and are kept as history.
Target
The Ghostlight library is a crate of its own. It owns the world kernel and everything consumer-neutral around it: the ontology and reducer, the journal, the mailbox, controllers and the Projector-Persona-Interpreter membrane, elaboration and seeding, the cover, the clock, inference ports, evidence sources, and consumer patch admission. Ghostlight Dungeon is a crate that consumes it: the daemon binary, HTTP routes, Eve projection, Heimdall and app sessions, CultMesh publication, and Idunn health.
After the cut, "Dungeon cannot reach kernel internals" is a compile error, not
a pub(crate) convention.
Invariants that must survive
-
Sealed kernel at the crate boundary. The library's public API exposes create/open, immutable snapshots, command submission, typed receipts, and the runner and port entry points Dungeon needs. It exposes no mutable
WorldState, canonical ID allocator, reducer entry, journal writer, or authenticated-caller constructor. Negative proofs are compile-fail tests from outside the library.Sealing means unforgeable admission, not unconstructible values (operator ruling Q1-9, 2026-09-16). Public ID types,
ScopeDigestandDecisionOpportunityderiveDeserializebecause Dungeon's own Eve payloads carry them, so any caller can build a syntactically valid one. The kernel must reject every one it did not issue, and rejection tests written from outside the crate are the proof. A compile-fail test pins a path name and cannot see constructibility: adding aDefaultimpl that mints an ID left all ten green. -
No behavior change. Every existing test passes unchanged in meaning. No schema string, command id namespace, digest preimage, or store layout changes: a
world.ccand controller work store written before the cut open and replay after it. -
No Dungeon concept in the library. No Dungeon type, route, Eve or Heimdall type, HTTP framework, or principal format enters the library. The principal evidence the kernel needs crosses as a library-owned type that Dungeon constructs from its own sessions.
-
Dependencies follow ownership. The library does not depend on axum, tower-http, jsonwebtoken, or the Heimdall and Eve surfaces. Dungeon depends on the library, never the reverse.
-
The release path keeps working. The
ghostlight-dungeonbinary name, its--state-rootcontract, and the Idunn recipe's build and test invocations still resolve, or are updated in the same cut with their owners. -
Existing pins are unaffected. Epiphany's pin of
ghostlight-persona-projectionby revision still resolves. -
Build fan-out stays bounded. One new library crate, no new binary, no new feature matrix beyond what test support strictly needs.
Out of scope
- Every library capability of plan step 15 L1–L4: lenses, detail rules, evidence binding, Draft sessions. L0 moves code; it adds no behavior.
- Renaming schemas, stores, or wire documents.
- Changing how external consumers reach the library over the network. The consumer patch HTTP route stays in Dungeon for now.
- Deployment cutover (the deployment gate).
Open questions for Imagination to bring back
- The library crate's name.
- Whether
vault.rs(markdown evidence source) andsdk_inference.rs(Claude SDK port) belong in the library, as consumer-neutral adapters, or in Dungeon. - The seam for principal evidence (
app_session::VerifiedPrincipalEvidence). - How test fixtures that span the boundary are shared without making sealed constructors public.
- Whether
ghostlight-persona-projectionstays a separate crate or folds into the library.