096 — Analysis passes declare their own records under lens prefixes

Type: reference/types/adr.md · Status: accepted

Status: accepted Date: 2026-09-29

Amended 2026-10-01: ADR 098 moves amendments to a separate reconciliation member and separates public synthesis from record reconciliation. Lens-prefixed identities and immutable analyst members remain in force; the location and combined-writing descriptions below record the prior decision.

Context

An agentic-system analysis set has one record namespace, and three passes add to it: the runtime pass and the memory and epistemic lenses, which run in parallel. Before this decision only the runtime pass minted canonical IDs. The lenses proposed records under local MEM- and EPI- IDs, the reconciliation mapped each proposal to a canonical ID in a table, and code or a job rewrote lens output with the mapped IDs. Memory finalization renamed tokens, converted merged declarations to annotations, removed rejected proposals and pinned the local report as finalized-from. Each reconciliation round then ran a runtime-final job, which declared registered EPI- records in the runtime member, and an epistemic-final job, which remapped the epistemic member's IDs.

The first code-scheduled run (AAS-2026-09-29-instinctual-memory-01) failed in that renaming: ten records the epistemic lens proposed were registered but declared in no member, so the set did not validate. The failure is structural: a record can go undeclared whenever a pass other than the one that established it must declare it.

Decision

The prefix of the pass that established a record is part of its canonical ID for the life of the set: none for the runtime pass (OBJ-1), MEM- for the memory lens (MEM-OBJ-1), EPI- for the epistemic lens (EPI-OBJ-1). Each pass declares its records in its own member, with the passages that support them. The epistemic member gains a ## Shared records section. Nothing is renamed.

No member is rewritten after the pass that wrote it. The runtime member is written once, before the lenses. The memory member is the specialist's accepted report, copied byte for byte; it keeps only the canonical-register-sha256 pin to its frozen input.

Amendments to any pass's records live in the overview's ## Reconciliation, as Amendment: paragraphs naming the record by full ID. When two passes established the same thing, both records stay declared, and the reconciliation supersedes one: Amendment: MEM-RTE-3 is superseded by RTE-7, with the evidence for the identity. References to either ID keep resolving.

The reconciliation keeps only judgment: supersessions, amendments, anchored conflicts, independent convergence, ownership checks, the memory-comparison check against the whole set, and the synthesis and limitations. Its validator checks that every ID it cites resolves in the set it will make. Each pass's validator checks that its member's citations resolve against the set so far.

This removes the mapping table, memory finalization and its commonplace-agentic-analysis-finalize memory command, the finalized-from field, member ## Amendments sections, the unintegrated-proposal check, and the runtime-final and epistemic-final jobs.

Considered alternatives

Keep proposals and mapping. No contract change, but the renaming step stays a place where a registered record can go undeclared or a reference can dangle, and the definition keeps the jobs and validators that exist only to guard it.

Canonical ID blocks per lens. Code would give each lens a numeric block per kind before the lenses start (memory OBJ-100…, epistemic OBJ-200…), and lenses would declare canonical IDs directly. IDs stay in one grammar, but a block is an arbitrary number a reader cannot tell apart from a runtime ID, and a block can overflow.

Amendments in the declaring member. Keeping amendments beside the record they correct needs a job that writes into every member after reconciliation, which reintroduces a rewriting step per round. The overview's Reconciliation is already where set-wide judgment lives and can cite every member.

A finalized memory copy with amendments appended. It would keep the memory member self-describing, at the cost of a second version of the specialist's report and a pin between the two. With amendments in the overview, the copy would differ from the report only by bookkeeping.

Consequences

IDs get longer, and a reader sees three ID families in one namespace; in exchange each ID says which pass established it. A lens can declare a record that duplicates a runtime record without anyone deciding, so the reconciliation instruction requires a search for duplicates, where the mapping used to force a decision per proposal. A blocker in the runtime or epistemic member that no amendment resolves stays a limitation, because those members are not rewritten.

The one retained set written under the old grammar (AAS-2026-09-28-pageindex-01) and its generated review were deleted rather than migrated; a rerun under this contract replaces them. The change takes effect for runs opened after the commit that lands it, since a run pins its method commit. The decision is untested by a completed run: its adoption test is one run through the code-scheduled definition that publishes with no renaming step and no job that exists only to declare or remap another pass's records.

This ADR adopts the design proposal Lens-prefixed canonical record IDs.