review round 2: in-Lean exact-cone audit + reproducibility + doc honesty
Addresses the round-2 reviewer punch-list. No theorem statement, proof term,
or fold definition changed; the eleven cones are unchanged (independent
collectAxioms dump in verification/RECORDED-RUN.md).
AUDIT GATE (both reviewers, the critical one)
- Retire the bash #print-axioms text parser (fail-open on empty/truncated
reports, and only a SUBSET check). Replace with verification/Proofs/Audit.lean:
reads each certificate's cone from the kernel via collectAxioms and asserts
EXACT set equality against its expected boundary. Extra axiom, dropped
oracle, renamed/deleted cert, or an axiom/opaque sham each throw -> non-zero
Lean exit. No text to misparse; nothing fails open. check.sh Phase 3 now just
compiles it (and still requires the explicit PASSED line).
- check-selftest.sh rewritten to attack the new gate: dead-file, smuggled extra
axiom (named), dropped-oracle (subset would pass, exact must not), and a
vanished certificate (the collectAxioms-returns-[] trap). All four rejected.
REPRODUCIBILITY (GPT B1.4 / B1.5)
- extract.sh refuses a wrong-commit or dirty source tree (fail-closed), takes
an optional source-path arg, and pins the source commit.
- verification/PROVENANCE.json: single machine-readable pin set (source +
charon + aeneas commits/channel + lean + ocaml) with generated-file sha256.
- Re-running extract.sh reproduces gen/SlhVerify/{Types,Funs}.lean
byte-identically (companion fips205-source commit adds Cargo.lock +
rust-toolchain.toml; verified not to perturb the model).
DOC HONESTY (both reviewers)
- README: fix the self-contradiction (apex "not yet proven" trailer vs the
proven apex), the false "oracles kept OUTSIDE every cone" (they are INSIDE,
by design), "deployed monomorphic path" and "semantics-identical for every
parameter set" overclaims, "only two lines changed", stale snapshot head;
retitle the stale future-tense "what will be claimed" section.
- TRUSTED-BASE: drop "nothing proven yet"; add base_2b-inner and deployment-
bridge non-claims explicitly; current pin.
- ChainSpec header: "deployed monomorphic path" -> private verify_mono facade
(comment only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:13:55 +00:00
{
review round 6: pin the auditor, purge every olean, pin gen/ as a set
Round 6 confirmed the digest redesign closed NEW-1/NEW-2/NEW-5 at the mechanism
("the first time in three rounds I have not been able to gut a certificate"),
then demonstrated two more ways to reach ALL GREEN with the committed digest
BYTE-IDENTICAL over a repository proving False. Both are fixed.
NEW-7 — the digest bound the audit's DATA, never its LOGIC. Flipping the two
fail-closed guards in Proofs/Audit.lean to `unless true` disabled every in-Lean
check; the block's inputs genuinely had not changed, so the digest still
matched. Total attacker diff: 2 files, 6 insertions. Worse, TRUSTED-BASE item 11
listed the trusted-unbound set and did NOT mention Audit.lean, so a reviewer
using it as a map of what to read by hand would have skipped the file that
computes the number it is judged by.
FIX: Proofs/Audit.lean is now sha256-pinned in harness_integrity_sha256,
symmetric with lean-guard, and item 11 says so — including the honest residue:
an author who edits the logic AND rotates its pin is caught only by reading the
diff at the pin.
NEW-8 — Phase 0's purge covered gen/ and Proofs/ while the stray check greped
only *.lean, so an ORPHAN verification/Evil.olean whose source had been DELETED
fell between them, satisfied an import, and was invisible to git status
(*.olean is gitignored).
FIX: purge every .olean under verification/, and forbid stray .lean AND .olean.
NEW-9 (partial) — gen/ was pinned by four NAMES, not as a SET, so a new file
there was neither hashed nor forbidden while LEAN_PATH contains $PWD/gen.
FIX: Phase 0 asserts the gen/*.lean file set equals the pin map exactly. This
found a real gap on its first run: Aeneas emits *_Template.lean scaffolding into
gen/ on every extraction — untracked byproducts (a fresh clone has only the four
pinned files) that nothing imports but that sat on LEAN_PATH unpinned. They are
now purged as byproducts before the set assertion.
Also, from the reviewer's §3 suggestion: the canonical block is now COMMITTED as
verification/AUDIT-MANIFEST.txt, so a digest mismatch prints a real diff instead
of writing an observed file with nothing to compare against; check.sh also fails
if the committed copy drifts from what Lean emits.
check-selftest.sh: 16 attacks, all rejected, plus the coverage check. Attacks 16
and 17 are the reviewer's two demonstrations. Attacks that mutate the audit's
DATA now re-pin Audit.lean first, so they still test the digest/enumeration
rather than being stopped by the byte pin; attack 17 deliberately does not
re-pin, because the pin is what it tests.
Housekeeping: PROVENANCE.json trailing newline restored (NEW-12).
Disclosed rather than buried: two more of my own assertion bugs this round —
attack 16 asserted the hygiene message when the correct rejection is the purge
plus a failed import, and the earlier gen/ set check surfaced the template files
only because it was written strictly. Both are the wrong-diagnostic class.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 07:22:12 +00:00
"_comment" : "Single machine-readable pin set to reproduce the extracted Lean model in gen/SlhVerify from source. External review rounds 2-5 (2026-07-24 .. 2026-07-27). Running verification/extract.sh against the pinned source tree with the pinned Charon/Aeneas toolchain reproduces the two aeneas-generated files byte-identically (generated_artifacts_sha256 below). The *External*.lean files are hand-maintained (not regenerated) and are NOT part of that reproducibility claim \u2014 but they ARE byte-pinned for integrity in model_integrity_sha256, since they carry the five oracle axioms and the discharged Step definitions. NOTE: SlhVerify.llbc is an intermediate artifact and is .gitignored, so its hash here can only be checked by a party who re-runs extract.sh." ,
review round 2: in-Lean exact-cone audit + reproducibility + doc honesty
Addresses the round-2 reviewer punch-list. No theorem statement, proof term,
or fold definition changed; the eleven cones are unchanged (independent
collectAxioms dump in verification/RECORDED-RUN.md).
AUDIT GATE (both reviewers, the critical one)
- Retire the bash #print-axioms text parser (fail-open on empty/truncated
reports, and only a SUBSET check). Replace with verification/Proofs/Audit.lean:
reads each certificate's cone from the kernel via collectAxioms and asserts
EXACT set equality against its expected boundary. Extra axiom, dropped
oracle, renamed/deleted cert, or an axiom/opaque sham each throw -> non-zero
Lean exit. No text to misparse; nothing fails open. check.sh Phase 3 now just
compiles it (and still requires the explicit PASSED line).
- check-selftest.sh rewritten to attack the new gate: dead-file, smuggled extra
axiom (named), dropped-oracle (subset would pass, exact must not), and a
vanished certificate (the collectAxioms-returns-[] trap). All four rejected.
REPRODUCIBILITY (GPT B1.4 / B1.5)
- extract.sh refuses a wrong-commit or dirty source tree (fail-closed), takes
an optional source-path arg, and pins the source commit.
- verification/PROVENANCE.json: single machine-readable pin set (source +
charon + aeneas commits/channel + lean + ocaml) with generated-file sha256.
- Re-running extract.sh reproduces gen/SlhVerify/{Types,Funs}.lean
byte-identically (companion fips205-source commit adds Cargo.lock +
rust-toolchain.toml; verified not to perturb the model).
DOC HONESTY (both reviewers)
- README: fix the self-contradiction (apex "not yet proven" trailer vs the
proven apex), the false "oracles kept OUTSIDE every cone" (they are INSIDE,
by design), "deployed monomorphic path" and "semantics-identical for every
parameter set" overclaims, "only two lines changed", stale snapshot head;
retitle the stale future-tense "what will be claimed" section.
- TRUSTED-BASE: drop "nothing proven yet"; add base_2b-inner and deployment-
bridge non-claims explicitly; current pin.
- ChainSpec header: "deployed monomorphic path" -> private verify_mono facade
(comment only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:13:55 +00:00
"parameter_set" : "SLH-DSA-SHA2-128s" ,
"source" : {
"repo" : "github.com/saymrwulf/fips205-source" ,
2026-07-28 12:42:46 +00:00
"head" : "a3ce8e8644fe302019ed7ae271912333f1476de4" ,
review round 2: in-Lean exact-cone audit + reproducibility + doc honesty
Addresses the round-2 reviewer punch-list. No theorem statement, proof term,
or fold definition changed; the eleven cones are unchanged (independent
collectAxioms dump in verification/RECORDED-RUN.md).
AUDIT GATE (both reviewers, the critical one)
- Retire the bash #print-axioms text parser (fail-open on empty/truncated
reports, and only a SUBSET check). Replace with verification/Proofs/Audit.lean:
reads each certificate's cone from the kernel via collectAxioms and asserts
EXACT set equality against its expected boundary. Extra axiom, dropped
oracle, renamed/deleted cert, or an axiom/opaque sham each throw -> non-zero
Lean exit. No text to misparse; nothing fails open. check.sh Phase 3 now just
compiles it (and still requires the explicit PASSED line).
- check-selftest.sh rewritten to attack the new gate: dead-file, smuggled extra
axiom (named), dropped-oracle (subset would pass, exact must not), and a
vanished certificate (the collectAxioms-returns-[] trap). All four rejected.
REPRODUCIBILITY (GPT B1.4 / B1.5)
- extract.sh refuses a wrong-commit or dirty source tree (fail-closed), takes
an optional source-path arg, and pins the source commit.
- verification/PROVENANCE.json: single machine-readable pin set (source +
charon + aeneas commits/channel + lean + ocaml) with generated-file sha256.
- Re-running extract.sh reproduces gen/SlhVerify/{Types,Funs}.lean
byte-identically (companion fips205-source commit adds Cargo.lock +
rust-toolchain.toml; verified not to perturb the model).
DOC HONESTY (both reviewers)
- README: fix the self-contradiction (apex "not yet proven" trailer vs the
proven apex), the false "oracles kept OUTSIDE every cone" (they are INSIDE,
by design), "deployed monomorphic path" and "semantics-identical for every
parameter set" overclaims, "only two lines changed", stale snapshot head;
retitle the stale future-tense "what will be claimed" section.
- TRUSTED-BASE: drop "nothing proven yet"; add base_2b-inner and deployment-
bridge non-claims explicitly; current pin.
- ChainSpec header: "deployed monomorphic path" -> private verify_mono facade
(comment only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:13:55 +00:00
"upstream_base" : "integritychain/fips205 @ 30bac08580aa61f653e5436d1bbacb5ffac446c4" ,
round 7: assert pin-map completeness (NEW-13), correct the count to 137, fix the regeneration-scope contradiction
The third reviewer demonstrated NEW-13: PROVENANCE.json is a tracked file that
nothing pins, and Phase 0's only completeness test was 'is the map non-empty'.
Deleting the harness_integrity_sha256 key therefore silently un-pinned BOTH
lean-guard and Proofs/Audit.lean with no diagnostic, after which the round-6
logic mutation ran to ALL GREEN over a repository proving False with the digest
byte-identical. Reproduced here before fixing. The required pin NAMES now live
hardcoded in check.sh — policy in the root of trust, values in the map — so a
shortened map is a build failure naming the missing entries. Self-test attack 18
performs the deletion.
GPT reviewer, independently: the documented '131 assertion points' was wrong.
Recounted from the code, the defensible figure is 137 mono-path evaluated cases
(9 retained original + 108 randomized + 10 NIST internal + 10 NIST
external-pure); 131 had folded in 3 deployed-only prehash cases while omitting
the retained test, and TRUSTED-BASE then decomposed it as 20 + 108 = 128,
contradicting itself. Item 9 now carries the full table, states that 127 of the
137 compare mono against deployed, keeps the 3 prehash cases explicitly outside
the total, and records that only two SHA2-512 and one SHAKE-256 vector are
executable there — so this is not NIST coverage of all four supported prehash
variants.
Also from GPT: PROVENANCE.json contradicted itself, saying extraction
'reproduces all four model files byte-identically' while its own _comment
correctly said the two *External files are hand-maintained. Extraction
regenerates two files; the other two are byte-pinned. Corrected.
TRUSTED-BASE item 11 now discloses that PROVENANCE.json is itself load-bearing
and unpinned, and item 7's stale snapshot head is fixed. README states the
lean-guard graceful fallback and that the empirical bridge runs on stable Rust
without any Lean toolchain (round-7 NEW-16), which is the first load-bearing
part of this work a third party can reproduce with cargo alone.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 11:03:35 +00:00
"upstream_deviation" : "verbatim import minus CI workflows; then the additive monomorphic verify_mono compat module + de-plumbing rounds 1-2, each an individually-justified commit; then NIST ACVP SHA2-128s sigVer vectors + an expanded differential bridge (TEST-ONLY: no verify-path function changed, and re-running extract.sh against this commit reproduces the TWO Aeneas-generated model files (Types.lean, Funs.lean) byte-identically; the two *External.lean files are hand-maintained and are NOT regenerated by extraction \u2014 they are separately byte-pinned in model_integrity_sha256 and were unchanged by this commit)" ,
review round 2: in-Lean exact-cone audit + reproducibility + doc honesty
Addresses the round-2 reviewer punch-list. No theorem statement, proof term,
or fold definition changed; the eleven cones are unchanged (independent
collectAxioms dump in verification/RECORDED-RUN.md).
AUDIT GATE (both reviewers, the critical one)
- Retire the bash #print-axioms text parser (fail-open on empty/truncated
reports, and only a SUBSET check). Replace with verification/Proofs/Audit.lean:
reads each certificate's cone from the kernel via collectAxioms and asserts
EXACT set equality against its expected boundary. Extra axiom, dropped
oracle, renamed/deleted cert, or an axiom/opaque sham each throw -> non-zero
Lean exit. No text to misparse; nothing fails open. check.sh Phase 3 now just
compiles it (and still requires the explicit PASSED line).
- check-selftest.sh rewritten to attack the new gate: dead-file, smuggled extra
axiom (named), dropped-oracle (subset would pass, exact must not), and a
vanished certificate (the collectAxioms-returns-[] trap). All four rejected.
REPRODUCIBILITY (GPT B1.4 / B1.5)
- extract.sh refuses a wrong-commit or dirty source tree (fail-closed), takes
an optional source-path arg, and pins the source commit.
- verification/PROVENANCE.json: single machine-readable pin set (source +
charon + aeneas commits/channel + lean + ocaml) with generated-file sha256.
- Re-running extract.sh reproduces gen/SlhVerify/{Types,Funs}.lean
byte-identically (companion fips205-source commit adds Cargo.lock +
rust-toolchain.toml; verified not to perturb the model).
DOC HONESTY (both reviewers)
- README: fix the self-contradiction (apex "not yet proven" trailer vs the
proven apex), the false "oracles kept OUTSIDE every cone" (they are INSIDE,
by design), "deployed monomorphic path" and "semantics-identical for every
parameter set" overclaims, "only two lines changed", stale snapshot head;
retitle the stale future-tense "what will be claimed" section.
- TRUSTED-BASE: drop "nothing proven yet"; add base_2b-inner and deployment-
bridge non-claims explicitly; current pin.
- ChainSpec header: "deployed monomorphic path" -> private verify_mono facade
(comment only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:13:55 +00:00
"cargo_lock" : "committed" ,
"rust_toolchain_toml" : "nightly-2026-06-01"
} ,
"transpiler" : {
review round 5: bind the policy, the specification bodies, and the harness
The third reviewer demonstrated that the round-4 gate was closed at the
EXPLOITS, not the MECHANISMS: it bound the manifest rows while the things he
moved sat outside the binding. Three fail-opens, each executed end-to-end with
the button printing ALL GREEN. No theorem, proof, fold, or model body changed.
NEW-1 — the policy constant was unbound. `manifestFingerprint` covered
`manifest` but never `allowedBoundary`, the sole predicate the enumeration
tests against; adding one name re-opened the False-proof with the committed
fingerprint BYTE-IDENTICAL.
NEW-2 — the specification bodies were unbound. The statement fingerprint pinned
each certificate's TYPE, which names its reference fold; redefining that fold to
*be* the extracted loop left cone and type-hash identical while the certificate
degenerated to `loop = loop`. 100% of the fidelity content lives in those defs.
NEW-3 — the harness was unbound. Stubbing verification/lean-guard alone, without
touching check.sh or the proofs, gave ALL GREEN in 3.6s over destroyed proofs.
FIX — one mechanism rather than three patches. Audit.lean now emits a canonical
AUDIT-MANIFEST block and check.sh binds to its SHA-256. The block covers the
POLICY constants, every certificate's fully-elaborated statement, and every
specification constant transitively reachable from those statements with its
fully-elaborated BODY (41 constants; the closure is computed, so a new fold
cannot appear without moving the digest; Prop-valued constants contribute their
statement, by proof irrelevance). This also retires the 32-bit Expr.hash as the
binding (NEW-5) — it survives only as a per-certificate diagnostic.
Enumeration now covers EVERY declaration kind (a `def : False` passed before)
in the eight certificate modules AND in Audit.lean itself — the auditor is no
longer exempt (round-5 R1). A bare `axiom` in audited scope is now an error.
Phase 0 purges stale .olean (the verdict must depend on committed bytes, not
.gitignored build state — NEW-4), forbids any .lean outside gen/ and Proofs/,
and sha256-pins the four model files AND lean-guard. lean-guard is KEPT rather
than removed (the reviewer's portability advice is declined by operator
decision): it is the memory cap and machine-wide lock that protect the build
machine after a 12.2GB OOM took the host down. That trade-off is documented.
check.sh's "Certificates proven:" line now comes from the audited manifest; the
hand-kept CERTS array — the one authoritative claim string nothing bound — is
deleted.
check-selftest.sh: 14 attacks, all rejected, plus a check that the hashed block
literally carries the twelve fold bodies. Attacks 9-14 are the reviewers' and an
independent drill's own exploits, turned into regression tests.
DOCS. TRUSTED-BASE gains item 11 (the REAL trusted computing base — lean-guard
pinned; check.sh, the toolchain env, $AENEAS_HOME, python3 and Lean still
trusted) and item 12 (the apex does not compose the ten). README: the audit
description rewritten; the XMSS sibling-order claim downgraded from "pins" to
"makes visible", with a new blanket non-claim covering all ten loop
certificates; the de-plumbing file claim corrected (round 1 touched only
verify_mono.rs, round 2 only helpers.rs — which is ON the deployed verify AND
sign paths, now disclosed; wots.rs was never patched).
RECORDED-RUN: three lines that stood inside a fence were a hand-written summary,
not console output — fabricated evidence in the file whose purpose is machine
evidence. They are removed and the fabrication is named in place, together with
the correction that the "INDEPENDENT RUN" block predates this gate. New rule:
nothing goes in a fence unless captured with tee/cat, and every block states its
date, pin, and who ran it. The transcripts added here follow it.
Also disclosed rather than buried: three bugs in my own test harness this round
(an olean-purge build-order break, an attack rejected by the wrong rule, and a
coverage assertion looking on the wrong line) — each would have let an attack
pass or fail for an unrelated reason.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:57:46 +00:00
"charon" : {
"commit" : "9dd7f23c" ,
"toolchain_channel" : "nightly-2026-06-01"
} ,
"aeneas" : {
"commit" : "bf13c42e"
}
review round 2: in-Lean exact-cone audit + reproducibility + doc honesty
Addresses the round-2 reviewer punch-list. No theorem statement, proof term,
or fold definition changed; the eleven cones are unchanged (independent
collectAxioms dump in verification/RECORDED-RUN.md).
AUDIT GATE (both reviewers, the critical one)
- Retire the bash #print-axioms text parser (fail-open on empty/truncated
reports, and only a SUBSET check). Replace with verification/Proofs/Audit.lean:
reads each certificate's cone from the kernel via collectAxioms and asserts
EXACT set equality against its expected boundary. Extra axiom, dropped
oracle, renamed/deleted cert, or an axiom/opaque sham each throw -> non-zero
Lean exit. No text to misparse; nothing fails open. check.sh Phase 3 now just
compiles it (and still requires the explicit PASSED line).
- check-selftest.sh rewritten to attack the new gate: dead-file, smuggled extra
axiom (named), dropped-oracle (subset would pass, exact must not), and a
vanished certificate (the collectAxioms-returns-[] trap). All four rejected.
REPRODUCIBILITY (GPT B1.4 / B1.5)
- extract.sh refuses a wrong-commit or dirty source tree (fail-closed), takes
an optional source-path arg, and pins the source commit.
- verification/PROVENANCE.json: single machine-readable pin set (source +
charon + aeneas commits/channel + lean + ocaml) with generated-file sha256.
- Re-running extract.sh reproduces gen/SlhVerify/{Types,Funs}.lean
byte-identically (companion fips205-source commit adds Cargo.lock +
rust-toolchain.toml; verified not to perturb the model).
DOC HONESTY (both reviewers)
- README: fix the self-contradiction (apex "not yet proven" trailer vs the
proven apex), the false "oracles kept OUTSIDE every cone" (they are INSIDE,
by design), "deployed monomorphic path" and "semantics-identical for every
parameter set" overclaims, "only two lines changed", stale snapshot head;
retitle the stale future-tense "what will be claimed" section.
- TRUSTED-BASE: drop "nothing proven yet"; add base_2b-inner and deployment-
bridge non-claims explicitly; current pin.
- ChainSpec header: "deployed monomorphic path" -> private verify_mono facade
(comment only).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 17:13:55 +00:00
} ,
"proof_env" : {
"lean" : "v4.30.0-rc2 (3dc1a088b6d2d8eafe25a7cd7ec7b58d731bd7cc)" ,
"ocaml" : "5.3.0"
} ,
"extraction" : {
"driver" : "verification/extract.sh (refuses a wrong-commit or dirty source tree)" ,
"charon" : "charon cargo --preset=aeneas --start-from crate::verify_mono::slh_verify_128s --opaque crate::verify_mono::oracle --opaque sha2 --opaque sha3 --opaque zeroize --opaque rand_core --hide-marker-traits --dest-file SlhVerify.llbc -- --no-default-features --features slh_dsa_sha2_128s" ,
"aeneas" : "aeneas -backend lean -split-files -subdir SlhVerify -dest gen SlhVerify.llbc"
} ,
"generated_artifacts_sha256" : {
"SlhVerify.llbc" : "d8ec0b00593eee1778bc4cc0cc1801fb6415bb294425f01384434849c6443f58" ,
"gen/SlhVerify/Types.lean" : "db720b4a30f512e6048212a472e6853b24931a8121cb94c4cf7e6489754d6384" ,
"gen/SlhVerify/Funs.lean" : "7b7de55fd0206142f2678a079a6ed4462292356bc7de08ecd55cac0c76a1da9f"
} ,
"hand_maintained_not_regenerated" : [
"gen/SlhVerify/TypesExternal.lean" ,
"gen/SlhVerify/FunsExternal.lean"
] ,
round 7: assert pin-map completeness (NEW-13), correct the count to 137, fix the regeneration-scope contradiction
The third reviewer demonstrated NEW-13: PROVENANCE.json is a tracked file that
nothing pins, and Phase 0's only completeness test was 'is the map non-empty'.
Deleting the harness_integrity_sha256 key therefore silently un-pinned BOTH
lean-guard and Proofs/Audit.lean with no diagnostic, after which the round-6
logic mutation ran to ALL GREEN over a repository proving False with the digest
byte-identical. Reproduced here before fixing. The required pin NAMES now live
hardcoded in check.sh — policy in the root of trust, values in the map — so a
shortened map is a build failure naming the missing entries. Self-test attack 18
performs the deletion.
GPT reviewer, independently: the documented '131 assertion points' was wrong.
Recounted from the code, the defensible figure is 137 mono-path evaluated cases
(9 retained original + 108 randomized + 10 NIST internal + 10 NIST
external-pure); 131 had folded in 3 deployed-only prehash cases while omitting
the retained test, and TRUSTED-BASE then decomposed it as 20 + 108 = 128,
contradicting itself. Item 9 now carries the full table, states that 127 of the
137 compare mono against deployed, keeps the 3 prehash cases explicitly outside
the total, and records that only two SHA2-512 and one SHAKE-256 vector are
executable there — so this is not NIST coverage of all four supported prehash
variants.
Also from GPT: PROVENANCE.json contradicted itself, saying extraction
'reproduces all four model files byte-identically' while its own _comment
correctly said the two *External files are hand-maintained. Extraction
regenerates two files; the other two are byte-pinned. Corrected.
TRUSTED-BASE item 11 now discloses that PROVENANCE.json is itself load-bearing
and unpinned, and item 7's stale snapshot head is fixed. README states the
lean-guard graceful fallback and that the empirical bridge runs on stable Rust
without any Lean toolchain (round-7 NEW-16), which is the first load-bearing
part of this work a third party can reproduce with cargo alone.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 11:03:35 +00:00
"byte_identical_regeneration_verified" : "2026-07-28 \u2014 scope stated precisely (round-7 review): extraction regenerates Types.lean and Funs.lean only, and both were byte-identical across the source rotation 797b4ef->3153988. The hand-maintained TypesExternal.lean/FunsExternal.lean are byte-PINNED, not regenerated; claiming extraction 'reproduces all four' was self-contradictory against this file's own _comment." ,
review round 4: bind the cert set, statements, and model bytes (F1/F2/F3)
The third reviewer demonstrated that the round-2 in-Lean exact-cone audit,
though sound for LISTED certs, left three fail-opens OUTSIDE the cone check —
and made check.sh print ALL GREEN over a repo proving False. All closed; no
theorem, proof, or fold changed (the 11 cones are unchanged).
F1 — the audited SET was unbound. Audit.lean now (a) enumerates EVERY theorem
defined in the eight certificate modules and requires each cone ⊆ boundary, so
an un-manifested `theorem _ : False := cheat _` fails regardless of naming
(this is the exact exploit the reviewer used); and (b) prints a MANIFEST
fingerprint over the whole committed manifest, which check.sh binds to — so
deleting/swapping a cert row fails outside Lean too.
F2 — only cones were bound, not statements. Each cert now also carries the
structural fingerprint (Expr.hash) of its elaborated type; a statement gutted
to a tautology of the same cone changes the fingerprint and fails.
F3 — the gen/ model bytes were unbound. New check.sh Phase 0 sha256-pins all
four gen/SlhVerify/*.lean (incl. the two hand-maintained *External files, now
hashed in PROVENANCE.json) BEFORE compiling; a hand-edited model fails first.
F4/F5 — docs. README cone diagram now roots honestly at slh_verify_internal
and states the pure/prehash domain-separator byte, the ctx>255 check, M'
assembly, and deserialization are ABOVE the root and uncovered (new
TRUSTED-BASE item 10). The false "rules out a wrong ADRS field" claim is
corrected in README + ChainSpec (a transliteration makes the field visible,
not excluded).
check-selftest.sh: eight attacks, all rejected (dead file; extra axiom;
dropped oracle; vanished cert; un-manifested False theorem; gutted statement;
hand-edited model; deleted manifest row). Full transcript + green check.sh in
verification/RECORDED-RUN.md.
Standing limit unchanged and disclosed: an audit cannot defend against an
author who edits the manifest AND check.sh AND the proofs together; the
consumer defense is the pinned commit reviewed at the pin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:47:39 +00:00
"model_integrity_sha256" : {
review round 5: bind the policy, the specification bodies, and the harness
The third reviewer demonstrated that the round-4 gate was closed at the
EXPLOITS, not the MECHANISMS: it bound the manifest rows while the things he
moved sat outside the binding. Three fail-opens, each executed end-to-end with
the button printing ALL GREEN. No theorem, proof, fold, or model body changed.
NEW-1 — the policy constant was unbound. `manifestFingerprint` covered
`manifest` but never `allowedBoundary`, the sole predicate the enumeration
tests against; adding one name re-opened the False-proof with the committed
fingerprint BYTE-IDENTICAL.
NEW-2 — the specification bodies were unbound. The statement fingerprint pinned
each certificate's TYPE, which names its reference fold; redefining that fold to
*be* the extracted loop left cone and type-hash identical while the certificate
degenerated to `loop = loop`. 100% of the fidelity content lives in those defs.
NEW-3 — the harness was unbound. Stubbing verification/lean-guard alone, without
touching check.sh or the proofs, gave ALL GREEN in 3.6s over destroyed proofs.
FIX — one mechanism rather than three patches. Audit.lean now emits a canonical
AUDIT-MANIFEST block and check.sh binds to its SHA-256. The block covers the
POLICY constants, every certificate's fully-elaborated statement, and every
specification constant transitively reachable from those statements with its
fully-elaborated BODY (41 constants; the closure is computed, so a new fold
cannot appear without moving the digest; Prop-valued constants contribute their
statement, by proof irrelevance). This also retires the 32-bit Expr.hash as the
binding (NEW-5) — it survives only as a per-certificate diagnostic.
Enumeration now covers EVERY declaration kind (a `def : False` passed before)
in the eight certificate modules AND in Audit.lean itself — the auditor is no
longer exempt (round-5 R1). A bare `axiom` in audited scope is now an error.
Phase 0 purges stale .olean (the verdict must depend on committed bytes, not
.gitignored build state — NEW-4), forbids any .lean outside gen/ and Proofs/,
and sha256-pins the four model files AND lean-guard. lean-guard is KEPT rather
than removed (the reviewer's portability advice is declined by operator
decision): it is the memory cap and machine-wide lock that protect the build
machine after a 12.2GB OOM took the host down. That trade-off is documented.
check.sh's "Certificates proven:" line now comes from the audited manifest; the
hand-kept CERTS array — the one authoritative claim string nothing bound — is
deleted.
check-selftest.sh: 14 attacks, all rejected, plus a check that the hashed block
literally carries the twelve fold bodies. Attacks 9-14 are the reviewers' and an
independent drill's own exploits, turned into regression tests.
DOCS. TRUSTED-BASE gains item 11 (the REAL trusted computing base — lean-guard
pinned; check.sh, the toolchain env, $AENEAS_HOME, python3 and Lean still
trusted) and item 12 (the apex does not compose the ten). README: the audit
description rewritten; the XMSS sibling-order claim downgraded from "pins" to
"makes visible", with a new blanket non-claim covering all ten loop
certificates; the de-plumbing file claim corrected (round 1 touched only
verify_mono.rs, round 2 only helpers.rs — which is ON the deployed verify AND
sign paths, now disclosed; wots.rs was never patched).
RECORDED-RUN: three lines that stood inside a fence were a hand-written summary,
not console output — fabricated evidence in the file whose purpose is machine
evidence. They are removed and the fabrication is named in place, together with
the correction that the "INDEPENDENT RUN" block predates this gate. New rule:
nothing goes in a fence unless captured with tee/cat, and every block states its
date, pin, and who ran it. The transcripts added here follow it.
Also disclosed rather than buried: three bugs in my own test harness this round
(an olean-purge build-order break, an attack rejected by the wrong rule, and a
coverage assertion looking on the wrong line) — each would have let an attack
pass or fail for an unrelated reason.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:57:46 +00:00
"_comment" : "All four Lean model files check.sh Phase 0 pins before compiling anything \u2014 the two aeneas-generated files AND the two hand-maintained *External files (which carry the five oracle axioms and the Step defs). A hand-edit of the model fails the build here (round-4 reviewer F3)." ,
2026-07-28 08:16:57 +00:00
"gen/SlhVerify/TypesExternal.lean" : "2988c04c5fc8c634aff4d9bd13604b8a47e677daa1f45e8f4f321368606cdd0a" ,
review round 5: bind the policy, the specification bodies, and the harness
The third reviewer demonstrated that the round-4 gate was closed at the
EXPLOITS, not the MECHANISMS: it bound the manifest rows while the things he
moved sat outside the binding. Three fail-opens, each executed end-to-end with
the button printing ALL GREEN. No theorem, proof, fold, or model body changed.
NEW-1 — the policy constant was unbound. `manifestFingerprint` covered
`manifest` but never `allowedBoundary`, the sole predicate the enumeration
tests against; adding one name re-opened the False-proof with the committed
fingerprint BYTE-IDENTICAL.
NEW-2 — the specification bodies were unbound. The statement fingerprint pinned
each certificate's TYPE, which names its reference fold; redefining that fold to
*be* the extracted loop left cone and type-hash identical while the certificate
degenerated to `loop = loop`. 100% of the fidelity content lives in those defs.
NEW-3 — the harness was unbound. Stubbing verification/lean-guard alone, without
touching check.sh or the proofs, gave ALL GREEN in 3.6s over destroyed proofs.
FIX — one mechanism rather than three patches. Audit.lean now emits a canonical
AUDIT-MANIFEST block and check.sh binds to its SHA-256. The block covers the
POLICY constants, every certificate's fully-elaborated statement, and every
specification constant transitively reachable from those statements with its
fully-elaborated BODY (41 constants; the closure is computed, so a new fold
cannot appear without moving the digest; Prop-valued constants contribute their
statement, by proof irrelevance). This also retires the 32-bit Expr.hash as the
binding (NEW-5) — it survives only as a per-certificate diagnostic.
Enumeration now covers EVERY declaration kind (a `def : False` passed before)
in the eight certificate modules AND in Audit.lean itself — the auditor is no
longer exempt (round-5 R1). A bare `axiom` in audited scope is now an error.
Phase 0 purges stale .olean (the verdict must depend on committed bytes, not
.gitignored build state — NEW-4), forbids any .lean outside gen/ and Proofs/,
and sha256-pins the four model files AND lean-guard. lean-guard is KEPT rather
than removed (the reviewer's portability advice is declined by operator
decision): it is the memory cap and machine-wide lock that protect the build
machine after a 12.2GB OOM took the host down. That trade-off is documented.
check.sh's "Certificates proven:" line now comes from the audited manifest; the
hand-kept CERTS array — the one authoritative claim string nothing bound — is
deleted.
check-selftest.sh: 14 attacks, all rejected, plus a check that the hashed block
literally carries the twelve fold bodies. Attacks 9-14 are the reviewers' and an
independent drill's own exploits, turned into regression tests.
DOCS. TRUSTED-BASE gains item 11 (the REAL trusted computing base — lean-guard
pinned; check.sh, the toolchain env, $AENEAS_HOME, python3 and Lean still
trusted) and item 12 (the apex does not compose the ten). README: the audit
description rewritten; the XMSS sibling-order claim downgraded from "pins" to
"makes visible", with a new blanket non-claim covering all ten loop
certificates; the de-plumbing file claim corrected (round 1 touched only
verify_mono.rs, round 2 only helpers.rs — which is ON the deployed verify AND
sign paths, now disclosed; wots.rs was never patched).
RECORDED-RUN: three lines that stood inside a fence were a hand-written summary,
not console output — fabricated evidence in the file whose purpose is machine
evidence. They are removed and the fabrication is named in place, together with
the correction that the "INDEPENDENT RUN" block predates this gate. New rule:
nothing goes in a fence unless captured with tee/cat, and every block states its
date, pin, and who ran it. The transcripts added here follow it.
Also disclosed rather than buried: three bugs in my own test harness this round
(an olean-purge build-order break, an attack rejected by the wrong rule, and a
coverage assertion looking on the wrong line) — each would have let an attack
pass or fail for an unrelated reason.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:57:46 +00:00
"gen/SlhVerify/FunsExternal.lean" : "5efe551c35969c9da28b2f3eaed4a6a67c410c62a1926aab390e3abf010390f8" ,
review round 4: bind the cert set, statements, and model bytes (F1/F2/F3)
The third reviewer demonstrated that the round-2 in-Lean exact-cone audit,
though sound for LISTED certs, left three fail-opens OUTSIDE the cone check —
and made check.sh print ALL GREEN over a repo proving False. All closed; no
theorem, proof, or fold changed (the 11 cones are unchanged).
F1 — the audited SET was unbound. Audit.lean now (a) enumerates EVERY theorem
defined in the eight certificate modules and requires each cone ⊆ boundary, so
an un-manifested `theorem _ : False := cheat _` fails regardless of naming
(this is the exact exploit the reviewer used); and (b) prints a MANIFEST
fingerprint over the whole committed manifest, which check.sh binds to — so
deleting/swapping a cert row fails outside Lean too.
F2 — only cones were bound, not statements. Each cert now also carries the
structural fingerprint (Expr.hash) of its elaborated type; a statement gutted
to a tautology of the same cone changes the fingerprint and fails.
F3 — the gen/ model bytes were unbound. New check.sh Phase 0 sha256-pins all
four gen/SlhVerify/*.lean (incl. the two hand-maintained *External files, now
hashed in PROVENANCE.json) BEFORE compiling; a hand-edited model fails first.
F4/F5 — docs. README cone diagram now roots honestly at slh_verify_internal
and states the pure/prehash domain-separator byte, the ctx>255 check, M'
assembly, and deserialization are ABOVE the root and uncovered (new
TRUSTED-BASE item 10). The false "rules out a wrong ADRS field" claim is
corrected in README + ChainSpec (a transliteration makes the field visible,
not excluded).
check-selftest.sh: eight attacks, all rejected (dead file; extra axiom;
dropped oracle; vanished cert; un-manifested False theorem; gutted statement;
hand-edited model; deleted manifest row). Full transcript + green check.sh in
verification/RECORDED-RUN.md.
Standing limit unchanged and disclosed: an audit cannot defend against an
author who edits the manifest AND check.sh AND the proofs together; the
consumer defense is the pinned commit reviewed at the pin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:47:39 +00:00
"gen/SlhVerify/Types.lean" : "db720b4a30f512e6048212a472e6853b24931a8121cb94c4cf7e6489754d6384" ,
correspondence: keep the artifact that says what the model must answer
Round-8 estate review (GPT-5.6): this repository shipped a
FunsExternal_Template.lean / FunsExternal.lean pair and NO correspondence
check at all. This commit explains why, and fixes the cause rather than
bolting a check onto a missing input.
THE TEMPLATE WAS BEING DELETED. check.sh removed `*_Template.lean` on every
run and .gitignore excluded it. The stated reason was sound — "the verdict must
depend on COMMITTED BYTES, never on untracked build state", and an untracked
file on LEAN_PATH is exactly that problem. But it is the weaker of the two
available remedies. The ed25519 forks face the identical choice and COMMIT AND
PIN their templates, which removes the untracked state just as completely and
keeps the evidence.
The evidence is the point. The template is Aeneas's own statement of what the
extracted Rust needs from outside, and it is the ONLY artifact against which
"does the hand-written model ANSWER the extraction?" can be asked. Deleting it
made that question unaskable here — which is precisely why no check existed.
· template committed and pinned in model_integrity_sha256
· .gitignore no longer excludes it
· check.sh no longer deletes it, and says why at length
· Phase 0d runs model-correspondence.py — the forks' scanner, including both
round-8 corrections: a named Lean `section` does not qualify declaration
names, and an EXTRA AXIOM in the model (an assumption no template asks for)
fails rather than passing as a silent row
· MODEL-CORRESPONDENCE.txt committed, pinned, and compared byte-for-byte
Result: 11 externals, every one answered by the pinned model, no UNRESOLVED and
no EXTRA-AXIOM. Negative-tested — deleting one `axiom` from the model yields
`verify_mono.oracle.h_msg|UNRESOLVED` and a non-zero exit; restoring it returns
to green.
AND A REPRODUCIBILITY RESULT, obtained while recovering the deleted template.
charon is not available on this machine (the same wall the reviewer hit), but
SlhVerify.llbc IS committed and Aeneas is installed, so extraction step [2/2]
was re-run alone from the committed LLBC:
Types.lean: IDENTICAL Funs.lean: IDENTICAL
The LLBC -> Lean half of the extraction reproduces byte-for-byte from committed
inputs, on demand, by anyone with Aeneas and this repository. This does NOT
close `slh-extraction-unreproduced`: the Rust -> LLBC half still requires
charon, and this was still run by the author. Half the chain, verifiable today.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 13:49:16 +00:00
"gen/SlhVerify/Funs.lean" : "7b7de55fd0206142f2678a079a6ed4462292356bc7de08ecd55cac0c76a1da9f" ,
"gen/SlhVerify/FunsExternal_Template.lean" : "b4f9c6ecdbd55599bc4d35720fff1accc71475b5702410b5a0666456439a4042"
review round 4: bind the cert set, statements, and model bytes (F1/F2/F3)
The third reviewer demonstrated that the round-2 in-Lean exact-cone audit,
though sound for LISTED certs, left three fail-opens OUTSIDE the cone check —
and made check.sh print ALL GREEN over a repo proving False. All closed; no
theorem, proof, or fold changed (the 11 cones are unchanged).
F1 — the audited SET was unbound. Audit.lean now (a) enumerates EVERY theorem
defined in the eight certificate modules and requires each cone ⊆ boundary, so
an un-manifested `theorem _ : False := cheat _` fails regardless of naming
(this is the exact exploit the reviewer used); and (b) prints a MANIFEST
fingerprint over the whole committed manifest, which check.sh binds to — so
deleting/swapping a cert row fails outside Lean too.
F2 — only cones were bound, not statements. Each cert now also carries the
structural fingerprint (Expr.hash) of its elaborated type; a statement gutted
to a tautology of the same cone changes the fingerprint and fails.
F3 — the gen/ model bytes were unbound. New check.sh Phase 0 sha256-pins all
four gen/SlhVerify/*.lean (incl. the two hand-maintained *External files, now
hashed in PROVENANCE.json) BEFORE compiling; a hand-edited model fails first.
F4/F5 — docs. README cone diagram now roots honestly at slh_verify_internal
and states the pure/prehash domain-separator byte, the ctx>255 check, M'
assembly, and deserialization are ABOVE the root and uncovered (new
TRUSTED-BASE item 10). The false "rules out a wrong ADRS field" claim is
corrected in README + ChainSpec (a transliteration makes the field visible,
not excluded).
check-selftest.sh: eight attacks, all rejected (dead file; extra axiom;
dropped oracle; vanished cert; un-manifested False theorem; gutted statement;
hand-edited model; deleted manifest row). Full transcript + green check.sh in
verification/RECORDED-RUN.md.
Standing limit unchanged and disclosed: an audit cannot defend against an
author who edits the manifest AND check.sh AND the proofs together; the
consumer defense is the pinned commit reviewed at the pin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 17:47:39 +00:00
} ,
review round 5: bind the policy, the specification bodies, and the harness
The third reviewer demonstrated that the round-4 gate was closed at the
EXPLOITS, not the MECHANISMS: it bound the manifest rows while the things he
moved sat outside the binding. Three fail-opens, each executed end-to-end with
the button printing ALL GREEN. No theorem, proof, fold, or model body changed.
NEW-1 — the policy constant was unbound. `manifestFingerprint` covered
`manifest` but never `allowedBoundary`, the sole predicate the enumeration
tests against; adding one name re-opened the False-proof with the committed
fingerprint BYTE-IDENTICAL.
NEW-2 — the specification bodies were unbound. The statement fingerprint pinned
each certificate's TYPE, which names its reference fold; redefining that fold to
*be* the extracted loop left cone and type-hash identical while the certificate
degenerated to `loop = loop`. 100% of the fidelity content lives in those defs.
NEW-3 — the harness was unbound. Stubbing verification/lean-guard alone, without
touching check.sh or the proofs, gave ALL GREEN in 3.6s over destroyed proofs.
FIX — one mechanism rather than three patches. Audit.lean now emits a canonical
AUDIT-MANIFEST block and check.sh binds to its SHA-256. The block covers the
POLICY constants, every certificate's fully-elaborated statement, and every
specification constant transitively reachable from those statements with its
fully-elaborated BODY (41 constants; the closure is computed, so a new fold
cannot appear without moving the digest; Prop-valued constants contribute their
statement, by proof irrelevance). This also retires the 32-bit Expr.hash as the
binding (NEW-5) — it survives only as a per-certificate diagnostic.
Enumeration now covers EVERY declaration kind (a `def : False` passed before)
in the eight certificate modules AND in Audit.lean itself — the auditor is no
longer exempt (round-5 R1). A bare `axiom` in audited scope is now an error.
Phase 0 purges stale .olean (the verdict must depend on committed bytes, not
.gitignored build state — NEW-4), forbids any .lean outside gen/ and Proofs/,
and sha256-pins the four model files AND lean-guard. lean-guard is KEPT rather
than removed (the reviewer's portability advice is declined by operator
decision): it is the memory cap and machine-wide lock that protect the build
machine after a 12.2GB OOM took the host down. That trade-off is documented.
check.sh's "Certificates proven:" line now comes from the audited manifest; the
hand-kept CERTS array — the one authoritative claim string nothing bound — is
deleted.
check-selftest.sh: 14 attacks, all rejected, plus a check that the hashed block
literally carries the twelve fold bodies. Attacks 9-14 are the reviewers' and an
independent drill's own exploits, turned into regression tests.
DOCS. TRUSTED-BASE gains item 11 (the REAL trusted computing base — lean-guard
pinned; check.sh, the toolchain env, $AENEAS_HOME, python3 and Lean still
trusted) and item 12 (the apex does not compose the ten). README: the audit
description rewritten; the XMSS sibling-order claim downgraded from "pins" to
"makes visible", with a new blanket non-claim covering all ten loop
certificates; the de-plumbing file claim corrected (round 1 touched only
verify_mono.rs, round 2 only helpers.rs — which is ON the deployed verify AND
sign paths, now disclosed; wots.rs was never patched).
RECORDED-RUN: three lines that stood inside a fence were a hand-written summary,
not console output — fabricated evidence in the file whose purpose is machine
evidence. They are removed and the fabrication is named in place, together with
the correction that the "INDEPENDENT RUN" block predates this gate. New rule:
nothing goes in a fence unless captured with tee/cat, and every block states its
date, pin, and who ran it. The transcripts added here follow it.
Also disclosed rather than buried: three bugs in my own test harness this round
(an olean-purge build-order break, an attack rejected by the wrong rule, and a
coverage assertion looking on the wrong line) — each would have let an attack
pass or fail for an unrelated reason.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:57:46 +00:00
"harness_integrity_sha256" : {
round 8: self-deriving harness pins, honest extraction guarantees, attestation basis
Third reviewer returned ATTEST-with-conditions at 1bc4f39. Its conditions are
committed verbatim as ATTESTATION-BASIS.md so the limits travel with the
artifact instead of living in a review document a consumer never sees. Condition
9 — that extract.sh's byte-identical regeneration has never been observed by any
party but the author — is the campaign's last open item, and the file records
that both reviewers are now blocked on it for different environmental reasons.
HARNESS PINS ARE NOW SELF-DERIVING. My round-7 fix hardcoded the required pin
names, which the reviewer correctly called a second thing to keep in sync, and
it supplied the boundary the harness does have: the executable bit. check.sh now
requires every executable file in verification/ to be pinned (itself excluded —
it cannot pin itself), plus Proofs/Audit.lean. A new harness script therefore
fails closed until pinned. Consequence, and the reviewer argued for it:
check-selftest.sh, drill.sh and extract.sh are now pinned too — the self-test is
the only artifact demonstrating the gates work, and its assertions have been
defective in four consecutive rounds, so weakening it should be a reviewable
rotation rather than an unnoticed edit.
THE EXTRACTION SCRIPT'S GUARANTEES ARE NOW STATED HONESTLY. The reviewer found a
tautological assert in it — comparing a dict against the comprehension that had
just built it — in the script written to fix a provenance-honesty defect. My
first repair (comparing kept[k] against t[k]) was tautological for the same
reason, which I confirmed by negative test. No check inside a transformer can
detect a corrupted input, because the transformer defines the output from that
input; that lesson is now recorded in the code. Both fake checks are gone and
the header and provenance text name what actually protects the result — the
pinned SOURCE_SHA256, the sk-must-be-present check, the group and test counts,
and verify mode — each of which I negative-tested.
Also: the self-test keeps its backups outside verification/ (cp -p preserves the
executable bit, so an in-tree backup would have looked like an unpinned harness
file and failed a run for an unrelated reason); the Phase-0 banner no longer
says a file 'differs' when an entry is simply absent; and attack 18's assertion
follows the renamed diagnostic and now requires both missing pins to be named.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 12:40:39 +00:00
"_comment" : "The harness is part of the trusted computing base and its membership is now SELF-DERIVING: check.sh requires every executable file in verification/ to appear here (round-8 review \u2014 a hardcoded list was itself a second thing to keep in sync), plus Proofs/Audit.lean, which is not executable but computes the digest it is judged by. check.sh itself is excluded: it cannot pin itself, and is disclosed as trusted-unbound in TRUSTED-BASE.md item 11. Pinning check-selftest.sh matters beyond the button: it is the only artifact demonstrating the gates work, and its assertions have been defective in four consecutive rounds, so weakening it is now a reviewable pin rotation rather than an unnoticed edit." ,
review round 6: pin the auditor, purge every olean, pin gen/ as a set
Round 6 confirmed the digest redesign closed NEW-1/NEW-2/NEW-5 at the mechanism
("the first time in three rounds I have not been able to gut a certificate"),
then demonstrated two more ways to reach ALL GREEN with the committed digest
BYTE-IDENTICAL over a repository proving False. Both are fixed.
NEW-7 — the digest bound the audit's DATA, never its LOGIC. Flipping the two
fail-closed guards in Proofs/Audit.lean to `unless true` disabled every in-Lean
check; the block's inputs genuinely had not changed, so the digest still
matched. Total attacker diff: 2 files, 6 insertions. Worse, TRUSTED-BASE item 11
listed the trusted-unbound set and did NOT mention Audit.lean, so a reviewer
using it as a map of what to read by hand would have skipped the file that
computes the number it is judged by.
FIX: Proofs/Audit.lean is now sha256-pinned in harness_integrity_sha256,
symmetric with lean-guard, and item 11 says so — including the honest residue:
an author who edits the logic AND rotates its pin is caught only by reading the
diff at the pin.
NEW-8 — Phase 0's purge covered gen/ and Proofs/ while the stray check greped
only *.lean, so an ORPHAN verification/Evil.olean whose source had been DELETED
fell between them, satisfied an import, and was invisible to git status
(*.olean is gitignored).
FIX: purge every .olean under verification/, and forbid stray .lean AND .olean.
NEW-9 (partial) — gen/ was pinned by four NAMES, not as a SET, so a new file
there was neither hashed nor forbidden while LEAN_PATH contains $PWD/gen.
FIX: Phase 0 asserts the gen/*.lean file set equals the pin map exactly. This
found a real gap on its first run: Aeneas emits *_Template.lean scaffolding into
gen/ on every extraction — untracked byproducts (a fresh clone has only the four
pinned files) that nothing imports but that sat on LEAN_PATH unpinned. They are
now purged as byproducts before the set assertion.
Also, from the reviewer's §3 suggestion: the canonical block is now COMMITTED as
verification/AUDIT-MANIFEST.txt, so a digest mismatch prints a real diff instead
of writing an observed file with nothing to compare against; check.sh also fails
if the committed copy drifts from what Lean emits.
check-selftest.sh: 16 attacks, all rejected, plus the coverage check. Attacks 16
and 17 are the reviewer's two demonstrations. Attacks that mutate the audit's
DATA now re-pin Audit.lean first, so they still test the digest/enumeration
rather than being stopped by the byte pin; attack 17 deliberately does not
re-pin, because the pin is what it tests.
Housekeeping: PROVENANCE.json trailing newline restored (NEW-12).
Disclosed rather than buried: two more of my own assertion bugs this round —
attack 16 asserted the hygiene message when the correct rejection is the purge
plus a failed import, and the earlier gen/ set check surfaced the template files
only because it was written strictly. Both are the wrong-diagnostic class.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 07:22:12 +00:00
"lean-guard" : "690d861cfd81b327604ffd5ef85599ee01b2bcd943907f5b71b8b6f99bad418f" ,
Phase 3c: declaration coverage in both directions, and the accounting identity
Completes the round-8 hardening of this repository. Round-8 review (Claude,
register keys `drv-surface-no-cones` and `accounting-certifies-enumeration`).
WHAT PHASE 3 DID NOT PIN. It proves each certificate's cone is exact and that
no declaration in scope carries a disallowed axiom. It does not pin WHICH
declarations exist: a new one that happens to be clean, and a silently vanished
one, both pass it.
inventory-allowlist.txt 265 rows — the audited corpus
driver-allowlist.txt 35 rows — the audit INSTRUMENT's own surface
both as INV|module|name|kind|CONE, diffed in BOTH directions by
inventory_gate.sh, the same implementation the ed25519 repositories use,
with a tag per surface.
The instrument surface carries cones because the reviewer showed enumeration is
not audit: a claim planted in an instrument is counted by an accounting identity
and then examined by nothing, if its row carries no cone and no allowlist
covers it. Here the instrument's 35 declarations are pinned exactly as the
corpus's 265 are.
INTERNAL NAMES ARE NO LONGER EXEMPT from the environment walk. They were
skipped, which was harmless while nothing compared that walk against the
kernel's view — and became a hole the moment something did: Phase 3b reads
object files, which contain the compiler's auxiliaries. Exempting them would
have left the accounting identity permanently short and forced the residual to
be "explained" by a constant. That is the shape of the fudge term four-fork data
refuted in the ed25519 repositories, and it is refused here before it can start.
THE ACCOUNTING IDENTITY, as SET CONTAINMENT and never arithmetic: every constant
the kernel holds must appear in one of the two walks. The kernel gate now emits
KERNEL-NAME rows so the comparison names what is missing rather than reporting a
count that has to be interpreted.
kernel 300 = inventory 265 + instrument 35 residual: none
Negative-tested, all three rejected by name and the tree restored to green:
· a deleted INV row -> UNCLASSIFIED: INV|Proofs.ApexSpec|List.allM.eq_1|theorem|
· a deleted DRV row -> UNCLASSIFIED: DRV|Proofs.Audit|SlhVerify.Audit.sortNames|def
· a row with no declaration behind it -> STALE: …|fips205.ghost_that_does_not_exist|…
Both allowlists join the pinned harness set: not executable, so the
executable-bit rule cannot reach them, and an allowlist an attacker may rewrite
pins nothing.
fips205-slhdsa-verified now has the ed25519 repositories' gate set: 0 hygiene,
0d correspondence, 1 model, 2 proofs, 3 in-Lean audit, 3b kernel-side axiom
gate, 3c coverage + accounting.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 15:34:00 +00:00
"Proofs/Audit.lean" : "3a1540187622c47ee2de4bf1dd2379fbbabf4a3d6ec902f2b602dcf486731691" ,
round 8: self-deriving harness pins, honest extraction guarantees, attestation basis
Third reviewer returned ATTEST-with-conditions at 1bc4f39. Its conditions are
committed verbatim as ATTESTATION-BASIS.md so the limits travel with the
artifact instead of living in a review document a consumer never sees. Condition
9 — that extract.sh's byte-identical regeneration has never been observed by any
party but the author — is the campaign's last open item, and the file records
that both reviewers are now blocked on it for different environmental reasons.
HARNESS PINS ARE NOW SELF-DERIVING. My round-7 fix hardcoded the required pin
names, which the reviewer correctly called a second thing to keep in sync, and
it supplied the boundary the harness does have: the executable bit. check.sh now
requires every executable file in verification/ to be pinned (itself excluded —
it cannot pin itself), plus Proofs/Audit.lean. A new harness script therefore
fails closed until pinned. Consequence, and the reviewer argued for it:
check-selftest.sh, drill.sh and extract.sh are now pinned too — the self-test is
the only artifact demonstrating the gates work, and its assertions have been
defective in four consecutive rounds, so weakening it should be a reviewable
rotation rather than an unnoticed edit.
THE EXTRACTION SCRIPT'S GUARANTEES ARE NOW STATED HONESTLY. The reviewer found a
tautological assert in it — comparing a dict against the comprehension that had
just built it — in the script written to fix a provenance-honesty defect. My
first repair (comparing kept[k] against t[k]) was tautological for the same
reason, which I confirmed by negative test. No check inside a transformer can
detect a corrupted input, because the transformer defines the output from that
input; that lesson is now recorded in the code. Both fake checks are gone and
the header and provenance text name what actually protects the result — the
pinned SOURCE_SHA256, the sk-must-be-present check, the group and test counts,
and verify mode — each of which I negative-tested.
Also: the self-test keeps its backups outside verification/ (cp -p preserves the
executable bit, so an in-tree backup would have looked like an unpinned harness
file and failed a run for an unrelated reason); the Phase-0 banner no longer
says a file 'differs' when an entry is simply absent; and attack 18's assertion
follows the renamed diagnostic and now requires both missing pins to be named.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 12:40:39 +00:00
"check-selftest.sh" : "c6811482e25ae6e1fffa6ca50e60541e8e609a70c951db6bec4d2d39a4849e9a" ,
"drill.sh" : "915cf9310fa168c14ca5d76a1b84fd3b19acdfef9dfd0b03b01b19883548719e" ,
correspondence: keep the artifact that says what the model must answer
Round-8 estate review (GPT-5.6): this repository shipped a
FunsExternal_Template.lean / FunsExternal.lean pair and NO correspondence
check at all. This commit explains why, and fixes the cause rather than
bolting a check onto a missing input.
THE TEMPLATE WAS BEING DELETED. check.sh removed `*_Template.lean` on every
run and .gitignore excluded it. The stated reason was sound — "the verdict must
depend on COMMITTED BYTES, never on untracked build state", and an untracked
file on LEAN_PATH is exactly that problem. But it is the weaker of the two
available remedies. The ed25519 forks face the identical choice and COMMIT AND
PIN their templates, which removes the untracked state just as completely and
keeps the evidence.
The evidence is the point. The template is Aeneas's own statement of what the
extracted Rust needs from outside, and it is the ONLY artifact against which
"does the hand-written model ANSWER the extraction?" can be asked. Deleting it
made that question unaskable here — which is precisely why no check existed.
· template committed and pinned in model_integrity_sha256
· .gitignore no longer excludes it
· check.sh no longer deletes it, and says why at length
· Phase 0d runs model-correspondence.py — the forks' scanner, including both
round-8 corrections: a named Lean `section` does not qualify declaration
names, and an EXTRA AXIOM in the model (an assumption no template asks for)
fails rather than passing as a silent row
· MODEL-CORRESPONDENCE.txt committed, pinned, and compared byte-for-byte
Result: 11 externals, every one answered by the pinned model, no UNRESOLVED and
no EXTRA-AXIOM. Negative-tested — deleting one `axiom` from the model yields
`verify_mono.oracle.h_msg|UNRESOLVED` and a non-zero exit; restoring it returns
to green.
AND A REPRODUCIBILITY RESULT, obtained while recovering the deleted template.
charon is not available on this machine (the same wall the reviewer hit), but
SlhVerify.llbc IS committed and Aeneas is installed, so extraction step [2/2]
was re-run alone from the committed LLBC:
Types.lean: IDENTICAL Funs.lean: IDENTICAL
The LLBC -> Lean half of the extraction reproduces byte-for-byte from committed
inputs, on demand, by anyone with Aeneas and this repository. This does NOT
close `slh-extraction-unreproduced`: the Rust -> LLBC half still requires
charon, and this was still run by the author. Half the chain, verifiable today.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 13:49:16 +00:00
"extract.sh" : "01cff43c350ed8eaac0e65ccd7599b68fef47c9434cdb5ad01c92d2127a3bbe9" ,
"model-correspondence.py" : "1942177f13d6ae229d87a3b0b33f7fbb4b2ae20fe1059cc83010e73f6a156427" ,
Phase 3c: declaration coverage in both directions, and the accounting identity
Completes the round-8 hardening of this repository. Round-8 review (Claude,
register keys `drv-surface-no-cones` and `accounting-certifies-enumeration`).
WHAT PHASE 3 DID NOT PIN. It proves each certificate's cone is exact and that
no declaration in scope carries a disallowed axiom. It does not pin WHICH
declarations exist: a new one that happens to be clean, and a silently vanished
one, both pass it.
inventory-allowlist.txt 265 rows — the audited corpus
driver-allowlist.txt 35 rows — the audit INSTRUMENT's own surface
both as INV|module|name|kind|CONE, diffed in BOTH directions by
inventory_gate.sh, the same implementation the ed25519 repositories use,
with a tag per surface.
The instrument surface carries cones because the reviewer showed enumeration is
not audit: a claim planted in an instrument is counted by an accounting identity
and then examined by nothing, if its row carries no cone and no allowlist
covers it. Here the instrument's 35 declarations are pinned exactly as the
corpus's 265 are.
INTERNAL NAMES ARE NO LONGER EXEMPT from the environment walk. They were
skipped, which was harmless while nothing compared that walk against the
kernel's view — and became a hole the moment something did: Phase 3b reads
object files, which contain the compiler's auxiliaries. Exempting them would
have left the accounting identity permanently short and forced the residual to
be "explained" by a constant. That is the shape of the fudge term four-fork data
refuted in the ed25519 repositories, and it is refused here before it can start.
THE ACCOUNTING IDENTITY, as SET CONTAINMENT and never arithmetic: every constant
the kernel holds must appear in one of the two walks. The kernel gate now emits
KERNEL-NAME rows so the comparison names what is missing rather than reporting a
count that has to be interpreted.
kernel 300 = inventory 265 + instrument 35 residual: none
Negative-tested, all three rejected by name and the tree restored to green:
· a deleted INV row -> UNCLASSIFIED: INV|Proofs.ApexSpec|List.allM.eq_1|theorem|
· a deleted DRV row -> UNCLASSIFIED: DRV|Proofs.Audit|SlhVerify.Audit.sortNames|def
· a row with no declaration behind it -> STALE: …|fips205.ghost_that_does_not_exist|…
Both allowlists join the pinned harness set: not executable, so the
executable-bit rule cannot reach them, and an allowlist an attacker may rewrite
pins nothing.
fips205-slhdsa-verified now has the ed25519 repositories' gate set: 0 hygiene,
0d correspondence, 1 model, 2 proofs, 3 in-Lean audit, 3b kernel-side axiom
gate, 3c coverage + accounting.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 15:34:00 +00:00
"MODEL-CORRESPONDENCE.txt" : "77bd374a60152689edcb3350c2a2547c6aaad192629e39e86d8548d2bad3f748" ,
"inventory_gate.sh" : "3ebc8027f14c9e037f36322ef4119183c33214658efcc1a7bc985a98a9c32e4e" ,
"inventory-allowlist.txt" : "6b27fb410f61d0d6e0d17f9089a5dc1f53027bec507c6c7c180554c5c8f40ede" ,
"driver-allowlist.txt" : "5f9a4167068407ae5e31ec0c7c55d78af455a7ed7f1913b79912f6ae50c13686"
review round 5: bind the policy, the specification bodies, and the harness
The third reviewer demonstrated that the round-4 gate was closed at the
EXPLOITS, not the MECHANISMS: it bound the manifest rows while the things he
moved sat outside the binding. Three fail-opens, each executed end-to-end with
the button printing ALL GREEN. No theorem, proof, fold, or model body changed.
NEW-1 — the policy constant was unbound. `manifestFingerprint` covered
`manifest` but never `allowedBoundary`, the sole predicate the enumeration
tests against; adding one name re-opened the False-proof with the committed
fingerprint BYTE-IDENTICAL.
NEW-2 — the specification bodies were unbound. The statement fingerprint pinned
each certificate's TYPE, which names its reference fold; redefining that fold to
*be* the extracted loop left cone and type-hash identical while the certificate
degenerated to `loop = loop`. 100% of the fidelity content lives in those defs.
NEW-3 — the harness was unbound. Stubbing verification/lean-guard alone, without
touching check.sh or the proofs, gave ALL GREEN in 3.6s over destroyed proofs.
FIX — one mechanism rather than three patches. Audit.lean now emits a canonical
AUDIT-MANIFEST block and check.sh binds to its SHA-256. The block covers the
POLICY constants, every certificate's fully-elaborated statement, and every
specification constant transitively reachable from those statements with its
fully-elaborated BODY (41 constants; the closure is computed, so a new fold
cannot appear without moving the digest; Prop-valued constants contribute their
statement, by proof irrelevance). This also retires the 32-bit Expr.hash as the
binding (NEW-5) — it survives only as a per-certificate diagnostic.
Enumeration now covers EVERY declaration kind (a `def : False` passed before)
in the eight certificate modules AND in Audit.lean itself — the auditor is no
longer exempt (round-5 R1). A bare `axiom` in audited scope is now an error.
Phase 0 purges stale .olean (the verdict must depend on committed bytes, not
.gitignored build state — NEW-4), forbids any .lean outside gen/ and Proofs/,
and sha256-pins the four model files AND lean-guard. lean-guard is KEPT rather
than removed (the reviewer's portability advice is declined by operator
decision): it is the memory cap and machine-wide lock that protect the build
machine after a 12.2GB OOM took the host down. That trade-off is documented.
check.sh's "Certificates proven:" line now comes from the audited manifest; the
hand-kept CERTS array — the one authoritative claim string nothing bound — is
deleted.
check-selftest.sh: 14 attacks, all rejected, plus a check that the hashed block
literally carries the twelve fold bodies. Attacks 9-14 are the reviewers' and an
independent drill's own exploits, turned into regression tests.
DOCS. TRUSTED-BASE gains item 11 (the REAL trusted computing base — lean-guard
pinned; check.sh, the toolchain env, $AENEAS_HOME, python3 and Lean still
trusted) and item 12 (the apex does not compose the ten). README: the audit
description rewritten; the XMSS sibling-order claim downgraded from "pins" to
"makes visible", with a new blanket non-claim covering all ten loop
certificates; the de-plumbing file claim corrected (round 1 touched only
verify_mono.rs, round 2 only helpers.rs — which is ON the deployed verify AND
sign paths, now disclosed; wots.rs was never patched).
RECORDED-RUN: three lines that stood inside a fence were a hand-written summary,
not console output — fabricated evidence in the file whose purpose is machine
evidence. They are removed and the fabrication is named in place, together with
the correction that the "INDEPENDENT RUN" block predates this gate. New rule:
nothing goes in a fence unless captured with tee/cat, and every block states its
date, pin, and who ran it. The transcripts added here follow it.
Also disclosed rather than buried: three bugs in my own test harness this round
(an olean-purge build-order break, an attack rejected by the wrong rule, and a
coverage assertion looking on the wrong line) — each would have let an attack
pass or fail for an unrelated reason.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-27 20:57:46 +00:00
} ,
"audit_gate" : "verification/Proofs/Audit.lean \u2014 in-Lean audit (round 5). Per certificate: exact cone equality (collectAxioms) + elaborated-statement check. Enumeration: EVERY declaration kind (def/theorem/opaque/axiom \u2014 round 4 matched theorems only, so a `def : False` passed) in the eight certificate modules AND in Audit.lean itself (the auditor is not exempt). Binding digest: check.sh binds to the SHA-256 of a canonical AUDIT-MANIFEST block covering the POLICY constants (allowedBoundary + certModules \u2014 round-5 NEW-1: widening allowedBoundary previously re-opened the False-proof with the fingerprint byte-identical), every certificate's fully-elaborated statement, and every reachable specification definition's fully-elaborated BODY (round-5 NEW-2: redefining a reference fold to *be* the extracted loop previously left cone and fingerprint intact while the certificate degenerated to `loop = loop`). The 32-bit Expr.hash is retained only as a per-certificate diagnostic, not as the binding. Fail-closed; adversarially exercised by check-selftest.sh. check.sh Phase 0 additionally purges stale .olean files, forbids stray .lean outside gen/ and Proofs/, and pins model + harness bytes."
correspondence: keep the artifact that says what the model must answer
Round-8 estate review (GPT-5.6): this repository shipped a
FunsExternal_Template.lean / FunsExternal.lean pair and NO correspondence
check at all. This commit explains why, and fixes the cause rather than
bolting a check onto a missing input.
THE TEMPLATE WAS BEING DELETED. check.sh removed `*_Template.lean` on every
run and .gitignore excluded it. The stated reason was sound — "the verdict must
depend on COMMITTED BYTES, never on untracked build state", and an untracked
file on LEAN_PATH is exactly that problem. But it is the weaker of the two
available remedies. The ed25519 forks face the identical choice and COMMIT AND
PIN their templates, which removes the untracked state just as completely and
keeps the evidence.
The evidence is the point. The template is Aeneas's own statement of what the
extracted Rust needs from outside, and it is the ONLY artifact against which
"does the hand-written model ANSWER the extraction?" can be asked. Deleting it
made that question unaskable here — which is precisely why no check existed.
· template committed and pinned in model_integrity_sha256
· .gitignore no longer excludes it
· check.sh no longer deletes it, and says why at length
· Phase 0d runs model-correspondence.py — the forks' scanner, including both
round-8 corrections: a named Lean `section` does not qualify declaration
names, and an EXTRA AXIOM in the model (an assumption no template asks for)
fails rather than passing as a silent row
· MODEL-CORRESPONDENCE.txt committed, pinned, and compared byte-for-byte
Result: 11 externals, every one answered by the pinned model, no UNRESOLVED and
no EXTRA-AXIOM. Negative-tested — deleting one `axiom` from the model yields
`verify_mono.oracle.h_msg|UNRESOLVED` and a non-zero exit; restoring it returns
to green.
AND A REPRODUCIBILITY RESULT, obtained while recovering the deleted template.
charon is not available on this machine (the same wall the reviewer hit), but
SlhVerify.llbc IS committed and Aeneas is installed, so extraction step [2/2]
was re-run alone from the committed LLBC:
Types.lean: IDENTICAL Funs.lean: IDENTICAL
The LLBC -> Lean half of the extraction reproduces byte-for-byte from committed
inputs, on demand, by anyone with Aeneas and this repository. This does NOT
close `slh-extraction-unreproduced`: the Rust -> LLBC half still requires
charon, and this was still run by the author. Half the chain, verifiable today.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 13:49:16 +00:00
}