How the formal-verification pilot actually works
Seven panels walk through how we formally verify kernels, exactly as the pipeline runs today on four named kernels. Each panel shows what ran, what the validated spec covers, and what stays out of scope. See Methods for the six general checking mechanisms this pilot sits alongside, and How the Kernel VM Works for the execution runtime this pipeline binds to.
Clause to spec
From regulation text to a spec a machine can check.
We draft each candidate spec from the cited regulation text itself, never from the kernel's code: a spec derived from the implementation can only show the implementation matches itself. Every spec file records the clause's source document, the date we retrieved it, a content digest, and a stored snapshot location, so you can check the exact text a spec implements even after the live regulation page changes. One spec (the payee name-match scorer) was initially drafted the wrong way around, from the code instead of the declared contract. We caught it, re-derived the spec independently without reading the kernel, and the two versions matched, so the signed spec stands.
Independence gates before trust
A spec earns trust by surviving checks it could fail.
The kernel's own golden fixtures are the obvious oracle, and a weak one: a spec transliterated from the kernel passes them trivially. So where a stronger public oracle exists, we use it. Appendix J publishes four fully worked transactions, and a spec has to reproduce them to two decimals before we trust any proof against it. The negative control is what actually earns trust: a spec that can never fail (even one we deliberately built wrong) isn't verifying anything. Mutation and vacuity checks close that gap by confirming the spec's obligations are strong enough to catch a broken proof.
Independent mechanical validation
A spec earns its verified status by surviving a gate ladder, not a signature.
By the time a proof runs, the spec it proves against has already cleared every gate above: the fixture-oracle check, the negative control, and the spec-strength checks. Each gate is a script anyone can re-run against the same spec and the same fixtures, and each result is recorded in that kernel's evidence vector alongside the gate that produced it. A person still drafts and reads every spec, today the same person who prompts its drafting, and we state that wherever it is relevant. What changed is what a verified claim rests on: the gate ladder, not that reading.
Verification tiers
What each verification tier actually claims.
These tier labels are our own, and we use them verbatim wherever a kernel's status appears. "Verified" always ships with the evidence vector and its stated assumptions visible next to the claim.
Execution binding
A proof binds to exact code, exact spec, and exact toolchain.
A proof only means something when it is bound to the exact code, spec, and toolchain that produced it. So at proof time we check three digests: the kernel's content digest, the signed spec's digest, and the pinned toolchain digest (the Dafny and Z3 versions, for the Class C leg). Execution itself runs through the same zk compute-proof and runtime-twin machinery as the rest of the suite. See How the Kernel VM Works for how one kernel source runs identically across runtimes and what execution_hash agreement actually checks.
Fixtures are not proofs: the Reg Z APR finding
A kernel can match every fixture and still be wrong past the fixtures' reach.
Reg Z Appendix J publishes four fully worked transactions with their APRs. The shipped kernel reproduces all four to the two decimals the regulation itself speaks in, and its own three golden fixtures pass unchanged. That is the entire evidence a fixture-only check would ever produce. The Dafny proof went further, because its spec was drafted from Appendix J's text rather than from the kernel. It found the kernel compounds interest across an odd-days fraction where Appendix J (b)(6) and (b)(8) prescribe simple interest: a deviation invisible at ordinary rates that grows to a measured 5.56 percentage points at the most extreme rate probed, breaching the §1026.22(a) tolerance above roughly 200% APR. Separately, the proof's solver harness exposed a Newton-iteration exit that could mark an unconverged result converged: true, returning the caller's own guess as if it had been computed. Both are documented findings, tracked for kernel repair as a separate step. See Methods for each kernel's current status.
What is not claimed
The scope, stated plainly.
The scope stays deliberately narrow. Existence of the root is not claimed: for the APR solver, Dafny's real type is rational and the root is irrational, so uniqueness and the bisection bracket are proved, existence itself is not. Date arithmetic is out of scope; deriving day counts and period fractions from calendar dates is neither in the spec nor proved, and it sits outside this pilot entirely. The Class C floor is not the same claim as a proof: the site-wide property-test floor (below) is internal engineering QC over a much larger kernel set, a different, weaker guarantee than this pilot's four mechanically validated, proved kernels, and it is never presented as equivalent to them. Mechanical validation is bounded by what the regulator publishes: each spec is checked against the kernel's own fixtures and, where one exists, the regulator's own published worked example, and whether the regulation means what its worked examples show is a question neither a machine, nor a signature, ever answered. Conformity of the shipped kernel to the clause is a separate question from spec correctness: a proof over a Dafny port establishes the port satisfies its obligations, while whether the shipped JavaScript computes the same function is checked separately, by differential testing, exactly as Panel 6 shows it can diverge. Coverage is four kernels, named, out of the catalog; no claim is made here about any other kernel, and nothing on this page certifies, warrants, or guarantees compliance with any regulation.
See the Terms & Reliance page for the full disclaimer, and Methods for the six general-purpose checking mechanisms this pilot sits alongside. The technical white paper covers the full verification ladder this pilot is one rung of.
Ratchet baseline ledger
Every shrink-only baseline in the estate, counted from the file itself.
Some gates in this codebase shield known, already-reviewed debt behind a committed baseline file rather than blocking the build outright. A baseline records exactly what already existed when the gate went live; a new violation fails the build immediately; the baseline itself may only shrink over time. This table is produced by scanning the repository for every file that follows that pattern, so a newly added baseline is picked up automatically the next time this page regenerates, and a retired one drops off the same way. Each count below is read from the named file at generation time; none of it is entered by hand.
| Class | File | Count | What is counted | Last changed |
|---|---|---|---|---|
| spec-page-parity-baseline | chaingraph/standard/spec-page-parity-baseline.json | 1 | spec sections with no matching page coverage | 2026-09-12 |
| a11y-baseline | scripts/a11y-baseline.json | 2 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-09 |
| amendment-detection-baseline | scripts/amendment-detection-baseline.json | 1 | baselined amendment-vs-citation contradictions (root list) | 2026-08-04 |
| ap2-contract-baseline | scripts/ap2-contract-baseline.json | 4 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-27 |
| ap2version-emission-baseline | scripts/ap2version-emission-baseline.json | 1 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-30 |
| asof-staleness-baseline | scripts/asof-staleness-baseline.json | 22 | baselined stale as-of table references | 2026-07-31 |
| authority-contradiction-baseline | scripts/authority-contradiction-baseline.json | 1 | baselined cross-authority contradictions (root list) | 2026-07-27 |
| binary-byte-allowlist | scripts/binary-byte-allowlist.json | 6 | files shielding a deliberate control byte | 2026-08-22 |
| c2patool-oracle-allowlist | scripts/c2patool-oracle-allowlist.json | 3 | fixtures where the structural check and the external oracle diverge, by design | 2026-08-13 |
| catalog-parity-baseline | scripts/catalog-parity-baseline.json | 21 | orphaned chain composer pages | 2026-08-11 |
| chain-handoff-register-baseline | scripts/chain-handoff-register-baseline.json | 671 | causation-register sentences across all baselined chain pages, summed | 2026-08-04 |
| chain-plan-parity-baseline | scripts/chain-plan-parity-baseline.json | 6 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-06 |
| chain-process-order-baseline | scripts/chain-process-order-baseline.json | 1 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-29 |
| chain-step-status-baseline | scripts/chain-step-status-baseline.json | 1 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-12 |
| citation-drift-baseline | scripts/citation-drift-baseline.json | 1 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-30 |
| comparator-epsilon-baseline | scripts/comparator-epsilon-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-02 |
| compute-proof-baseline | scripts/compute-proof-baseline.json | 3 | nodes with a deferred compute-integrity proof | 2026-09-12 |
| copy-hallmarks-baseline | scripts/copy-hallmarks-baseline.json | 8563 | em-dash/jargon/bold/insider/AI-vocabulary hits across all baselined pages, summed | 2026-08-29 |
| cross-surface-baseline | scripts/cross-surface-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-23 |
| csp-consistency-baseline | scripts/csp-consistency-baseline.json | 6 | pages missing a matching CSP profile | 2026-09-03 |
| csv-injection-baseline | scripts/csv-injection-baseline.json | 84 | CSV emitters without the injection-prefix guard | 2026-07-21 |
| dead-link-baseline | scripts/dead-link-baseline.json | 0 | known dead internal links | 2026-09-12 |
| deeplink-contract-baseline | scripts/deeplink-contract-baseline.json | 62 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-10 |
| flag-mirror-baseline | scripts/flag-mirror-baseline.json | 7 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-12 |
| flags-computed-baseline | scripts/flags-computed-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-01 |
| floor-label-strength-baseline | scripts/floor-label-strength-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-29 |
| frozen-clock-baseline | scripts/frozen-clock-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-12 |
| fv-floor-coverage-baseline | scripts/fv-floor-coverage-baseline.json | 0 | live kernels with no property-test floor | 2026-08-13 |
| gate-selftest-pairing-baseline | scripts/gate-selftest-pairing-baseline.json | 4 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-23 |
| generator-check-baseline | scripts/generator-check-baseline.json | 35 | writer scripts with no dedicated freshness check | 2026-07-15 |
| hub-chrome-baseline | scripts/hub-chrome-baseline.json | 4 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-23 |
| inline-ssot-sync-baseline | scripts/inline-ssot-sync-baseline.json | 1 | pinned legacy inline-copy variants | 2026-08-02 |
| internal-lang-leak-baseline | scripts/internal-lang-leak-baseline.json | 20 | internal-language marker hits across all baselined pages, summed | 2026-09-10 |
| kernel-determinism-allowlist | scripts/kernel-determinism-allowlist.json | 27 | files calling an approximated transcendental, plus pre-existing hard-ban hits, combined | 2026-08-27 |
| manifest-schema-baseline | scripts/manifest-schema-baseline.json | 2 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-12 |
| narrative-vocab-baseline | scripts/narrative-vocab-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-05 |
| nav-island-baseline | scripts/nav-island-baseline.json | 2 | by-design unreachable pages (root list) | 2026-09-09 |
| node-completeness-baseline | scripts/node-completeness-baseline.json | 15 | nodes carrying legacy completeness debt | 2026-08-20 |
| original-authorship-bundle-allowlist | scripts/original-authorship-bundle-allowlist.json | 3 | bundle files carrying a recorded original-authorship reason | 2026-08-16 |
| output-schema-baseline | scripts/output-schema-baseline.json | 4 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-05 |
| page-determinism-baseline | scripts/page-determinism-baseline.json | 26 | pre-existing page-determinism defects | 2026-07-28 |
| page-kernel-digest-baseline | scripts/page-kernel-digest-baseline.json | 593 | node pages carrying no kernel-digest sentinel yet | 2026-08-23 |
| phasing-notes-baseline | scripts/phasing-notes-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-30 |
| pii-banner-baseline | scripts/pii-banner-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-03 |
| recompute-equality-quarantine | scripts/recompute-equality-quarantine.json | 21 | nodes with a named, observed recompute-equality mismatch | 2026-09-01 |
| s18-digest-freshness-baseline | scripts/s18-digest-freshness-baseline.json | 133 | nodes with a stale compute-integrity digest | 2026-08-01 |
| served-egress-allowlist | scripts/served-egress-allowlist.json | 0 | root list length (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-03 |
| showcase-prompts-baseline | scripts/showcase-prompts-baseline.json | 4 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-09-05 |
| site-egress-baseline | scripts/site-egress-baseline.json | 11 | files carrying a reviewed, inert egress-shaped text match | 2026-09-03 |
| vow-vs-code-baseline | scripts/vow-vs-code-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-28 |
| year-fallback-parity-baseline | scripts/year-fallback-parity-baseline.json | 3 | top-level entries (generic fallback, no dedicated extractor yet in gen-debt-ledger.mjs) | 2026-08-28 |
Last changed is the most recent commit date on that file, so a class that has been still for a long time reads as stable and one that moved recently reads as active. The trend for any class is the git history of its own file, linked above; this page keeps no separate time series.
Chain-level composition checks (L2)
Edge contracts composed and machine-checked: a different claim than the Dafny pilot above.
A separate, estate-wide checker asks a narrower question about every chain: does each step's decision gate read a value the producing tool's published output actually guarantees, and the consuming step's published input actually assume? This is "L2: contract composition" on our own verification ladder: assume-guarantee composition against published manifest schemas, never an execution of any kernel.
Contracts are checked against the published schemas and the cited primary text; whether the regulation means what its text and worked examples show is a question no machine and no signature has ever answered. No kernel becomes more correct because its chain composes, and a perfectly composed chain can still be the wrong workflow for the rule. This is not formal verification: L2 checks declared assume-guarantee composition only, no kernel is ever executed, and end-to-end chain properties (L3) remain a separate, unbuilt tier. Nor does it check that one step's output flows into the next step's input at runtime; chains are provenance-linked bundles of independently parameterised kernels rather than data pipelines, and each step's inputs come from the caller or a fixture, never the prior step's output.