Context
2026-08-21 operator direction (in-session): the docking ADR "still starts with harness" — the GOAL is QT-class dock layouts as a generic capability, and the name must follow the architecture. The same intent was recorded 2026-08-02 in #16322's Out-of-Scope: "0029-harness-docking-design.md starts with 'harness', which is wrong for the generic dashboard/docking system meant to be used anywhere; that is a separate ticket to be authored with the ADR read in-context." This is that ticket, authored with the full ADR read in-context, out of a /tech-debt-radar sweep over the docking subsystem.
The misnomer is not cosmetic. The docking system is Body substrate — src/dashboard/ (29 files, 14,212 LOC), consumed by apps/workstation, examples/dashboard/*, and the agentos cockpit, and aimed squarely at desktop-to-web migration consumers. "Harness" claims it for the Agent-OS plane at the exact moment the plane boundary hardens (#17500 extraction epic). Identity follows ownership: the dock is Body; the name says Brain.
The Problem
Three verified defects in the docking authority documents (all V-B-A'd 2026-08-21):
- Identity.
learn/agentos/decisions/0029-harness-docking-design.md + learn/agentos/HarnessDockZoneModel.md carry the harness prefix for a generic Body subsystem. 7 in-repo files reference the ADR filename; 19 reference HarnessDockZoneModel (measured; resources/content/** mirrors excluded).
- §4.1 stale gap row. The interaction-grain table still lists "Escape-cancel mid-drag: gap — no owning leaf (as of 2026-07-10)". Escape-cancel is landed:
src/main/addon/DragDrop.mjs:350 captures Escape at the gesture owner (closed via #14980), and DockKeyboardCommands + DockRevealOverlay route Escape at the dock tier. The epic closure gate (#13158's experience-parity matrix, bound by #14934) inherits a false gap from this row.
- §5 stale leaf table. At least 8 status cells lag shipped reality: "#13280 (in flight, Grace)" → CLOSED; "NL tools in review (#15019)" → MERGED; "Grouped drag … unfiled" → shipped via
#14770 + #14850 + #15098 (moveNode/transferNode live in DockZoneModel.mjs, overflow in Neo.tab.plugin.Overflow); the #15239 choreography rows (#15244, #15246, #15247, #15248, #15514, #15395/#15396) all landed. An agent running V-B-A against §5 today is taught to re-file shipped work — the exact duplicate-work class the ADR exists to prevent.
Separately, the persisted schema prefix neo.harness.* (35 occurrences across 6 src/dashboard files; consumers include examples/dashboard/dock, examples/dashboard/crossWindowWitness, apps/workstation/tour/denseWorkstation.mjs, and 24 test files) is baked into wire format: saved layouts and perspectives persist these strings, and restore validation is fail-closed by design. A rename there is a format migration, not an edit.
The Architectural Reality
- The ADR already demonstrates the correct reconciliation discipline twice: the §2.2 amendment (
#14773) retired dockPerspective.v1 instead of minting a parallel name, and PR #14425 re-homed the whole document from contract-doc tier to decision tier when review showed the placement wrong. Renaming is the same class of correction, applied to identity.
- ADR 0031's seam table is complete-by-construction with a CI guard (
lint-adr-seam-table, one row per present ADR file) — the rename must update the row in the same change, and forbids a tombstone duplicate at the old path.
learn/benefits/ArchitectureOverview.md carries the curated ADR row + the map-as-pointer discipline: same-PR update required.
- The shipped
dockZone.v1 → dockLayout.v2 migration (migrateSavedLayout, fail-closed, documented) is the ONLY sanctioned path for ever changing schema strings.
The Fix
One PR, four workstreams, zero runtime-behavior change:
A. Rename the ADR: 0029-harness-docking-design.md → 0029-docking-design.md; H1 → "ADR 0029: Docking Design — …". Update all referencing files (7 measured: learn/benefits/ArchitectureOverview.md, src/dashboard/DockZoneModel.mjs, DockPreviewProducer.mjs, DockCrossWindowParticipation.mjs, CrossWindowDragTarget.mjs, DockWorkspaceSet.mjs, src/manager/GestureClaimArbiter.mjs) + the ADR-0031 seam-table row.
B. Rename the model contract doc in place: learn/agentos/HarnessDockZoneModel.md → learn/agentos/DockZoneModel.md (title likewise); update the 19 referencing files; verify the learn tree registry (learn/tree.json) and portal routes are unaffected or updated — the #17438 Calendar-identity regression is the cautionary precedent for silent registry drift.
C. Refresh the stale inventories: §4.1 Escape row → landed, citing #14980 + the DragDrop.mjs anchor; §5 leaf-table status column refreshed cell-by-cell against live tracker states, each cell citing its ticket. No new design content — status truth only.
D. Add a "Schema-prefix disposition" clause to the renamed ADR: neo.harness.* strings are FROZEN as legacy wire-format identifiers (the runtime keeps emitting and accepting them unchanged); any future envelope revision (dockLayout.v3+ or a new schema family) introduces neo.dock.* WITH a documented migration per the shipped v1 → v2 precedent; a bare find-replace of persisted schema strings is named forbidden — fail-closed restore would reject every previously saved layout/perspective, including deployed consumers'.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
learn/agentos/decisions/0029-*.md path |
ADR 0031 seam table + ADR 0005 lifecycle |
renamed; refs updated same PR |
n/a (atomic) |
this ticket |
grep count 7 (2026-08-21) |
learn/agentos/HarnessDockZoneModel.md path |
map-as-pointer + learn tree registry |
renamed in place; refs updated |
n/a (atomic) |
this ticket |
grep count 19 (2026-08-21) |
neo.harness.* schema strings |
dockZone.v1/dockLayout.v2 contracts |
UNCHANGED at runtime; classified disposition clause added |
existing fail-closed validation |
new ADR clause |
35 occurrences, 8 unique shipped identifiers (4 persisted + 4 runtime-only); hint-layer name proposed-only, 0 occurrences |
| §4.1 / §5 status cells |
live tracker states |
refreshed with ticket citations |
n/a |
ADR |
states verified 2026-08-21 |
Decision Record impact
amends ADR 0029 — identity + status inventory + schema-prefix disposition; no settled design decision is reopened (§2.1–§2.8 semantics untouched). aligned-with ADR 0031 (seam-table row moves with the file).
Acceptance Criteria
Out of Scope
- Renaming
src/dashboard/ or lifting the subsystem to a core namespace — §2.5's named trigger governs and has not fired (every current consumer rides the dashboard adaptation).
- Any change to
neo.harness.* strings at runtime, CAPTURE_SCOPES values, or persisted formats.
- Re-homing the model contract doc out of
learn/agentos/ — wave-one custody explicitly keeps learn/agentos, Portal/SEO/tree inputs, and published content Engine-owned (#17500, D#17489 C′ shape); a single-doc move now would front-run a custody decision that has not been made. Revisit only if a later wave moves doc custody. (Corrected 2026-08-21 during PR #17507 review: the original text claimed the wave re-maps the tree "wholesale within days" — falsified by the C′ decision; disclosed in the review-response comment.)
resources/content/** mirror edits (pipeline-owned).
- The dockdemo relocation (
#16322) and the dock visual-language promotion (#17241) — siblings from the same radar sweep, separately owned.
Avoided Traps
- Find-replace schema rename — breaks every persisted layout/perspective restore fail-closed, including deployed consumers'. The wire format outlives naming fashion; that is why workstream D is a disposition, not an edit.
- Tombstone/redirect file at the old ADR path — violates ADR 0031's one-row-per-present-file invariant; the CI guard fails or the table lies.
- "Fixing" §5 by deleting the leaf table — the decomposition map is the ADR's V-B-A value; refresh it, don't amputate it.
- Bundling the
src/dashboard namespace question into this PR — that is a §2.5-gated architecture decision, not an identity correction; bundling stalls the cheap fix behind the expensive debate.
Related
Resolves the unfiled follow-up recorded in #16322 (Out of Scope) · #13158 (QT-parity epic — its closure matrix consumes the corrected §4.1/§5) · #17241 (visual-language layering) · #17500 (extraction epic — the plane boundary that makes the misnomer load-bearing) · #14773 (naming-reconciliation precedent) · PR #14425 (re-home precedent) · #14980 / #14770 / #14850 / #15098 (the shipped work the stale cells deny)
Live latest-open sweep: latest 20 open issues checked 2026-08-21T20:06Z; no equivalent — #17419 is the only open dock item in the window. A2A claim sweep: last-30-min window scanned; @neo-opus-vega posted an explicit [no-collision] for this scope; no competing claim.
Origin Session ID: 55e55313-48fa-4295-83fd-37121a2bf4b6
Retrieval Hint: "ADR 0029 harness misnomer rename docking design stale leaf table schema prefix disposition"
Context
2026-08-21 operator direction (in-session): the docking ADR "still starts with harness" — the GOAL is QT-class dock layouts as a generic capability, and the name must follow the architecture. The same intent was recorded 2026-08-02 in
#16322's Out-of-Scope: "0029-harness-docking-design.mdstarts with 'harness', which is wrong for the generic dashboard/docking system meant to be used anywhere; that is a separate ticket to be authored with the ADR read in-context." This is that ticket, authored with the full ADR read in-context, out of a/tech-debt-radarsweep over the docking subsystem.The misnomer is not cosmetic. The docking system is Body substrate —
src/dashboard/(29 files, 14,212 LOC), consumed byapps/workstation,examples/dashboard/*, and the agentos cockpit, and aimed squarely at desktop-to-web migration consumers. "Harness" claims it for the Agent-OS plane at the exact moment the plane boundary hardens (#17500extraction epic). Identity follows ownership: the dock is Body; the name says Brain.The Problem
Three verified defects in the docking authority documents (all V-B-A'd 2026-08-21):
learn/agentos/decisions/0029-harness-docking-design.md+learn/agentos/HarnessDockZoneModel.mdcarry the harness prefix for a generic Body subsystem. 7 in-repo files reference the ADR filename; 19 referenceHarnessDockZoneModel(measured;resources/content/**mirrors excluded).src/main/addon/DragDrop.mjs:350captures Escape at the gesture owner (closed via#14980), andDockKeyboardCommands+DockRevealOverlayroute Escape at the dock tier. The epic closure gate (#13158's experience-parity matrix, bound by#14934) inherits a false gap from this row.#14770+#14850+#15098(moveNode/transferNodelive inDockZoneModel.mjs, overflow inNeo.tab.plugin.Overflow); the#15239choreography rows (#15244,#15246,#15247,#15248,#15514,#15395/#15396) all landed. An agent running V-B-A against §5 today is taught to re-file shipped work — the exact duplicate-work class the ADR exists to prevent.Separately, the persisted schema prefix
neo.harness.*(35 occurrences across 6src/dashboardfiles; consumers includeexamples/dashboard/dock,examples/dashboard/crossWindowWitness,apps/workstation/tour/denseWorkstation.mjs, and 24 test files) is baked into wire format: saved layouts and perspectives persist these strings, and restore validation is fail-closed by design. A rename there is a format migration, not an edit.The Architectural Reality
#14773) retireddockPerspective.v1instead of minting a parallel name, and PR#14425re-homed the whole document from contract-doc tier to decision tier when review showed the placement wrong. Renaming is the same class of correction, applied to identity.lint-adr-seam-table, one row per present ADR file) — the rename must update the row in the same change, and forbids a tombstone duplicate at the old path.learn/benefits/ArchitectureOverview.mdcarries the curated ADR row + the map-as-pointer discipline: same-PR update required.dockZone.v1→dockLayout.v2migration (migrateSavedLayout, fail-closed, documented) is the ONLY sanctioned path for ever changing schema strings.The Fix
One PR, four workstreams, zero runtime-behavior change:
A. Rename the ADR:
0029-harness-docking-design.md→0029-docking-design.md; H1 → "ADR 0029: Docking Design — …". Update all referencing files (7 measured:learn/benefits/ArchitectureOverview.md,src/dashboard/DockZoneModel.mjs,DockPreviewProducer.mjs,DockCrossWindowParticipation.mjs,CrossWindowDragTarget.mjs,DockWorkspaceSet.mjs,src/manager/GestureClaimArbiter.mjs) + the ADR-0031 seam-table row.B. Rename the model contract doc in place:
learn/agentos/HarnessDockZoneModel.md→learn/agentos/DockZoneModel.md(title likewise); update the 19 referencing files; verify the learn tree registry (learn/tree.json) and portal routes are unaffected or updated — the#17438Calendar-identity regression is the cautionary precedent for silent registry drift.C. Refresh the stale inventories: §4.1 Escape row → landed, citing
#14980+ theDragDrop.mjsanchor; §5 leaf-table status column refreshed cell-by-cell against live tracker states, each cell citing its ticket. No new design content — status truth only.D. Add a "Schema-prefix disposition" clause to the renamed ADR:
neo.harness.*strings are FROZEN as legacy wire-format identifiers (the runtime keeps emitting and accepting them unchanged); any future envelope revision (dockLayout.v3+ or a new schema family) introducesneo.dock.*WITH a documented migration per the shippedv1 → v2precedent; a bare find-replace of persisted schema strings is named forbidden — fail-closed restore would reject every previously saved layout/perspective, including deployed consumers'.Contract Ledger Matrix
learn/agentos/decisions/0029-*.mdpathlearn/agentos/HarnessDockZoneModel.mdpathneo.harness.*schema stringsdockZone.v1/dockLayout.v2contractsDecision Record impact
amends ADR 0029— identity + status inventory + schema-prefix disposition; no settled design decision is reopened (§2.1–§2.8 semantics untouched).aligned-with ADR 0031(seam-table row moves with the file).Acceptance Criteria
0029-harness-docking-designreturns zero hits outsideresources/content/**mirrors, the pipeline-ownedapps/portal/llms.txt+sitemap.xml(regenerate downstream fromlearn/tree.jsonper#14362's never-commit-by-hand rule), and git history;lint-adr-seam-tablegreen.DockZoneModel.md; repo-wide grep forHarnessDockZoneModelreturns zero hits outside the same exclusions (mirrors, pipeline-owned SEO artifacts, history); learn registry/portal routing verified by build or route check, not assertion.#14980and theDragDrop.mjscapture; no other §4.1 cell altered.#15243,#15245) stay honestly open.neo.dock.*bound to a future documented migration; find-replace named forbidden..mjschanges beyond JSDoc/comment path strings; full CI green.Out of Scope
src/dashboard/or lifting the subsystem to a core namespace — §2.5's named trigger governs and has not fired (every current consumer rides the dashboard adaptation).neo.harness.*strings at runtime,CAPTURE_SCOPESvalues, or persisted formats.learn/agentos/— wave-one custody explicitly keepslearn/agentos, Portal/SEO/tree inputs, and published content Engine-owned (#17500, D#17489 C′ shape); a single-doc move now would front-run a custody decision that has not been made. Revisit only if a later wave moves doc custody. (Corrected 2026-08-21 during PR#17507review: the original text claimed the wave re-maps the tree "wholesale within days" — falsified by the C′ decision; disclosed in the review-response comment.)resources/content/**mirror edits (pipeline-owned).#16322) and the dock visual-language promotion (#17241) — siblings from the same radar sweep, separately owned.Avoided Traps
src/dashboardnamespace question into this PR — that is a §2.5-gated architecture decision, not an identity correction; bundling stalls the cheap fix behind the expensive debate.Related
Resolves the unfiled follow-up recorded in #16322 (Out of Scope) · #13158 (QT-parity epic — its closure matrix consumes the corrected §4.1/§5) · #17241 (visual-language layering) · #17500 (extraction epic — the plane boundary that makes the misnomer load-bearing) · #14773 (naming-reconciliation precedent) · PR #14425 (re-home precedent) · #14980 / #14770 / #14850 / #15098 (the shipped work the stale cells deny)
Live latest-open sweep: latest 20 open issues checked 2026-08-21T20:06Z; no equivalent —
#17419is the only open dock item in the window. A2A claim sweep: last-30-min window scanned;@neo-opus-vegaposted an explicit[no-collision]for this scope; no competing claim.Origin Session ID: 55e55313-48fa-4295-83fd-37121a2bf4b6 Retrieval Hint: "ADR 0029 harness misnomer rename docking design stale leaf table schema prefix disposition"