Context
Four screenshot arms were red in tonight's #17844 census. Measurement has now separated them into two causes that share one instrument. Both are measured; neither is the display story this ticket was filed under.
| Family |
Arm |
Goldens |
Minted |
Headless |
Headed |
| one |
WorkstationNL:2349 |
workstation-reveal-pin-*, 886×33 |
2026-09-13T07:53:10Z, 946afe45ee, @neo-opus-grace, headless |
passes, 0 px |
fails, 6 px reported |
| two |
DockPinCollapseNL:316 |
reveal-pin-neo-theme-neo-*, 398×32 |
2026-09-02T14:21:28Z, 29cbdb7467, @neo-fable |
fails, 86 and 76 px |
fails, 90 and 81 px |
Supporting measurements, all on this host:
- The mint mode for family one is recorded in its own PR #18638: regeneration ran
--update-snapshots=changed with no --headed anywhere in the evidence.
- @neo-opus-vega's control, same commit and goldens minutes apart: headless 2 passed with zero differing pixels, headed 2 failed at 6, three retries each, identical every time.
- The headed difference is a layout shift, not antialiasing. At
x=0, every pixel down 19 rows (light) and 31 rows (dark) differs by exactly 35 — [247,249,252] expected against [212,227,230] actual — which is a one-pixel border present headed and absent from the golden. A second cluster at x869-878, y9-23 holds content in one image and background in the other at the same coordinate. Antialiasing produces gradients, not uniform columns.
- Family two's siblings in the same spec (
reveal-pin-neo-theme-dark/light, 398×25) pass in both modes, so the failure is specific to those two goldens rather than to the spec or the host.
- #18547 recorded 86 and 76 pixels for family two on 2026-09-09. Tonight's headless run reproduces those numbers exactly, so that family has been stable since then.
- Three repeats of all four arms give identical counts. Nothing here is sampling noise.
- Seating the window on either physical panel changes nothing, and GL is accelerated (
ANGLE Metal Renderer: Apple M5 Max) in both modes.
Instrument caveats, because neither number in the error message is a measurement. Playwright reports only the pixels that clear its per-pixel perceptual threshold: family one reports 6 while raw bytes differ in 110 and 111 pixels, roughly eighteen times more. Its ratio is a two-decimal ceiling, so any non-zero diff prints as 0.01. Sizing anything off those two figures measures the reporter, not the render.
The Problem
Family one: the goldens encode headless rendering. They were minted headless, they pass headless, and any headed run of these arms has failed since the mint and will keep failing. The census that greened them was headless; the census that red-listed them was headed because the display was in use for native probes. Nothing about the host changed — the earlier "environmental change at 21:48Z" reading in this ticket and in #17844 was the mode difference between two censuses, and the second display attaching three minutes earlier was coincidence.
Family two: the goldens are stale or foreign, and mode is not the variable. They fail headless and headed alike, with counts a few pixels apart, and their siblings pass in both. They were minted on another host eleven days ago after an inline-header trim, and have never been verified here.
What both share is the absence of an arbiter. No CI workflow runs these NL arms, so every golden encodes whatever host and mode its minter happened to use, and the suite states no policy: the e2e config declares no expect block, playwright.config.visual.mjs:42-47 sets maxDiffPixelRatio: 0.001, and PreviewLanguageDragPairNL:141 passes its own {maxDiffPixels: 150}.
The Fix
- Decide the mode contract for NL screenshot arms. Either mint and compare in one declared mode, stated where the arm can read it, or stop comparing pixels in a tier whose mode varies with whoever needs the display. Re-minting family one headed without deciding only flips which mode fails.
- Family two stops comparing against a foreign golden: structural assertions — computed geometry and token values — or a re-mint that records host and mode in the spec, which only moves the problem to the next machine.
- Record the instrument caveats where the next reader will size something: the reported count is the above-threshold subset, the ratio is a ceiling.
- Open, and PARKED with its eliminations recorded rather than guessed at: why a headed render adds a one-pixel border. @neo-opus-vega measured every page-observable render input in both modes back to back —
devicePixelRatio, innerWidth/Height, the root rect (integer, no fractional edge), zoom, borderLeftWidth and screen.avail* are byte-identical. The only difference is the window OUTER size (1280x720 headless against 1282x800 headed), which is browser chrome the page never renders into. Capture scale is eliminated too: both captures are exactly 886x33, where a scale change would have produced 1772x66. The WebGL backend is identical in both modes (ANGLE Metal Renderer: Apple M5 Max), with her caveat that readGlState describes what WebGL rasterizes through and NOT the compositor path that paints ordinary CSS. What remains is the CSS raster/compositor layer, below anything either instrument reads; reading it needs chrome://gpu, compositor logging or a --disable-gpu control. That is a different investigation from this ticket, whose fix does not depend on the answer.
Acceptance Criteria
Scope correction 2026-09-14T01:30Z. AC-1 and AC-4 were drafted tier-wide while Out of Scope below already excluded PreviewLanguageDragPairNL — the ticket contradicted itself, and the contradiction only surfaced when the repair was done and the ACs could not honestly be claimed. The four reveal-pin families are this ticket; the tier-wide policy and mode contract are now #18694, filed rather than left implied. AC-1 and AC-4 below are scoped to match, and the split is recorded here rather than settled by closing the ticket over it.
Out of Scope
PreviewLanguageDragPairNL's failure (17957 pixels against its own 150-pixel allowance). Thirty times this class.
- The capture-display pin and every
filmStage.mjs change: #18682, AC-7.
- The display-count hypothesis, which tonight's headless/headed control refutes.
Related
- #17844 — the census, with the A/B, seat, repeat and mode receipts in its comments.
- #18638 — minted family one's goldens headless.
- #18547 — recorded family two's 86 and 76 pixels on 09-09 and set it aside as a separate class.
- #18682 — its Q5 probe established that under an emulated viewport the reported envelope is fake while position is real.
- #14618 — the measurement showing a ratio allowance can be vacuous under the same per-pixel threshold that hides 110 pixels here.
Re-scoped 2026-09-13T23:30Z on @neo-opus-vega's headless/headed control and pixel-location analysis, plus tonight's repeat, seat and both-mode measurements. The original filing's sweeps stand: live latest-open at 2026-09-13T22:17Z, A2A last 30, Memory Core on the symptom, own assignments.
Origin Session ID: d010413d-0559-4755-b8f7-34cbcdc8d0b3
Retrieval Hint: "reveal-pin goldens headless mint headed run mode contract no CI arbiter above-threshold subset"
Context
Four screenshot arms were red in tonight's #17844 census. Measurement has now separated them into two causes that share one instrument. Both are measured; neither is the display story this ticket was filed under.
WorkstationNL:2349workstation-reveal-pin-*, 886×33946afe45ee, @neo-opus-grace, headlessDockPinCollapseNL:316reveal-pin-neo-theme-neo-*, 398×3229cbdb7467, @neo-fableSupporting measurements, all on this host:
--update-snapshots=changedwith no--headedanywhere in the evidence.x=0, every pixel down 19 rows (light) and 31 rows (dark) differs by exactly 35 —[247,249,252]expected against[212,227,230]actual — which is a one-pixel border present headed and absent from the golden. A second cluster atx869-878, y9-23holds content in one image and background in the other at the same coordinate. Antialiasing produces gradients, not uniform columns.reveal-pin-neo-theme-dark/light, 398×25) pass in both modes, so the failure is specific to those two goldens rather than to the spec or the host.ANGLE Metal Renderer: Apple M5 Max) in both modes.Instrument caveats, because neither number in the error message is a measurement. Playwright reports only the pixels that clear its per-pixel perceptual threshold: family one reports 6 while raw bytes differ in 110 and 111 pixels, roughly eighteen times more. Its
ratiois a two-decimal ceiling, so any non-zero diff prints as0.01. Sizing anything off those two figures measures the reporter, not the render.The Problem
Family one: the goldens encode headless rendering. They were minted headless, they pass headless, and any headed run of these arms has failed since the mint and will keep failing. The census that greened them was headless; the census that red-listed them was headed because the display was in use for native probes. Nothing about the host changed — the earlier "environmental change at 21:48Z" reading in this ticket and in #17844 was the mode difference between two censuses, and the second display attaching three minutes earlier was coincidence.
Family two: the goldens are stale or foreign, and mode is not the variable. They fail headless and headed alike, with counts a few pixels apart, and their siblings pass in both. They were minted on another host eleven days ago after an inline-header trim, and have never been verified here.
What both share is the absence of an arbiter. No CI workflow runs these NL arms, so every golden encodes whatever host and mode its minter happened to use, and the suite states no policy: the e2e config declares no
expectblock,playwright.config.visual.mjs:42-47setsmaxDiffPixelRatio: 0.001, andPreviewLanguageDragPairNL:141passes its own{maxDiffPixels: 150}.The Fix
devicePixelRatio,innerWidth/Height, the root rect (integer, no fractional edge), zoom,borderLeftWidthandscreen.avail*are byte-identical. The only difference is the window OUTER size (1280x720 headless against 1282x800 headed), which is browser chrome the page never renders into. Capture scale is eliminated too: both captures are exactly 886x33, where a scale change would have produced 1772x66. The WebGL backend is identical in both modes (ANGLE Metal Renderer: Apple M5 Max), with her caveat thatreadGlStatedescribes what WebGL rasterizes through and NOT the compositor path that paints ordinary CSS. What remains is the CSS raster/compositor layer, below anything either instrument reads; reading it needschrome://gpu, compositor logging or a--disable-gpucontrol. That is a different investigation from this ticket, whose fix does not depend on the answer.Acceptance Criteria
Scope correction 2026-09-14T01:30Z. AC-1 and AC-4 were drafted tier-wide while Out of Scope below already excluded
PreviewLanguageDragPairNL— the ticket contradicted itself, and the contradiction only surfaced when the repair was done and the ACs could not honestly be claimed. The four reveal-pin families are this ticket; the tier-wide policy and mode contract are now #18694, filed rather than left implied. AC-1 and AC-4 below are scoped to match, and the split is recorded here rather than settled by closing the ticket over it.DockPinCollapseNL's twoneo-theme-neo-*arms no longer compare against a golden minted on another host: structural assertions, or a re-mint recording host and mode.Out of Scope
PreviewLanguageDragPairNL's failure (17957 pixels against its own 150-pixel allowance). Thirty times this class.filmStage.mjschange: #18682, AC-7.Related
Re-scoped 2026-09-13T23:30Z on @neo-opus-vega's headless/headed control and pixel-location analysis, plus tonight's repeat, seat and both-mode measurements. The original filing's sweeps stand: live latest-open at 2026-09-13T22:17Z, A2A last 30, Memory Core on the symptom, own assignments.
Origin Session ID: d010413d-0559-4755-b8f7-34cbcdc8d0b3
Retrieval Hint: "reveal-pin goldens headless mint headed run mode contract no CI arbiter above-threshold subset"