2026-07-02 12:17:44 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
# check.sh — THE button. Compiles EVERY shipped .lean file and axiom-audits
|
|
|
|
|
# EVERY layer certificate. If a file is in this repo, this script checks it;
|
|
|
|
|
# if this script doesn't check it, it must not be in the repo.
|
|
|
|
|
#
|
|
|
|
|
# Phases:
|
|
|
|
|
# 0. resource + source-integrity guards
|
|
|
|
|
# 1. stub audit: no `by trivial` specs, no True-target theorems, and — the
|
|
|
|
|
# anti-axiom-smuggling gate — ZERO `axiom` declarations under Proofs/
|
|
|
|
|
# (external models in gen/ are the only sanctioned axiom site)
|
|
|
|
|
# 2. compile gen/ + Proofs/ in dependency order (explicit -o, capped cores,
|
|
|
|
|
# per-file timeout). Any "declaration uses 'sorry'" warning is a FAILURE
|
|
|
|
|
# (this catches sorry robustly — text greps can't, comments mention it).
|
|
|
|
|
# 3. axiom audit: #print axioms for every certificate in CERTS; each must
|
|
|
|
|
# report exactly [propext, Classical.choice, Quot.sound]
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
source ~/aeneas-toolchain/env.sh
|
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
|
AENEAS_LEAN="$AENEAS_HOME/backends/lean"
|
|
|
|
|
TIMEOUT="${LEAN_TIMEOUT:-300}"
|
2026-07-03 10:54:26 +00:00
|
|
|
export LEAN_MEM_MB="${LEAN_MEM_MB:-8192}" # 8192: ReduceSpec exceeds 6144 (coherence pass 2)
|
2026-07-02 12:17:44 +00:00
|
|
|
CORES="${LEAN_MAX_CORES:-0-3}"
|
|
|
|
|
|
|
|
|
|
# Layer manifests (extended as the pyramid grows; ORDER = import order).
|
|
|
|
|
GEN_MODULES=(
|
|
|
|
|
CurveField/TypesExternal
|
|
|
|
|
CurveField/Types
|
|
|
|
|
CurveField/FunsExternal
|
|
|
|
|
CurveField/Funs
|
|
|
|
|
)
|
|
|
|
|
PROOFS=(
|
|
|
|
|
Basic
|
|
|
|
|
Denote
|
|
|
|
|
P25519
|
|
|
|
|
ReduceSpec
|
|
|
|
|
SubNegSpec
|
|
|
|
|
ConstSpecs
|
|
|
|
|
AddSpec
|
|
|
|
|
MulSpec
|
|
|
|
|
SquareSpec
|
|
|
|
|
Square2Spec
|
|
|
|
|
Field
|
|
|
|
|
InvertSpec
|
|
|
|
|
FieldMain
|
|
|
|
|
FeQ
|
2026-07-02 12:50:42 +00:00
|
|
|
EdCurve
|
|
|
|
|
EdDenote
|
|
|
|
|
EdDouble
|
|
|
|
|
EdAddProjNiels
|
|
|
|
|
EdAddAffNiels
|
|
|
|
|
EdConvert
|
|
|
|
|
EdMain
|
2026-07-02 12:17:44 +00:00
|
|
|
)
|
|
|
|
|
# Fully-qualified certificate names; each must be axiom-clean.
|
|
|
|
|
CERTS=(
|
|
|
|
|
CurveFieldProofs.fieldImplementation
|
2026-07-02 12:50:42 +00:00
|
|
|
CurveFieldProofs.edwardsImplementation
|
2026-07-02 12:17:44 +00:00
|
|
|
)
|
|
|
|
|
# Imports needed so every certificate in CERTS is in scope for the audit.
|
|
|
|
|
AUDIT_IMPORTS=(
|
|
|
|
|
Proofs.FieldMain
|
2026-07-02 12:50:42 +00:00
|
|
|
Proofs.EdMain
|
2026-07-02 12:17:44 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# ── Phase 0: resource + integrity guards ────────────────────────────────────
|
|
|
|
|
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/CurveField/*.lean "$HERE"/Proofs/*.lean; do
|
|
|
|
|
[ -f "$f" ] || continue
|
|
|
|
|
if ! grep -qE '^(/-|import |namespace |theorem |def |open |set_option |--)' "$f"; then
|
|
|
|
|
echo "CORRUPTED: $f is not Lean source (olean clobber?). Restore: git checkout HEAD -- $f"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
echo " all sources valid"
|
|
|
|
|
|
|
|
|
|
# ── Phase 1: stub + axiom-smuggling audit ───────────────────────────────────
|
|
|
|
|
echo "=== Phase 1: stub audit ==="
|
|
|
|
|
if grep -rn 'by trivial' "$HERE"/Proofs/*Spec*.lean 2>/dev/null; then
|
|
|
|
|
echo "STUB DETECTED: 'by trivial' in spec files"; 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 declaration under Proofs/ — forbidden."
|
|
|
|
|
echo "External models belong in gen/*/FunsExternal.lean and must stay outside"
|
|
|
|
|
echo "every certificate's dependency cone (Phase 3 verifies that)."
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
echo " clean: no trivial stubs, no True targets, no axioms outside gen/"
|
|
|
|
|
|
|
|
|
|
# ── Phase 2: compile everything shipped ─────────────────────────────────────
|
|
|
|
|
echo "=== Phase 2: compile ==="
|
|
|
|
|
LOG=$(mktemp /tmp/check-compile-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\"
|
2026-07-02 14:10:55 +00:00
|
|
|
LEAN_TIMEOUT=$TIMEOUT LEAN_MAX_CORES=$CORES '$HERE/lean-guard' \"\${1}.lean\" 2>&1 | tee -a '$LOG' || { echo \"FAIL: \$1\"; exit 1; }
|
2026-07-02 12:17:44 +00:00
|
|
|
}
|
|
|
|
|
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 listed in manifest\"; exit 1; }
|
|
|
|
|
compile \"Proofs/\$m\"
|
|
|
|
|
done
|
|
|
|
|
# every shipped proof file must be in the manifest (no dead files)
|
|
|
|
|
for f in Proofs/*.lean; do
|
|
|
|
|
b=\$(basename \"\$f\" .lean)
|
|
|
|
|
[ \"\$b\" = AxiomCheck ] && continue
|
2026-07-03 10:54:26 +00:00
|
|
|
case \"\$b\" in Scalar*) continue;; esac # scalar layer: checked by check-scalar.sh (coherence pass 2)
|
2026-07-02 12:17:44 +00:00
|
|
|
case \" ${PROOFS[*]} \" in (*\" \$b \"*) ;; (*) echo \"DEAD FILE: \$f not in check manifest\"; exit 1;; esac
|
|
|
|
|
done
|
|
|
|
|
"
|
|
|
|
|
if grep -q "uses 'sorry'" "$LOG"; then
|
|
|
|
|
echo "STUB DETECTED: a compiled declaration uses 'sorry'"; exit 1; fi
|
|
|
|
|
rm -f "$LOG"
|
|
|
|
|
|
|
|
|
|
# ── Phase 3: axiom audit of every certificate ───────────────────────────────
|
|
|
|
|
echo "=== Phase 3: axiom audit ==="
|
|
|
|
|
EXPECTED="[propext, Classical.choice, Quot.sound]"
|
|
|
|
|
cd "$AENEAS_LEAN"
|
|
|
|
|
lake env bash -c "
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
cd '$HERE/gen' && export LEAN_PATH=\"\$LEAN_PATH:\$PWD:$HERE\"
|
|
|
|
|
cd '$HERE'
|
2026-07-03 10:54:26 +00:00
|
|
|
AUD=\$(mktemp '$HERE/.audit-XXXX.lean')
|
2026-07-02 12:17:44 +00:00
|
|
|
{
|
|
|
|
|
for i in ${AUDIT_IMPORTS[*]}; do echo \"import \$i\"; done
|
|
|
|
|
for c in ${CERTS[*]}; do echo \"#print axioms \$c\"; done
|
|
|
|
|
} > \"\$AUD\"
|
2026-07-03 10:54:26 +00:00
|
|
|
OUT=\$(LEAN_TIMEOUT=$TIMEOUT LEAN_MEM_MB=4096 '$HERE/lean-guard' \"\$AUD\" 2>&1)
|
2026-07-02 12:17:44 +00:00
|
|
|
echo \"\$OUT\"
|
|
|
|
|
rm -f \"\$AUD\"
|
|
|
|
|
N_CLEAN=\$(echo \"\$OUT\" | grep -cF \"depends on axioms: $EXPECTED\" || true)
|
|
|
|
|
if [ \"\$N_CLEAN\" -ne ${#CERTS[@]} ]; then
|
|
|
|
|
echo \"AXIOM AUDIT FAILED: \$N_CLEAN/${#CERTS[@]} certificates clean\"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
"
|
|
|
|
|
echo ""
|
|
|
|
|
echo "ALL PROOFS PASS. ALL CERTIFICATES AXIOM-CLEAN. NO DEAD FILES."
|