LearnNewsExamplesServices
Frontmatter
id17820
titleDockSplitter previews geometry live before semantic commit
stateClosed
labels
enhancementaitestingarchitectureperformancecore
assigneesneo-fable
createdAtAug 27, 2026, 9:52 PM
updatedAtAug 29, 2026, 6:04 PM
githubUrlhttps://github.com/neomjs/neo/issues/17820
authorneo-gpt-emmy
commentsCount1
parentIssue13158
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 17837 Cut DockLayouts anatomy and wire vocabulary to final form, [x] 17819 Splitter supports proxy-free live sibling resizing
blocking[]
closedAtAug 29, 2026, 6:04 PM

DockSplitter previews geometry live before semantic commit

Closed Backlog/active-chunk-18 enhancementaitestingarchitectureperformancecore
neo-gpt-emmy
neo-gpt-emmy commented on Aug 27, 2026, 9:52 PM

Context

Neo.dashboard.DockSplitter already provides persisted interactive resizing: it captures split-child sizes at drag start, moves a proxy, and commits one resizeSplit semantic operation at drag end. The workspace then re-projects the committed dock document.

The interaction remains visually deferred: panes keep their old geometry while the proxy moves, then jump to the committed sizes. For dashboards and DockLayouts—where pane proportions are the workspace itself—live feedback has substantially higher product value than it does for a generic separator.

Live latest-open sweep: checked the latest 20 open issues at 2026-08-27T19:52:11.351Z; no equivalent found. The latest 30 A2A messages contained no overlapping claim. The newly filed generic primitive leaf #17819 is complementary rather than duplicate. Knowledge Base, Memory Core, live search, and local corpus sweeps found the existing semantic resize implementation and historical geometry fixes, but no live-preview leaf.

The Problem

The current DockSplitter listens only to drag:start and drag:end. Mid-gesture pixel geometry exists only in the moving proxy; projected split children do not preview the changing size vector. The user therefore cannot judge the actual dashboard composition until after the semantic operation commits and projection settles.

A naïve live implementation would violate the dock contract by writing persisted dockZone.v1 sizes on every pointer event. Another naïve implementation would mutate only one pane, allowing total geometry to drift. The live preview must remain runtime-only, preserve the adjacent pair's total, and leave resizeSplit as the single committed mutation.

The Architectural Reality

  • ADR 0029 §2.1 classifies splitter pixel math mid-drag as per-window runtime interaction state and committed dock documents as worker-owned shared truth.
  • ADR 0029's splitter reconciliation keeps Neo.dashboard.DockSplitter separate from Neo.component.Splitter: the dock surface must commit through the semantic reducer.
  • DockSplitter#captureDragStart() already captures child sizes, and #resolveSizeVector() already converts pointer delta into an adjacent size pair.
  • DockSplitter#onDragEnd() is the sole resizeSplit commit boundary.
  • DockLayoutAdapter projects committed sizes into Flexbox children; transient preview belongs on those projected children, not in the document.
  • #17819 supplies the shared no-proxy DragZone mechanism and exact cancel/destruction lifecycle.
  • The transform-immune measurement repairs delivered through #16375 protect Grid geometry during repeated dock re-layout; their witnesses must remain green under continuous preview.

The Fix

  1. Add public reactive Neo.dashboard.DockSplitter#liveResize, defaulting to true for DockLayouts. false retains the current proxy-and-commit presentation.
  2. In live mode, use the no-proxy DragZone path from #17819 so the real splitter remains the affordance and ordinary drag:move frames reach the App Worker.
  3. At drag start, capture the two children adjacent to boundaryIndex, their exact projected wrapperStyle values, and their rendered size total.
  4. At each move, resolve the candidate size vector and apply only the adjacent pair's transient Flexbox preview. Do not mutate dockZoneDocument, saved layouts, or perspective state.
  5. At drag end, commit exactly one resizeSplit descriptor through the existing reducer. The resulting document and re-projection become authority; transient preview styles are cleared.
  6. On Escape/rejection/destruction, restore the captured projected styles and commit no operation.
  7. Prove the interaction in the standalone dock example and Workstation with heavy Grid/TreeGrid panes, both axes, repeated moves, and cancellation.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
New Neo.dashboard.DockSplitter#liveResize Parent #13158 + ADR 0029 §2.1 splitter/runtime-state contract Default true: projected adjacent panes preview the current drag while the real splitter follows their Flexbox geometry false retains the existing proxy presentation; persisted semantics are identical JSDoc + DockLayouts guide/example Standalone + Workstation real-pointer e2e
Runtime preview size vector Existing captureDragStart(), resolveSizeVector(), and projected child wrapperStyle Only the two children around boundaryIndex change transiently; their total remains constant Invalid/rejected vector restores the capture and emits no commit JSDoc on preview helpers Unit matrix for boundaries, axes, repeated moves, and restoration
Semantic commit boundary Existing onDragEnd() → resizeSplit reducer path; ADR 0029 one-mutation-path rule Exactly one descriptor commits at successful drag end; re-projected document replaces preview authority Escape, rejection, or destruction commits zero operations and leaves the document byte-identical Existing ADR/contract links retained Operation counter + document equality + browser geometry witnesses

Decision Record impact

aligned-with ADR 0029 — this implements its existing runtime/persisted geometry split and does not amend schema, reducer authority, or package ownership.

Acceptance Criteria

  • liveResize: true is the DockSplitter default and creates no drag proxy.
  • A real drag continuously updates only the adjacent projected panes; the visible splitter follows their live Flexbox boundary.
  • Horizontal and vertical split nodes preserve the adjacent pair's total size throughout the preview.
  • dockZoneDocument, saved layouts, and perspective state remain byte-identical during every move frame.
  • Successful release commits exactly one resizeSplit; the committed normalized sizes match the final preview and re-projection does not jump.
  • Escape, rejected vectors, and destruction restore exact pre-drag styles, commit no operation, and leave no dragging/disabled/proxy residue.
  • liveResize: false retains the current proxy-and-commit interaction.
  • The standalone dock example and Workstation pass real-pointer repeated-drag coverage with representative Grid and TreeGrid panes; header/body geometry and final scrollability remain coherent. Deferred-evidence annotation (added by the claimer, PR #17849): the heavy-grid journeys are whitebox-NL-tier and external-Brain-runtime-gated post-split; #17844 owns running the battery at ≥ the merge SHA and posting receipts. The rendered component tier delivers the real-pointer tracking/parity/Escape coverage in-repo.
  • Existing DockSplitter proxy-paint, zone-id/cancel, Grid transform-immune sizing, and DockFlip motion witnesses remain green.

Out of Scope

  • Edge-zone boundary resizing or new edge-zone persisted vocabulary.
  • Dashboard module restructuring or import-path migration.
  • Changing DockZoneModel schemas or operation names.
  • Making Neo.component.Splitter aware of dock documents.
  • A parallel main-thread resize system.
  • Deleting proxy rendering; it remains the explicit fallback mode.

Avoided Traps

  • Committing on every move: violates JSON-first reducer authority and creates persistence churn.
  • One-pane mutation: can drift the split total and make preview disagree with the eventual normalized commit.
  • Full workspace re-projection per pointer frame: needlessly rebuilds the tree; preview only the adjacent projected styles, then re-project once from committed truth.
  • Absorbing edge-zone design: that changes persisted vocabulary and remains a separate architecture decision.
  • Claiming smoothness without a heavy surface: Grid/TreeGrid plus repeated real drags are the falsifier, not a blank panel.

Related

Parent: #13158
BLOCKED_BY #17819
Related: #16375
Related: #16391

Origin Session ID: 38d9509c-f70b-4ece-bab9-d810e86175ea

Retrieval Hint: query_raw_memories("DockSplitter live preview runtime-only geometry resizeSplit commit-on-end")