LearnNewsExamplesServices
Frontmatter
id18379
titleThe rendered two-root drag receipt for criterion 10: a tab dragged from one full Workstation root over a second full root never previews, stages or commits there, once two roots can coexist
stateOpen
labels
enhancementaitestingdashboard
assignees[]
createdAtSep 5, 2026, 11:27 PM
updatedAtSep 23, 2026, 1:51 AM
githubUrlhttps://github.com/neomjs/neo/issues/18379
authorneo-opus-vega
commentsCount3
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[ ] 19103 Canvas worker per window group: a second root must not kill the first, [x] 18376 A second full Workstation root opened without an opener kills the first root''s renderer: its sparklines draw through a lazily started canvas worker that is a SharedWorker
blocking[]

The rendered two-root drag receipt for criterion 10: a tab dragged from one full Workstation root over a second full root never previews, stages or commits there, once two roots can coexist

Open Backlog/active-chunk-21 enhancementaitestingdashboard
neo-opus-vega
neo-opus-vega commented on Sep 5, 2026, 11:27 PM

Context

#18303's closeout matrix requires, for criterion 10, L3 — preview and staging absence observed in a second independent full root, with a same-Group positive control. #18284 (PR #18368) delivers the ownership axis and proves the boundary at two levels: the composed four-participation unit arm (L2) and the cross-window witness — a real browser App Worker driving the real Neo.manager.DragCoordinator and real window/Participation instances, with injected window rects and a stubbed hit-test (examples/dashboard/crossWindowWitness/Harness.mjs, test/playwright/e2e/dashboard/DockCrossWindowWitnessNL.spec.mjs). What it cannot deliver is the rendered observation the matrix names: two full Workstation roots on one App SharedWorker, a header tab dragged from root A across root B's window, and root B's own DOM showing no drop indicator, no preview affordance and no staged pane, followed by the same drag committing into root A's own vessel.

The obstacle is #18376: a second full Workstation root kills the first root's renderer (its OffscreenCanvases are driven by the shared App Worker in the first root's process). The topology spec's pane-host second root (?popout=<pane>) survives but carries no workspace, so it registers no drag surface a gesture could be foreign to. Until #18376 lands, this receipt cannot be produced in the harness. This ticket owns that residual, so PR #18368's evidence declaration can name it truthfully and #18284 can close on its own acceptance criteria.

The Problem

Criterion 10 has an owner for its implementation (#18284) but, once #18284 closes, no owner for its L3 receipt. The witness stands in at contract level; the epic's matrix row stays unsatisfied at the level it names.

The Architectural Reality

  • WorkstationTopologyGroupsNL.spec.mjs already boots two roots in one context and reads the manager through root A's live Workspace over the Neural Link; its second root is the pane-host mode for the reason above.
  • WorkstationNativeTitlebarDragNL.spec.mjs and WorkstationNativePopupOverPopupNL.spec.mjs drive real cross-window drags from a main window into popups and assert rendered outcomes (.neo-dashboard-dock-drop-indicators:not(.neo-dashboard-dock-drop-indicators-hidden), .neo-dock-preview-affordance, .neo-dashboard-dock-drop-indicator-active) — the pieces the two-root journey reuses.
  • The negative reading must be taken in root B's page while the drag from root A is held over it; the positive control is the same gesture committing into A's own popup, exactly the shape of the witness's journey but rendered.

The Fix

A WorkstationTwoRootsDragNL.spec.mjs journey: boot two full roots (context.newPage()), pop a vessel out of each so both hold a popup with the same bare workspace ids under different Groups, drag a header tab from A's main window over B's popup and over B's main window — asserting in B's pages: zero visible drop indicators, zero preview affordances, no staged pane, B's documents byte-identical — then continue the same drag into A's popup and assert exactly one commit there. Runs under playwright.config.e2e.mjs once #18376's fix lets two full roots coexist.

Acceptance Criteria

  • AC-1 — The journey exists and is red-first meaningful: with both roots' resolveOwnershipId forced to one Group (a measured mutation, not committed), the negative assertions fail; restored, they pass.
  • AC-2 — The negative reading is taken from root B's own DOM during the held drag: no visible drop indicator, no preview affordance, no staged pane; B commits nothing — its commit count and transaction history are unchanged, not only its two documents byte-identical, so a no-op or history-only commit cannot hide behind equal documents.
  • AC-3 — The positive control commits exactly once into root A's own vessel in the same gesture.
  • AC-4 — #18303's criterion-10 row cites this spec as its L3 receipt, and PR #18368's residual is discharged.

Out of Scope

  • Making two full roots coexist — #18376.
  • The contract-level witness and the unit arms — delivered by #18284.

Related

  • #18303 — the epic; criterion 10
  • #18284 / PR #18368 — the implementation and the contract-level receipts; this ticket owns the residual named in its body
  • #18376 — the blocker
  • #18309 / PR #18351 — the two-root topology spec this journey extends

Blocked by #18376.

Live latest-open sweep: latest 10 open issues read at 2026-09-05 21:26Z; no equivalent (#18376 records the coexistence defect and expressly excludes this journey). A2A claim sweep: no claim; Emmy's round-2 disposition on PR #18368 (21:23Z) asks for exactly this residual to have concrete ownership.

Origin Session ID: 3711ad57-061d-43fb-b1f1-aa9dc21dedda

tobiu unassigned from @neo-gpt on Sep 14, 2026, 8:22 PM