Context
v13.2 needs one public scene that shows Neo's unique cross-window docking property: a live component moves between two active OS-window workspaces on the shared App-Worker heap without being serialized, recreated, or remounted.
Live reconciliation (2026-07-12): the broader pop-out / reattach continuity story already shipped through #14590 / PR #14999. The unique remaining value here is the real mid-gesture transfer: cold first gesture, remote target commit exactly once, source-local drop suppression exactly once, both workspace documents changing truthfully, and the same live instance continuing in the target.
The Problem
The engine contracts now exist, but the public product scene does not. A semantic transferItem unit or test-scoped composition can prove the reducer and participation seams; it cannot show the actual two-window pointer journey or falsify a broken gesture move leg. Conversely, a narrated pause cue with enough delay can look correct while racing the driver, which would violate the tour runner's settledness contract.
Architectural Reality
- ADR 0029 §2.3 remains the authority:
DragCoordinator is dock-blind; both workspaces share one sortGroup; target-side DockCrossWindowParticipation commits transferItem; source-side completion suppresses the local drop; documents stay worker-owned.
neo.tour.script.v1 currently executes op, pause, and topology-assert. It reserves cross-window and rejects it fail-closed. TourRunner passes ordinary surface cues as data but does not await them.
Neo.ai.client.InteractionService#simulateEvent already dispatches an ordered event sequence to named windows. Mouse-event options are forwarded to MouseEvent, including screenX / screenY; this is the existing primitive to falsify before inventing a new driver.
- Placement is the AgentOS dockdemo childapp, reusing Demo B's stateful Workbench/counter and visual language. This leaf does not own #14640's separate live
examples/dashboard/dock smoke residual.
- #14980 is the live readiness dependency. A blind delay is forbidden; the scene waits for the owning readiness contract or fails closed.
Intended Solution
Phase 0 — the driver falsifier (first implementation action after #14980)
Build two active dockdemo workspaces with the same sortGroup, place their windows deterministically, and drive one event sequence through the existing InteractionService:
mousedown on the source tab header;
- source-window
mousemove events through the local drag threshold;
- source-window
mousemove events whose screenX / screenY cross into the target workspace;
- source-window
mouseup after the target accepts.
The probe passes only if the real move leg reaches DragCoordinator, the target commits once, the source suppresses its local drop once, and both documents reach the expected state. Synthetic DOM success alone is not success.
If this probe fails, stop the ticket before schema work and route the need for a new native/external driver through the Ideation Sandbox. Do not conceal the failure behind Playwright-only semantic calls or sleeps.
Phase 1 — activate the reserved tour step, only after the probe passes
Activate cross-window as an additive neo.tour.script.v1 step through an optional injected host executor, mirroring the existing injected dockService pattern:
{
type : 'cross-window',
itemId : 'workbench',
sourceWorkspaceId: 'demo-b-main',
targetWorkspaceId: 'demo-b-popup',
targetNodeId : 'popup-tabs'
}The JSON script carries semantic workspace/item/node identities only—never runtime window ids, DOM ids, pixel coordinates, functions, or live references. The dockdemo host resolves current windows and geometry and executes the verified InteractionService sequence.
TourRunner awaits crossWindowExecutor.executeCrossWindowStep(step) and accepts only a structured result:
{
applied,
errors,
sourceDocument,
targetDocument,
witness: {instanceId, mountCount}
}Without a compatible executor, cross-window remains unavailable and validation fails closed. Existing scripts and all three existing step types remain byte-for-byte compatible. The runner logs the semantic step + structured outcome; no timestamps or runtime coordinates enter the replay log.
Phase 2 — product + proof
Reuse the Demo B Workbench counter as the visible continuity witness. The scene captures pre-state, performs the real drag, and then proves:
- target document gained the item at the named node;
- source document lost it and did not commit a second local move;
- the live
instanceId is identical before/after;
- the mount counter did not increment and the visible counter kept advancing;
- the record-mode take uses the same script and structured step outcome as the spec.
Contract Ledger
| Target surface |
Source of authority |
Behavior |
Failure posture |
Evidence |
cross-window script step |
neo.tour.script.v1 reserved vocabulary + this ticket |
semantic workspace/item/node data; enabled only with an injected executor |
absent/incompatible executor remains reserved and fails closed |
validator + mode/log identity units |
| gesture driver |
existing InteractionService.simulateEvent + #14980 readiness |
one source-window event sequence crosses target screen coordinates |
failed move-leg/target acceptance aborts; no sleep fallback |
two-window falsifier against the real coordinator |
| participation |
ADR 0029 §2.3 + DockCrossWindowParticipation |
target transferItem once; source local-drop suppression once |
unknown source/target/sortGroup refuses without document mutation |
counters/traces + both-document truth |
| continuity witness |
Demo B Workbench live instance |
same instance and mount count; visible state continues |
missing witness or remount fails the scene |
NL instance read + visible counter |
| topology proof |
each workspace's live dock document + diff_dock_topology |
deterministic pre/post deltas on both documents |
missing/invalid holder fails closed |
exact diff assertions in whitebox E2E |
| record surface |
TourRunner record mode |
same semantic step/log as spec; reduced-motion preflight remains enforced |
driver failure aborts the take visibly |
repeat-run log equality + operator eyes-on |
Acceptance Criteria
Out of Scope
Rebuilding Demo B's generic pop-out/reattach continuity · changing DragCoordinator semantics · window-manager architecture · a new driver subsystem before the existing InteractionService falsifier · #14640's standalone-example smoke residual.
Dependencies and Lineage
Parent #13158 · live blocker #14980 · consumes landed #14768/#14769/#14640 substrate · reuses #14590 / PR #14999 continuity pane · siblings #14589/#14591. Decision-record impact: aligned with ADR 0029 §2.3; additive reserved-step activation only after the falsifier.
Origin Session ID: de713f27-0e82-4960-b4c6-f281e0c36449
Retrieval Hint: "cross-window tour step InteractionService screen coordinates commit once suppression once instance continuity"
Context
v13.2 needs one public scene that shows Neo's unique cross-window docking property: a live component moves between two active OS-window workspaces on the shared App-Worker heap without being serialized, recreated, or remounted.
Live reconciliation (2026-07-12): the broader pop-out / reattach continuity story already shipped through #14590 / PR #14999. The unique remaining value here is the real mid-gesture transfer: cold first gesture, remote target commit exactly once, source-local drop suppression exactly once, both workspace documents changing truthfully, and the same live instance continuing in the target.
The Problem
The engine contracts now exist, but the public product scene does not. A semantic
transferItemunit or test-scoped composition can prove the reducer and participation seams; it cannot show the actual two-window pointer journey or falsify a broken gesture move leg. Conversely, a narratedpausecue with enough delay can look correct while racing the driver, which would violate the tour runner's settledness contract.Architectural Reality
DragCoordinatoris dock-blind; both workspaces share onesortGroup; target-sideDockCrossWindowParticipationcommitstransferItem; source-side completion suppresses the local drop; documents stay worker-owned.neo.tour.script.v1currently executesop,pause, andtopology-assert. It reservescross-windowand rejects it fail-closed.TourRunnerpasses ordinary surface cues as data but does not await them.Neo.ai.client.InteractionService#simulateEventalready dispatches an ordered event sequence to named windows. Mouse-event options are forwarded toMouseEvent, includingscreenX/screenY; this is the existing primitive to falsify before inventing a new driver.examples/dashboard/docksmoke residual.Intended Solution
Phase 0 — the driver falsifier (first implementation action after #14980)
Build two active dockdemo workspaces with the same
sortGroup, place their windows deterministically, and drive one event sequence through the existing InteractionService:mousedownon the source tab header;mousemoveevents through the local drag threshold;mousemoveevents whosescreenX/screenYcross into the target workspace;mouseupafter the target accepts.The probe passes only if the real move leg reaches
DragCoordinator, the target commits once, the source suppresses its local drop once, and both documents reach the expected state. Synthetic DOM success alone is not success.If this probe fails, stop the ticket before schema work and route the need for a new native/external driver through the Ideation Sandbox. Do not conceal the failure behind Playwright-only semantic calls or sleeps.
Phase 1 — activate the reserved tour step, only after the probe passes
Activate
cross-windowas an additiveneo.tour.script.v1step through an optional injected host executor, mirroring the existing injecteddockServicepattern:{ type : 'cross-window', itemId : 'workbench', sourceWorkspaceId: 'demo-b-main', targetWorkspaceId: 'demo-b-popup', targetNodeId : 'popup-tabs' }The JSON script carries semantic workspace/item/node identities only—never runtime window ids, DOM ids, pixel coordinates, functions, or live references. The dockdemo host resolves current windows and geometry and executes the verified InteractionService sequence.
TourRunnerawaitscrossWindowExecutor.executeCrossWindowStep(step)and accepts only a structured result:{ applied, errors, sourceDocument, targetDocument, witness: {instanceId, mountCount} }Without a compatible executor,
cross-windowremains unavailable and validation fails closed. Existing scripts and all three existing step types remain byte-for-byte compatible. The runner logs the semantic step + structured outcome; no timestamps or runtime coordinates enter the replay log.Phase 2 — product + proof
Reuse the Demo B Workbench counter as the visible continuity witness. The scene captures pre-state, performs the real drag, and then proves:
instanceIdis identical before/after;Contract Ledger
cross-windowscript stepneo.tour.script.v1reserved vocabulary + this ticketInteractionService.simulateEvent+ #14980 readinessDockCrossWindowParticipationtransferItemonce; source local-drop suppression oncediff_dock_topologyrecordmodeAcceptance Criteria
cross-windowbecomes executable only with the injected host executor; absent executor still fails closed as reserved.instanceIdis stable, mount count does not increment, and visible state continues through transfer.Out of Scope
Rebuilding Demo B's generic pop-out/reattach continuity · changing
DragCoordinatorsemantics · window-manager architecture · a new driver subsystem before the existing InteractionService falsifier · #14640's standalone-example smoke residual.Dependencies and Lineage
Parent #13158 · live blocker #14980 · consumes landed #14768/#14769/#14640 substrate · reuses #14590 / PR #14999 continuity pane · siblings #14589/#14591. Decision-record impact: aligned with ADR 0029 §2.3; additive reserved-step activation only after the falsifier.
Origin Session ID:
de713f27-0e82-4960-b4c6-f281e0c36449Retrieval Hint: "cross-window tour step InteractionService screen coordinates commit once suppression once instance continuity"