From d43446866a129a607b891ab29e7f0aa58da3bdd6 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 9 Nov 2026 14:15:42 +0000 Subject: [PATCH 1/2] feat(verification): re-home the Lean engineering proofs to Idris2; ledger rows now proven Third PR of the proof-ledger stack. The owner decided (2026-11-09) to re-home the Lean engineering proofs now rather than record their kernel axioms as necessary. That is PROOF-POLICY section 3: interface and engineering statements live in Idris2. - verification/proofs/idris2/ gains RateLimiting, BayesianUpdate, ParserTotality, PageRankInvariants and ESNSpectralScaling, theorem for theorem, with the Lean names in camelCase. All are under `%default total`, with no believe_me, assert_total or holes. - Four of the Lean files had rested on propext, or on propext and Quot.sound, per Lean.collectAxioms. Idris2 has neither. Their ledger rows (now rate-limiting, bayesian-update, parser-totality, pagerank-preconditions and esn-preconditions) are proven. The census moves from 18 to 22 proven of 42, with 0 proven-with-postulates. - verification/proofs/lean4/ is removed. The `lake build` job becomes `Lean hole re-check (HYP-01 control)`: the pinned Lean stays, only for the verdict fixture. That job is not a required check. - README, AFFIRMATION, EXPLAINME, PROOF-STATUS and needs.adoc describe the move. The `claims` gate caught all four stale census quotes before they were updated. - tests/proof-ledger-test.sh: the axiom contracts target rows that exist, and `mutate` now fails when its target row is missing. A vanished row would otherwise make a contract pass for the wrong reason. Local receipt, Idris2 0.7.0 built from source with Chez: - all 12 verification/proofs/idris2/*.idr pass idris2 --check; - the hypatia-abi and hypatia-verify ipkgs build (exit 0); - check-verdicts passes (2 positive controls, 5 expected rejections); - check-trusted-base is OK. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01CYR5bf5FBLS7cXQK72aVNM --- .github/workflows/verify-proofs.yml | 44 ++-- .machine_readable/testing/blitz.a2ml | 2 +- AFFIRMATION.adoc | 12 +- CHANGELOG.adoc | 12 + EXPLAINME.adoc | 20 +- README.adoc | 8 +- docs/proofs/gap-analysis.adoc | 6 + docs/proofs/needs.adoc | 6 +- tests/proof-ledger-test.sh | 9 +- verification/PROOF-STATUS.adoc | 63 ++--- verification/proof-ledger.jsonl | 12 +- verification/proofs/idris2/BayesianUpdate.idr | 189 +++++++++++++++ .../proofs/idris2/ESNSpectralScaling.idr | 126 ++++++++++ .../proofs/idris2/PageRankInvariants.idr | 89 +++++++ verification/proofs/idris2/ParserTotality.idr | 145 ++++++++++++ verification/proofs/idris2/RateLimiting.idr | 222 +++++++++++++++++ verification/proofs/lean4/.gitignore | 4 - verification/proofs/lean4/BayesianUpdate.lean | 188 --------------- .../proofs/lean4/ESNSpectralScaling.lean | 148 ------------ .../proofs/lean4/PageRankInvariants.lean | 120 ---------- verification/proofs/lean4/ParserTotality.lean | 191 --------------- verification/proofs/lean4/RateLimiting.lean | 223 ------------------ verification/proofs/lean4/lakefile.lean | 12 - verification/proofs/lean4/lean-toolchain | 1 - 24 files changed, 874 insertions(+), 978 deletions(-) create mode 100644 verification/proofs/idris2/BayesianUpdate.idr create mode 100644 verification/proofs/idris2/ESNSpectralScaling.idr create mode 100644 verification/proofs/idris2/PageRankInvariants.idr create mode 100644 verification/proofs/idris2/ParserTotality.idr create mode 100644 verification/proofs/idris2/RateLimiting.idr delete mode 100644 verification/proofs/lean4/.gitignore delete mode 100644 verification/proofs/lean4/BayesianUpdate.lean delete mode 100644 verification/proofs/lean4/ESNSpectralScaling.lean delete mode 100644 verification/proofs/lean4/PageRankInvariants.lean delete mode 100644 verification/proofs/lean4/ParserTotality.lean delete mode 100644 verification/proofs/lean4/RateLimiting.lean delete mode 100644 verification/proofs/lean4/lakefile.lean delete mode 100644 verification/proofs/lean4/lean-toolchain diff --git a/.github/workflows/verify-proofs.yml b/.github/workflows/verify-proofs.yml index 7fa7acf4..eea9c8e2 100644 --- a/.github/workflows/verify-proofs.yml +++ b/.github/workflows/verify-proofs.yml @@ -12,7 +12,6 @@ on: - Justfile - pack.toml - verification/proofs/idris2/** - - verification/proofs/lean4/** - verification/proofs/tlaplus/** - verification/proofs/agda/** - verification/PROOF-STATUS.adoc @@ -43,7 +42,6 @@ on: - Justfile - pack.toml - verification/proofs/idris2/** - - verification/proofs/lean4/** - verification/proofs/tlaplus/** - verification/proofs/agda/** - verification/PROOF-STATUS.adoc @@ -231,8 +229,11 @@ jobs: done } >> "$GITHUB_STEP_SUMMARY" - lake-build: - name: lake build + # Lean is no longer a proof lane here: the engineering proofs it held moved + # to Idris2 (PROOF-POLICY section 3; verification/proofs/idris2/). It stays + # for the HYP-01 positive control, which re-runs Lean on a fixture. + lean-hole-recheck: + name: Lean hole re-check (HYP-01 control) runs-on: ubuntu-latest timeout-minutes: 20 permissions: @@ -240,25 +241,20 @@ jobs: env: ELAN_VERSION: v4.0.0 - # Pinned (not :stable) so the proofs are checked against the exact Lean - # they were verified with. Matches verification/proofs/lean4/lean-toolchain; - # bump both together. A moving :stable can break version-sensitive lemmas. + # Pinned (not :stable): tests/accept/LeanHoleRecheckSound.idr records + # the Lean version whose output it digests. LEAN_TOOLCHAIN: leanprover/lean4:v4.30.0 steps: - name: Checkout uses: actions/checkout@v7.0.1 - - name: Cache Lean toolchain and build + - name: Cache Lean toolchain id: cache-lean uses: actions/cache@v6.1.0 with: - path: | - ~/.elan - verification/proofs/lean4/.lake - key: lean-${{ env.ELAN_VERSION }}-${{ env.LEAN_TOOLCHAIN }}-${{ hashFiles('verification/proofs/lean4/lakefile.lean', 'verification/proofs/lean4/*.lean') }} - restore-keys: | - lean-${{ env.ELAN_VERSION }}-${{ env.LEAN_TOOLCHAIN }}- + path: ~/.elan + key: lean-${{ env.ELAN_VERSION }}-${{ env.LEAN_TOOLCHAIN }}-toolchain - name: Install elan + Lean 4 if: steps.cache-lean.outputs.cache-hit != 'true' @@ -270,33 +266,23 @@ jobs: - name: Put elan on PATH run: echo "$HOME/.elan/bin" >> "$GITHUB_PATH" - - name: lake build - working-directory: verification/proofs/lean4 - run: | - set -euo pipefail - lean --version - lake --version - lake build - # HYP-01 positive control: the SoundVerdict in # tests/accept/LeanHoleRecheckSound.idr records digests of a Lean run. # Re-run Lean on the fixture from the repository root (where the # control's paths are relative to) and require both digests to match. - name: Re-check the Lean proof-hole fixture against the HYP-01 control - run: bash scripts/recheck-lean-hole.sh + run: | + set -euo pipefail + lean --version + bash scripts/recheck-lean-hole.sh - name: Summary if: always() run: | { - echo "## Lean proof verification" + echo "## Lean (HYP-01 positive control)" echo "" echo "- Toolchain: \`${LEAN_TOOLCHAIN}\` via elan \`${ELAN_VERSION}\`" - echo "- Proof files:" - for f in verification/proofs/lean4/*.lean; do - [ "$(basename "$f")" = "lakefile.lean" ] && continue - echo " - \`$(basename "$f")\`" - done } >> "$GITHUB_STEP_SUMMARY" # Estate PROOF-POLICY / Mathesis Grade 3 gate for the one Agda artefact: diff --git a/.machine_readable/testing/blitz.a2ml b/.machine_readable/testing/blitz.a2ml index cba82d31..25f3e6ba 100644 --- a/.machine_readable/testing/blitz.a2ml +++ b/.machine_readable/testing/blitz.a2ml @@ -267,7 +267,7 @@ evidence = [ [aspects.safety] status = "strong" -evidence = ["verification/proofs/tlaplus/", "verification/proofs/idris2/", "verification/proofs/lean4/"] +evidence = ["verification/proofs/tlaplus/", "verification/proofs/idris2/"] banned-patterns-clean = true default-total-idris = true diff --git a/AFFIRMATION.adoc b/AFFIRMATION.adoc index 5defac9a..7b8eee48 100644 --- a/AFFIRMATION.adoc +++ b/AFFIRMATION.adoc @@ -20,15 +20,15 @@ state and commitments. Companion detail: `guix.scm` / guix channels are the sole reproducible-build manifests. No `flake.nix` remains; all references reconciled. * *The formal-proof corpus checks in CI* across Idris 2 (v0.7.0), - Lean 4 (v4.30.0), Agda (2.8.0.2, one artefact) and TLA+ (bounded TLC + Agda (2.8.0.2, one artefact) and TLA+ (bounded TLC model checking, which is `tested-only`, not a proof). What each artefact proves, and how strongly, is the proof ledger (`verification/proof-ledger.jsonl`, rendered in - `verification/PROOF-STATUS.adoc#proof-ledger`): 18 proven of 42; - 4 proven-with-postulates, 11 tested-only, 2 argued, 7 open. The four - `proven-with-postulates` rows are Lean proofs that rest on the Lean kernel - axioms `propext` and `Quot.sound`. A source scan does not see those - axioms; `Lean.collectAxioms` does. *Zero escape hatches outside + `verification/PROOF-STATUS.adoc#proof-ledger`): 22 proven of 42; + 0 proven-with-postulates, 11 tested-only, 2 argued, 7 open. Four of the + Lean proofs rested on the Lean kernel axioms `propext` and `Quot.sound`, + which a source scan does not see and `Lean.collectAxioms` does; they moved + to Idris2 on 2026-11-09, which has no such axioms. *Zero escape hatches outside `test/soundness/fixtures/`* (`believe_me` / `sorry` / `postulate` / `assert_total` / `admit` / `native_decide`). Re-measured 2026-09-26 over the git-tracked tree by `scripts/check-trusted-base.sh`: outside that diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index e705a9b7..16d8e368 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,18 @@ https://semver.org/[Semantic Versioning]. === Changed +==== Lean engineering proofs move to Idris2 (2026-11-09) + +* `RateLimiting`, `BayesianUpdate`, `ParserTotality`, `PageRankInvariants` + and `ESNSpectralScaling` are now Idris2 (`verification/proofs/idris2/`, + `%default total`), theorem for theorem (PROOF-POLICY §3; owner decision). + Four of them had rested on the Lean kernel axioms `propext` and + `Quot.sound`; the ledger rows are now `proven`, which makes the census + 22 proven of 42. +* `verification/proofs/lean4/` is removed. The `lake build` job becomes + `Lean hole re-check (HYP-01 control)`, which keeps the pinned Lean only for + the verdict fixture. + ==== Proof claims follow the machine proof ledger (2026-11-09) * `EXPLAINME.adoc` is back at the repository root, as README-EXPLAINME diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index ec95ac8b..c473c572 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -84,7 +84,7 @@ link:lib/fleet_dispatcher.ex[] line 267. Caveat:: That recipe quarantine is not `Hypatia.Safety.Quarantine`, which nothing -calls (<>). The Lean model of the update uses natural-number +calls (<>). The Idris2 model of the update uses natural-number pseudo-counts, not Elixir floats. === Machine-checked proofs @@ -92,20 +92,22 @@ pseudo-counts, not Elixir floats. [quote, README.adoc] ____ *Machine-checked proofs* — Idris2 proofs of the ABI and the decision logic (confidence bounds, - safety-triangle routing, dispatch thresholds, quarantine, rollback), Lean 4 proofs of the Bayesian - update and rate-limiting properties, one Agda model of the Logtalk-to-Elixir migration, and a TLA+ + safety-triangle routing, dispatch thresholds, quarantine, rollback, the Bayesian update and rate + limiting), one Agda model of the Logtalk-to-Elixir migration, and a TLA+ model of the Kin gate that is model-checked on a bounded instance. The proofs are about models of - the code, not the Elixir runtime itself. Proof ledger: 18 proven of 42; 4 proven-with-postulates, + the code, not the Elixir runtime itself. Proof ledger: 22 proven of 42; 0 proven-with-postulates, 11 tested-only, 2 argued, 7 open ____ How this is implemented:: See <>. link:.github/workflows/verify-proofs.yml[] runs -`idris2 --check` per proof file, `idris2 --build` of both ipkgs, `lake -build`, Agda in its strict profile and TLC. +`idris2 --check` per proof file, `idris2 --build` of both ipkgs, Agda in +its strict profile and TLC; Lean runs only for the HYP-01 control. Caveat:: -Four of the five Lean rows rest on `propext` (two also on `Quot.sound`). +The Bayesian-update, rate-limiting, parser and neural-precondition proofs moved +from Lean to Idris2 on 2026-11-09, which removed the Lean kernel axioms +(`propext`, `Quot.sound`) four of them rested on. The TLA+ row is `tested-only`: one bounded instance. The modelled rate limiter is not called by any dispatch path. The census matches the ledger. @@ -267,7 +269,7 @@ workflow (debt register T-1). | `lib/outcome_tracker.ex` | Beta update; re-scan with `panic-attack assail` | `lib/application.ex` | What is supervised | `.github/workflows/zig.yml` | FFI tests run; exactly 18 `hypatia_*` exports -| `.github/workflows/verify-proofs.yml` | Idris2, Lean, Agda and TLC in CI +| `.github/workflows/verify-proofs.yml` | Idris2, Agda and TLC in CI; Lean for the HYP-01 control | `docs/DEBT-REGISTER.adoc` | What is broken, ungated or stale |=== @@ -283,7 +285,7 @@ Census, from `scripts/proof-ledger.sh check`: [source,text] ---- -18 proven of 42; 4 proven-with-postulates, 11 tested-only, 2 argued, 7 open. +22 proven of 42; 0 proven-with-postulates, 11 tested-only, 2 argued, 7 open. ---- Of the three theory rows, `logtalk-migration` is `PWG-3`; diff --git a/README.adoc b/README.adoc index b4c34733..8647158e 100644 --- a/README.adoc +++ b/README.adoc @@ -25,10 +25,10 @@ It combines: * *Bayesian confidence* — every recipe carries a Beta-distributed confidence updated from real outcomes, which gates whether a fix is applied automatically, proposed as a PR, or merely reported * *Machine-checked proofs* — Idris2 proofs of the ABI and the decision logic (confidence bounds, - safety-triangle routing, dispatch thresholds, quarantine, rollback), Lean 4 proofs of the Bayesian - update and rate-limiting properties, one Agda model of the Logtalk-to-Elixir migration, and a TLA+ + safety-triangle routing, dispatch thresholds, quarantine, rollback, the Bayesian update and rate + limiting), one Agda model of the Logtalk-to-Elixir migration, and a TLA+ model of the Kin gate that is model-checked on a bounded instance. The proofs are about models of - the code, not the Elixir runtime itself. Proof ledger: 18 proven of 42; 4 proven-with-postulates, + the code, not the Elixir runtime itself. Proof ledger: 22 proven of 42; 0 proven-with-postulates, 11 tested-only, 2 argued, 7 open (link:EXPLAINME.adoc#proof-ledger[details]) === Core philosophy @@ -80,7 +80,7 @@ PatternRegistry ──> TriangleRouter ──> FleetDispatcher ──> DispatchM | `src/Hypatia/ABI/` | Idris2 ABI — Types, GraphQL, gRPC, REST, FFI, RuleEngine | `ffi/zig/` | Zig C ABI bridge — 18 exports + 16 protocol connectors | `adapters/ cli/ data/ fixer/ integration/` | Rust workspace -| `verification/` | Proof ledger and proofs: Idris2, Lean 4, Agda, TLA+ +| `verification/` | Proof ledger and proofs: Idris2, Agda, TLA+ |=== See link:docs/architecture/topology.md[docs/architecture/topology.md] for the full map. diff --git a/docs/proofs/gap-analysis.adoc b/docs/proofs/gap-analysis.adoc index dddf4b28..4332b9fd 100644 --- a/docs/proofs/gap-analysis.adoc +++ b/docs/proofs/gap-analysis.adoc @@ -1,5 +1,11 @@ == Proofs Gap Analysis +NOTE: Historical (2026-04-22), kept as the record of that analysis. Since then +the Lean engineering proofs moved to Idris2 (2026-11-09), an Agda artefact +returned, and every prover runs in CI. The current state is the proof ledger +(`+verification/proof-ledger.jsonl+`); the convergence plan is +`+docs/proofs/HANDOVER-neural-convergence.adoc+`. + *Date:* 2026-04-22 *Scope:* VCL query correctness + neural ensemble convergence *Status:* Inventory + prioritised plan. No code changes yet. diff --git a/docs/proofs/needs.adoc b/docs/proofs/needs.adoc index 99360ad3..079917ce 100644 --- a/docs/proofs/needs.adoc +++ b/docs/proofs/needs.adoc @@ -20,9 +20,9 @@ Plans: * Neural convergence (rows `+pagerank-convergence+` and `+esn-echo-state+`): `+docs/proofs/HANDOVER-neural-convergence.adoc+`. Agda first, over constructive reals, then the Rocq and Lean legs. -* Lean engineering proofs (rows `+lean-*+`): moving to Idris2 (PROOF-POLICY - §3; owner decision 2026-11-09). The move also removes the Lean kernel - axioms (`+propext+`, `+Quot.sound+`) that four of them rest on. +* The Lean engineering proofs moved to Idris2 on 2026-11-09 (PROOF-POLICY §3; + owner decision), which removed the Lean kernel axioms (`+propext+`, + `+Quot.sound+`) four of them rested on. Prover mapping and statuses: the estate PROOF-POLICY (`+metadatastician/standards/3-practice/PROOF-POLICY.adoc+`). diff --git a/tests/proof-ledger-test.sh b/tests/proof-ledger-test.sh index be137ba3..c9af3000 100755 --- a/tests/proof-ledger-test.sh +++ b/tests/proof-ledger-test.sh @@ -22,6 +22,11 @@ expect() { #