--- name: reference-verification-ladder description: Canonical home for the proven verification instruments — the named gates any session reaches for instead of re-deriving. Steward-authorized consolidation 2026-06-05 (skill-harvest ruling); ends the per-wrap re-proposing of individual instruments. metadata: node_type: memory type: reference originSessionId: b3202a24-301f-499d-af9e-ac5368dd2c73 permalink: claude-memory/reference-verification-ladder --- # The Verification Ladder — named instruments Proven gates, each earned from a real catch. Reach for the one the claim's shape demands; a claim without its gate is an assertion. Linked disciplines: [[feedback-trust-prior-pass-frame]], [[feedback-verify-each-post-type-after-changes]], [[feedback-rank-on-fields-you-actually-write]]. ## Output-equivalence claims ("this refactor changes nothing") - **Byte-identical compile gate** — prove with `cmp`/`diff` at BOTH the direct-invocation level and the full-pipeline level. Proven 3×: SCSS Stage 1 (`c37a3bd`), site.hs listing generator, §I.k transform dormancy. - **Expected-delta gate** — when diff=0 is impossible, prove the delta's *complete shape*: `sort -u` over all per-file diffs; every line must belong to a named class (2026-06-04). - **Delta classification** — corpus-wide variant: classify EVERY changed line into named classes; the unclassified residue must be exactly empty-or-whitespace. Catches what sampling misses, including one's own shipping comments (decompose + SEO passes, 2026-06-05). - **Delayer-diff** (2026-06-08) — for an `@layer`/structural-wrap refactor where the compiled output gains uniform wrappers: strip the `@layer X{`/closing-`}` wrappers from the compiled CSS (brace-aware script), diff vs the true baseline; byte-identical proves nothing *moved, dropped, or changed* — only got wrapped. Proven 3× in W3R Stage 2a. **CAUTION — byte-identical ≠ rendered-identical under `@layer`:** `@layer` overrides specificity, so a structural-wrap byte-proof is *necessary but not sufficient*; render-review is the gate when the cascade *basis* changes (a 5-layer wrap was byte-true yet produced 3 render inversions the diff could not see — the steward's eye caught them). Rendered-identity is then argued *by construction* (only already-winning rules promoted) AND render-reviewed — not inferred from the byte-diff. - **Hold or exclude volatile build-stamps** — a build-date/commit stamp (colophon `_build_info`) differs between baseline and post builds and falsely flags a byte-diff. Hold it constant or exclude it, and say which (2026-06-10, Stage-G close). - **Two-hat commit separation** — name the hat each commit wears: a *refactor* commit's compiled output is byte-identical (or carries a pre-stated classified delta); a *feature* commit is where rendered values change. Makes the gate above applicable per-commit instead of per-session (2026-06-08, from Fowler). - **Lossless-relocation gate** — restructuring an index or moving prose between files: line-range **slices, never retyping**, + md5-conservation per moved slice + a link-resolution canary over every `](file.md)` and `[[wikilink]]`. Proven on the MEMORY.md two-file split (2026-07-06) and again on the skill-harvest split (2026-08-01, archive byte-identical over 166,027 bytes). ## Mechanical text transforms ("strip/replace token X across the file") - **Token-strip hits prose** (2026-06-08) — a whole-file `sed s/…!important…//` (or any token strip) also removes the token from comments, code-refs, and docstrings, silently mangling prose. Scope the transform to declaration lines, OR compare raw-before vs clean-declaration counts and verify comment integrity after (caught 4 mangled comments via the 56-vs-70 count mismatch; restored). Same family as *Count first, then look* — the word lives in prose too. ## Coverage claims ("all X were handled") - **Exhaustive route/rule census** — enumerate ALL routes/rules/sections before classifying any; classify each explicitly; no sampling. (The censused-routes discipline; §I.k.c measuring read.) - **Count first, then look** — never read a census through truncation (`| head`, clipped listings). `wc -l` before inspection; 3 same-day instances 2026-06-05 (chamber/CM-AI/studium untracked files). - **Re-audit with the TOOL's recognizer, not the classifier that shares its blind spot** — when a classifier and the tool it feeds share a predicate, the classifier's *mis*-classifications masquerade as genuine new categories. Size a gap by running the tool's own recognizer over the corpus. - **A silent safety net is uninformative, not reassuring** — a fallback / fail-loud branch / `unrecognized` kind that never fires across N real cases has not been shown to work; census the substrate for what it should have caught. (Generalized from the negative-grep class to net-silence.) - **Verify at the granularity of the mutation, not the aggregate** — a document-wide word-multiset guard PASSES while a per-item swap (a word from note A landing in note B) violates the intent, because the total bag is unchanged. Check per item, keyed by the item's own identity. - **Work-in-omnibus: verify the interior, not the endpoints** — when a sidecar brackets one work out of a multi-work source by heading boundaries, sample the span INTERIOR and scan for embedded works and editorial apparatus; endpoint-verification passes over a wrong interior. ## Build/render claims ("it works / it looks right") - **Render-and-LOOK** — render the artifact and read it before asserting; never reason from the remembered model (caught glued FR colons, feTurbulence errors, viewport misreads). - **Per-type × per-viewport** — after any shared CSS/template change, every content type on desktop AND phone ([[feedback-verify-each-post-type-after-changes]]). - **Compiled-selector grep gate** — after SCSS changes, grep the *compiled* CSS for retired/duplicated selectors and late overrides (caught opacity duplicates + silent font-family override, 2026-06-03). - **Governed-char byte gate** — verify specific codepoints by byte (`[8239]` probes), not by eye; verify test INPUTS too (the `\x202Fc` hex-escape trap). - **Measure the box model before theorizing the mechanism** — headless-Chrome measurement caught a per-point *padding asymmetry* where the theory said width (2026-06-09). Reinforced across four days; the standing harness is `/measure-render`. - **Measure the font's true average advance before a character-count measure** — the 0.5em convention misestimated EB Garamond by 32% (0.377em measured); measure over real corpus prose including spaces (2026-06-09). - **Element shot = `scrollIntoView({block:'center'})` + full-viewport, never computed clip** — box-clip math off `getBoundingClientRect` kept landing on page-top and burned several shots (2026-06-13). - **CSS mask fills WHITE, not black** — a `mask`/`-webkit-mask` SVG must fill the shape opaque; a black fill renders BLANK (luminance-vs-alpha). ~6 debug rounds (2026-06-13). - **Live-CSS-patch in `_site` for in-browser iteration** — `sed` the value in the built CSS and refresh to let the steward judge sizes in the real browser, then lock the chosen value in source SCSS. Turned a multi-round sizing decision into one sitting. ## Toolchain claims ("the parser/build does X") - **Measure-toolchain-before-spec** — probe actual behavior (ghci/REPL probes) before writing spec text that presumes it («» parse as Str; BulletList misparse; 2026-06-04/05). - **Feature-detect gates can lie** — `@supports(animation-timeline:view())` returns true on iOS Safari 26 where mobile WebKit will not drive it. A capability probe reports the parser, not the behaviour; verify on the target (2026-06-12). - **Parse-and-validate an artifact before its first machine consumption** — a hand-authored YAML/config that humans have only ever *read* is unvalidated input the moment code consumes it. All four chamber reading-index YAMLs failed on first parse (2026-06-12). ## Numeric/accessibility claims - **Compute, don't eyeball** — WCAG contrast via calculator (1.84:1 vs an assumed "fine"; 2026-06-03). - **CI-upper-bound + drop-one robustness — STANDARD for every ESCALATE** (jurist-ruled 2026-07-04): grade on the one-sided 90% Clopper–Pearson **upper** bound, never the point estimate, and re-check with any one confirmed case dropped. A point estimate at n=40 conceals how little it constrains. ## Remote/persistence claims ("it's backed up / deployed") - **Fresh-clone gate** — verify a remote by independent clone and content check, never by push exit-code (chamber-library LFS: the remote held stubs for months while pushes "succeeded"; 2026-06-05). - **Live-fetch gate** — verify deploys by fetching the live URL and reading bytes (robots.txt, 403 differentials; 2026-06-05). - **Cross-volume verify-before-delete** — `rsync -a` → exact file-count match + `du` (never a byte-sum; mine computed 0=0 vacuously) + rc=0 → *only then* `rm` the source. Isolate flaky-remote pushes so a hang cannot mask a failure. ## Extension claims ("the earlier verification covers this too") - **Re-verify at the extension's scope** — the prior pass tested what it tested ([[feedback-trust-prior-pass-frame]]; now also a Symmetria §3 flag). - **Extending a tool re-tests its foundations** — a widen exercises shared machinery the original's tests never hit, so the extension's `--validate` must assert the *shared* invariants too. Building the block-id handler surfaced a latent duplicate-id defect (2026-07-11). - **A stronger gate obliges a retroactive sweep** (jurist Q1b) — a stronger check existing and not pointed at what shipped under the weaker one is the exact gap the discipline exists to close. ## Causal claims about running systems ("X is what's pinning the CPU / blocking the loop") - **Sampling-profile gate** — name the hot path by measurement (process sample / SIGUSR1→CDP CPU profile) before naming the culprit; log shape suggests mechanism but does not prove it (circle-forward read as a retry queue from log census; profile + code read showed fire-and-forget and the pin elsewhere entirely — temporal; 2026-06-06). Corollary: write the inferred-vs-measured split explicitly in any outward claim — when the profile overturns the lean, sharpening costs nothing where retraction would have. - **Exit-code-over-tail gate** (2026-06-06): never read success from prettified command output — `git push 2>&1 | tail -1` rendered a REJECTION as the soothing fragment "...and the repository exists." Check `$?` (or let the tool surface stderr whole) before claiming a push/deploy landed. Caught same-session; the byte cost of `; echo exit=$?` is zero. - **Verify the RUNNING BINARY's provenance, not source HEAD** — check the compiled `dist/` mtime and grep the compiled symbols before reasoning about live behaviour. A whole "schema-drift" mechanism inverted on this: HEAD carried a migration the running process did not. - **Quantify the removed cost as the A/B control** — when a fix *removes* a hot operation, time the removed operation on real data rather than racing a flaky end-to-end. (2.56 s vs 0.003 s on the real 676k graph.) - **Confirm a named cause by swap-in** — naming the true reference/config/cause is identification, not proof; swap the candidate in and watch the anomaly collapse, ideally to zero. - **Split cause from magnitude before sizing a remedy** — a bucket keyed on one summary axis holds heterogeneous causes, and a single label silently implies a single fix at a single scale. Read the substrate and split first. - **Revert-and-redo-smaller** — when a gate fails and the cause is not immediately visible, return to the last green state and redo the step smaller; do not debug forward. Named as the reflex we most lack (2026-06-08, from Fowler). ## Enforcement rules built on a "never occurs" premise ("ARC English never uses the em dash") - **Corpus-census-the-premise gate** (2026-06-07): before an enforcement transform ships, grep the corpus for the premise's counterexamples — the §I.k.b em→en rule's "never uses it" was false for exactly one fixed convention (the Chicago `———.` bibliographic repeat, 2 carriers), and it mangled Sources blocks for three days because both the build and the audit verified the rule-as-stated, not the premise-against-the-corpus. One grep would have caught it. ## Render-gate comparisons ("the steward rules on render") - **Element-census the comparison page** (2026-06-07): before spending the steward's eye, verify the offered page actually carries the element under judgment — the first hr-gate page offered had zero bare `