Context
WorkstationTabRestoreNL has been red in every #17844 census I have measured — at 3044d7f86b and at 28584754ff — and it fails in isolation as well as inside the 281-test battery, taking the full 60-second timeout each time. It never reaches its gesture, so the behaviour it exists to prove (a tab dragged out of its group is not restored into the source header) has been unwitnessed for as long as it has been failing.
The arm was one of the 14 unowned reds in tonight's census triage. This ticket takes it.
The Problem
Its readiness gate (:117-124) waits for the rendered tab bars to equal the committed tabs nodes:
const tabsNodes = Object.values(doc?.nodes || {}).filter(node => node.type === 'tabs').length,
bars = await page.locator('.neo-tab-header-toolbar').count();
return tabsNodes > 0 && bars === tabsNodesInstrumented at rest, before any gesture, six identical poll samples:
tabsNodes 6 [scale-tabs, heavy-tabs, left-tabs, right-top-tabs, right-bottom-tabs, bottom-tabs]
bars 8 ["", "Queues", "100k Matrix", "Priority Alert Observatory", "MetricsAudit", "Commits", "Live Event Stream", ""]
Nothing is missing a header. There are two surplus bars, both empty, and the count equality fails in the opposite direction from what the arm's own message asserts — "every committed tabs node must have a rendered header before the gesture" sends the next reader hunting for an absent header. It cost me exactly that detour tonight.
The first surplus bar, named from the DOM:
cls neo-dashboard-dock-reveal-header neo-tab-container-inline neo-tab-header-toolbar neo-toolbar
ancestors neo-dashboard-dock-reveal-overlay-1 → neo-dashboard-dock-rail-1[neo-dashboard-dock-edge-rail-left]
rect 0×0, visible false, buttons 1, text ""
The dock's edge-rail reveal overlay carries neo-tab-header-toolbar in its class list. It is hidden, it is not a committed tabs node, and it never will be. The second surplus bar is last in the list with the same shape and emptiness — the right rail's overlay is the obvious candidate, but my capture truncated before it, so that one is inferred rather than measured.
The Architectural Reality
test/playwright/e2e/workstation/WorkstationTabRestoreNL.spec.mjs:117-124 — the predicate, with a 60s timeout.
src/tab/header/Toolbar.mjs:30 — baseCls: ['neo-tab-header-toolbar', 'neo-toolbar'], the real header.
src/draggable/tab/header/toolbar/SortZone.mjs:24 — the same two classes on a drag surface, a second source of matches.
- The reveal overlay reuses the header's classes deliberately: #18014 / PR #18019 replaced its standalone ghost button composition with a real
Neo.tab.header.Toolbar so the reveal preview matches inline tab chrome. The chrome is correct; the spec's assumption that the class implies a dock tabs node is not.
The Fix
In the spec only:
- Scope the predicate to dock tab headers — count within the projected dock tabs containers, or exclude
.neo-dashboard-dock-reveal-header — so a reveal overlay can neither satisfy nor break the gate.
- Make the failure message name both sides of the comparison, so a future mismatch reads in the direction it actually failed.
- Let the gesture run, and record what the arm's own assertions then report.
Acceptance Criteria
Out of Scope
- The other 13 unowned reds in #17844's triage.
WorkstationTabDragLabelOverlapNL's "the Metrics tab header button must be visible". Its snapshot shows no Metrics tab at all, which is a different shape; grouping the two on the word "header" is the error this ticket exists to undo.
- The reveal overlay's use of the header classes, which is intended chrome.
Related
- #17844 — the census that red-listed it; tonight's triage comment carries the unowned set.
- #18014 / PR #18019 — gave the reveal overlay a real tab header toolbar.
Live latest-open sweep: latest 20 open issues at 2026-09-13T23:37Z, no equivalent. A2A claim sweep: last 30 messages, no competing claim; my own defect-note declares this intent. Memory Core sweep: only this session's own attribution, no prior decision. Own-assignment sweep: 12 open, none covers it.
Origin Session ID: d010413d-0559-4755-b8f7-34cbcdc8d0b3
Retrieval Hint: "TabRestoreNL readiness predicate reveal overlay header counted as tab bar 8 against 6"
Context
WorkstationTabRestoreNLhas been red in every #17844 census I have measured — at3044d7f86band at28584754ff— and it fails in isolation as well as inside the 281-test battery, taking the full 60-second timeout each time. It never reaches its gesture, so the behaviour it exists to prove (a tab dragged out of its group is not restored into the source header) has been unwitnessed for as long as it has been failing.The arm was one of the 14 unowned reds in tonight's census triage. This ticket takes it.
The Problem
Its readiness gate (
:117-124) waits for the rendered tab bars to equal the committedtabsnodes:const tabsNodes = Object.values(doc?.nodes || {}).filter(node => node.type === 'tabs').length, bars = await page.locator('.neo-tab-header-toolbar').count(); return tabsNodes > 0 && bars === tabsNodesInstrumented at rest, before any gesture, six identical poll samples:
Nothing is missing a header. There are two surplus bars, both empty, and the count equality fails in the opposite direction from what the arm's own message asserts — "every committed tabs node must have a rendered header before the gesture" sends the next reader hunting for an absent header. It cost me exactly that detour tonight.
The first surplus bar, named from the DOM:
The dock's edge-rail reveal overlay carries
neo-tab-header-toolbarin its class list. It is hidden, it is not a committedtabsnode, and it never will be. The second surplus bar is last in the list with the same shape and emptiness — the right rail's overlay is the obvious candidate, but my capture truncated before it, so that one is inferred rather than measured.The Architectural Reality
test/playwright/e2e/workstation/WorkstationTabRestoreNL.spec.mjs:117-124— the predicate, with a 60s timeout.src/tab/header/Toolbar.mjs:30—baseCls: ['neo-tab-header-toolbar', 'neo-toolbar'], the real header.src/draggable/tab/header/toolbar/SortZone.mjs:24— the same two classes on a drag surface, a second source of matches.Neo.tab.header.Toolbarso the reveal preview matches inline tab chrome. The chrome is correct; the spec's assumption that the class implies a dock tabs node is not.The Fix
In the spec only:
.neo-dashboard-dock-reveal-header— so a reveal overlay can neither satisfy nor break the gate.Acceptance Criteria
Out of Scope
WorkstationTabDragLabelOverlapNL's "the Metrics tab header button must be visible". Its snapshot shows no Metrics tab at all, which is a different shape; grouping the two on the word "header" is the error this ticket exists to undo.Related
Live latest-open sweep: latest 20 open issues at 2026-09-13T23:37Z, no equivalent. A2A claim sweep: last 30 messages, no competing claim; my own defect-note declares this intent. Memory Core sweep: only this session's own attribution, no prior decision. Own-assignment sweep: 12 open, none covers it.
Origin Session ID: d010413d-0559-4755-b8f7-34cbcdc8d0b3
Retrieval Hint: "TabRestoreNL readiness predicate reveal overlay header counted as tab bar 8 against 6"