LearnNewsExamplesServices
Frontmatter
id19897
titleWorkstation's tab-chrome receipts read the outgoing shell mid-swap
stateClosed
labels
bugaidashboard
assigneesneo-opus-grace
createdAtOct 20, 2026, 12:51 PM
updatedAtOct 20, 2026, 2:41 PM
githubUrlhttps://github.com/neomjs/neo/issues/19897
authorneo-opus-grace
commentsCount0
parentIssue19655
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtOct 20, 2026, 2:41 PM

Workstation's tab-chrome receipts read the outgoing shell mid-swap

Closed Backlog/active-chunk-9 bugaidashboard
neo-opus-grace
neo-opus-grace commented on Oct 20, 2026, 12:51 PM

Context

WorkstationReclaimEmbodimentNL › Reset and Undo carry the same live pane across the window boundary… has been quarantined since 2026-10-13 (accountable: me). It always fails at spec :200 ("the home strip projects a tab for the reclaimed item", Expected: not null). The poll just before it had already passed: holders [main], the pane mounted in root, root DOM 1, popup DOM 0. Red on both attempts in 38427910487/115402110808; healed on retry in three other runs. About 5 of 21 first attempts failed.

The Problem

Reset commits restorePerspective, a topology-class change, so the root runs the staged reconcile. Retained tab containers move into the staged shell at items[1], the swap flight runs, and only then does host.remove(outgoing) make the new shell items[0] (src/dashboard/dock/projection/Reconciler.mjs ~639–679, 883–925). During that window getTabChromeIdentity reads dock-host.items[0], the outgoing shell, which has no tabs left, and returns null (apps/workstation/view/Workspace.mjs ~510–517). getShellIdentity (~322) reads the same slot. Reconciler.liveShell(host, shellIndex) exists for exactly this window, and src/dashboard/dock/plugin/Maximize.mjs:354 already uses it.

The model and DOM are fine, and DockFlip is not involved: the read walks the App Worker component tree. The timing is inferred from code order, not witnessed.

The Fix (product)

getTabChromeIdentity and getShellIdentity resolve the shell through DockProjectionReconciler.liveShell(this.getReference('dock-host'), this.dockShellIndex) (already imported). Keep the spec's single read at :200 as the regression witness, and remove the quarantine entry.

Acceptance Criteria

  • AC-1: Both readers resolve the live shell, so a read during the swap sees the incoming shell.
  • AC-2: A unit arm reads both methods with a retiring outgoing shell at items[0] and the incoming at items[1]; it is red before the fix and green after.
  • AC-3: The quarantine entry is gone, and the spec passes on every attempt across ≥ 5 hosted runs.

Out of Scope

  • The same single-read hazard in WorkstationPopupReturnNL:113 and WorkstationReopenedPopupReturnNL:66: they read through these methods and are fixed by AC-1 without spec changes.

Related

Parent #19655 · #19718 (this spec's earlier quarantine exit).

Diagnosis: a read-only subagent of this session, key code facts re-read before filing. Sweeps at 10:50Z: live latest-20 open issues, A2A claims (none).

Origin Session ID: 1cc54e4a-b230-43bc-ac83-7519d425f6e7

tobiu referenced in commit 8955ed6 - "fix(workstation): tab-chrome and shell receipts read the live shell during a projection swap (#19897) (#19905) on Oct 20, 2026, 2:41 PM
tobiu closed this issue on Oct 20, 2026, 2:41 PM