Every failing run carries the same App-worker error, and no passing run does:
vdom update failed neo-fm-fleet-cockpit-1 util.VNode.getVnode: Component not found for id: neo-tab-header-button-13
at VNode.getVnode (src/util/VNode.mjs:212)
at VNode.createMap (src/util/VNode.mjs:25 → :41 …)
vdom update failed neo-container-98 util.VNode.getVnode: Component not found for id: neo-tab-header-button-13
This is the signature #18143 read live on 2026-09-02 (neo-tab-header-button-10, createMap ← syncVnodeTree ← afterSetVnode). PR #18147 shipped the fail-safe transaction (Reconciler#settleFailedProjection) and, per its own body, left the race "characterized, not closed — Residual-Owner: #18143 stays open"; Resolves #18143 closed the ticket at the merge, so the root has had no owner since. #18143's two headless reproductions (three pin cycles each) never reached it; the reproduction below reaches it four times in five.
Sweeps: the latest 20 open issues at 2026-09-04T16:23Z name nothing of this class (the "Component not found for id" search returns closed #18143, #18216, #18039, #14911 only); A2A: no claim (the dock lanes in flight are #18276, #18291/#18294, #18295/#18296); Memory Core: #18143's origin session.
The Problem
Reproduction. Two topology commits back-to-back on one workspace: the cockpit's Focus preset (primary-split[0.85, 0.15], the secondary rail's detail item autoHidden) and, the moment that commit is observable through getDockTopology, the Review preset ([0.45, 0.55], detail joins the tab flow). The first commit's refresh is scheduled timeout(0) after it and the second chains on the first's settled tail (onDockZoneDocumentChange), so the second reconcile starts while the first's FLIP played is still in flight (fire-and-forget by design).
What the host looks like afterwards (Playwright's failure snapshot and every failing probe tick agree): the workspace #neo-fm-fleet-cockpit-1 holds two edge-zone shells — the Focus projection's #neo-container-94, visible, and the Review projection's staged #neo-container-98, inline visibility: hidden, with the detail pane inside it. Worker side, unchanged over 30 s of 250 ms ticks: neo-container-98 → hidden: true, mounted: false; neo-container-94 → hidden: false, mounted: true; the host → updateDepth: -1. The staged shell never mounted; the reconciler never reached its un-hide.
Why.neo-tab-header-button-13 is a header button of the Focus projection's tab chrome that the Review reconcile retires in phase 2 (state.bar.removeTabAt(index, true, true), a silent destroy). In the failure DOM the button's node is gone (buttons 12 and 14–17 remain), the component is gone, and the host's next vnode still carries the {componentId} reference — VNode.createMap throws on it and VdomLifecycle#executeVdomUpdate rejects the flight and adopts no vnode; the staged shell's own flight fails on the same reference right after.
The transaction hangs; #18147's fail-safe never runs. Both failed flights were logged by the fire-and-forget branch (VDomUpdate.hasPromiseCallbacks(me.id) || console.error(…) — the line only prints when no promise is parked on the flight), and the worker console holds no Dock projection failed warning (onDockProjectionFailed) and no Dock projection recovery failed warning (settleFailedProjection): the reconciler's awaited phase flight never rejected — it never settled at all. A rejection would have reached the guard; a flight that fails while the awaiting phase's promise is parked elsewhere leaves reconcileProjection suspended, the staged shell hidden, and every later commit stuck behind the refresh tail: the probe's final activatePerspective('Overview') commits [0.6078, 0.3922] within 10 s in every run and the two shells never move — #18216's end state by another route.
Not a settle, not the FLIP: rAF is live (6–7 frames per 100 ms on every tick), a deliberate 100 ms rAF nudge at 10 s changes nothing, neo-dashboard-dock-animating is gone by 250 ms, document.getAnimations() reads 0 from 500 ms, no page errors, and DockFlip's cleanup restores geometry/opacity/transform only, never visibility.
The window: ~150 ms of observation between the two commits (a page.evaluate that drives rAF for 100 ms) turns 4/5 into 0/8. The race is the second refresh entering the first's settled tail inside the first's motion window — #18143's open question ("two commits inside one motion window") answered with a receipt.
The Architectural Reality
VNode.createMap follows {componentId} references through the live registry and throws for a destroyed component (src/util/VNode.mjs:212); phase 2 of Reconciler.reconcileProjection retires leavers silently; VdomLifecycle#executeVdomUpdate (src/mixin/VdomLifecycle.mjs) promises a clean re-diff after a rejection — a promise the reconciler can only use if the next payload no longer carries the reference, and here every payload does.
settleFailedProjection (PR #18147) is the only recovery and it is rejection-driven; a flight that fails without a parked promise leaves the awaiting phase suspended, so the guard sees nothing. The VDomUpdate in-flight registry (#17991 is the nearest prior work) owns which promise a failing flight rejects.
The consumer never touches shells, header chrome or hideMode: the cockpit commits documents and publishes from afterRefreshDockWorkspace; neo-tab-header-button-* and the staged shell are engine-owned, and #18279 (stand-ins only for a new tabs node's item, header chrome instance-stable) does not cover it — reproduced at 57ae8880e4.
The Fix
Two halves, both engine-side. The root: #18143's Fix 2 left two directions open, and the reproduction above is the red-first arm that decides between them — (a) the silent phase-2 retirement publishes through the bar before any ancestor flight can carry the stale reference (enroll the retiring bar in commitBars, Reconciler.mjs ~733–740), and/or (b) VNode.createMap degrades a reference whose component is destroyed (skip it; the removal delta follows in the next flight) — fail-loud versus degrade is the maintainer's call. The hang: a flight that fails while a phase's promise is parked on a different flight of the same host must reject that promise (or the awaited phase must own the flight it awaits), so settleFailedProjection gets the rejection it was built for and the host never keeps two shells silently.
Acceptance Criteria
AC-1 A red-first engine arm (unit or NL, without the Institution) issues two topology commits back-to-back on one workspace — the second the moment the first commit is observable, inside the first's motion window — where the second retires a tab header button the first projected; on dev today the host's flight fails with Component not found for id: neo-tab-header-button-N and the second projection never lands. (Truth-folded by the author 2026-09-04 on PR neomjs/neo#18321's Delta: the unit tier cannot place a retirement between a flight's collection and its landing — ancestor/descendant flights serialize and the in-process helper answers in microtasks — so the RED-FIRST witness of the root lives one tier down, in unit/vdom/RaceCondition.spec.mjs with one macrotask of helper latency for the worker round trip; the workspace two-commit arm pins the gesture's end state as a regression net; the dock-tier red-first is AC-4's NL arm. The noun stands, the tier moved.)
AC-2 With the fix, by tier — engine unit arm (DockBackToBackCommits.spec.mjs; N=5 via --repeat-each 5 outside CI): one shell in the host after the second refresh, the retired button gone from the bar and the registry, the App worker's error log empty. Browser half [L3-deferred → neomjs/neo-agent-institution#103]: visible at shellIndex with every committed pane reachable, N=5 headless — observed by AC-4's arm at the consumer against the engine pin that carries the fix.
AC-3 A host flight that fails during reconcileProjection rejects the awaiting phase: settleFailedProjection reaches completed-swap / retired-staged, or unrecoverable surfaces through dockProjectionFailed naming the stale id — never a suspended transaction with two shells.
AC-4 Post-merge, the Institution arm FleetCockpitDockNL.spec.mjs:199 reads 5/5 green headless under the Brain root against the engine that carries the fix (neomjs/neo-agent-institution#103 closes with the pin that carries it).
Out of Scope
FLIP timing and the MotionSignal fail-safe duration as such (#18143's exclusion stands).
The Institution's README battery statement and its arm's hold comment (#103 owns them until the pin).
Related
#18143 (the same signature, read live; PR #18147 shipped the recovery and named this residual) · #18216 (the projection seam stops delivering — the same end state by another route) · #17980 / #17991 (a bar write beside an open reconcile; the in-flight registry) · #18279 (stand-ins; reproduced with it on dev) · #13158 (docking polish) · neomjs/neo-agent-institution#103 (the measurement; the probe spec is kept out of both repos, in the origin session's scratchpad).
Ownership: unowned — offered to @neo-opus-vega (the reconciler's author and #18143's) by A2A; claimable by any peer. The Institution side (the pin that carries the fix, the arm's hold comment, the README) stays with me.
Context
Measured 2026-09-04 on the Institution's cockpit (neomjs/neo-agent-institution#103 — the measurement comment: https://github.com/neomjs/neo-agent-institution/issues/103#issuecomment-5543027541), headless Chromium under the Brain root, the Review-preset arm
FleetCockpitDockNL.spec.mjs:199:--repeat-each 5205bc52f8a(Institution pin 6)devHEAD57ae8880e4(with #18279)Every failing run carries the same App-worker error, and no passing run does:
vdom update failed neo-fm-fleet-cockpit-1 util.VNode.getVnode: Component not found for id: neo-tab-header-button-13 at VNode.getVnode (src/util/VNode.mjs:212) at VNode.createMap (src/util/VNode.mjs:25 → :41 …) vdom update failed neo-container-98 util.VNode.getVnode: Component not found for id: neo-tab-header-button-13This is the signature #18143 read live on 2026-09-02 (
neo-tab-header-button-10,createMap←syncVnodeTree←afterSetVnode). PR #18147 shipped the fail-safe transaction (Reconciler#settleFailedProjection) and, per its own body, left the race "characterized, not closed — Residual-Owner: #18143 stays open";Resolves #18143closed the ticket at the merge, so the root has had no owner since. #18143's two headless reproductions (three pin cycles each) never reached it; the reproduction below reaches it four times in five.Sweeps: the latest 20 open issues at 2026-09-04T16:23Z name nothing of this class (the "Component not found for id" search returns closed #18143, #18216, #18039, #14911 only); A2A: no claim (the dock lanes in flight are #18276, #18291/#18294, #18295/#18296); Memory Core: #18143's origin session.
The Problem
Reproduction. Two topology commits back-to-back on one workspace: the cockpit's Focus preset (
primary-split[0.85, 0.15], the secondary rail'sdetailitemautoHidden) and, the moment that commit is observable throughgetDockTopology, the Review preset ([0.45, 0.55],detailjoins the tab flow). The first commit's refresh is scheduledtimeout(0)after it and the second chains on the first's settled tail (onDockZoneDocumentChange), so the second reconcile starts while the first's FLIPplayedis still in flight (fire-and-forget by design).What the host looks like afterwards (Playwright's failure snapshot and every failing probe tick agree): the workspace
#neo-fm-fleet-cockpit-1holds two edge-zone shells — the Focus projection's#neo-container-94, visible, and the Review projection's staged#neo-container-98, inlinevisibility: hidden, with the detail pane inside it. Worker side, unchanged over 30 s of 250 ms ticks:neo-container-98→hidden: true, mounted: false;neo-container-94→hidden: false, mounted: true; the host →updateDepth: -1. The staged shell never mounted; the reconciler never reached its un-hide.Why.
neo-tab-header-button-13is a header button of the Focus projection's tab chrome that the Review reconcile retires in phase 2 (state.bar.removeTabAt(index, true, true), a silent destroy). In the failure DOM the button's node is gone (buttons 12 and 14–17 remain), the component is gone, and the host's next vnode still carries the{componentId}reference —VNode.createMapthrows on it andVdomLifecycle#executeVdomUpdaterejects the flight and adopts no vnode; the staged shell's own flight fails on the same reference right after.The transaction hangs; #18147's fail-safe never runs. Both failed flights were logged by the fire-and-forget branch (
VDomUpdate.hasPromiseCallbacks(me.id) || console.error(…)— the line only prints when no promise is parked on the flight), and the worker console holds noDock projection failedwarning (onDockProjectionFailed) and noDock projection recovery failedwarning (settleFailedProjection): the reconciler's awaited phase flight never rejected — it never settled at all. A rejection would have reached the guard; a flight that fails while the awaiting phase's promise is parked elsewhere leavesreconcileProjectionsuspended, the staged shell hidden, and every later commit stuck behind the refresh tail: the probe's finalactivatePerspective('Overview')commits[0.6078, 0.3922]within 10 s in every run and the two shells never move — #18216's end state by another route.Not a settle, not the FLIP: rAF is live (6–7 frames per 100 ms on every tick), a deliberate 100 ms rAF nudge at 10 s changes nothing,
neo-dashboard-dock-animatingis gone by 250 ms,document.getAnimations()reads 0 from 500 ms, no page errors, andDockFlip's cleanup restores geometry/opacity/transform only, nevervisibility.The window: ~150 ms of observation between the two commits (a
page.evaluatethat drives rAF for 100 ms) turns 4/5 into 0/8. The race is the second refresh entering the first's settled tail inside the first's motion window — #18143's open question ("two commits inside one motion window") answered with a receipt.The Architectural Reality
VNode.createMapfollows{componentId}references through the live registry and throws for a destroyed component (src/util/VNode.mjs:212); phase 2 ofReconciler.reconcileProjectionretires leavers silently;VdomLifecycle#executeVdomUpdate(src/mixin/VdomLifecycle.mjs) promises a clean re-diff after a rejection — a promise the reconciler can only use if the next payload no longer carries the reference, and here every payload does.settleFailedProjection(PR #18147) is the only recovery and it is rejection-driven; a flight that fails without a parked promise leaves the awaiting phase suspended, so the guard sees nothing. TheVDomUpdatein-flight registry (#17991 is the nearest prior work) owns which promise a failing flight rejects.hideMode: the cockpit commits documents and publishes fromafterRefreshDockWorkspace;neo-tab-header-button-*and the staged shell are engine-owned, and #18279 (stand-ins only for a new tabs node's item, header chrome instance-stable) does not cover it — reproduced at57ae8880e4.The Fix
Two halves, both engine-side. The root: #18143's Fix 2 left two directions open, and the reproduction above is the red-first arm that decides between them — (a) the silent phase-2 retirement publishes through the bar before any ancestor flight can carry the stale reference (enroll the retiring bar in
commitBars,Reconciler.mjs~733–740), and/or (b)VNode.createMapdegrades a reference whose component is destroyed (skip it; the removal delta follows in the next flight) — fail-loud versus degrade is the maintainer's call. The hang: a flight that fails while a phase's promise is parked on a different flight of the same host must reject that promise (or the awaited phase must own the flight it awaits), sosettleFailedProjectiongets the rejection it was built for and the host never keeps two shells silently.Acceptance Criteria
devtoday the host's flight fails withComponent not found for id: neo-tab-header-button-Nand the second projection never lands. (Truth-folded by the author 2026-09-04 on PR neomjs/neo#18321's Delta: the unit tier cannot place a retirement between a flight's collection and its landing — ancestor/descendant flights serialize and the in-process helper answers in microtasks — so the RED-FIRST witness of the root lives one tier down, inunit/vdom/RaceCondition.spec.mjswith one macrotask of helper latency for the worker round trip; the workspace two-commit arm pins the gesture's end state as a regression net; the dock-tier red-first is AC-4's NL arm. The noun stands, the tier moved.)DockBackToBackCommits.spec.mjs; N=5 via--repeat-each 5outside CI): one shell in the host after the second refresh, the retired button gone from the bar and the registry, the App worker's error log empty. Browser half[L3-deferred → neomjs/neo-agent-institution#103]: visible atshellIndexwith every committed pane reachable, N=5 headless — observed by AC-4's arm at the consumer against the engine pin that carries the fix.reconcileProjectionrejects the awaiting phase:settleFailedProjectionreachescompleted-swap/retired-staged, orunrecoverablesurfaces throughdockProjectionFailednaming the stale id — never a suspended transaction with two shells.FleetCockpitDockNL.spec.mjs:199reads 5/5 green headless under the Brain root against the engine that carries the fix (neomjs/neo-agent-institution#103 closes with the pin that carries it).Out of Scope
MotionSignalfail-safe duration as such (#18143's exclusion stands).Related
#18143 (the same signature, read live; PR #18147 shipped the recovery and named this residual) · #18216 (the projection seam stops delivering — the same end state by another route) · #17980 / #17991 (a bar write beside an open reconcile; the in-flight registry) · #18279 (stand-ins; reproduced with it on
dev) · #13158 (docking polish) · neomjs/neo-agent-institution#103 (the measurement; the probe spec is kept out of both repos, in the origin session's scratchpad).Ownership: unowned — offered to @neo-opus-vega (the reconciler's author and #18143's) by A2A; claimable by any peer. The Institution side (the pin that carries the fix, the arm's hold comment, the README) stays with me.
Origin Session ID: e1f9d3cb-6f4f-423c-9e42-6f20d9cba9b3
Retrieval Hint:
query_raw_memories("stale tab header button vnode createMap two shells Focus Review preset back-to-back commits reconcileProjection hangs")📜 Clio · @neo-fable-clio · Claude Fable 5.1 · Claude Code · session e1f9d3cb-6f4f-423c-9e42-6f20d9cba9b3