L1+L2: hashing shapes, domain separation, MTH/Root/ConsRec with termination
Accumulator pyramid layers 1-2, mechanizing paper SS5.3/SS6 groundwork:
- gen/LTLAcc/HashExternal.lean: the single sanctioned axiom, opaque
sha256 (no properties assumed - the soundness theorems downstream are
constructive collision extractors).
- Proofs/Basic.lean: hleaf/hnode (0x00/0x01 domain stamps); Lemma 1
(domsep) proven AXIOM-FREE; kbelow (largest power of two below n)
with pos/lt/le-two bound lemmas; MTH, Root (Option = rejection),
ConsRec (four cases, b-flag, pinned anchor) - all with kernel-checked
termination via the kbelow bounds.
- check.sh: estate discipline (stub audit, axiom-smuggling gate,
lean-guard compilation, boundary-exact per-certificate cone audit).
All green; observed cones pinned exactly.
Zero contact with the live LTL: no appends, no server, accumulator
frozen at 12 leaves throughout this project.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:58:00 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
# check.sh — THE button (accumulator corpus). Same discipline as the
|
|
|
|
|
# *-ed25519-verified repos: compiles every shipped .lean through lean-guard
|
|
|
|
|
# and axiom-audits every certificate against its DOCUMENTED exact cone,
|
|
|
|
|
# both directions.
|
|
|
|
|
#
|
|
|
|
|
# Phases: 0 resource/integrity · 1 stub+axiom-smuggling audit ·
|
|
|
|
|
# 2 compile manifest · 3 boundary-exact axiom audit
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
source ~/aeneas-toolchain/env.sh
|
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
AENEAS_LEAN="$AENEAS_HOME/backends/lean"
|
|
|
|
|
TIMEOUT="${LEAN_TIMEOUT:-600}"
|
|
|
|
|
export LEAN_MEM_MB="${LEAN_MEM_MB:-4096}"
|
|
|
|
|
CORES="${LEAN_MAX_CORES:-0-3}"
|
|
|
|
|
|
|
|
|
|
GEN_MODULES=( LTLAcc/HashExternal )
|
2026-07-11 18:23:49 +00:00
|
|
|
PROOFS=( Basic Completeness Extract Descent Consistency Binding3 Refactor Theorem3 PinStore )
|
L1+L2: hashing shapes, domain separation, MTH/Root/ConsRec with termination
Accumulator pyramid layers 1-2, mechanizing paper SS5.3/SS6 groundwork:
- gen/LTLAcc/HashExternal.lean: the single sanctioned axiom, opaque
sha256 (no properties assumed - the soundness theorems downstream are
constructive collision extractors).
- Proofs/Basic.lean: hleaf/hnode (0x00/0x01 domain stamps); Lemma 1
(domsep) proven AXIOM-FREE; kbelow (largest power of two below n)
with pos/lt/le-two bound lemmas; MTH, Root (Option = rejection),
ConsRec (four cases, b-flag, pinned anchor) - all with kernel-checked
termination via the kbelow bounds.
- check.sh: estate discipline (stub audit, axiom-smuggling gate,
lean-guard compilation, boundary-exact per-certificate cone audit).
All green; observed cones pinned exactly.
Zero contact with the live LTL: no appends, no server, accumulator
frozen at 12 leaves throughout this project.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:58:00 +00:00
|
|
|
|
|
|
|
|
# Certificates and their exact expected cones (observed at first green
|
|
|
|
|
# compile, 2026-07-10; any drift in EITHER direction is a failure).
|
|
|
|
|
declare -A CONES=(
|
|
|
|
|
[LTLAcc.domsep]=""
|
|
|
|
|
[LTLAcc.kbelow_pos]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.kbelow_lt]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.le_two_kbelow]="propext, Quot.sound"
|
2026-07-11 10:26:04 +00:00
|
|
|
[LTLAcc.kbelow_pow2]="propext, Quot.sound"
|
L1+L2: hashing shapes, domain separation, MTH/Root/ConsRec with termination
Accumulator pyramid layers 1-2, mechanizing paper SS5.3/SS6 groundwork:
- gen/LTLAcc/HashExternal.lean: the single sanctioned axiom, opaque
sha256 (no properties assumed - the soundness theorems downstream are
constructive collision extractors).
- Proofs/Basic.lean: hleaf/hnode (0x00/0x01 domain stamps); Lemma 1
(domsep) proven AXIOM-FREE; kbelow (largest power of two below n)
with pos/lt/le-two bound lemmas; MTH, Root (Option = rejection),
ConsRec (four cases, b-flag, pinned anchor) - all with kernel-checked
termination via the kbelow bounds.
- check.sh: estate discipline (stub audit, axiom-smuggling gate,
lean-guard compilation, boundary-exact per-certificate cone audit).
All green; observed cones pinned exactly.
Zero contact with the live LTL: no appends, no server, accumulator
frozen at 12 leaves throughout this project.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:58:00 +00:00
|
|
|
[LTLAcc.MTH]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.Root]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.ConsRec]="propext, LTLAcc.sha256, Quot.sound"
|
2026-07-11 10:06:20 +00:00
|
|
|
[LTLAcc.Path]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.incl_complete]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
S3/L4-L5: root binding (Lemma 2, Path instance) + Theorem 2, constructive
The crux layer — the statement whose HAND proof once carried the frontier
coverage bug is now kernel-checked.
- gen: hash outputs refactored to Hash = {l : List UInt8 // l.length = 32}.
MECHANIZATION FINDING: the paper's pair-coincidence step ('equal hnode
values of distinct argument pairs are a collision') is load-bearing on
FIXED-WIDTH outputs — with unconstrained byte strings x++s = X++Y does
not split. hnode_preimage_inj (cone: propext) makes this explicit via
List.append_inj on equal-length components. Queued as a half-sentence
for the paper's next cycle.
- HasCollision := ∃ x y, x ≠ y ∧ sha256 x = sha256 y — appears ONLY as a
conclusion, never a hypothesis (no collision-resistance assumed).
- hnode_inj_or_collision / hleaf_inj_or_collision: the per-node dichotomy.
- root_binding: any accepting reconstruction from (v,P) to the honest root
either IS the honest receipt (leaf hash AND full path P = Path m D — case
(ii) pinning every consumed sibling) or exhibits a collision. Motive
quantifies (v,P); induction on Path; k-fold discipline.
- incl_sound (Theorem 2, position binding): accepting a wrong leaf at m
yields a collision. Cone [propext, Classical.choice, LTLAcc.sha256,
Quot.sound] — the single hash axiom, pinned in check.sh. ALL GREEN.
Also: Root n=1 branch changed from list-match to decidable 'if P = []'
(well-founded unfolding generated a spurious exhaustiveness obligation);
Root_one_cons added. Fable-5 statement-audit passed. LTL untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:21:17 +00:00
|
|
|
[LTLAcc.hnode_preimage_inj]="propext"
|
S3.5: explicit collision extractor — Theorem 2 made non-vacuous, vacuous forms removed
The S3 Socratic re-audit found incl_sound was kernel-perfect but VACUOUS:
its '... ∨ HasCollision' disjunct (∃ x y, x≠y ∧ sha256 x = sha256 y) is
provable by pigeonhole ALONE (sha256: infinite List UInt8 → finite
32-byte Hash), so the theorem said nothing about forgeries. Even a
data-carrying {p // IsCollision p} disjunct fails (Classical.choice
inhabits it). The only faithful rendering of the paper's 'explicit
algorithm 𝓔' is a NAMED FUNCTION whose correctness is a claim about ITS
OUTPUT.
- extractIncl (m D d P): total function that walks the honest tree and
returns the concrete colliding preimage pair at the first divergence
(a node preimage pair, or the leaf preimage pair at the bottom).
- extractIncl_correct: d ≠ D[m] ∧ accepting-receipt →
IsCollision (extractIncl …).1 (extractIncl …).2. A statement ABOUT the
fixed function's output; pigeonhole cannot discharge it.
ADVERSARIAL CHECK (probe, since removed): proved
¬ IsCollision (extractIncl 0 [[7]] [7] []) — i.e. on a NON-forgery input
the output is provably NOT a collision, so the conclusion is genuinely
false for some inputs ⇒ non-vacuous, choice-proof.
- Removed the vacuous theorems entirely (incl_sound, root_binding,
hnode/hleaf_inj_or_collision, HasCollision def) so no hollow statement
survives in a corpus destined for the log. Kept the real building
blocks (hnode_preimage_inj [propext]; eq_dropLast helper moved to
Completeness; Binding.lean deleted).
extractIncl_correct cone [propext, Classical.choice, LTLAcc.sha256,
Quot.sound]. THE button green (14 certs). Fable statement-audit passed.
LTL untouched (12 leaves, bcd15f9d).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 13:31:21 +00:00
|
|
|
[LTLAcc.IsCollision]="LTLAcc.sha256"
|
|
|
|
|
[LTLAcc.extractIncl]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.extractIncl_correct]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
2026-07-11 14:38:34 +00:00
|
|
|
[LTLAcc.extractIncl_nonvacuous]="propext, LTLAcc.sha256, Quot.sound"
|
2026-07-11 14:46:58 +00:00
|
|
|
[LTLAcc.extractMTH]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.extractMTH_correct]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.extractMTH_nonvacuous]="propext, LTLAcc.sha256, Quot.sound"
|
2026-07-11 15:53:43 +00:00
|
|
|
[LTLAcc.kbelow_prefix_eq]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.take_take_le]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.take_drop_prefix]="propext, Classical.choice, Quot.sound"
|
2026-07-11 15:55:51 +00:00
|
|
|
[LTLAcc.extractConsNode]="propext, LTLAcc.sha256, Quot.sound"
|
S5.3: consRecBinding PROVEN — Theorem 3 steps 1-2 kernel-checked (the hardest object)
The single hardest proof in the corpus is complete, no sorry. Under the
value-equality invariant y = MTH D₁, an accepting ConsRec fold either
makes extractConsNode output a genuine collision or its first component
is the honest prefix root MTH(D₁.take n₀).
- ConsRec base changed from list-match to decidable if (if C=[] /
if C.length=1) — same root-cause fix as Root, avoids WF-unfold
exhaustiveness obligations; more faithful to the deployed Python.
Whole chain (Basic..Consistency) rebuilt clean.
- consRecBinding by ConsRec.induct (10 cases): 4 base/singleton, 3
rejection/none contradictions, 2 recursive (n₀≤k, n₀>k). The n₀>k
none-branch is where all S5.1 infrastructure interlocks:
kbelow_prefix_eq (prefix splits at same k) + take_take_le +
take_drop_prefix assemble x = hnode s xx into MTH(D₁.take n₀). The
collision branches use append_inj (fixed-width Hash) + MTH_split.
- take_all helper (take-whole-list).
Cone [propext, Classical.choice, LTLAcc.sha256, Quot.sound] — single hash
axiom. 24 certs green. Fable statement-audit: matches paper Thm 3
steps 1-2. LTL untouched (12 leaves, bcd15f9d).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 17:18:26 +00:00
|
|
|
[LTLAcc.take_all]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.consRecBinding]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
2026-07-11 17:25:04 +00:00
|
|
|
[LTLAcc.consRec_base_false_eq]="propext, Quot.sound"
|
|
|
|
|
[LTLAcc.consRec_base_true_eq]="propext, Quot.sound"
|
S5.4: THEOREM 3 COMPLETE — extractCons assembly + non-vacuity witness
The paper's hardest theorem is fully kernel-checked. extractCons joins
the two proven halves: extractConsNode's collision (via consRecBinding,
steps 1-2) or the descent extractMTH D₀ (D₁.take n₀) (step 3, S4).
- extractCons_correct: acceptance ConsRec n₀ |D₁| C ⊤ (MTH D₀) =
some (MTH D₀, MTH D₁) with D₀ ≠ D₁.take n₀ (and |D₀| = n₀ ≤ |D₁|,
0 < n₀) ⇒ IsCollision of THIS function's output. Statement matches
paper Thm 3 verbatim (the n₀ = 0 escape is vacuous there: [] is
always the real prefix). Compiled on first attempt — the pre-verified
skeleton held exactly.
- extractCons_nonvacuous (queued requirement honored): on a non-rewrite
input the output is provably NOT a collision — choice-proof.
Cones: extractCons_correct [propext, Classical.choice, LTLAcc.sha256,
Quot.sound] — single hash axiom, no collision-resistance assumed
anywhere. 29 certs green. Fable statement-audit passed. LTL untouched
(12 leaves, bcd15f9d).
Corpus now holds kernel-checked: Lemma 1, Theorem 1, Theorem 2,
Theorem 3 (+ whole-tree Lemma 2). Remaining: Prop 1 (S6), fidelity
harness (S7), freeze (S8).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 18:07:20 +00:00
|
|
|
[LTLAcc.extractCons]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.extractCons_correct]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.extractCons_nonvacuous]="propext, LTLAcc.sha256, Quot.sound"
|
2026-07-11 18:23:49 +00:00
|
|
|
[LTLAcc.pinAccept_monotone]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.pin_prefix_correct]="propext, Classical.choice, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.fork_distinct]="propext, LTLAcc.sha256, Quot.sound"
|
|
|
|
|
[LTLAcc.pin_prefix_nonvacuous]="propext, LTLAcc.sha256, Quot.sound"
|
L1+L2: hashing shapes, domain separation, MTH/Root/ConsRec with termination
Accumulator pyramid layers 1-2, mechanizing paper SS5.3/SS6 groundwork:
- gen/LTLAcc/HashExternal.lean: the single sanctioned axiom, opaque
sha256 (no properties assumed - the soundness theorems downstream are
constructive collision extractors).
- Proofs/Basic.lean: hleaf/hnode (0x00/0x01 domain stamps); Lemma 1
(domsep) proven AXIOM-FREE; kbelow (largest power of two below n)
with pos/lt/le-two bound lemmas; MTH, Root (Option = rejection),
ConsRec (four cases, b-flag, pinned anchor) - all with kernel-checked
termination via the kbelow bounds.
- check.sh: estate discipline (stub audit, axiom-smuggling gate,
lean-guard compilation, boundary-exact per-certificate cone audit).
All green; observed cones pinned exactly.
Zero contact with the live LTL: no appends, no server, accumulator
frozen at 12 leaves throughout this project.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 21:58:00 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
free -m | awk '/Mem:/{if($7<2048){print "FATAL: <2GB RAM available — refusing to compile"; exit 1}}'
|
|
|
|
|
echo "=== Phase 0: source integrity ==="
|
|
|
|
|
for f in "$HERE"/gen/LTLAcc/*.lean "$HERE"/Proofs/*.lean; do
|
|
|
|
|
[ -f "$f" ] || continue
|
|
|
|
|
if ! grep -qE '^(/-|import |namespace |theorem |def |noncomputable |open |set_option |--|abbrev )' "$f"; then
|
|
|
|
|
echo "CORRUPTED: $f is not Lean source. Restore: git checkout HEAD -- $f"; exit 1
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
echo " all sources valid"
|
|
|
|
|
|
|
|
|
|
echo "=== Phase 1: stub + axiom-smuggling audit ==="
|
|
|
|
|
if grep -rn 'by trivial' "$HERE"/Proofs/*.lean 2>/dev/null; then
|
|
|
|
|
echo "STUB DETECTED"; exit 1; fi
|
|
|
|
|
if grep -rn ' : True :=' "$HERE"/Proofs/*.lean 2>/dev/null; then
|
|
|
|
|
echo "STUB DETECTED: True-target theorem"; exit 1; fi
|
|
|
|
|
if grep -rnE '^(private |protected |noncomputable )*axiom ' "$HERE"/Proofs/*.lean 2>/dev/null; then
|
|
|
|
|
echo "AXIOM SMUGGLING DETECTED: axiom under Proofs/ — gen/ is the only sanctioned site."; exit 1
|
|
|
|
|
fi
|
|
|
|
|
echo " clean"
|
|
|
|
|
|
|
|
|
|
echo "=== Phase 2: compile ==="
|
|
|
|
|
LOG=$(mktemp /tmp/acc-check-XXXX.log)
|
|
|
|
|
cd "$AENEAS_LEAN"
|
|
|
|
|
lake env bash -c "
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
cd '$HERE/gen' && export LEAN_PATH=\"\$LEAN_PATH:\$PWD:$HERE\"
|
|
|
|
|
compile() {
|
|
|
|
|
echo \" · \$1\"
|
|
|
|
|
LEAN_TIMEOUT=$TIMEOUT LEAN_MAX_CORES=$CORES '$HERE/lean-guard' \"\${1}.lean\" 2>&1 | tee -a '$LOG' || { echo \"FAIL: \$1\"; exit 1; }
|
|
|
|
|
}
|
|
|
|
|
for m in ${GEN_MODULES[*]}; do compile \"\$m\"; done
|
|
|
|
|
cd '$HERE'
|
|
|
|
|
for m in ${PROOFS[*]}; do
|
|
|
|
|
[ -f \"Proofs/\$m.lean\" ] || { echo \"MISSING: Proofs/\$m.lean\"; exit 1; }
|
|
|
|
|
compile \"Proofs/\$m\"
|
|
|
|
|
done
|
|
|
|
|
for f in Proofs/*.lean; do
|
|
|
|
|
b=\$(basename \"\$f\" .lean)
|
|
|
|
|
[ \"\$b\" = AxiomCheck ] && continue
|
|
|
|
|
case \" ${PROOFS[*]} \" in (*\" \$b \"*) ;; (*) echo \"DEAD FILE: \$f\"; exit 1;; esac
|
|
|
|
|
done
|
|
|
|
|
"
|
|
|
|
|
if grep -q "uses 'sorry'" "$LOG"; then echo "STUB: sorry detected"; exit 1; fi
|
|
|
|
|
rm -f "$LOG"
|
|
|
|
|
|
|
|
|
|
echo "=== Phase 3: boundary-exact axiom audit ==="
|
|
|
|
|
AUD=$(mktemp /tmp/acc-audit-XXXX.log)
|
|
|
|
|
cd "$AENEAS_LEAN"
|
|
|
|
|
lake env bash -c "
|
|
|
|
|
cd '$HERE' && export LEAN_PATH=\"\$LEAN_PATH:$HERE/gen:$HERE\"
|
|
|
|
|
LEAN_TIMEOUT=300 LEAN_MAX_CORES=$CORES '$HERE/lean-guard' Proofs/AxiomCheck.lean
|
|
|
|
|
" > "$AUD" 2>&1 || { cat "$AUD"; exit 1; }
|
|
|
|
|
FAIL=0
|
|
|
|
|
for cert in "${!CONES[@]}"; do
|
|
|
|
|
want="${CONES[$cert]}"
|
|
|
|
|
if [ -z "$want" ]; then
|
|
|
|
|
exp="'$cert' does not depend on any axioms"
|
|
|
|
|
else
|
|
|
|
|
exp="'$cert' depends on axioms: [$want]"
|
|
|
|
|
fi
|
|
|
|
|
if ! grep -qF "$exp" "$AUD"; then
|
|
|
|
|
echo " CONE DRIFT: $cert"
|
|
|
|
|
echo " expected: $exp"
|
|
|
|
|
echo " observed: $(grep -F "'$cert'" "$AUD" || echo '(missing)')"
|
|
|
|
|
FAIL=1
|
|
|
|
|
else
|
|
|
|
|
echo " ✓ $cert [$want]"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
rm -f "$AUD"
|
|
|
|
|
[ "$FAIL" = 0 ] || exit 1
|
|
|
|
|
echo "=== ALL GREEN ==="
|