ci: re-check the build with the nanoda kernel checker - #21
Merged
Merged
Conversation
daira
marked this pull request as ready for review
August 10, 2026 04:24
|
interesting, haven't used nanoda before. let's also apply this to ironwood! ACK |
TalDerei
approved these changes
Aug 10, 2026
Add a CI job that exports the built library with lean4export and re-checks every declaration with nanoda, an independent Rust reimplementation of the Lean kernel. A kernel soundness bug would then have to appear in two distinct implementations to go unnoticed. The job depends on the build job, so the fast build check can gate PR acceptance on its own, and restores that job's build cache rather than rebuilding. The committed nanoda config is a machine-checked axiom census: strict mode rejects any axiom declared outside the permitted list, and the pp_declars list fails the run if an expected native_decide axiom disappears from the export. scripts/check_export_axioms.py closes the remaining gap: axioms that Lean core declares unconditionally (sorryAx and the legacy compiler-trust axioms) must be permitted, so it checks that nothing cites them. sorryAx, Lean.ofReduceBool, and Lean.ofReduceNat are cited by nothing — in particular a sorry anywhere in the library fails the check — and Lean.trustCompiler only by core's deprecated reduceBool and reduceNat gates. The script verifies the export's structural conventions rather than assuming them, and distinguishes census violations from structural errors. scripts/check_nanoda.sh drives the pipeline and asserts that every project module is reachable from the export roots, so a module cannot silently drop out of the re-check. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Re-checks the entire built library with nanoda, an independent reimplementation of the Lean kernel in Rust. As noted in the postmortem of leanprover/lean4#14576, doing this implies that a kernel soundness bug has to appear in two independently implemented kernels to go unnoticed. Builds on #20, whose
+native(...)owner census pins the per-usenative_decideaxiom names that the checker's permitted list needs.scripts/nanoda-config.json— the machine-checked axiom census. Strict mode (unpermitted_axiom_hard_error) fails on any axiom declared outsidepermitted_axioms;pp_declarsfails the run if an expectednative_decideaxiom disappears from the export; the admitted axioms are pretty-printed into the CI log with their types (the primitivity certificates show their literal roots of unity).scripts/check_export_axioms.py— lean4export dumps the whole environment, so axioms Lean core declares unconditionally (sorryAx,Lean.trustCompiler,Lean.ofReduceBool,Lean.ofReduceNat) must be permitted for strict mode to run at all, and permitting a declaration says nothing about use. This script closes the gap by scanning the export: the declared axioms are exactly the permitted list;sorryAx/ofReduceBool/ofReduceNatare cited by nothing (in particular, asorryanywhere in the library fails CI here); andtrustCompileris cited only by core's deprecatedreduceBool/reduceNatgates. The export's structural conventions (pinned format version, closed shape set, dense ids, no forward or dangling references) are verified rather than assumed; census violations (exit 1, census still printed) are distinguished from structural errors (exit 2).scripts/check_nanoda.sh— drives export → census check → nanoda, and asserts that every project module is reachable from the export roots, so a module cannot silently drop out of the re-check.MetaCheckis deliberately outside the roots: its forged axioms exist to be rejected.nanodajob withneeds: build, so the fast build check reports on its own and can gate PR acceptance; the job restores the build job's cache instead of rebuilding, then builds lean4export at the toolchain's tag and nanoda at a pinned revision.The full pipeline (coverage check, export of 314,801 declarations at 1.8 GB, census check, 4-thread nanoda) runs in 5m 13s on an M-series laptop, on top of an up-to-date
lake build.🤖 Claude Fable 5