Context
Film v1 lane 4 from the operator-endorsed claim round. The operator's v0 verdict named the missing beat directly: "we do not show the 'good parts' yet like moving one drag proxy over multiple valid target dropzones and visual hover effects." This is the beat the dock-affordance system exists to earn, and the v0 cut never shows it.
The Problem
The v0 journey exercises resizeSplit, theme flips, and the tear-out, but never the in-window cross-zone grammar: dragging one live item across a workspace while each candidate target answers with indicators and a placement preview. No journey executor drives it, no tour scene plays it, and no take has recorded it. The good parts are not missing from the product; they are missing from the choreography.
The Architectural Reality
Verified against the live source and focused headed E2E path:
apps/workstation/view/Workspace.mjs composes Neo.dashboard.DockPreview and Neo.dashboard.DockDropIndicators as persistent siblings of the projection child, then gives them to the app-neutral Neo.dashboard.DockDragAffordances controller.
Workspace#projectDockModel routes onDockCrossZoneDragMove into dragAffordances.onDragMove(...) and onDockCrossZoneDrop into dragAffordances.onDrop(...). Candidate state and the eventual descriptor therefore come from the shipped gesture owner, not a screenplay-side geometry re-derivation.
Workspace#executeTearOutStep is the sibling executor pattern: real InteractionService pointer input with film-pace tunables and observable terminal receipts.
- PR #15926 is merged; its synthetic film cursor can ride this executor's own coordinate stream.
- The original ticket premise that a margin from the window edge prevents tear-out was falsified.
Neo.draggable.container.SortZone#checkWindowBoundary measures the drag proxy against boundaryContainerRect, and the projected dock sort zone receives the source tab toolbar as that boundary. Any valid cross-zone gesture must leave that strip. The choreography must therefore suppress only enableProxyToPopup for its gesture and restore the exact prior value on every terminal. The window-edge inset remains a visual-stage safety rule, not the grammar-isolation mechanism.
- Once a sort arms, the dense toolbar can replace the source button's DOM identity. The native mouse sensor is document-global at that point, so post-arm simulated moves and terminals must use a stable
document/document.body event carrier; the sensor still derives hover truth with elementFromPoint.
The Fix
Choreography only, across three surfaces:
- Add
Workspace#executeCrossZoneShowcaseStep beside executeTearOutStep. It arms a real drag on a named live tab, temporarily disables popup conversion, walks a film-paceable path through at least two foreign zones and two placement kinds, and then settles as either:
commit: release at the final active candidate and prove the committed document equals that preview's exact operation applied to pre-gesture truth;
cancel: dispatch Escape plus release, wait for the sort zone's observable idle contract, and prove byte-identical document truth plus retired overlays.
- Add a
cross-zone-showcase cue to apps/workstation/tour/denseWorkstation.mjs so demo playback, tests, and film takes consume one screenplay.
- Add a focused leg to
test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs: default mode uses fast pacing; film mode uses the same assertions with D-010 pacing and visible dwells.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
New Workstation.view.Workspace#executeCrossZoneShowcaseStep(step, options) |
#15933; shipped DockDragAffordances move/drop contract |
Drive one native-event drag through at least two distinct foreign zones and placement kinds; beat-log the controller's active previews; commit exactly the final preview or cancel with zero document mutation. |
Reject malformed source/dwells/terminal; cancel on runtime failure; restore the exact prior enableProxyToPopup value and destroy the film cursor in finally. |
Full JSDoc on the new method and options. |
WorkstationFiveBeatNL.spec.mjs: two fresh boots, cancel + commit per boot, exact descriptor/document equality, overlay retirement, pane identity, heartbeat, and identical semantic logs. |
Existing Workstation.view.Workspace#executeCue(cue) |
Existing tour surface; #15933 |
Route type: 'cross-zone-showcase' to the new executor with the cue's own options. |
Existing unknown-cue error remains unchanged. |
Existing method remains the routing anchor; tour script documents the cue. |
denseWorkstation.spec.mjs cue vocabulary + visible-tour E2E receipt. |
Existing workstationTourScript in apps/workstation/tour/denseWorkstation.mjs |
#15252 film spine; #15933 choreography |
Add one pause cue that moves audit from right-top-tabs, dwells on scale-tabs edge-bottom and right-bottom-tabs tab-into, then commits the center merge. |
No direct reducer operation is added to the document-tier operation list; failures surface through the cue receipt. |
Script summary/caption updated. |
Unit script contract plus WorkstationNL.spec.mjs visible-tour document and cue receipts. |
Existing SortZone.enableProxyToPopup config consumed by the executor |
src/draggable/container/SortZone.mjs; live projected dock config |
Set false only for the active showcase gesture so leaving the source toolbar cannot enter popup conversion; restore the captured value in finally. |
Every return, cancel, commit, and exception restores the prior value. Window-edge margin remains presentation-only. |
Inline rationale at the mutation seam. |
Focused E2E traverses foreign zones with tear-out enabled on the workstation and proves both terminals; source lookup anchors boundary semantics. |
Existing Workspace#cancelTearOutGesture(button, release, options) internal helper |
SortZone#processDragEnd async cleanup contract; #15933 |
Optionally accept the active sort zone and stable terminal target, then poll observable zone-idle facts before reporting settled: true. Existing callers that omit options retain their prior behavior. |
Bounded poll returns settled: false; the showcase terminal treats that as residue. |
JSDoc for optional sortZone and targetId. |
Cancel followed immediately by a second gesture in each focused E2E run; no transient-layout sample or stale sensor ownership. |
Acceptance Criteria
Out of Scope
- Cross-window traverse and conversion — #15906 stage B.
- Changes to
DockDragAffordances, DockPreview, DockDropIndicators, or DockLayoutAdapter; this ticket consumes the shipped grammar.
- Sibling v1 lanes: #15923 (vessel theming), #15927 (one-frame blanks), and #15924/PR #15926 (stage + cursor).
Avoided Traps
- Confusing window margin with tear-out isolation: the tear-out boundary is the source toolbar. Executor-scoped config suppression/restoration is the isolation contract; the margin is visual only.
- A second source of truth: the beat log reads the affordance session's candidate state, never a parallel DOM/geometry inference.
- Stale source-node dispatch: after arming, the dense toolbar can replace the dragged button DOM. The stable document carrier preserves the real native sensor stream.
- Fake gestures: no direct document mutation dressed as a drag;
simulateEvent drives the native mouse path end-to-end and the shipped controller owns every preview/drop.
- Premature cancel claims: Escape dispatch is not settlement. The receipt waits for the sort zone's observable idle facts before allowing a successor gesture.
Related
#15252 (film) · #15924 / PR #15926 (stage + cursor) · #15923 · #15927 · #15906 (cross-window sibling)
Decision Record impact: none — consumes the shipped affordance grammar and adds app-owned choreography plus executable evidence.
Live latest-open sweep: checked latest 20 open issues at 2026-07-25T18:52Z; no equivalent (nearest neighbors #15924/#15926 = stage + cursor, #15906 = cross-window).
Origin Session ID: db73adaf-4f37-4d7b-9db7-f13477f2f92e
Retrieval Hint: query_raw_memories("in-window cross-zone showcase beat DockDragAffordances indicators preview dwell")
Originally authored by Mnemosyne (@neo-fable, Fable 5, Claude Code); intake correction and Contract Ledger by Emmy (@neo-gpt-emmy).
Context
Film v1 lane 4 from the operator-endorsed claim round. The operator's v0 verdict named the missing beat directly: "we do not show the 'good parts' yet like moving one drag proxy over multiple valid target dropzones and visual hover effects." This is the beat the dock-affordance system exists to earn, and the v0 cut never shows it.
The Problem
The v0 journey exercises
resizeSplit, theme flips, and the tear-out, but never the in-window cross-zone grammar: dragging one live item across a workspace while each candidate target answers with indicators and a placement preview. No journey executor drives it, no tour scene plays it, and no take has recorded it. The good parts are not missing from the product; they are missing from the choreography.The Architectural Reality
Verified against the live source and focused headed E2E path:
apps/workstation/view/Workspace.mjscomposesNeo.dashboard.DockPreviewandNeo.dashboard.DockDropIndicatorsas persistent siblings of the projection child, then gives them to the app-neutralNeo.dashboard.DockDragAffordancescontroller.Workspace#projectDockModelroutesonDockCrossZoneDragMoveintodragAffordances.onDragMove(...)andonDockCrossZoneDropintodragAffordances.onDrop(...). Candidate state and the eventual descriptor therefore come from the shipped gesture owner, not a screenplay-side geometry re-derivation.Workspace#executeTearOutStepis the sibling executor pattern: realInteractionServicepointer input with film-pace tunables and observable terminal receipts.Neo.draggable.container.SortZone#checkWindowBoundarymeasures the drag proxy againstboundaryContainerRect, and the projected dock sort zone receives the source tab toolbar as that boundary. Any valid cross-zone gesture must leave that strip. The choreography must therefore suppress onlyenableProxyToPopupfor its gesture and restore the exact prior value on every terminal. The window-edge inset remains a visual-stage safety rule, not the grammar-isolation mechanism.document/document.bodyevent carrier; the sensor still derives hover truth withelementFromPoint.The Fix
Choreography only, across three surfaces:
Workspace#executeCrossZoneShowcaseStepbesideexecuteTearOutStep. It arms a real drag on a named live tab, temporarily disables popup conversion, walks a film-paceable path through at least two foreign zones and two placement kinds, and then settles as either:commit: release at the final active candidate and prove the committed document equals that preview's exact operation applied to pre-gesture truth;cancel: dispatch Escape plus release, wait for the sort zone's observable idle contract, and prove byte-identical document truth plus retired overlays.cross-zone-showcasecue toapps/workstation/tour/denseWorkstation.mjsso demo playback, tests, and film takes consume one screenplay.test/playwright/e2e/workstation/WorkstationFiveBeatNL.spec.mjs: default mode uses fast pacing; film mode uses the same assertions with D-010 pacing and visible dwells.Contract Ledger
Workstation.view.Workspace#executeCrossZoneShowcaseStep(step, options)DockDragAffordancesmove/drop contractenableProxyToPopupvalue and destroy the film cursor infinally.WorkstationFiveBeatNL.spec.mjs: two fresh boots, cancel + commit per boot, exact descriptor/document equality, overlay retirement, pane identity, heartbeat, and identical semantic logs.Workstation.view.Workspace#executeCue(cue)type: 'cross-zone-showcase'to the new executor with the cue's own options.denseWorkstation.spec.mjscue vocabulary + visible-tour E2E receipt.workstationTourScriptinapps/workstation/tour/denseWorkstation.mjsauditfromright-top-tabs, dwells onscale-tabsedge-bottom andright-bottom-tabstab-into, then commits the center merge.WorkstationNL.spec.mjsvisible-tour document and cue receipts.SortZone.enableProxyToPopupconfig consumed by the executorsrc/draggable/container/SortZone.mjs; live projected dock configfalseonly for the active showcase gesture so leaving the source toolbar cannot enter popup conversion; restore the captured value infinally.Workspace#cancelTearOutGesture(button, release, options)internal helperSortZone#processDragEndasync cleanup contract; #15933settled: true. Existing callers that omit options retain their prior behavior.settled: false; the showcase terminal treats that as residue.sortZoneandtargetId.Acceptance Criteria
filmPaceblock with cursor and dwell pacing; the assertion set is identical to default mode.enableProxyToPopupvalue is restored for every terminal. The pointer path also retains a window-edge visual safety inset.auditinright-bottom-tabs, while preserving live pane/chrome identity.Out of Scope
DockDragAffordances,DockPreview,DockDropIndicators, orDockLayoutAdapter; this ticket consumes the shipped grammar.Avoided Traps
simulateEventdrives the native mouse path end-to-end and the shipped controller owns every preview/drop.Related
#15252 (film) · #15924 / PR #15926 (stage + cursor) · #15923 · #15927 · #15906 (cross-window sibling)
Decision Record impact: none — consumes the shipped affordance grammar and adds app-owned choreography plus executable evidence.
Live latest-open sweep: checked latest 20 open issues at 2026-07-25T18:52Z; no equivalent (nearest neighbors #15924/#15926 = stage + cursor, #15906 = cross-window).
Origin Session ID: db73adaf-4f37-4d7b-9db7-f13477f2f92e
Retrieval Hint:
query_raw_memories("in-window cross-zone showcase beat DockDragAffordances indicators preview dwell")Originally authored by Mnemosyne (@neo-fable, Fable 5, Claude Code); intake correction and Contract Ledger by Emmy (@neo-gpt-emmy).