Context
Promoted from two of my defect-notes (2026-10-22 12:51Z and 18:45Z); @neo-opus-vega's triage left the filing with the seat that holds the logs. It bears on the v13.3 release question in D#19994: ordinary use exposing failures our evidence does not observe.
Observed (local; the workstation + dashboard e2e directories in one npm run test-e2e run, --workers=1): after a main-window page.reload() late in the run, .workstation-dock-host mounts but the retained panes never become visible. Two cases of test/playwright/e2e/workstation/WorkstationTopologyGroupsNL.spec.mjs:
:365 warm F5 preserves the Workspace and its live panes while the Group rebinds: at :419 the .reload-retained-witness grid resolves, its aria-rowcount climbing 31 → 81 (the feed is live), and stays hidden for 5 s.
:598 A and its pop-out share one Group … reloading A moves one generation: at :667, 17 then 7 .neo-tab-header-button.neo-draggable matches, none visible for 60 s. The page snapshot holds the toolbar and counters, no dock content.
The :598 trace (run at 47f93aad8f) shows the main thread dropping deltas ~80 ms after the reload's .workstation-dock-host wait began (src/main/DeltaUpdates.mjs:467 and :553):
insertNode: Parent not found {parentId: neo-container-1, index: 1}
insertNode: Parent not found {parentId: neo-tab-header-toolbar-11, index: 1} (also -12, -15)
insertNodeBatch: Parent not found {parentId: neo-tab-header-toolbar-13, index: 12} (also -14)
insertNode: Parent not found {parentId: neo-container-25, index: 1} (also -27, -28, -30, -31)Frequency, eleven local runs that included the spec (UTC):
| Time |
Head |
Tests |
Result |
| 12:44 |
#19992 branch |
115 |
:365 ✘ |
| 12:46 |
control |
14 |
✓ |
| 12:47 / 12:48 |
#19992 branch |
13 / 13 |
:365 ✘ / ✓ |
| 14:56 / 15:26 |
#19990 branch |
210 / 221 |
✓ / ✓ |
| 16:41 |
#20016's branch |
222 |
:365 ✘ |
| 17:56 / 18:25 |
#20006 local |
228 / 228 |
:365 ✘ / :365 ✘ |
| 18:27 |
#20006 local, this file alone |
9 |
✓ 9/9 |
| 18:44 |
47f93aad8f (#20016's head) |
226 |
:598 ✘ |
It predates #20016 (the 12:4x runs), so that PR does not introduce it. It is a month older than that: #17844's 2026-09-23 census recorded the same .reload-retained-witness red, 1 in 3 whole-file runs on clean dev, as "pre-existing and unowned". It was never filed. Hosted CI has not shown it: the last 40 E2E (Brain-gated tier) runs have 4 failures, none of this symptom. The file is not in buildScripts/util/e2eCiSelection.mjs. A sharded job runs it in a much shorter session.
The Problem
A user who presses F5 on a busy Workstation can get the toolbar back and no dock content. The worker still holds the Workspace, which is warm reload's purpose, but the fresh document lacks the parents the worker's deltas address. The 60 s wait at :667 suggests the loss is permanent, not a delay. Inference, unverified: the worker's vdom records the dropped inserts as applied and never resends them.
No oracle catches the drop itself. The automatic workerErrors fixture (test/playwright/fixtures.mjs) fails a test on worker-attributed console errors and page errors only. DeltaUpdates' console.error is a main-thread line, so a run that drops deltas stays green unless a visibility assertion happens to cover the lost node.
This is the fourth failure class on this warm-F5 arm. #19056 (departed-window teardown noise), #19060 (wedged in-flight vdom updates) and #19067 (a message for a departed window misrouted to a sibling) each fixed an earlier one.
The Architectural Reality
- Design authority:
src/manager/Transaction.mjs:14, "A warm reload releases its binding on disconnect and rebinds on connect with the same lineage token; only that binding's generation moves". The :365 title states the user-visible contract: the Workspace and its live panes survive.
- Reconnect:
src/worker/App.mjs onConnect() (:623) waits 10 ms, reads the window data, fires connect. The Group rebind runs in Neo.manager.Transaction.
- Routing:
worker.Base#sendMessage resolves a port by window id, then opts.port, then opts.windowId, then appName. Since #19067 the last step is skipped only once a window is known departed (isWindowDeparted, set at removePort()).
- Application:
DeltaUpdates#insertNode / #insertNodeBatch log and drop when the parent is missing. They do not retry and do not report back to the worker.
The Fix
Diagnose before prescribing. Two hypotheses with falsifiers; both can hold:
- H1, a stale generation's deltas land in the new one. Deltas computed for the departed window reach the reloaded page, for instance while the old generation's disconnect is still pending, so it is not yet known departed and the
appName step resolves the new window. Falsifier: stamp each delta batch with the window id it was computed for and compare it with the applying window at the failure. If the failing batches were computed for the new window, H1 falls.
- H2, incremental updates outrun the remount. Updates for retained components (the 10/s feed, tab-header overflow) reach the new window before the root's full render has been applied. Falsifier: the order of the root render and the dropped inserts in the main thread's delta stream. If the root render precedes the drops, H2 falls.
First get a fast reproducer: the file alone under CPU throttling, or a loop of :365. Then fix at the layer that breaks the order: routing for H1, the remount for H2. Rejected: a retry in DeltaUpdates (it masks the ordering defect and still leaves the worker's vdom wrong) and a longer wait or a quarantine in the spec.
Acceptance Criteria
Out of Scope
- Making the
workerErrors fixture observe main-thread errors in general: that is D#19994's detection contract. AC-3 covers this symptom only.
- The other intermittents in the same runs (FiveBeat
:3031, DemoATour, TearOutMatrix row 7, TabDragHeadersStay, …) unless the diagnosis shows they share this cause.
- The tear-out release that leaves a pane in provisional chrome (separate defect-note, @neo-opus-vega).
Related
- #19060, #19067, #19056: earlier classes on this arm. #18303 (closed): the reload epic.
- #20016, #20006: the heads where most runs were taken.
- D#19994: release-time discovery of Workstation interaction failures.
Sweeps: live latest-open (20) at 2026-10-22T21:19Z, no equivalent. Issue search for WorkstationTopologyGroupsNL, warm F5, warm reload hidden and Parent not found: closed lineage only, listed above. A2A claims in the last hour: none on this scope. Memory Core: #19060's lineage, and #17844's ordering notes on warm reload. Own assignments: #20004 and #20006 touch drag and vessel identity, not reload.
Origin Session ID: cdb5023d-349c-443c-b1ad-d8c57688c97c
Retrieval Hint: "warm reload remount insertNode Parent not found WorkstationTopologyGroupsNL hidden panes"
Context
Promoted from two of my defect-notes (2026-10-22 12:51Z and 18:45Z); @neo-opus-vega's triage left the filing with the seat that holds the logs. It bears on the v13.3 release question in D#19994: ordinary use exposing failures our evidence does not observe.
Observed (local; the
workstation+dashboarde2e directories in onenpm run test-e2erun,--workers=1): after a main-windowpage.reload()late in the run,.workstation-dock-hostmounts but the retained panes never become visible. Two cases oftest/playwright/e2e/workstation/WorkstationTopologyGroupsNL.spec.mjs::365warm F5 preserves the Workspace and its live panes while the Group rebinds: at:419the.reload-retained-witnessgrid resolves, itsaria-rowcountclimbing 31 → 81 (the feed is live), and stayshiddenfor 5 s.:598A and its pop-out share one Group … reloading A moves one generation: at:667, 17 then 7.neo-tab-header-button.neo-draggablematches, none visible for 60 s. The page snapshot holds the toolbar and counters, no dock content.The
:598trace (run at47f93aad8f) shows the main thread dropping deltas ~80 ms after the reload's.workstation-dock-hostwait began (src/main/DeltaUpdates.mjs:467and:553):insertNode: Parent not found {parentId: neo-container-1, index: 1} insertNode: Parent not found {parentId: neo-tab-header-toolbar-11, index: 1} (also -12, -15) insertNodeBatch: Parent not found {parentId: neo-tab-header-toolbar-13, index: 12} (also -14) insertNode: Parent not found {parentId: neo-container-25, index: 1} (also -27, -28, -30, -31)Frequency, eleven local runs that included the spec (UTC):
:365✘:365✘ / ✓:365✘:365✘ /:365✘47f93aad8f(#20016's head):598✘It predates #20016 (the 12:4x runs), so that PR does not introduce it. It is a month older than that: #17844's 2026-09-23 census recorded the same
.reload-retained-witnessred, 1 in 3 whole-file runs on cleandev, as "pre-existing and unowned". It was never filed. Hosted CI has not shown it: the last 40E2E (Brain-gated tier)runs have 4 failures, none of this symptom. The file is not inbuildScripts/util/e2eCiSelection.mjs. A sharded job runs it in a much shorter session.The Problem
A user who presses F5 on a busy Workstation can get the toolbar back and no dock content. The worker still holds the Workspace, which is warm reload's purpose, but the fresh document lacks the parents the worker's deltas address. The 60 s wait at
:667suggests the loss is permanent, not a delay. Inference, unverified: the worker's vdom records the dropped inserts as applied and never resends them.No oracle catches the drop itself. The automatic
workerErrorsfixture (test/playwright/fixtures.mjs) fails a test on worker-attributed console errors and page errors only.DeltaUpdates'console.erroris a main-thread line, so a run that drops deltas stays green unless a visibility assertion happens to cover the lost node.This is the fourth failure class on this warm-F5 arm. #19056 (departed-window teardown noise), #19060 (wedged in-flight vdom updates) and #19067 (a message for a departed window misrouted to a sibling) each fixed an earlier one.
The Architectural Reality
src/manager/Transaction.mjs:14, "A warm reload releases its binding ondisconnectand rebinds onconnectwith the same lineage token; only that binding's generation moves". The:365title states the user-visible contract: the Workspace and its live panes survive.src/worker/App.mjsonConnect()(:623) waits 10 ms, reads the window data, firesconnect. The Group rebind runs inNeo.manager.Transaction.worker.Base#sendMessageresolves a port by window id, thenopts.port, thenopts.windowId, thenappName. Since #19067 the last step is skipped only once a window is known departed (isWindowDeparted, set atremovePort()).DeltaUpdates#insertNode/#insertNodeBatchlog and drop when the parent is missing. They do not retry and do not report back to the worker.The Fix
Diagnose before prescribing. Two hypotheses with falsifiers; both can hold:
appNamestep resolves the new window. Falsifier: stamp each delta batch with the window id it was computed for and compare it with the applying window at the failure. If the failing batches were computed for the new window, H1 falls.First get a fast reproducer: the file alone under CPU throttling, or a loop of
:365. Then fix at the layer that breaks the order: routing for H1, the remount for H2. Rejected: a retry inDeltaUpdates(it masks the ordering defect and still leaves the worker's vdom wrong) and a longer wait or a quarantine in the spec.Acceptance Criteria
Parent not found. A witness asserts it, so the drop reds without a visibility assertion.:365and:598pass in three consecutive fullworkstation+dashboardruns at--workers=1(today: 6 of 11 runs red).Out of Scope
workerErrorsfixture observe main-thread errors in general: that is D#19994's detection contract. AC-3 covers this symptom only.:3031, DemoATour, TearOutMatrix row 7, TabDragHeadersStay, …) unless the diagnosis shows they share this cause.Related
Sweeps: live latest-open (20) at 2026-10-22T21:19Z, no equivalent. Issue search for
WorkstationTopologyGroupsNL,warm F5,warm reload hiddenandParent not found: closed lineage only, listed above. A2A claims in the last hour: none on this scope. Memory Core: #19060's lineage, and #17844's ordering notes on warm reload. Own assignments: #20004 and #20006 touch drag and vessel identity, not reload.Origin Session ID: cdb5023d-349c-443c-b1ad-d8c57688c97c
Retrieval Hint: "warm reload remount insertNode Parent not found WorkstationTopologyGroupsNL hidden panes"