Context
test/playwright/e2e/workstation/WorkstationNL.spec.mjs — "a narrow long-title reveal stays contained and reads as an elevated pane" (the #18028 / PR #18038 containment arm, 420 × 900 viewport, the left rail's Dependency Graph Explorer reveal) — went red once in a whole-file run of the dense Workstation control on dev@6bfb02fc16 (2026-09-23 11:32Z, headless Chromium on the seat's own Neural Link bridge, NEO_NL_PORT per #19066), right after #19111 merged. The same arm passed 4 of 4 in isolation two minutes later (--repeat-each=4, 10 s). The whole-file reading was 7 of 9: this arm and #19094's overflow frame (PR #19109 owns that one).
The Problem
The arm compares two rendered edges that are equal by design with an exact <=:
expect(geometry.pin.right).toBeLessThanOrEqual(geometry.header.right); // :2546
Expected: <= 226.12691497802734
Received: 226.12692260742188
The pin button sits flush with the reveal header's right edge; both numbers come from getBoundingClientRect() on different nodes, and they differ by 7.6 × 10⁻⁶ px. Nothing overflowed; the layout is the intended one, and the assertion reads float noise as a containment defect. Five assertions in the arm (:2542–:2546) compare rect edges exactly; the other four are between edges separated by padding today, so only this pair is at risk — until a stylesheet makes another pair flush.
Observation vs inference: the red and the four greens are observed; why the whole-file order produced the extra 7.6 µpx (the dense tour's tabs and split fractions left on the same page) is not classified and does not need to be — an exact comparison between equal-by-design edges is wrong at any order.
The Architectural Reality
- The reveal header is a flex row and the pin is its last item, so the pin's right edge is the header's right edge by construction (the containment fix #18038 made the pin part of the header's box).
- Playwright rects are doubles from Chromium's layout units (1/64 px); sub-pixel disagreement between two nodes' rounded rects is a property of
getBoundingClientRect, not a layout fact.
- The sibling containment arms in this file (
readDockChrome, the split-chrome census) already read integers or use tolerances; this arm predates that convention.
The Fix
Compare the pin's right edge to the header's with a tolerance below a pixel and above layout-unit noise — expect(geometry.pin.right).toBeLessThanOrEqual(geometry.header.right + 0.5) — and give the four sibling edge comparisons the same half-pixel allowance, with one comment naming why (rects are rounded per node). Test-only; no engine or app file changes.
Acceptance Criteria
Out of Scope
- #19094 / PR #19109 (the whole-file run's other red); #19086's post-merge line (whole-file 9/9 ×3 on
dev), which this arm's tolerance serves but does not close.
- The reveal's containment itself (#18028, closed): the layout is right; the measurement is what moves.
Related
#18028 · PR #18038 · #19086 · #19094 · #17844 (the NL battery census)
Sweeps: live latest-20 open at 2026-09-23T11:34:03Z — none equivalent; gh issue list --search "long-title reveal" — #18028 (closed, the containment fix), #18410 / #18089 (other reveal specs, closed); A2A claims — none on this arm; query_raw_memories on the arm — no prior decision; own open assignments (#19094, #19101, #15252) — no overlap.
unowned-rationale: a one-line test tolerance any seat can land; I carry the receipt (the whole-file log and the 4/4 isolation run) and am on the notes survey; claim by self-assigning.
Origin Session ID: 522f6841-f568-4800-bff8-7ee8e1f99dd3
Retrieval Hint: query_raw_memories("WorkstationNL long-title reveal pin.right header.right sub-pixel toBeLessThanOrEqual flake whole-file")
🪢 Mnemosyne (Claude Fable 5.1 · Claude Code) · session 522f6841-f568-4800-bff8-7ee8e1f99dd3
Context
test/playwright/e2e/workstation/WorkstationNL.spec.mjs— "a narrow long-title reveal stays contained and reads as an elevated pane" (the #18028 / PR #18038 containment arm, 420 × 900 viewport, the left rail's Dependency Graph Explorer reveal) — went red once in a whole-file run of the dense Workstation control ondev@6bfb02fc16(2026-09-23 11:32Z, headless Chromium on the seat's own Neural Link bridge,NEO_NL_PORTper #19066), right after #19111 merged. The same arm passed 4 of 4 in isolation two minutes later (--repeat-each=4, 10 s). The whole-file reading was 7 of 9: this arm and #19094's overflow frame (PR #19109 owns that one).The Problem
The arm compares two rendered edges that are equal by design with an exact
<=:The pin button sits flush with the reveal header's right edge; both numbers come from
getBoundingClientRect()on different nodes, and they differ by 7.6 × 10⁻⁶ px. Nothing overflowed; the layout is the intended one, and the assertion reads float noise as a containment defect. Five assertions in the arm (:2542–:2546) compare rect edges exactly; the other four are between edges separated by padding today, so only this pair is at risk — until a stylesheet makes another pair flush.Observation vs inference: the red and the four greens are observed; why the whole-file order produced the extra 7.6 µpx (the dense tour's tabs and split fractions left on the same page) is not classified and does not need to be — an exact comparison between equal-by-design edges is wrong at any order.
The Architectural Reality
getBoundingClientRect, not a layout fact.readDockChrome, the split-chrome census) already read integers or use tolerances; this arm predates that convention.The Fix
Compare the pin's right edge to the header's with a tolerance below a pixel and above layout-unit noise —
expect(geometry.pin.right).toBeLessThanOrEqual(geometry.header.right + 0.5)— and give the four sibling edge comparisons the same half-pixel allowance, with one comment naming why (rects are rounded per node). Test-only; no engine or app file changes.Acceptance Criteria
WorkstationNL.spec.mjs:2542–:2546tolerate sub-pixel disagreement (≤ 0.5 px) and still fail on a real overflow — a control that widens the title by 1 px past the pin reds the arm.WorkstationNL.spec.mjson the seat's own bridge at the PR head.Out of Scope
dev), which this arm's tolerance serves but does not close.Related
#18028 · PR #18038 · #19086 · #19094 · #17844 (the NL battery census)
Sweeps: live latest-20 open at 2026-09-23T11:34:03Z — none equivalent;
gh issue list --search "long-title reveal"— #18028 (closed, the containment fix), #18410 / #18089 (other reveal specs, closed); A2A claims — none on this arm;query_raw_memorieson the arm — no prior decision; own open assignments (#19094, #19101, #15252) — no overlap.unowned-rationale: a one-line test tolerance any seat can land; I carry the receipt (the whole-file log and the 4/4 isolation run) and am on the notes survey; claim by self-assigning.
Origin Session ID: 522f6841-f568-4800-bff8-7ee8e1f99dd3 Retrieval Hint:
query_raw_memories("WorkstationNL long-title reveal pin.right header.right sub-pixel toBeLessThanOrEqual flake whole-file")🪢 Mnemosyne (Claude Fable 5.1 · Claude Code) · session 522f6841-f568-4800-bff8-7ee8e1f99dd3