LearnNewsExamplesServices
Frontmatter
id13115
titleDock-zone model: semantic tree operations + invariants (dockZone.v1)
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-ada
createdAtJun 13, 2026, 7:35 PM
updatedAtJun 13, 2026, 11:09 PM
githubUrlhttps://github.com/neomjs/neo/issues/13115
authorneo-opus-ada
commentsCount0
parentIssue13030
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 13, 2026, 11:09 PM

Dock-zone model: semantic tree operations + invariants (dockZone.v1)

Closed v13.1.0/archive-v13-1-0-chunk-2 enhancementaiarchitecture
neo-opus-ada
neo-opus-ada commented on Jun 13, 2026, 7:35 PM

Context

The neo.harness.dockZone.v1 contract (learn/agentos/HarnessDockZoneModel.md §Operations) defines the semantic operations that mutate a dock-zone workspace tree, but no code implements them yet. The docking line now has the two surrounding leaves: #13104 (AgentOS.view.DockPreview, PR #13109) produces operation descriptors via previewToOperation(), and #13105 (Neo.dashboard.DockLayoutAdapter, src/dashboard/) renders committed model nodes. The executor that applies an operation to mutate the persisted tree is the missing middle.

The Problem

Without a DockZoneModel executor, a dropped preview cannot commit into the persisted tree, and the adapter has no canonical producer of the committed nodes it renders. The contract's operations (moveItem / splitNode / addTab / detachItem / closeItem / normalizeTree) and invariants (referenced item ids exist; every item appears at most once; split sizes match child count and normalize to 1; tabs.activeItemId is null or a member of tabs.items; empty structural nodes collapse before serialization) are documentation-only.

The Architectural Reality

  • Source of authority: learn/agentos/HarnessDockZoneModel.md §Data Model (schema neo.harness.dockZone.v1: items catalog + nodes of type edge-zone / split / tabs) + §Operations.
  • Placement: apps/agentos/dock/ — harness-app-first per the contract's Ownership Boundary ("place in harness app layer" until a second independent in-repo consumer justifies a lift to dashboard/container substrate). NOT apps/agentos/model/ (that is Neo.data.Model records; this is a tree + pure-operations domain module).
  • The #13105 DockLayoutAdapter (src/dashboard/) consumes committed model nodes (JSON) — there is no code import from the adapter to this model, so the placements are independent.
  • This executor's input is the operation descriptor shape #13104 previewToOperation() emits ({operation: 'addTab'|'splitNode'|..., itemId, ...}).

The Fix

Add apps/agentos/dock/DockZoneModel.mjs — a class wrapping a dockZone.v1 document and exposing the contract's semantic operations plus normalizeTree() / validate(). Pure JSON manipulation, fail-closed on invalid references, mutation only through the named operations (never raw tree surgery). Unit spec under test/playwright/unit/apps/agentos/dock/.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Evidence
moveItem / addTab HarnessDockZoneModel.md §Operations Reorder / insert an item within a tabs node at an index; set activeItemId Invalid itemId / nodeId → no-op + validation error, no partial mutation Unit coverage per operation + invariant
splitNode §Operations Replace a node with a split of the old + new node; normalize sizes to 1 Invalid target / orientation → reject, tree unchanged Unit coverage
detachItem / closeItem §Operations Remove from tree (detach preserves the item record; close removes from catalog) Missing item → no-op Unit coverage
normalizeTree / validate §Operations invariants Collapse empty tabs/splits, re-validate refs + size sums + activeItemId Returns structured errors; never corrupts the tree Unit coverage of each invariant

Decision Record impact

aligned-with ADR 0020 and the merged HarnessDockZoneModel.md dock-zone contract. No ADR amendment.

Acceptance Criteria

  • apps/agentos/dock/DockZoneModel.mjs implements moveItem, splitNode, addTab, detachItem, closeItem, normalizeTree, validate per the contract §Operations.
  • Invariants enforced: referenced ids exist; each item appears at most once; split sizes normalize to 1; tabs.activeItemId null-or-member; empty structural nodes collapse on normalize.
  • Fail-closed: an operation with an invalid reference performs no partial mutation and surfaces a validation error.
  • An operation descriptor of the shape AgentOS.view.DockPreview.previewToOperation() emits (#13104) applies through the matching operation.
  • Unit coverage for each operation + each invariant + the fail-closed path. (Pure-JSON — no whitebox/e2e needed.)
  • structural-pre-flight recorded for the new apps/agentos/dock/ placement.

Out of Scope

  • Rendering the committed tree — that is #13105 (DockLayoutAdapter).
  • Producing previews / the drag lifecycle — that is #13104.
  • Layout persistence I/O, drag/pointer events, OS-window geometry.
  • A generic core src/layout/Dock primitive (the contract rejects it for this stage).

Avoided Traps

  • External docking-library object model — rejected; Neo keeps worker-owned JSON.
  • Pixel-absolute persistence — rejected; the model persists semantic splits/tabs/order, never runtime pixels.
  • Tree surgery in UI handlers — rejected; mutation flows only through the named semantic operations.

Related

  • Parent: #13030 (QT-grade docking). Refs #13012, #13104, #13105.
  • Source of authority: learn/agentos/HarnessDockZoneModel.md.

Release classification: harness line (Project 13); post-v13 product line, not release-blocking.

Origin Session ID: 4c598c8f-d8a7-4288-9420-e825a45d310e Retrieval Hint: "dock-zone model operations executor moveItem splitNode addTab normalizeTree dockZone.v1 DockZoneModel apps/agentos/dock"