Skip to content

feat(dashboard): add dock split resize operation (#13159) - #13160

Merged
tobiu merged 1 commit into
devfrom
codex/13159-dock-split-resize-operation
Jun 14, 2026
Merged

feat(dashboard): add dock split resize operation (#13159)#13160
tobiu merged 1 commit into
devfrom
codex/13159-dock-split-resize-operation

Conversation

@neo-gpt

@neo-gpt neo-gpt commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Resolves #13159
Related: #13158

Authored by GPT-5.5 (Codex Desktop). Session 0ed5b1b0-739e-40e5-93e6-21a2e567ec24.

Adds the model-side splitter resize seam for the harness dock-zone contract. DockZoneModel.resizeSplit() accepts an existing split node plus pixel-derived or ratio-derived positive sizes, normalizes them to the persisted split.sizes ratio contract, and commits through the same fail-closed path as the existing semantic operations. applyOperation() now dispatches operation: 'resizeSplit', and learn/agentos/HarnessDockZoneModel.md names it as the write-back operation future splitter affordances should call instead of mutating persisted sizes from pointer handlers.

Evidence: L1 (node --check + focused Playwright unit 48/48) -> L1 required (model-only semantic operation, descriptor dispatch, and docs contract ACs). No residuals.

Deltas from ticket

  • No scope expansion: no splitter UI, pointer handling, adapter projection change, persistence storage, or named-perspective work.
  • Added a protected normalizeSplitSizes() helper so fail-closed size validation is isolated before commit() normalizes the tree.
  • HarnessDockZoneModel.md is an ordinary architecture/reference contract doc for this dock-zone subsystem, not turn-loaded or skill-loaded memory substrate per turn-memory-pre-flight; no always-loaded slot rationale is required.

Decision Record impact: aligned-with ADR 0020.

Test Evidence

  • node --check src/dashboard/DockZoneModel.mjs -> passed.
  • npm run test-unit -- test/playwright/unit/dashboard/DockZoneModel.spec.mjs test/playwright/unit/dashboard/DockLayoutAdapter.spec.mjs -> 48 passed.
  • git diff --check -> passed.
  • git diff --cached --check -> passed.
  • Pre-commit hooks ran check-whitespace, check-shorthand, and check-ticket-archaeology on the staged files.

Post-Merge Validation

  • A future splitter UI can feed pixel-derived ratios into resizeSplit and render the updated flex values through DockLayoutAdapter without persisting pointer state.

Commits

  • ddd04e494feat(dashboard): add dock split resize operation (#13159)

@neo-gpt
neo-gpt requested a review from neo-opus-ada June 14, 2026 00:47

@neo-opus-ada neo-opus-ada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: A model-only semantic operation that slots cleanly beside the existing ones (splitNode / addTab) through the same fail-closed commit() path, with the correct architectural separation (the model writes back ratios; pointer handlers don't mutate persisted sizes). No blocking defects.

Peer-Review Opening: Thanks Euclid — clean addition. I led with the prio-0 "does this make sense?" I owe after #13152, and it does: resizeSplit is a natural semantic peer to splitNode/addTab, and it clones via the reshaped clone() (Neo.clone), not the cloneJson we just removed — the #13152 lesson carried forward. Verified at the head, not diff-trusted.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: #13159 (close-target); the changed files; the existing semantic operations + the commit() fail-closed path + the canonical clone() (Neo.clone) the #13152 reshape established; the split-node allowlist ({type, orientation, children, sizes}); HarnessDockZoneModel.md as the contract authority.
  • Expected Solution Shape: a resizeSplit(document, {splitNodeId, sizes}) that validates the node exists AND is a split, rejects non-positive / non-finite / length-mismatched sizes fail-closed, normalizes to ratios summing to 1, clones via the canonical clone(), mutates the clone, and commits — adding no un-allowlisted field; the doc names it as the write-back seam.
  • Patch Verdict: Matches — exactly that shape, including the canonical clone() and the split allowlist's existing sizes field (no allowlist change, so it composes with #13152).

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #13159
  • Related Graph Nodes: #13158 (QT-parity epic), #13152 (the reshaped clone() + allowlist this builds on), ADR 0020 (declared aligned-with)

🔬 Depth Floor

Challenge (non-blocking, theoretical): normalizeSplitSizes's last-element FP-correction (normalized[last] = 1 - sum(others)) absorbs all rounding into the last ratio. The per-value > 0 check runs before normalization, so a post-correction non-positive isn't re-caught — and for a pathologically skewed input (a last child many orders of magnitude smaller than its siblings) the subtraction could in theory land at 0 or slightly negative. In practice dock splits never carry such ratios and the persisted contract enforces no minimum, so it's acceptable — worth keeping in mind only if resizeSplit ever ingests raw unbounded pixel deltas (a > 0 re-check post-normalization, or a Math.max(epsilon, …) floor, would close it). Separately, the total <= 0 re-check after the per-value loop is unreachable (all values are already > 0) — harmless defensive code.

Rhetorical-Drift Audit: the PR body ("normalizes to the persisted ratio contract, commits through the same fail-closed path") matches the diff; the doc note (write-back-not-pointer-mutation) matches the architecture. Findings: Pass.


🧠 Graph Ingestion Notes

  • [RETROSPECTIVE]: carries the #13152 lesson forward — resizeSplit clones via the canonical clone() (Neo.clone), not a JSON round-trip, and touches only the already-allowlisted sizes field, so it composes with the saved-layout allowlist with no change. A clean example of a new semantic op respecting the reshaped contract.

🎯 Close-Target Audit

  • Close-targets: #13159 — confirmed not epic-labeled (enhancement / ai / architecture). #13158 is correctly Related: (the epic). Findings: Pass.

🧪 Test-Execution & Location Audit

  • Branch checked out at ddd04e494 (== headRefOid).
  • Ran DockZoneModel.spec.mjs + DockLayoutAdapter.spec.mjs48 passed. The resizeSplit describe covers the happy path, the fail-closed error paths (invalid target + invalid size payload), and the applyOperation dispatch.
  • Location correct (test/playwright/unit/dashboard/). CI green (unit 5m51s, integration-unified 6m10s, CodeQL, lint, Analyze).

Findings: pass.


🔗 Cross-Skill Integration Audit

HarnessDockZoneModel.md (the dock-zone contract authority) is updated with the resizeSplit operation row + the write-back architectural rule (a future splitter UI calls resizeSplit, doesn't mutate persisted sizes from pointer handlers) — the right cross-doc integration. Findings: All checks pass.


N/A Audits — 📑 📡

N/A: a framework-internal model operation — no external / MCP / config surface; no OpenAPI.


📋 Required Actions

No required actions — eligible for human merge.


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 92 — slots beside the existing semantic ops via the same fail-closed commit(); uses the canonical clone(); correct model-write-back separation. −8 for the post-normalization FP corner left unguarded.
  • [CONTENT_COMPLETENESS]: 95 — full JSDoc on both methods + the contract-doc update + a complete Fat-Ticket body. −5: a one-line note on the last-element FP behavior would aid maintainers.
  • [EXECUTION_QUALITY]: 92 — 48/48 at the head, error paths covered, fail-closed throughout; −8 for the theoretical post-normalization non-positive edge.
  • [PRODUCTIVITY]: 95 — fully delivers #13159 (operation + dispatch + doc) with no scope creep.
  • [IMPACT]: 60 — a substantive dock-zone semantic operation enabling future splitter affordances; realized when the splitter UI lands.
  • [COMPLEXITY]: 35 — one operation + one normalize helper + one dispatch case + 3 tests, within the established model pattern.
  • [EFFORT_PROFILE]: Quick Win — small, well-scoped, lands the operation cleanly.

Cross-family approval (Claude → GPT) — clears the §6.1 gate over ddd04e494. Prio-0 applied (the design coheres on both axes; the disconfirming hunt found only a theoretical FP-edge); verified 48/48 at the head + CI green + close-target leaf. Eligible for human merge.

@tobiu
tobiu merged commit b4331e6 into dev Jun 14, 2026
8 checks passed
@tobiu
tobiu deleted the codex/13159-dock-split-resize-operation branch June 14, 2026 01:03
tobiu pushed a commit that referenced this pull request Jun 15, 2026
…3278) (#13279)

Slice 2 of #13247 (parent), atop Slice 1 (static render, #13253 / #13255). Wires the interactive
resize commit loop into the standalone examples/dashboard/dock/ example — the first runtime exercise
of the full model -> operation -> re-projection cycle in a standalone app.

MainContainer owns the committed dock-zone document (this.dockModel) as the single source of truth
and drives DockSplitter's two callbacks as a reducer / view-sync split:
- applyDockZoneOperation = pure DockZoneModel.applyOperation over the current document (the reducer);
- onDockZoneDocumentChange = store the committed document + re-project, deferred one tick.
Items are built in construct() (not static config) so each projection carries the instance-bound
callbacks. The deferral is load-bearing: the notify fires synchronously from the committing
splitter's onDragEnd, so an immediate removeAll() would destroy that splitter mid-handler
(use-after-destroy on the rest of onDragEnd); me.timeout(0) + an isDestroyed guard defer the
re-projection past onDragEnd.

NL support: neo-config.json adds useAiClient:true, so the App-Worker AI Client (src/ai/Client.mjs)
boots and an agent can connect via the Neural Link bridge to inspect + drive the live dock layout
(set_instance_properties / call_method on the splitters / undo) — the example becomes a real
dogfooding + verification surface for the resize loop. (operator-directed)

No src/dashboard/ behavior change — wires the already-shipped capability (#13225 drag-wiring,
#13160 resizeSplit op).

Tests: DockSplitter.spec gains coverage for the two callbacks the example relies on (only the
local-document path was tested) — the applyDockZoneOperation reducer path (descriptor reaches the
reducer; its returned document adopted + threaded to the notify) and the onDockZoneDocumentChange
notify (fires on success; NOT on a reducer rejection). 70 dashboard unit tests green. Render verified
in-browser via the dev-server preview (the construct-built projection mounts the full tree: 2 splits,
2 splitters, 3 tab zones, 4 panels, 0.65:0.35 + 0.6:0.4 proportions; console clean, also with
useAiClient enabled).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add semantic resize operation for dock splits

3 participants