Repository navigation
wcag: linearize below the cited 0.04045 knee, not the older 0.03928 - #13414
Conversation
The cited WCAG 2.2 definition of relative luminance specifies the sRGB threshold 0.04045 (its Note 2 records 0.03928 as the value before May 2021); the code's linearize_channel_scaled used 392/10000. The two constants agree on every 8-bit channel at unity white -- the disagreement window (scale-10000 393..404) is reachable only through scaled entries, which is why the module's pins never sampled it. New witnesses pin the cited knee at 393 (30, against the defective 29) and pin an outcome flip at a real threshold: the pair (393,0,500)/(8000,1000,8000) fails AA normal text under the cited knee while the defective knee called it sufficient. A third witness transcribes the threshold half of the citation against the live criterion text: 450/300/700 (SC 1.4.3, SC 1.4.11, SC 1.4.6) -- verified unchanged. RFM receipt appended under a_citation_attests_a_decision_rule_the_code_does_not_implement (wcag half).
The dated repair receipt for the wcag half of a_citation_attests_a_decision_rule_the_code_does_not_implement lands with the PR that carries the fix (the knee repair in wcag_contrast.dag), so the ledger is true at this head; the semver half's receipt lives with #13412.
briansrls
left a comment
There was a problem hiding this comment.
The code and ledger pass.
At scale 10,000, c <= 0.04045 is exactly c_scaled <= 404; 405 represents 0.0405 and belongs on the gamma arm. The 393 control discriminates the old and cited knees, and the composed color-pair control reaches a real AA-normal verdict flip rather than merely pinning the constant. The existing 450/300/700 rows agree with WCAG 2.2's 4.5:1 AA normal-text, 3:1 AA large-text/non-text, and 7:1 AAA normal-text criteria.
The RFM is truthful at this exact head: it contains the WCAG repair receipt only and explicitly says the semver half is repaired in separate PR #13412. Conversely, #13412's exact head contains the semver repair receipt only.
One nonblocking PR-description correction remains: the body says both repair receipts landed with #13412. They did not; the receipts are split across the two exact heads. Please correct that sentence, and preserve both receipts when this branch later merges/rebases over whichever sibling lands first.
All four exact-head jobs are green. No code blocker.
Repairs the wcag half of
a_citation_attests_a_decision_rule_the_code_does_not_implement.Cited rule (re-read live, www.w3.org/TR/WCAG22/#dfn-relative-luminance, retrieved 2026-10-05). For the sRGB colourspace, each channel c linearizes as c/12.92 when c <= 0.04045, else ((c+0.055)/1.055)^2.4. Note 2 on that definition records 0.03928 as the threshold before May 2021; the current threshold is 0.04045, aligned with sRGB. The cited definition carries no large-text distinction — that lives in SC 1.4.3/1.4.6/1.4.11, whose ratios the module's rows already transcribe correctly (4.5:1, 3:1, 7:1; verified against the live criterion text and pinned by
witness_cited_knee_threshold_rows_match_criterion_text).Defect.
linearize_channel_scaledused the older 392/10000 knee. The two constants disagree only on scale-10000 channels 393..404 — a window no 8-bit channel at unity white reaches (10/255 = 0.03922 is below both), which is why the module's existing pins never sampled it.Evidence. Red before the fix:
linearize_channel_scaled(393)returned the gamma-curve value (29) instead of the cited c/12.92 value (30), and the colour pair (393,0,500)/(8000,1000,8000) — a fresh input outside the old pins — PASSED AA normal text under the defective knee while the cited knee says it must FAIL (100*(1789+500)=228900 < 450*(9+500)=229050). Green after (remoteclaim_batch --claim-run, lane witnesses). No stage0 mirror exists for this module (drift list from--required-regennames only the semver mirror).Dated repair receipts for both halves of the RFM row landed with the semver PR (#13412), which this PR follows.