Skip to content

Re-record 127 stale baselines and delete the tolerance shield - #566

Merged
pftg merged 6 commits into
masterfrom
baseline-rerecord
Aug 22, 2026
Merged

Re-record 127 stale baselines and delete the tolerance shield#566
pftg merged 6 commits into
masterfrom
baseline-rerecord

Conversation

@pftg

@pftg pftg commented Aug 21, 2026

Copy link
Copy Markdown
Member

First green macOS visual suite since #540. 79 runs, 218 assertions, 0 failures / [snap_diff] 134 screenshots compared, no failures.

Why they were stale

#560 established the mechanism: the gate's default tolerance was ~50x blind AND on every PASS the gem restores the git-HEAD image over the fresh capture, so baselines fossilized. The reds were never flake and never a bad machine — they were real, correctly-detected changes nobody could re-record while the gate kept restoring the old bytes.

What was accepted, and on what evidence

Every one of the 50 macOS re-records was classified by pixel-transition histogram, never by difference_level:

n class evidence
42 #540 dark-surface recolour rgb(0,0,0)rgb(20,17,15) = 94–100% of changed px
3 #520 description backfill rendered lead matches the frontmatter string verbatim
2 #552 course module eyebrow ruby eyebrow above H1 shifts the page
3 #528 eyebrow consolidation 1px vertical offset; realigning by 1px → residual exactly 0.0000

Zero unexplained diffs — nothing was accepted as "probably drift".

Shield deleted, on a measurement

#560 introduced SECTION_CONFIGS as a documented temporary shield holding ~22 section screenshots at the old 0.02 "until their drift is measured and re-recorded". That exit condition is now met, and the cost was measured rather than assumed: shield in place = 48 failures, shield emptied = 50 — cost +2, both the #528 1px offset. The suite was re-run with the shield deleted before those two baselines were accepted, and reported exactly the two predicted failures and no others. DEFAULT_SCREENSHOT_CONFIG survives at 0.0001.

Linux

CI update-baselines dispatch on this branch (run 32526977795, native amd64), then screened with the gate's own instrument (libvips dE00 vs the 0.0001 default): 83 recorded → 77 kept, 6 dropped (difference_level exactly 0 = encoder churn). The 8 new keys include friday_report and all three next/* register pilots.

Two corrections to prior documented beliefs

  1. The diagnosis's "36 failing screenshots" was low — actual was 48 of 134, and the mobile suite (never measured before) contributed 7.
  2. test-gates.md misattributed all five failing /services/ screenshots to Phase 1a.4: dark surfaces onto --surface-ink, --ruby-on-ink, and two live AA fixes #540; only two are — the other three are Phase 1a.4: one eyebrow style (4 variants → 1) #528's 1px shift (≤0.13% black→ink transition). Corrected in the bundle.

Instrument error caught before it became a finding

The first transition script reused a temp filename; libvips caches operations by filename, so runs 2..n silently re-compared image 1 and reported a baseline as a pure-black frame. Refuted by a brightness audit of all 155 tracked macOS baselines (darkest mean 69/255). The rewritten script carries a permanent control: an unchanged baseline must report exactly 0 changed pixels. Also measured: run-to-run noise is ~1e-6, not 0 — still 100x under the floor, and the comment now says what was observed.

🤖 Generated with Claude Code

https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7fe80e0b-57b9-476f-bcd4-f63027d017df


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

pftg and others added 6 commits August 21, 2026 23:38
…pting

The macOS visual suite has been red on master since #540. `bin/rake
test:system` at clean HEAD: 79 runs, 26 failures, 134 screenshots compared,
48 failures. All 48 are correctly-detected staleness, not regressions -
nothing here was verified by difference_level alone.

Why they went stale: a green run restores the git-HEAD image over the fresh
capture, so any change small enough to pass fossilizes the baseline. #540
was large enough to fail and simply was not re-recorded; the rest had been
accumulating under the old 0.02 default since #520 and #528.

Classification (baseline-vs-candidate pixel transitions, not diff levels):

  42  #540 dark-surface recolour. rgb(0,0,0) -> rgb(20,17,15) accounts for
      94-100% of every changed pixel in each file (--surface-ink #14110f).
      Footers, CTA bands, contact_us, both pagination frames, codeblock
      frames - the same surfaces #540's own commit message lists as failing.

   3  Post `description` backfilled by #520, which the post template renders
      as a grey lead above the body, pushing content down. Verified the
      rendered text is the frontmatter string verbatim, e.g.
      stimulus-keyboard-event-filter: "In the last update of Stimulus
      v3.2.2, the ability to filter the event by PageDown and PageUp keys
      was added." (desktop+mobile code_highlight_post, inline_style_post)

   2  Course module eyebrow added by #552 - "MODULE 1 - HYPOTHESIS & SMOKE
      TEST" now renders in ruby above the H1, shifting the page down.
      (desktop+mobile course/chapter)

   1  services/_testimonials-header: a 1px vertical offset from #528's
      eyebrow consolidation. #528 touched services-critical.css and
      content-block.css and re-recorded only the two sections that exceeded
      0.02; the sections below the eyebrow shifted 1px, passed under the old
      default, and fossilized. Measured, not inferred: realigning the
      baseline by dy=+1 drops the residual to exactly 0.0000, i.e. the
      content is pixel-identical and only its position moved.

Evidence that these are stale baselines rather than flaky rendering: two
consecutive runs of DesktopSiteTest#test_services reported difference_levels
identical to 17 decimal places (_technologies 0.013838252314814815,
_use-cases 0.01749807098765432, _testimonials-header 0.005922550154320988),
and a second full-suite run produced the same 48-file set.

One instrument error worth recording, since it nearly became a finding: the
first transition script loaded each baseline from a reused temp filename, and
libvips caches operations by filename - so runs 2..n silently re-compared
image 1. It reported services/_footer's baseline as a pure-black frame. A
brightness audit over all 155 tracked macOS baselines refuted it (darkest
mean is 69/255, none below 1.0), and reloading from git buffers fixed it. The
control that keeps the rewritten script honest: an unchanged baseline
(desktop/vibe_code_rescue) reports exactly 0 changed pixels.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
…easured

SECTION_CONFIGS was introduced one day ago as an explicitly TEMPORARY shield
holding ~22 section screenshots at the old 0.02 tolerance while their drift
was unmeasured, with the exit condition written into its own comment: "delete
it once they are measured and re-recorded."

Measured both ways on the full macOS system suite, same environment, only this
variable changed:

  shield in place    134 screenshots compared, 48 failures
  shield emptied     134 screenshots compared, 50 failures

Cost of deleting it: +2 screenshots, both on /services/ -
desktop/services/_use-cases (0.017498) and desktop/services/_technologies
(0.013838). Both are the same 1px vertical offset from #528's eyebrow
consolidation already classified in the previous commit: realigning baseline
to candidate by one pixel drops the residual to exactly 0.0000 in several
bands, so the content is pixel-identical and only its position moved. Both are
re-recorded here, which is the last thing the exit condition asked for.

Deleted: SECTION_CONFIGS, screenshot_config_for, extract_section_key,
test/support/screenshot_section_config.rb and its unit test. That file existed
so the table could be unit-tested without booting Hugo or Capybara; with the
table gone there is no logic left to test, only a constant.
DEFAULT_SCREENSHOT_CONFIG moves onto ApplicationSystemTestCase unchanged at
0.0001. Per-call tolerances are untouched - ~30 calls pin their own, mostly
0.03, and those still win over the default.

Gates, all on this exact tree:
  bin/rake test:unit    287 runs, 6143 assertions, 0 failures
  bin/hugo-build        clean, 8 validators passed
  bin/rake test:system  79 runs, 218 assertions, 0 failures
                        [snap_diff] 134 screenshots compared, no failures

The suite was run with the shield deleted BEFORE these two baselines were
accepted, and reported exactly the 2 predicted failures and no others - so the
deletion is measured, not assumed.

.okf/build/test-gates.md is updated: the shield paragraph is replaced by the
measurement, and a misattribution is corrected. That file claimed all five
failing /services/ screenshots were the #540 dark-surface recolour; only the
two large ones are. The three small ones carry 0.13% or less of the
black->ink transition and are #528's 1px shift.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
The re-record was dispatched to CI on this branch (run 32526977795, native
amd64 - the only trusted way to record linux/ baselines; local ARM Docker
plants false drift) and succeeded. FORCE_SCREENSHOT_UPDATE re-records
EVERYTHING, so the bot commit touched 83 files and needed screening.

Screened with the gate's OWN instrument rather than by eye or by file size:
capybara-screenshot-diff counts a pixel as differing only above
perceptual_threshold = 2.0 dE00, and the default tolerance is now 0.0001 of
the frame. Computing that same libvips dE00 fraction for every file in the bot
commit splits it cleanly:

  keep  77  would FAIL the gate, so the rewrite is real
  drop   6  difference_level exactly 0.00000000 - would have PASSED

The 6 dropped are pure encoder churn with zero perceptual difference:
desktop+mobile course/landing, desktop+mobile blog/special/codeblocks/text,
clients/agent-inbox/_overview, clients/single-full.

Of the 77 kept, 8 are NEW keys with no linux baseline at all - friday_report
(desktop+mobile) and the three register pilots next/{editorial,precision,
rescue-room} (desktop+mobile) - and the rest span 0.000139 to 0.973.

Why the Linux set is broader than the macOS one (77 vs 50), which looks wrong
until you check it: earlier PRs re-recorded only the macOS side. #528 committed
macos/mobile/services.png and left its linux/ twin stale, so linux/mobile/services
carries a visible vertical shift that macOS no longer has - confirmed by
painting the dE00 mask over the capture: identical content, offset position.
The reverse also holds - linux/desktop/blog/special/inline_style_post barely
moves (0.000139) because the Linux blog baselines were already re-recorded
after #520, while macOS was 25% stale. Neither OS is a subset of the other.

Two kept files were inspected directly rather than accepted on their number:
linux/desktop/404.png (0.001235) is a 4px-wide strip at the right edge - a
scrollbar artifact, page content identical, and 4 x 640 px is exactly the
reported difference_level; linux/mobile/services.png (0.1389) is the #528
shift above. Both render correctly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
… a subset of the other

Records the Linux leg of the re-record in .okf/log.md and lifts two rules into
test-gates.md that were learned doing it:

- Screen a FORCE_SCREENSHOT_UPDATE record with the gate's own instrument (the
  libvips dE00 fraction above perceptual_threshold 2.0, compared to the 0.0001
  default), not by eye or file size. 83 files split 77 keep / 6 drop with no
  judgement call.
- Neither OS baseline set is a subset of the other, because earlier PRs
  re-recorded only the OS they ran on. Do not reason about one from the other.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
Independent review measured what the evidence actually supports:
- run-to-run noise is ~1e-6, not 0 (test-gates said 0.0 while the code
  comment in the same PR said 1e-6 - one PR, two numbers)
- realigning 1px zeroes SEVERAL BANDS, not the page: a sub-pixel shift
  re-rasterizes glyphs, so _use-cases still differs in 22,895 px after the
  best alignment. Content identical on inspection; the conclusion holds,
  the sentence did not
- "nothing unexplained" is really "every dominant cause explained" - three
  files carry a secondary 1px shift and two carry #540's sibling
  --ruby-on-ink token
- 20.10 still pointed at test/support/screenshot_section_config.rb, which
  this PR deletes

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
@pftg
pftg force-pushed the baseline-rerecord branch from 3d5ea96 to bbe61c1 Compare August 21, 2026 21:39
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

@pftg
pftg merged commit 6420e64 into master Aug 22, 2026
4 of 6 checks passed
@pftg
pftg deleted the baseline-rerecord branch August 22, 2026 08:21
pftg added a commit that referenced this pull request Aug 22, 2026
…d the one red (#567)

The repositioned pilot copy lived only in a scratchpad that dies with the
session, so it is now 20.09 with its apply checklist and the three claims
still awaiting Paul. Ledger carries the positioning change, #566's result,
and the residual Linux failure with the evidence that it is a stale baseline
rather than flake - plus the two wrong diagnoses it defeated, so the next
session does not repeat them.


Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Aug 22, 2026
Reflection on #566: I read a run-level conclusion of success while the job
had concluded failure, and told Paul a re-run had passed when it had not.
The same session also had a monitor fire a false 'settled' because an empty
check list contains no 'pending' to wait on. Both are the same mistake -
trusting a summary signal over the specific one, and reading 'no data yet'
as 'done'. Costly here because the screenshot job is routinely expected-red
and every merge decision depends on reading it precisely.


Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
pftg added a commit that referenced this pull request Aug 22, 2026
… it justified (#593)

The codeblocks drift was stale baselines; close it and cancel the work it justified

Re-recorded linux/ on master (dc11791, all 55) and ran local bin/dtest against
it: 55 screenshots compared, no failures. Debian ARM and Ubuntu ARM are
pixel-identical. The drift that produced five explanations over three weeks was
old amd64/Chrome-152 recordings compared against current renders.

Because a green gate and a blind gate look the same, the instrument was checked
before the result was believed: forcing background-color #ff0000 on
.post-article .highlight pre produced 16 failures - all 8 desktop plus all 8
mobile codeblocks keys and nothing else - and reverting returned it to 0. Clean
0 -> injected 16 -> reverted 0.

The consequence worth the most is a deletion. The GHCR container-publishing
plan - publish this 2.54 GB image, run CI inside it - existed solely to close a
Debian-vs-Ubuntu gap by construction. There is no gap, so it is cancelled
rather than left in the doc as a tempting someday. The rejected alternative, a
split where CI owned pixel truth and dtest was merely behavioural with
divergent keys screened, is dead too: an expected-red list is what rotted into
"everything is expected red" before #566.

What replaces both: bin/dtest is authoritative for DETECTING visual defects, so
a local red is a real defect and there is no expected-red list. CI keeps
RECORDING, because the agreement is measured rather than structural - Debian
and Ubuntu upgrade freetype independently, so it can end with nothing in this
repo changing. Reopen only on a dtest red that a master re-record then makes
green.

Two rules added, both about the shape rather than this drift:

- Suspect the baselines BEFORE the mechanism. All five theories were stories
  about a mechanism; none was a check on the instrument. "Are these current?"
  is the cheapest question available and would have ended it in a day.
- Two observers agreeing proves nothing when they share the input under test.
  Local and CI failing the same 8 keys read as corroboration and was an
  artifact - both were reading the same stale baselines, so every hypothesis
  predicted red on both.

Also records why this family and not another: dense monospace text is where any
rendering difference lands first, so the codeblocks screenshots are the suite's
canary, not an arbitrary victim - which is why they kept looking like evidence
for whichever theory was current. And docs 20.10's O3 entry is corrected; it
asserted "the 10 red Linux baselines are NOT stale", which was exactly backwards
and was repeated for three weeks.

Gates: OKF 0 ERRORs, bash -n clean, unit 289 runs / 6185 assertions / 0
failures, hugo-build green.


Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant