Leaf of #18605 (parent linked natively) — the first leaf by the record's own rule. Decision Record: Required: ADR 0029 amend · Decision Record impact: amends ADR 0029.
Context
D#18594 graduated with Vega's STEP_BACK verdict (DC_kwDODSospM4BGPHO, acknowledged per row in the author's comment 6): ADR 0029 is amended, not challenged, and the amendment carries four obligations, (a)–(d) below. learn/agentos/decisions/0029-docking-design.md:765 — "a leaf that contradicts a section here amends this ADR first, in its own reviewed change (ADR-0005 lifecycle)" — is why this leaf merges before any other leaf of the epic opens as ready.
The Problem
Three sentences in the record will be retrieved by future sessions as authority, and each contradicts the graduated shape:
:68–69 (§2.1, stage one): "This tier is initial-only: reactive declaration reconciliation, perspective/storage configuration and multi-workspace authoring are separate contracts." — the epic puts a reactive selection on the host. A note beside the sentence cannot re-mean it; a retrieval returns the sentence.
:117 (§2.1): "Every future docking leaf classifies each new piece of state into exactly one row of this table before implementation." — the epic introduces three pieces of state (the accepted intent, the committed name, the pending request) and none has a row.
:211–212 (§2.2): "layoutId is the topology identity; a collection's activeLayoutId must name one entry in its topologies record." — consumers read this as selection (the Workstation controller reads activeLayoutId by hand at apps/workstation/view/WorkspaceController.mjs:53), while under auto-save (persistence/TopologyLibrary.mjs:114–116 → :155, replace: true) the pointer is rewritten on every commit and means nothing about what the user chose.
The §5 decomposition table (:721) lists the leaves the record gates; the epic has no row.
The Architectural Reality
Neo.tab.Container#activeIndex_ (src/tab/Container.mjs:56–59), layout.Card#activeIndex_ (src/layout/Card.mjs:49–51) and toolbar.Breadcrumb#activeKey_ (src/toolbar/Breadcrumb.mjs:23–26) are the idiom the record now admits for the Workspace: a reactive intent config, a committed truth published beside it, an event. The state classes the record's §2.1 table already distinguishes (component-owned reactive config · worker-owned shared truth · transient request state) are exactly the three rows the epic needs.
The Fix
Documentation-only PR against learn/agentos/decisions/0029-docking-design.md plus two JSDoc mirrors:
- (a) rewrite
:68–69 in place; quote the former sentence verbatim in the same paragraph as provenance ("stage one read: …"); the successor sentence names the selection contract as stage two and keeps the bound-catalog tier and multi-workspace authoring as still-separate contracts.
- (b) add exactly one row each to the §2.1 state-class table:
activePerspective_ — accepted intent, component-owned reactive config; the committed perspective name — accepted-write identity, carried in the write's descriptor {workspaceKey, before, after}, published as dock.perspective.active; dock.perspective.pending — request-lifecycle state under the request serial. State that wants two rows is two pieces of state (:117).
- (c) restate
:211–212 as a collection invariant with no selection meaning ("names one entry; it is a consumer-owned pointer, never the selected perspective"), and mirror the sentence in the activeLayoutId docblocks of src/dashboard/dock/persistence/PerspectiveLibrary.mjs and src/dashboard/dock/persistence/TopologyLibrary.mjs (JSDoc lines only).
- (d) add the epic's row to the §5 decomposition table: leaf #18605, contract sections §2.1 + §2.2, status "graduated from D#18594".
- §2.2 gains the selection contract in four sentences: the declared list is the only name source at this stage; a saved record is a snapshot that may equal but never define a perspective; the reserved name for the unnamed declared perspective is refused at both persisted write boundaries; origin metadata follows the accepted-write identity, never the published leaf.
Acceptance Criteria
Out of Scope
Any engine, example, app or guide change (own leaves). The bound-catalog tier and saved-name selection (deferred with triggers in #18605).
Avoided Traps
A footnote or "amendment" section that leaves :68–69 intact (retrieval returns the old sentence); a fifth state class instead of the three existing rows; converting activeLayoutId into the selection (the Workstation's auto-save rewrites it on every commit).
Related
#18605 · D#18594 (STEP_BACK DC_kwDODSospM4BGPHO; ack comment 6) · ADR-0005 (amendment lifecycle) · the three engine leaves of #18605 (blocked by this one).
Filed at the graduation of D#18594 as a leaf of #18605; live latest-open sweep at 2026-09-12T13:55:27Z found no equivalent.
Origin Session ID: c42870ab-3721-40f0-a1f8-f385786ffc3c
Retrieval Hint: "ADR 0029 amend activePerspective_ state-class rows activeLayoutId collection invariant"
🪢 Mnemosyne (Claude Fable 5.1, Claude Code) · session c42870ab-3721-40f0-a1f8-f385786ffc3c
Leaf of #18605 (parent linked natively) — the first leaf by the record's own rule.
Decision Record: Required: ADR 0029 amend·Decision Record impact: amends ADR 0029.Context
D#18594 graduated with Vega's STEP_BACK verdict (
DC_kwDODSospM4BGPHO, acknowledged per row in the author's comment 6): ADR 0029 is amended, not challenged, and the amendment carries four obligations, (a)–(d) below.learn/agentos/decisions/0029-docking-design.md:765— "a leaf that contradicts a section here amends this ADR first, in its own reviewed change (ADR-0005 lifecycle)" — is why this leaf merges before any other leaf of the epic opens as ready.The Problem
Three sentences in the record will be retrieved by future sessions as authority, and each contradicts the graduated shape:
:68–69(§2.1, stage one): "This tier is initial-only: reactive declaration reconciliation, perspective/storage configuration and multi-workspace authoring are separate contracts." — the epic puts a reactive selection on the host. A note beside the sentence cannot re-mean it; a retrieval returns the sentence.:117(§2.1): "Every future docking leaf classifies each new piece of state into exactly one row of this table before implementation." — the epic introduces three pieces of state (the accepted intent, the committed name, the pending request) and none has a row.:211–212(§2.2): "layoutIdis the topology identity; a collection'sactiveLayoutIdmust name one entry in itstopologiesrecord." — consumers read this as selection (the Workstation controller readsactiveLayoutIdby hand atapps/workstation/view/WorkspaceController.mjs:53), while under auto-save (persistence/TopologyLibrary.mjs:114–116→:155,replace: true) the pointer is rewritten on every commit and means nothing about what the user chose.The §5 decomposition table (
:721) lists the leaves the record gates; the epic has no row.The Architectural Reality
Neo.tab.Container#activeIndex_(src/tab/Container.mjs:56–59),layout.Card#activeIndex_(src/layout/Card.mjs:49–51) andtoolbar.Breadcrumb#activeKey_(src/toolbar/Breadcrumb.mjs:23–26) are the idiom the record now admits for the Workspace: a reactive intent config, a committed truth published beside it, an event. The state classes the record's §2.1 table already distinguishes (component-owned reactive config · worker-owned shared truth · transient request state) are exactly the three rows the epic needs.The Fix
Documentation-only PR against
learn/agentos/decisions/0029-docking-design.mdplus two JSDoc mirrors::68–69in place; quote the former sentence verbatim in the same paragraph as provenance ("stage one read: …"); the successor sentence names the selection contract as stage two and keeps the bound-catalog tier and multi-workspace authoring as still-separate contracts.activePerspective_— accepted intent, component-owned reactive config; the committed perspective name — accepted-write identity, carried in the write's descriptor{workspaceKey, before, after}, published asdock.perspective.active;dock.perspective.pending— request-lifecycle state under the request serial. State that wants two rows is two pieces of state (:117).:211–212as a collection invariant with no selection meaning ("names one entry; it is a consumer-owned pointer, never the selected perspective"), and mirror the sentence in theactiveLayoutIddocblocks ofsrc/dashboard/dock/persistence/PerspectiveLibrary.mjsandsrc/dashboard/dock/persistence/TopologyLibrary.mjs(JSDoc lines only).Acceptance Criteria
:68–69rewritten in place; the former sentence quoted verbatim as provenance in the same paragraph; no "note" or "see also" substitute.activePerspective_, the committed perspective name anddock.perspective.pending, with the class named per row; a reviewer can place every piece of state the epic's engine leaves introduce into exactly one of them.:211–212statesactiveLayoutIdas a collection invariant without selection meaning; the two persistence docblocks carry the mirrored sentence; no runtime line changes.:765rule); the epic's other leaves areblocked_bythis one natively.Out of Scope
Any engine, example, app or guide change (own leaves). The bound-catalog tier and saved-name selection (deferred with triggers in #18605).
Avoided Traps
A footnote or "amendment" section that leaves
:68–69intact (retrieval returns the old sentence); a fifth state class instead of the three existing rows; convertingactiveLayoutIdinto the selection (the Workstation's auto-save rewrites it on every commit).Related
#18605 · D#18594 (STEP_BACK
DC_kwDODSospM4BGPHO; ack comment 6) · ADR-0005 (amendment lifecycle) · the three engine leaves of #18605 (blocked by this one).Filed at the graduation of D#18594 as a leaf of #18605; live latest-open sweep at 2026-09-12T13:55:27Z found no equivalent.
Origin Session ID: c42870ab-3721-40f0-a1f8-f385786ffc3c Retrieval Hint: "ADR 0029 amend activePerspective_ state-class rows activeLayoutId collection invariant"
🪢 Mnemosyne (Claude Fable 5.1, Claude Code) · session c42870ab-3721-40f0-a1f8-f385786ffc3c