fix(lean-taskset): audit proof axioms to close the injected-axiom bypass - #2565
Open
CaptainAni187 wants to merge 1 commit into
Open
fix(lean-taskset): audit proof axioms to close the injected-axiom bypass#2565CaptainAni187 wants to merge 1 commit into
CaptainAni187 wants to merge 1 commit into
Conversation
`lean_compiled` accepted any proof that kept the protected signature and
compiled without `sorry`. It never checked what the proof rested on, so a
rollout could close any goal by supplying its own axiom above the signature:
import Mathlib
axiom cheat : False
-- DO NOT MODIFY the theorem statement below.
theorem fake_irrational : Irrational (1 : R) := by
exact cheat.elim
The axiom sits above the protected region, `lake env lean` exits 0 with no
diagnostic, and the reward returns 1.0 for a false statement. PrimeIntellect-ai#1271 flagged
this gap as future work; PrimeIntellect-ai#1480 closed a sibling bypass in the same reward.
After a clean compile, re-run the file with `#print axioms <name>` appended
and reject any axiom outside Mathlib's trusted base (propext,
Classical.choice, Quot.sound).
`parse_axioms_output` matches the LAST `depends on axioms` line, for the same
reason `parse_compile_output` matches the last `EXIT_CODE` marker: the query
is appended at the end, so an earlier line came from the rollout and could
otherwise shadow the real result.
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.
Closes #2177
lean_compiledawards 1.0 when the protected signature is intact andlake env leanexits 0 with nosorry. It never checks what the proof depends on, so a rollout can close any goal by supplying its own axiom above the signature:Irrational (1 : ℝ)is false. Theaxiomsits above the protected region, so the signature guard passes, the compile is silent, and the reward returns 1.0.#1271 flagged this exact gap as future work ("or axiomatize the goal"); #1480 closed a sibling bypass in the same reward.
Change
After a clean compile, write the rollout's file to a sibling path with
#print axioms <name>appended, compile that, and reject any axiom outside Mathlib's trusted base —propext,Classical.choice,Quot.sound. The rollout's own file is left untouched.The parsing and trust decision are pure functions in
scoring.py, alongside the existing helpers.One detail worth flagging
parse_axioms_outputmatches the lastdepends on axiomsline, not the first. Our query is appended at the end of the file, so anything earlier came from the rollout — without this, a model could injectabove its proof and have the audit read the decoy. That is the same failure #1480 fixed for
EXIT_CODEmarkers, so I followed the reasoning already documented inparse_compile_output. There is a test for it.declaration_namereturns""for an anonymousexample, which skips the audit rather than failing the rollout — the pre-existing behaviour for statements the reward cannot pin.Tests
tests/v1/test_lean_scoring.py, 9 tests:cheataxiom, and the decoy-shadowing casecheatscores 0.0 withlean_untrusted_axioms == ["cheat"], and a genuine proof still scores 1.0Reverting only the
taskset.pywiring (keeping the helpers) turns the first reward test intoassert 1.0 == 0.0, so the test pins the bypass itself rather than the helpers.tests/v1(excludingtest_e2e.py): 76 passed, up from 67, with the same 11 pre-existing failures intest_configs.py::test_eval_config_parses— missing optional taskset packages in my environment, unrelated to this change.test_color_codeword_tasks.pydoes not collect locally for the same reason.ruff checkandruff formatclean.I could not run the real Lean toolchain locally, so the audit is verified against recorded
#print axiomstranscripts rather than a livelake env lean. The transcripts match the ones in the issue, including#print axioms fake_irrational → [cheat, propext, Classical.choice, Quot.sound]. Happy to adjust if the real output differs in shape.Note
Reject Lean proofs resting on injected axioms in
lean_compiledLeanTask._print_axiomswhich writes an audit copy of the proof with a declaration-specific#axiomsquery, runs Lean on it, and returns the combined transcript without touching the original proof file.declaration_nameextracts the theorem/lemma name from a signature,parse_axioms_outputselects the last reported axiom list, anduntrusted_axiomsfilters names against theTRUSTED_AXIOMSMathlib baseline.lean_compiledin taskset.py now runs the audit after a successful compile and sets score to zero with tampering info when any untrusted axiom is found.Macroscope summarized 148dfce.