Skip to content

Pilots A+B: comparison column was rendering in body ink (specificity) - #564

Merged
pftg merged 1 commit into
masterfrom
pilots-muted-fix
Aug 21, 2026
Merged

Pilots A+B: comparison column was rendering in body ink (specificity)#564
pftg merged 1 commit into
masterfrom
pilots-muted-fix

Conversation

@pftg

@pftg pftg commented Aug 21, 2026

Copy link
Copy Markdown
Member

One-line scope fix per file: .rr-td-muted (0,1,0) lost to .rr-table tbody td (0,1,2), so both merged pilots' "Full-time CTO" columns rendered identical to the "ours" column — the comparison table stopped comparing. Found by pilot C's author (C shipped with the fix), confirmed on master by C's verifier with computed colors and a generalized detector (A=1, B=1, C=0 hits).

Fix: .rr-table tbody .rr-td-muted (0,2,0). Computed before→after on true production bundles (BASE_URL-local, own fingerprinted CSS confirmed loading): A #3d3733#6b625c (5.95:1), B #45413d#6b6560 (5.74:1), all five rows each.

One baseline re-recorded (A desktop — the only capture whose frame reaches tbody rows; B's stops at the header, verified by reading the PNG). The failing diff was 0.0007 — silently green under the pre-#560 tolerance. Unit 292/6164/0; all three pilots' scoped screenshots 8/8 green; pilot C untouched.

Demo-relevant: without this, registers A and B misrepresent themselves on the lightning-demo board.

🤖 Generated with Claude Code

https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ

…in body ink

Both merged register pilots carry the specificity defect found while building
pilot C: `.rr-table tbody td` scores 0,1,2 on its two tag names and beats the
bare `.rr-td-muted` at 0,1,0 that layouts/next/landing.html puts on the
full-time column. The muted tone IS the comparison - without it the two columns
read as equally weighted and the table stops arguing anything. The CSS looks
correct in source, which is why it shipped twice.

One line each, the same scope change pilot C already uses:
`.rr-td-muted` -> `.rr-table tbody .rr-td-muted`.

Measured on PRODUCTION builds (baseURL pointed at a local origin so the browser
renders the actually-purged bundle, not jetthoughts.com's), computed colour of
all five "theirs" cells, before -> after:

- pilot A rescue-room: rgb(61, 55, 51) #3d3733 (--rr-body) -> rgb(107, 98, 92)
  #6b625c (--rr-muted), 5.95:1 on its ground
- pilot B editorial:   rgb(69, 65, 61) #45413d (--ed-body) -> rgb(107, 101, 96)
  #6b6560 (--ed-muted), 5.74:1 on its ground

Both were identical to their "ours" column before and are distinct from it
after; both cuts still clear AA. The fixed selector survives PurgeCSS in both
production bundles.

Only ONE baseline moved. Pilot A's desktop capture reaches two tbody rows, so
it failed at difference_level 0.0007 in region [1140, 991, 1351, 1064] - the
"theirs" cells exactly - and is re-recorded here with that column visibly
lighter than the one beside it. Pilot B's desktop capture stops at the table
HEADER row, and the header was never affected (only tbody cells carry the
class), so it is correctly unchanged rather than silently missed. Both mobile
captures end above the table and stayed green; neither was re-recorded.

Gates: bin/hugo-build clean; bin/rake test:unit 292 runs, 6164 assertions, 0
failures; all three pilots' desktop+mobile screenshot tests green post-commit
(8 runs, 8 screenshots, 0 failures); banned-string sweep across the built
pilots dir unchanged at zero matches, with the same grep still finding
"Typically required" 3x to show it reads the files; pilot C untouched - zero
changes to any precision file.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: 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: 0f0f83af-4ab1-404f-8d1c-86c6f65c27e0


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.

@github-actions

Copy link
Copy Markdown
Contributor

@pftg
pftg merged commit 0c23219 into master Aug 21, 2026
4 of 5 checks passed
@pftg
pftg deleted the pilots-muted-fix branch August 21, 2026 20:13
pftg added a commit that referenced this pull request Aug 21, 2026
…nc (#565)

Board carries the three live /next/ URLs, the four-persona ballots with
self-objections, the Editorial 4-1 artifact head-to-head, the fable
recommendation with its graft package, and the decision protocol - Paul
picks. Ledger rows updated for #561-#564 and the #560 gate repair; OKF
gains the BASE_URL local-production-check rule.


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
Gate fault-injection audit: 3 of 8 defects caught

Injected eight defects modelled on ones this repo has shipped, one at a
time, each followed by the narrowest gate that should catch it. Predictions
were written before any run; two were wrong and both are recorded as wrong.

Caught: above-fold contrast (A), smoothed testimonial (C), lost noindex (E).
Missed: below-fold visual (B), frozen tenure (D), banned phrase (F), the
<th> purge trap (G), broken internal link (H).

Two findings the predictions did not anticipate:

- test:links checks almost nothing. The production build renders internal
  links absolute, and lychee --offline excludes all http(s) URIs, so 133,874
  of 149,516 links are excluded; the homepage checks exactly one link, its
  own #main-content anchor. A --remap of the host onto the build dir was
  verified to catch the planted break.
- MarketingCopyTest's rendered ratchet has three hits of slack (baseline 14,
  actual 11), which is what let the injected banned phrase through.

Below-fold coverage quantified for task #12: the viewport-sized capture gates
28.3% of the editorial pilot (1080px of 3822px). The injected #564-class
defect sits at y=1090 - ten pixels outside the frame.

No baselines re-recorded; every injection reverted.


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

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Aug 22, 2026
…sted

The 2026-08-22 audit planted eight defects and the suite caught three. Three of
the five misses get gates here. Every one was injected, watched fail, reverted
and watched pass - green alone proves a test runs, not that it works.

D - a frozen tenure number. The rendered assertion cannot tell `derived` from
`frozen` while both read "18+" in 2026, and saying so in the test body is
honest but guards nothing. The freeze is plainly visible one layer down, so
NextRailTest now asserts both halves: the rendered value, and that every pilot
stub carries `derived: tenure` with no stat frozen at today's derived string.
Not a config test - the hardcoded literal IS the defect class, the way the
2026-08-14 canon audit found the founding year wrong in eight places because
each kept its own copy.

G - the PurgeCSS trap the audit called unguardable. It is unguardable by the
VISUAL gate, which builds production and so purges exactly as production does,
matching its own baseline. It is trivially visible to a set diff: styled in the
register's source CSS, present on an element in the rendered HTML, absent from
the bundle the page links. next_purge_guard_test.rb is keyed on that mechanism
rather than on `th`, so the next element type Hugo stops recording is covered
without an edit, and it reads the bundle from the page's own href - stale
fingerprinted bundles sit in the same directory.

B and the contrast hole - computed styles, not per-band screenshots. The
audit's own recommendation buys four more baselines per pilot, each needing its
noise floor measured on the platform that judges it, and still returns a pixel
delta rather than a ratio - so an intentional recolour and an AA regression stay
indistinguishable. next_pilot_contrast_test.rb asserts the comparison table's
"theirs" column computes the register's own --*-muted token, then walks every
visible text run for 4.5:1 (3:1 large, SC 1.4.3) and every control fill for 3:1
against its surround (SC 1.4.11). ~1.3s for three pages, no baselines, wired
into test:critical. It closes the hole the audit flagged separately: nothing in
this suite measured contrast as a number, and a 3.33:1 black-on-ruby button
shipped this rail on human review alone.

One mistake worth keeping. The muted-column assertion was first written as
"differs from the sibling cell and from body colour" and PASSED the exact #564
injection - in that register the "ours" column IS body colour and the injected
ink is a third value. Wrong for two runs, green both times; only the injection
said so.

Injections and failures, all reverted before the next:

  D  `derived: tenure` -> `value: "18+"`
     the tenure stat must be `derived: tenure` so layouts/next/landing.html
     computes it from site.Params.foundingYear
  D  a second stat frozen at "18+" alongside the derived one
     Expected ["Years of average developer experience"] to be empty
  G  class="rr-th-theirs" on a <th> + a matching rule
     Expected ["rr-th-theirs"] to be empty
     control: the SAME class moved onto the <td> in that row goes green, so it
     flags the purge and not merely a new class
  B  .rr-td-muted -> var(--ed-ink), below the fold
     computes rgb(27, 28, 28), not --ed-muted (rgb(107, 101, 96)).
     It resolves to --ed-ink
  A  .rr-btn-primary label -> var(--ed-ink) on the accent fill
     2.31:1 (needs 4.5:1) text a.rr-btn.rr-btn-primary
  A' .rr-td-muted -> #b5b0ab, below the fold - invisible to every screenshot
     2.15:1 (needs 4.5:1) on five cells
  A" a near-paper button fill with a readable label
     1.12:1 (needs 3.0:1) fill a.rr-btn.rr-btn-primary

Each walk asserts it measured something (>50 text pairs, >0 fills, a non-empty
styled-and-rendered set) - a walk that finds nothing is empty, and empty passes.

Gates: test:unit 289 runs / 6187 assertions / 0 failures in 1.42s (287 / 6143 /
1.33s before - the purge guard reuses the build the suite already makes);
test:critical 38 runs / 0 failures, 55 screenshots compared, no failures, no
baseline rewritten; bin/hugo-build clean; standardrb clean on the new files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011SP5gaqXEgUie8pdFrmbeJ
pftg added a commit that referenced this pull request Aug 22, 2026
Close three fault-injection gaps: 8 of 8, each gate broken before trusted

The 2026-08-22 audit planted eight defects and the suite caught three. Three of
the five misses get gates here. Every one was injected, watched fail, reverted
and watched pass - green alone proves a test runs, not that it works.

D - a frozen tenure number. The rendered assertion cannot tell `derived` from
`frozen` while both read "18+" in 2026, and saying so in the test body is
honest but guards nothing. The freeze is plainly visible one layer down, so
NextRailTest now asserts both halves: the rendered value, and that every pilot
stub carries `derived: tenure` with no stat frozen at today's derived string.
Not a config test - the hardcoded literal IS the defect class, the way the
2026-08-14 canon audit found the founding year wrong in eight places because
each kept its own copy.

G - the PurgeCSS trap the audit called unguardable. It is unguardable by the
VISUAL gate, which builds production and so purges exactly as production does,
matching its own baseline. It is trivially visible to a set diff: styled in the
register's source CSS, present on an element in the rendered HTML, absent from
the bundle the page links. next_purge_guard_test.rb is keyed on that mechanism
rather than on `th`, so the next element type Hugo stops recording is covered
without an edit, and it reads the bundle from the page's own href - stale
fingerprinted bundles sit in the same directory.

B and the contrast hole - computed styles, not per-band screenshots. The
audit's own recommendation buys four more baselines per pilot, each needing its
noise floor measured on the platform that judges it, and still returns a pixel
delta rather than a ratio - so an intentional recolour and an AA regression stay
indistinguishable. next_pilot_contrast_test.rb asserts the comparison table's
"theirs" column computes the register's own --*-muted token, then walks every
visible text run for 4.5:1 (3:1 large, SC 1.4.3) and every control fill for 3:1
against its surround (SC 1.4.11). ~1.3s for three pages, no baselines, wired
into test:critical. It closes the hole the audit flagged separately: nothing in
this suite measured contrast as a number, and a 3.33:1 black-on-ruby button
shipped this rail on human review alone.

One mistake worth keeping. The muted-column assertion was first written as
"differs from the sibling cell and from body colour" and PASSED the exact #564
injection - in that register the "ours" column IS body colour and the injected
ink is a third value. Wrong for two runs, green both times; only the injection
said so.

Injections and failures, all reverted before the next:

  D  `derived: tenure` -> `value: "18+"`
     the tenure stat must be `derived: tenure` so layouts/next/landing.html
     computes it from site.Params.foundingYear
  D  a second stat frozen at "18+" alongside the derived one
     Expected ["Years of average developer experience"] to be empty
  G  class="rr-th-theirs" on a <th> + a matching rule
     Expected ["rr-th-theirs"] to be empty
     control: the SAME class moved onto the <td> in that row goes green, so it
     flags the purge and not merely a new class
  B  .rr-td-muted -> var(--ed-ink), below the fold
     computes rgb(27, 28, 28), not --ed-muted (rgb(107, 101, 96)).
     It resolves to --ed-ink
  A  .rr-btn-primary label -> var(--ed-ink) on the accent fill
     2.31:1 (needs 4.5:1) text a.rr-btn.rr-btn-primary
  A' .rr-td-muted -> #b5b0ab, below the fold - invisible to every screenshot
     2.15:1 (needs 4.5:1) on five cells
  A" a near-paper button fill with a readable label
     1.12:1 (needs 3.0:1) fill a.rr-btn.rr-btn-primary

Each walk asserts it measured something (>50 text pairs, >0 fills, a non-empty
styled-and-rendered set) - a walk that finds nothing is empty, and empty passes.

Gates: test:unit 289 runs / 6187 assertions / 0 failures in 1.42s (287 / 6143 /
1.33s before - the purge guard reuses the build the suite already makes);
test:critical 38 runs / 0 failures, 55 screenshots compared, no failures, no
baseline rewritten; bin/hugo-build clean; standardrb clean on the new files.


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