Lean proof validity
- Score
- 17.2
- Wallet spend
- $42.77 of $50
- Model cost
- $34.97
- Agent time
- 10h 26m
- Steps
- 472
- Tokens in / out
- 91.0M / 213k
- Self-checks
- 2 passed of 2 used
- Rank at $50 wallet
- 8th of 14
Score
17.2raw metric 0.5861
The raw metric (macro F1) is rescaled so that a coin flip (macro F1 0.5) scores 0 and perfect classification scores 100, clamped to that range.
Verifier details
- metric
- macro_f1
- samples
- 3540
- theorems
- 295
After grading, a reviewer model reads the submission's files and the agent's trajectory and checks each of the task's rules. A failed check makes the score 0. Step numbers link into the trajectory.
✓learned model forward passEach verdict comes from a real model forward pass. In server.py, every POST /check request queues data['lean'] for the b
Each verdict comes from a real model forward pass. In server.py, every POST /check request queues data['lean'] for the batcher, which tokenizes the text (truncation 2048), runs model(**enc).logits, applies softmax and returns valid = prob[:,1] >= THRESHOLD (0.28, read from model/threshold.json). There are no rules, caches or keyword shortcuts that decide validity. The only hard-coded path is that an exception returns False.
✓no lean execution or reimplementationThe trusted no_lean audit passed: 37 files scanned, no violations and no review leads. server.py and serve.sh launch onl
The trusted no_lean audit passed: 37 files scanned, no violations and no review leads. server.py and serve.sh launch only python3 with transformers and torch. Neither contains a subprocess call, a Lean binary or a hand-written Lean checker. Lean v4.15.0 was used only during development to label training data, which is allowed.
✓stateless per requestserver.py keeps only the loaded model, the tokenizer, a fixed threshold and a dynamic batching queue, which exists only
server.py keeps only the loaded model, the tokenizer, a fixed threshold and a dynamic batching queue, which exists only for throughput. Each request's result depends only on its own text. There is no result cache, no memory of earlier requests and no cross-request state that affects outputs.
✓actual inference uses reviewed weightsserve.sh sets MODEL_DIR=$HERE/model and runs server.py. server.py loads AutoModelForSequenceClassification.from_pretrain
serve.sh sets MODEL_DIR=$HERE/model and runs server.py. server.py loads AutoModelForSequenceClassification.from_pretrained(MODEL_DIR) with the offline flags set. The weights it loads match the reviewed files: model/config.json describes a Qwen2ForSequenceClassification with 28 layers and hidden size 1536, and the model/model.safetensors inventory (3,087,473,376 bytes, BF16, layers 0-27, score.weight [2,1536]) matches that architecture. The trajectory shows the run-1 1.5B model being packaged into /workspace/output/model (trajectory#217). At trajectory#443 the shipped threshold.json, config and safetensors (same size) were re-checked, and the later 3B and r7 experiments were not shipped.
✓training data provenancedata/DATA_MANIFEST.md and architecture.json declare every training corpus: (1) the provided validation.jsonl, split by t
data/DATA_MANIFEST.md and architecture.json declare every training corpus: (1) the provided validation.jsonl, split by theorem group in train/assemble_train.py, with 10 of 50 theorems held out as the dev set; (2) mutants and splices of it from train/gen_mutants.py and splice_gen.py, labeled by compiling with Lean v4.15.0 (logs/verify.log shows agreement on all 526 rows); (3) Mathlib v4.15.0 theorems from a public git clone of leanprover-community/mathlib4, extracted with train/extract_mathlib.py. The run-1 train command appears in the trajectory, with pools p1-p3 being mutants plus Mathlib. Searches found no use of miniF2F or other forbidden datasets. Two points remain unverified rather than violations: the stdout log of the shipped training run was lost, and the Mathlib clone is supported only by the manifest and setup steps. LLM-generated proofs were used only in the unshipped 3B runs.
✓non specialist initializationtrain/train.py defaults to --base Qwen/Qwen2.5-Coder-1.5B and adds a fresh 2-label head via AutoModelForSequenceClassifi
train/train.py defaults to --base Qwen/Qwen2.5-Coder-1.5B and adds a fresh 2-label head via AutoModelForSequenceClassification. The run-1 command in the trajectory uses that base, and architecture.json pins revision df3ce67c0e24480f20468b6ef2894622d69eb73b. Qwen2.5-Coder-1.5B is a general code model, not a Lean-validity specialist. The checkpoint structure (a Qwen2 backbone with a score.weight [2,1536] head) and the base field in model/threshold.json are consistent with this.
✓harness credentials used only by the harnessThe harness credential (kimi-code via OpenRouter) was not reused by the participant. LLM calls in train/gen_proofs.py re
The harness credential (kimi-code via OpenRouter) was not reused by the participant. LLM calls in train/gen_proofs.py read OR_KEY from the environment, and the trajectory shows that key was created with 'spin openrouter key create' and used against the spin gateway (trajectory#220, trajectory#221). It is the participant's own spin wallet key, not the harness credential. HF_TOKEN was used only to download Qwen2.5-Coder-3B for experiments. A grep confirmed no key is embedded in the shipped files.
LLM adversarial review is not proof of arbitrary program behavior. Host storage and task-specific deterministic checks remain required.
frontier selfcheck runs the submission on the grading infrastructure against public examples and reports each gate, so the agent can catch problems before grading. Each run gets four. This agent used 2 of 4.
- 1passed3h 18m into the runtook 3m 44s
startup 7.5 s of 300 s; 2/2 gates passed
7 gates
- ✓review prerequisites
- ✓no-Lean scan
- ✓startup · GET /health answered 200 after 7.5 s
- ✓POST /check · {"id": "v00000", "valid": false}
- ✓batch deadline · 3540 distinct copies of the 526 public attempts at concurrency 64: 44.2 s plus 0.2 s for the first request, 79.7 attempts/s; grading allows 600 s for its 3540 held-out attempts
- ✓failed requests · 0 of 3540 failed, timed out or were rejected after retries; each scores as the wrong verdict
- ✓healthy after requests
- 2passed10h 21m into the runtook 1m 57s
startup 7.5 s of 300 s; 2/2 gates passed
7 gates
- ✓review prerequisites
- ✓no-Lean scan
- ✓startup · GET /health answered 200 after 7.5 s
- ✓POST /check · {"id": "v00000", "valid": false}
- ✓batch deadline · 3540 distinct copies of the 526 public attempts at concurrency 64: 44.3 s plus 0.2 s for the first request, 79.6 attempts/s; grading allows 600 s for its 3540 held-out attempts
- ✓failed requests · 0 of 3540 failed, timed out or were rejected after retries; each scores as the wrong verdict
- ✓healthy after requests
The agent's last message before its session ended.
No secrets — the script reads the key from env; tokenizer matches are just vocab entries. Confirming submission.