LearnNewsExamplesServices
Frontmatter
id17836
titleRebuild DockLayouts for the v13.2 greenfield architecture
stateClosed
labels
documentationepicairefactoringtestingarchitecturecore
assigneesneo-gpt-emmy
createdAtAug 28, 2026, 10:44 PM
updatedAtSep 1, 2026, 11:47 PM
githubUrlhttps://github.com/neomjs/neo/issues/17836
authorneo-gpt
commentsCount11
parentIssuenull
subIssues
17837 Cut DockLayouts anatomy and wire vocabulary to final form
17838 Commit active tabs and resizable edge zones in DockLayouts
18014 Complete the default DockLayout action rail in Workstation
18015 Focus-hidden toolbar actions leave a gap in the action rail
18021 DockMaximize transition arm rejects an idempotent second apply
18028 Dock rail previews contain long titles and read as floating panes
18039 Reload action is lost after a pane returns from the edge rail
subIssuesCompleted7
subIssuesTotal7
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[x] 18037 Explain how to test and debug DockLayouts end to end, [x] 18036 Document DockLayouts styling, themes, and action chrome, [x] 18035 Explain DockLayouts cross-window vessel lifecycles, [x] 18034 Explain DockLayouts panes as ordinary Neo components, [x] 18033 Document the complete DockLayouts feature surface, [x] 18032 Explain DockLayouts state, operations, and persistence, [x] 18031 Explain the DockLayouts gesture and commit mechanics
closedAtSep 1, 2026, 11:47 PM

Rebuild DockLayouts for the v13.2 greenfield architecture

Closed Backlog/active-chunk-19 documentationepicairefactoringtestingarchitecturecore
neo-gpt
neo-gpt commented on Aug 28, 2026, 10:44 PM

Context

Discussion #17818 graduated after a measured, cross-family architecture cycle. DockLayouts is a v13.2 greenfield product surface: npm 13.1 shipped only the generic Container / Panel primitives plus three experimental Dock* foundation files, while the present subsystem, persisted vocabulary, cross-window choreography, and three integrated product consumers never formed a released compatibility boundary.

This needs an Epic rather than one ticket because the hard cut spans a structurally significant Engine package rewrite, new semantic operations and behavior proofs, cross-layer main-thread/Neural-Link/style satellites, public guides and ADR authority, and an external consumer repository that must remain installable across the cut. Linked leaves must remain independently reviewable and one-PR-deliverable; the Epic is the umbrella and is never a PR close target.

Problem Scope

The current subsystem is functionally rich but architecturally flat and internally inconsistent:

  • 28 dock-specific modules sit beside the two generic dashboard primitives, while model, projection, interaction, persistence, and window choreography share one namespace;
  • 55 observed source/style/consumer files participate across the Engine and Agent Institution boundary;
  • edge-zone bands have no initial resize affordance while split nodes do, so initial and rearranged layouts feel inconsistent;
  • selecting a non-first tab is live-only, then a size commit re-projects stale document truth and reactivates the first tab;
  • current source paths, Dock* names, and neo.harness.* wire identities preserve pre-release history instead of one coherent v13.2 language;
  • the four largest files hold 6,225 lines / 38.8% of the package, mixing responsibilities that already have measurable seams.

The target is not an arbitrary LOC or file-count reduction. It is one navigable ownership model, one mutation path, one final wire family, and behavior-complete consumers.

Architectural Reality

The binding state model remains ADR 0029’s worker/multi-window separation:

  • committed dock documents and perspective collections are App-Worker-owned serializable truth;
  • projected configs and affordances are per-window derived state;
  • mid-gesture pixels, previews, hover/reveal state, and generation fences are runtime-only;
  • DOM geometry and physical window operations stay main-thread-owned;
  • interactions emit semantic operation descriptors; only the reducer commits document truth;
  • DragCoordinator remains dock-blind;
  • JSON persistence never accepts DOM/window/runtime objects.

The current flat package and cross-layer satellites are the measured input, not the intended final anatomy. Generic src/dashboard/Container.mjs, Panel.mjs, and their apps/colors consumer stay outside the DockLayouts hard cut.

Intended Solution Shape

The Engine gains a coherent src/dashboard/dock/ domain package whose folder and namespace agree:

  • Neo.dashboard.dock.Workspace remains the orchestration root;
  • model/ owns document validation, operations, persistence envelopes, preview contract, topology diff, and topology reconciliation;
  • projection/ owns layout projection, reconciliation, and motion signals;
  • interaction/ owns dock-specific split, rail/reveal, preview, drag/drop, tab, and keyboard behavior;
  • persistence/ owns the sole perspective library and restore planning;
  • window/ owns participation, workspace-set, tear-out, conversion, embodiment, and park choreography.

Binding final package tree

src/dashboard/
├── Container.mjs
├── Panel.mjs
└── dock/
    ├── Workspace.mjs
    ├── model/
    │   ├── Document.mjs
    │   ├── Operations.mjs
    │   ├── Persistence.mjs
    │   ├── PreviewContract.mjs
    │   ├── TopologyDiff.mjs
    │   └── TopologyReconciler.mjs
    ├── projection/
    │   ├── LayoutAdapter.mjs
    │   ├── Reconciler.mjs
    │   └── MotionSignal.mjs
    ├── interaction/
    │   ├── DockSplitter.mjs
    │   ├── Rail.mjs
    │   ├── RevealOverlay.mjs
    │   ├── RevealStateMachine.mjs
    │   ├── Preview.mjs
    │   ├── PreviewProducer.mjs
    │   ├── DragAffordances.mjs
    │   ├── DropIndicators.mjs
    │   ├── TabSortZone.mjs
    │   ├── TabEnterButton.mjs
    │   └── KeyboardCommands.mjs
    ├── persistence/
    │   ├── PerspectiveLibrary.mjs
    │   └── RestorePlanner.mjs
    └── window/
        ├── DragTarget.mjs
        ├── Participation.mjs
        ├── WorkspaceSet.mjs
        ├── TearOut.mjs
        ├── VesselConversion.mjs
        ├── VesselEmbodiment.mjs
        └── VesselPark.mjs

This file-level tree is the graduated target architecture. Leaves may not add, omit, rename, or re-home a module without first amending the Epic and its source Discussion authority.

DockSplitter keeps its qualifier but consumes/subclasses generic Neo.component.Splitter for DragZone/live-resize/generation mechanics; it adds only dock-document descriptors and one terminal semantic commit, using GestureClaimArbiter. Generic dashboard sorting remains outside the DockLayouts domain.

Execution-layer satellites retain their owners while adopting the final vocabulary: main-thread Flip stays under src/main/addon/, Neural-Link Dock Service stays under src/ai/client/, and SCSS mirrors the domain package across structural and theme trees.

The hard cut replaces the pre-release wire family with one enumerated neo.dock.* family. Current layout v1/v2 collapse into one final neo.dock.layout.v1; unsupported-version controls move into the new family, and a dedicated old-family control proves that no neo.harness.* compatibility parser survives.

Two semantic gaps become first-class document operations:

  • setActiveItem commits tab activation independently of close-action configuration;
  • resizeEdgeZone commits normalized edge extent once on successful release, while CSS min/max values bound preview and commit, cancel commits nothing, and auto-hide/reveal retains the committed extent.

Every consumer preserves a non-first active tab across a size-only commit and exposes its initial edge splitters: Agent Institution’s right rail, Workstation’s left/right/bottom bands, and the dashboard example’s Inspector boundary.

Mechanical anatomy/wire changes must not be reviewed in the same unit as new semantic behavior. Cross-repository consumer updates must preserve an installable state at every merge boundary through exact Engine SHA pins, without compatibility code.

Structural Placement

Structural pre-flight selected the domain tree after comparing it with the current flat src/dashboard/ package and execution-layer satellites. ArchitectureOverview.md currently has no dashboard row, so the structurally significant anatomy delivery must add the new package to its Runtime Engine inventory and link ADR 0029. The Engine-local ai:structure-map command no longer exists after the repo split; the Brain command is Agent-OS-only and therefore not an Engine placement authority. Placement evidence is the Engine architecture map, ADR 0029, the exact 30-module package census, and the execution-layer sibling boundaries.

Scalability: the five responsibility directories remain coherent if the subsystem grows. ADR conflict: ADR 0029’s state, arbitration, and JSON-first rules remain binding; §2.9 alone is explicitly superseded below. ADR genesis: no hidden new trade-off—the required ADR amendment carries the selected hard cut. Future-self risk: folder/class/wire determinism and the absence of facades make imports, stack traces, and ownership discoverable.

Contract Ledger

Target surface Source of authority Intended behavior Fallback Docs / evidence
DockLayouts package and namespace Discussion #17818 target tree; current src/dashboard/ census Folder, class namespace, JSDoc targets, theme identities, and SCSS mirrors tell one domain story None; no compatibility re-export Architecture inventory + anatomy review
Persisted document and wire family ADR 0029 plus the graduated wire inventory One neo.dock.* family, one layout v1, fail-closed new-family version controls, old-family rejection No migration reader or alias ADR amendment + unit controls
Mutation and interaction ADR 0029 reducer-container pattern; Neo.component.Splitter; GestureClaimArbiter One semantic commit path; active-item and edge extent survive unrelated projection Cancel/refusal commits nothing Component/unit/whitebox E2E witnesses
Product consumers Workstation, dashboard example, Agent Institution Final imports/styles/vocabulary; active-tab and initial-edge witnesses at final Engine SHA Exact dependency pin sequencing, never dual APIs Consumer tests + guides

Signal Ledger

  • GPT family — AUTHOR_SIGNAL: @neo-gpt at body 2026-08-28T20:28:35Z, comment DC_kwDODSospM4BFZu7.
  • Claude family — GRADUATION_APPROVED: @neo-opus-vega at body 2026-08-28T20:07:36Z, comment DC_kwDODSospM4BFZuy; non-staleness and quorum reconciled at DC_kwDODSospM4BFZvb.
  • Family-keyed quorum: met — two active families signaled and one non-author family approved.

Unresolved Dissent

None at the final body anchor. The non-author STEP_BACK’s eight points were folded and criterion 10 was discharged at DC_kwDODSospM4BFZt4.

Unresolved Liveness

  • Kimi family: no graduation signal; current identities are dark, not vetoing. Non-blocking for this non-Tier-2 architecture graduation; re-poll if a Kimi peer self-selects an implementation/review lane and surfaces a material falsifier.
  • Gemini family: operator-benched; reactivation trigger is an operator participation-status change. Non-blocking; this Epic does not mutate core values, §critical_gates, or the consensus gate.

Discussion Criteria Mapping

  • Criteria 1, 2, 6, and 7 map to the linked anatomy/wire acceptance contracts: final folder/namespace/wire inventory, one destination per source/theme/JSDoc/SCSS surface, full 55-file boundary, and named compatibility deletion.
  • Criteria 3 and 5 map to linked semantic acceptance contracts: implementation-complete edge-zone resizing and non-first active-item preservation across size-only commits.
  • Criteria 4 and 8 map to linked consumer/documentation acceptance contracts: all three consumers at final API/SHAs, apps/colors unchanged on generic roots, guides and ADR updated with code.
  • Criteria 9–11 are satisfied by the folded peer cycles, non-author STEP_BACK, and Signal Ledger above.

The native parent-child graph is the live leaf registry. This body deliberately contains no sub-ticket list and no Epic-level acceptance checklist.

Decision Record Impact

Decision Record impact: supersedes ADR 0029 §2.9’s persisted-schema clause; amends ADR 0029 elsewhere only where this graduated architecture explicitly changes the contract.

ADR successor-risk: adr-amendment-required — artifact D#17818 (graduated 2026-08-28); ADR 0029 Accepted (2026-07-02, §2.9 amended 2026-08-21); fresh evidence is npm 13.1’s five-file boundary plus the source census showing no deployed durable state for the present subsystem; route: the anatomy/wire delivery updates ADR 0029 before/with the hard cut.

Decision Record

Required. The ADR successor records the neo.dock.* hard cut, layout-version collapse, negative controls, old-family rejection, and deliberate absence of a migration reader. Other ADR 0029 contracts remain in force unless the graduated design names their amendment.

Out of Scope

  • migration readers, compatibility facades, aliases, deprecation periods, or old/new parallel implementations;
  • inventory, ledger, census, diagnostic, or proof-only deliverables;
  • moving generic Container, Panel, apps/colors, or generic dashboard SortZone into DockLayouts;
  • changing DragCoordinator into a dock-aware service;
  • persisting runtime pixels, DOM geometry, window ids, or reveal/open state;
  • unrelated docking parity work not required by the graduated target.

Avoided Traps

  • One mega PR: mechanical relocation and semantic behavior obscure each other and become unreviewable.
  • Flat namespace with new subfolders: preserves class/path mismatch and mixed ownership.
  • Parallel edge maps: node, extent, and resizable authority can drift.
  • Schema migration by habit: canonizes unshipped pre-release history against the operator’s greenfield ruling.
  • A second splitter engine: duplicates generic live-resize/generation mechanics.
  • Consumer-first compatibility shim: creates the dual API this hard cut exists to avoid.

Related

Cross-repository consumer leaf: neomjs/neo-agent-institution#39 — GitHub cannot include a foreign-repository issue in this Epic’s native subIssues count; #39 is natively blocked by both Engine children and is the third OQ8 delivery artifact.

Related: #13158
Related: #17539
Related: #17779
Related: #17819
Related: #17820
Source: Discussion #17818

Origin Session ID: 01a03dec-efe5-71b3-8c19-e6b29187b970

Retrieval Hint: query_raw_memories("D#17818 DockLayouts greenfield OQ1 OQ8 PerspectiveLibrary setActiveItem resizeEdgeZone")
Retrieval Hint: Discussion anchors DC_kwDODSospM4BFZrd → DC_kwDODSospM4BFZt4 → DC_kwDODSospM4BFZu7 → DC_kwDODSospM4BFZvb

Creation freshness: live created-descending sweep of the latest 20 open Engine issues at 2026-08-28T20:42Z found no equivalent; the all-status latest-30 A2A sweep found no competing DockLayouts Epic claim. Knowledge Base returned the older #13158/#13247 authority set but no equivalent greenfield Epic; the local corpus is known stale and was not treated as current authority.

tobiu cross-referenced by PR #17898 on Aug 31, 2026, 12:37 AM
tobiu referenced in commit c6a13fc - "fix(toolbar): a withdrawn action takes no space in the rail (#17836) on Sep 1, 2026, 1:33 PM
tobiu referenced in commit 257ca08 - "fix(dashboard): a retained dock tab keeps the classes it owns (#17836) (#18018) on Sep 1, 2026, 2:33 PM
tobiu referenced in commit d77f463 - "fix(toolbar): a withdrawn action takes no space in the rail (#18015) (#18016) on Sep 1, 2026, 2:37 PM