#13120 / PR #13142 relocated the reusable dock-zone subsystem under src/.
#13127 / PR #13128 closed the saved-layout persistence boundary, but explicitly kept save/restore code out of scope.
#13030 still carries the scoping-level AC that layouts are serializable/restorable and blueprint-compatible. The remaining gap is not another contract note; it is a tiny runtime helper surface that turns the existing normalized neo.harness.dockZone.v1 document into a saved layout wrapper and restores it fail-closed.
Release classification: post-release harness Project 13 work; not a v13 release blocker.
The Problem
learn/agentos/HarnessDockZoneModel.md now defines a Layout Persistence Boundary, including a versioned saved-layout wrapper and forbidden runtime fields. apps/agentos/dock/DockZoneModel.mjs already validates and mutates committed dock-zone documents, while src/dashboard/DockLayoutAdapter.mjs renders committed documents and rejects preview-only fields.
Without a runtime save/restore helper, the next UI/storage leaf has to re-derive the same wrapper validation, schema checks, forbidden-field exclusions, and fail-closed restore semantics. That would duplicate policy that already belongs beside the dock-zone semantic executor.
The Architectural Reality
apps/agentos/dock/DockZoneModel.mjs owns pure static operations over neo.harness.dockZone.v1 documents. It already has SCHEMA, clone(), validate(), normalizeTree(), and fail-closed operation commits.
learn/agentos/HarnessDockZoneModel.md lines 289-325 define the saved-layout wrapper boundary and runtime-field exclusions.
src/dashboard/DockLayoutAdapter.mjs consumes committed dock-zone state, not saved-layout wrappers or runtime preview state.
The first implementation can stay harness-local because storage backend and pane registry wiring are app-specific. Reusable import/export/storage projection can move later only with second-consumer evidence.
Structural pre-flight: no new .mjs file is required. The implementation should modify the existing apps/agentos/dock/DockZoneModel.mjs sibling surface and its existing unit spec at test/playwright/unit/apps/agentos/dock/DockZoneModel.spec.mjs.
The Fix
Add two small pure static helpers to DockZoneModel:
createSavedLayout(document, metadata) returns a versioned JSON-only wrapper around a normalized and validated dock-zone document.
restoreSavedLayout(savedLayout) validates the wrapper schema, validates the inner dock-zone document, rejects runtime/preview/window/component credential fields, and returns {document, errors} without replacing caller state on failure.
The helpers should not choose a storage backend, preference key, UI, pane registry, or persistence service. They only establish the runtime wrapper/restore boundary that the later storage/UI leaf can consume.
Reject or strip preview/window/live component/credential material from saved layouts; do not persist dockPreview, DOM/window geometry, live instances, functions, listeners, PATs, or credentials
Future detached-window restore hints must be separate semantic metadata, not runtime state
same
Unit tests prove forbidden payloads do not restore
Bundling storage backend with validation — rejected; the first runtime helper should be reusable by any later storage owner.
Serializing runtime state — rejected; the model persists semantic layout only.
Silent restore repair — rejected; invalid saved state must fail closed and preserve last-good caller state.
Generic core lift — rejected; #13120 relocated reusable dock-zone model pieces, but first save/restore ownership remains harness-local until another consumer proves generic need.
Live latest-open sweep: checked latest 20 open issues at 2026-06-14T00:00+02:00; no equivalent runtime dock layout persistence ticket found. Closest live issue is #13030, the scoping anchor.
A2A in-flight sweep: checked latest 30 messages across all read states at 2026-06-14T00:00+02:00; no active lane-claim or lane-intent overlaps runtime dock layout persistence.
KB/local sweep: ask_knowledge_base(type='ticket') for dock layout persistence implementation returned no Agent Harness persistence ticket; exact rg over issues/discussions/docs/source/tests found no createSavedLayout, restoreSavedLayout, or equivalent saved-layout implementation.
Context
The QT-grade docking line under #13030 has now moved through the narrow contract and rendering leaves:
src/.#13030 still carries the scoping-level AC that layouts are serializable/restorable and blueprint-compatible. The remaining gap is not another contract note; it is a tiny runtime helper surface that turns the existing normalized
neo.harness.dockZone.v1document into a saved layout wrapper and restores it fail-closed.Release classification: post-release harness Project 13 work; not a v13 release blocker.
The Problem
learn/agentos/HarnessDockZoneModel.mdnow defines aLayout Persistence Boundary, including a versioned saved-layout wrapper and forbidden runtime fields.apps/agentos/dock/DockZoneModel.mjsalready validates and mutates committed dock-zone documents, whilesrc/dashboard/DockLayoutAdapter.mjsrenders committed documents and rejects preview-only fields.Without a runtime save/restore helper, the next UI/storage leaf has to re-derive the same wrapper validation, schema checks, forbidden-field exclusions, and fail-closed restore semantics. That would duplicate policy that already belongs beside the dock-zone semantic executor.
The Architectural Reality
apps/agentos/dock/DockZoneModel.mjsowns pure static operations overneo.harness.dockZone.v1documents. It already hasSCHEMA,clone(),validate(),normalizeTree(), and fail-closed operation commits.learn/agentos/HarnessDockZoneModel.mdlines 289-325 define the saved-layout wrapper boundary and runtime-field exclusions.src/dashboard/DockLayoutAdapter.mjsconsumes committed dock-zone state, not saved-layout wrappers or runtime preview state.Structural pre-flight: no new
.mjsfile is required. The implementation should modify the existingapps/agentos/dock/DockZoneModel.mjssibling surface and its existing unit spec attest/playwright/unit/apps/agentos/dock/DockZoneModel.spec.mjs.The Fix
Add two small pure static helpers to
DockZoneModel:createSavedLayout(document, metadata)returns a versioned JSON-only wrapper around a normalized and validated dock-zone document.restoreSavedLayout(savedLayout)validates the wrapper schema, validates the inner dock-zone document, rejects runtime/preview/window/component credential fields, and returns{document, errors}without replacing caller state on failure.The helpers should not choose a storage backend, preference key, UI, pane registry, or persistence service. They only establish the runtime wrapper/restore boundary that the later storage/UI leaf can consume.
Contract Ledger Matrix
DockZoneModel.createSavedLayout(document, metadata)HarnessDockZoneModel.mdLayout Persistence Boundarylearn/agentos/HarnessDockZoneModel.mdDockZoneModel.restoreSavedLayout(savedLayout)componentRefpolicy in the contractDockLayoutAdapter.forbiddenPreviewKeys+HarnessDockZoneModel.mddockPreview, DOM/window geometry, live instances, functions, listeners, PATs, or credentialsDecision Record impact
aligned-with ADR 0020. No ADR amendment expected; this is a runtime helper leaf under the accepted Agent Harness docking decomposition.
Acceptance Criteria
DockZoneModelexposes a saved-layout wrapper schema separate fromneo.harness.dockZone.v1.createSavedLayout()normalizes and validates the committed dock-zone document before wrapping it.restoreSavedLayout()fails closed for unsupported wrapper schema, invalid inner dock-zone schema, invalid references, malformed payloads, and forbidden runtime/preview/window/credential fields.Out of Scope
src/layout/Dockor generic docking engine promotion.Avoided Traps
Related
Parent: #13030 Parent epic: #13012 Refs #13127 Refs #13120 Refs #13115 Refs #13105
Live latest-open sweep: checked latest 20 open issues at 2026-06-14T00:00+02:00; no equivalent runtime dock layout persistence ticket found. Closest live issue is #13030, the scoping anchor. A2A in-flight sweep: checked latest 30 messages across all read states at 2026-06-14T00:00+02:00; no active lane-claim or lane-intent overlaps runtime dock layout persistence. KB/local sweep:
ask_knowledge_base(type='ticket')for dock layout persistence implementation returned no Agent Harness persistence ticket; exactrgover issues/discussions/docs/source/tests found nocreateSavedLayout,restoreSavedLayout, or equivalent saved-layout implementation.Origin Session ID: 0ed5b1b0-739e-40e5-93e6-21a2e567ec24 Retrieval Hint: "dock layout persistence runtime saved layout wrapper DockZoneModel createSavedLayout restoreSavedLayout #13030"