Skip to content

ADR-0064: Persistent record store: the world-consequence durable path

the same sanctioned-outcome boundary), ADR-0049 (dossier-commit is no longer the sole durable write), ADR-0043 (objective resolution gains a record-write outcome type), ADR-0055 (the settlement pass may apply planted records), ADR-0051 (world_generate consults the durable store where a region overlaps it), ADR-0056 (the store lives in its own file outside the UDS, per the Decision-7 DOSSIER precedent) Related: ../software/runtime/persistent-record-store.md (the design note this ADR ratifies; the detailed companion), ../software/cartridges/modules/cloneshop.md (the Tier 1 treatment the store serves), ADR-0057 (the 2026-08-22 two-route capstone amendment), ADR-0061 (deck-state gate values; the append-and-migrate persistence discipline), ADR-0005 (NoshAPI; unchanged by this ADR), ADR-0011 / ADR-0019 (the storage medium: the device microSD and its partition layout), ADR-0063 (the breach-target designation), ../software/runtime/world-engine.md, ../software/programs/enrichment-contract.md, ../software/runtime/economy-model.md, ../software/runtime/aethernet.md, ../software/programs/dossier.md

CLONESHOP’s treatment turns the intrusion loop inward. The operator breaks into the system that holds employment or housing records and leaves a row behind; from then on the registry answers when queried. The row must outlive the mission that planted it, and the screening that pays the cart off happens missions later, across cart swaps and power cycles. The platform forbids this today: world-engine.md invariant 3 rules the mission world-region run-state with dossier-commit as the sole durable consequence of play, and enrichment-contract.md §4/§6 state the same single path. DOSSIER holds what the operator knows. No store holds what the operator changed.

Josh settled the storage model in the 2026-08-22 design session. The design note persistent-record-store.md records the decisions in detail and remains the detailed companion; this ADR ratifies them: the store, the second sanctioned durable path that writes it, the observation rule that bounds it, the provenance shape, the read surface, and the storage home.

The decision below rests on three facts checked in the runtime source:

  1. There is no single world seed to persist. mission_board.c draws a fresh policy seed per generation pass (g_gen_pending_seed) and parks it on each minted instance as narrative_seed; accepting a contract publishes it as the MISSION_ACCEPTED payload’s world_seed (per ADR-0051). Seeds are per-contract, and the deck holds no seed registry.
  2. The region that produced a row is replaced at the next accept. mission_world.c resets the prior mission region at the mission-instance boundary (on_mission_accepted calls world_region_reset before world_generate(seed, arch, WORLD_CLASS_LIVE), folding in the contract id when the seed is unset). A bare seed cannot re-derive a row once its region is gone; provenance has to ride the record.
  3. WorldRegion carries no durable field. The region (runtime/src/world_engine.h) is process-global run-state: seed, archetype, a generation counter for the :invalid-world guard, the node array, the clock counters, and the breach-target address the intrusion carts read. That last field shipped with GWP-807 as WorldRegion.target, engine-set by world_designate_target and read through the (world-target w) accessor, per ADR-0063. Every one of these is run-state: target is re-designated on each contract accept and dies with the region, so it is no more durable than the seed. Nothing in the region survives a region reset, which is why provenance has to ride the record rather than the world.

The platform gains a single durable, tag-filtered record store. A record is one row attached to a world-entity identity. A “system” (a company HR host, a housing registry, a tax mirror) is a tag on a record; the engine simulates no separate per-system databases. Cross-system corroboration is a filter-and-compare over the one table. There is one store for the whole platform; a cart that needs durable world records uses this store or has none.

2. Engine-applied record writes are the second sanctioned durable path

Section titled “2. Engine-applied record writes are the second sanctioned durable path”

Records are written through the engine’s mission-outcome path, the ADR-0043 / ADR-0055 pattern: the cart reports a goal, and the engine applies the outcome to its own store at mission resolution. A planted record is such an outcome. No cart or program write path exists at any tier, and none is added later without superseding this decision.

The durable-consequence set is now two sanctioned engine paths:

  • dossier-commit: the operator-knowledge durable path (unchanged; ADR-0049 N4/N6). What the operator learned.
  • Engine-applied record writes: the world-consequence durable path (this ADR). What the operator changed.

The two-path model replaces the single-path invariant. world-engine.md invariant 3, enrichment-contract.md §4/§6, and ADR-0049 N4’s sole-durable-write clause are widened in the same PR that lands this ADR. The program- and cart-reachable durable surface is unchanged: dossier-commit remains the one durable verb any Lisp tier can invoke, and the wallet writer set is untouched (ADR-0055).

The store persists two things and nothing else:

  1. Records the operator planted: the record of the operator’s interference.
  2. References to records the operator saw: captured as DOSSIER facts holding entity references; the content is re-derivable from the reference’s provenance.

There is no separate seed registry: each row carries its own generation inputs inside the Decision 4 provenance triple, because seeds are per contract instance (verified fact 2) and no single world seed exists to persist. The world is definite only where someone has looked. A region no operator has touched regenerates identical from its generation inputs, per the World Engine’s determinism rule.

Mission worlds stay ephemeral run-state: one region per mission, reset at the mission-instance boundary, as today. Where a region overlaps the store (an entity a persisted row is attached to), the region references the store. This obligates world_generate to consult the durable store during generation, so a persisted row overlays the regenerated content at its entity address; that obligation is recorded as ADR-0051’s amendment.

4. Provenance is the generating seed, the archetype, and the entity address

Section titled “4. Provenance is the generating seed, the archetype, and the entity address”

Each persisted record and each seen-record reference carries its originating triple: the generating seed, the archetype, and the entity address within that generation. Untouched content re-derives from the triple as a deterministic function (seed × archetype × address, the World Engine’s materialization rule), so a row stays resolvable after the region that produced it is replaced (verified fact 2).

Considered and rejected: stable global entity identifiers minted at persist time. Global ids need their own allocator and a mapping table from id back to generated entity; the provenance triple re-derives the entity from data the generator already owns, so the store adds no registry. The named revisit trigger: re-derivation measured too slow on device hardware. That measurement reopens this choice; nothing else does.

5. Reads are the verification query surface; no primitives are bound

Section titled “5. Reads are the verification query surface; no primitives are bound”

The read surface is the verification query surface CLONESHOP’s screening loop defines:

  • The pre-check: a single tag-filtered lookup (does the tagged system hold a row answering this claim).
  • The screener: a multi-tag join run to a scrutiny depth (do the tagged systems agree, and how far down the audit goes).

This ADR binds no FFI primitives. CLONESHOP is Tier 1, and binding waits for its implementation; the ADR-0005 enumeration is unchanged today. What this ADR fixes is the contract the future primitives implement: tag-filtered lookup and scrutiny-depth join over the one table, read-only at the cart and program tiers.

6. The storage home is its own durable file outside the UDS

Section titled “6. The storage home is its own durable file outside the UDS”

The store lives in its own durable file beside the deck-state file, following the GWP-711 own-file DOSSIER precedent (ADR-0056 Decision 7) and the keystore commit pattern (a single sanctioned mutator, no raw write path; ADR-0056 Decision 1). The UDS carries zero record-store bytes.

The durability requirement is pinned here: records survive power-off, mission boundaries, and cart swaps. The requirement is shared with DOSSIER’s open power-off storage-home question, and the device-side storage mechanics (file format, commit timing, integrity discipline) belong to the implementation task, on the storage medium ADR-0011 and ADR-0019 define: the device microSD, where the deck-state file already lives.

Sizing is a measurement, never a budget. Capacity grows as records accumulate until the device’s measured limits are reached; no fixed byte budget and no record ceiling constrain the design. The first implementation question is that measurement.

Settled in the same session, carried by their home documents, and recorded here so the decision trail is in one place:

  1. Legend flags live on the legend artifact. Pre-check suspicion flags and screening scrutiny are properties of the legend object, never of the operator: the operator’s visibility state and the region trace do not move on a pre-check (aethernet.md carries the ruling; cloneshop.md states the mechanics).
  2. Client-forgery outcomes ride mission resolution. A client job resolves as a contract, so the fee lands through mission resolution, the sanctioned wallet writer; the outcome mail is narrative plus a reputation event with a named cause. Neither the order, the mail, nor the event touches this store or adds a wallet writer (economy-model.md carries the ruling).
  3. DOSSIER fact capacity grows. The fixed 64-fact inbox is the shipped store’s current layout, never a design ceiling: fact capacity grows as needed until the device’s measured limits, the same sizing rule as Decision 6. This widens dossier.md Tier 3; its capacity sentence is edited in the PR that lands this ADR.
  • CLONESHOP’s one new engineering requirement has a ratified contract: what persists, who writes it, how a row is addressed, where it lives, and what reads it.
  • The world gains memory of the operator’s interference along observed paths while staying a deterministic function everywhere untouched; save data stays proportional to play.
  • The write boundary stays engine-owned at every tier. Widening the durable-consequence set adds no cart- or program-callable write, so the ADR-0040 sanctioned-outcome model holds in kind: durable state changes as the earned consequence of a resolved mission, never as a command.
  • The provenance triple adds no id allocator, no mapping table, and no registry to the runtime.
  • Two durable stores beside the UDS (the DOSSIER file and this one) mean two file-format and commit disciplines to implement and test; the keystore pattern bounds the shape, and the cost is real.
  • world_generate gains an overlay step (consult the store where the region overlaps it), a new coupling between generation and durable state that the determinism tests must cover.
  • The single-path invariant was cited across the corpus; each citation had to widen, and future docs state the two-path model, a longer rule than the one it replaces.
  • Implementation task (runtime): the store file beside the deck-state file (header + CRC + version discipline per deck.c), the record row and tag layout, and the commit seam applied at mission resolution inside the ADR-0055 settlement pass.
  • world_generate overlay: consult the store where a region overlaps persisted rows; determinism tests extended to cover overlay-vs-regeneration.
  • The verification query primitives: pre-check lookup and screener join, bound at CLONESHOP implementation with the ADR-0005 amendment logged then.
  • The sizing measurement: how many records the device holds before its actual limits; the measurement, and the growth mechanics it justifies, land with the implementation task.
  • DOSSIER capacity growth: the 64-fact inbox grows past its fixed layout, with the shared power-off storage-home work.

Part of the decision. A PR that lands this ADR without these edits fails review.

ADR-0057 and ADR-0061 already carry their 2026-08-22 / gate-value rulings; ADR-0005 binds nothing yet; ADR-0011 / ADR-0019 are the storage-medium references. Those five are referenced above and carry no amendment entry.

The deck has always been allowed to remember what the operator learned; DOSSIER is that memory, and one sanctioned verb feeds it. What the deck could never remember was what the operator did to the world: the invariant that kept mission worlds cheap and deterministic also guaranteed that a planted record evaporated with its region. CLONESHOP made the gap a design problem, because a forged life is nothing except rows left behind in other people’s systems, checked missions later by a scanner that does not care how the row got there. Josh’s answer keeps the old discipline and widens it by one path: the engine, and only the engine, writes a second durable store at mission resolution, tagged rows hanging off world entities, provenance enough to rebuild everything around them from seed. The world stays generated; the interference persists; and the registry answers when queried.