Skip to content

Commit a55fb9b

Browse files
fluffy314cursoragent
authored andcommitted
feat(autoresearch): certify autonomous proof decomposition
Require bounded, isolated proof workers to produce host-validated premise audits and complete Lean reduction certificates so false or irrelevant branches cannot masquerade as mathematical progress. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a42dd8e commit a55fb9b

10 files changed

Lines changed: 5839 additions & 185 deletions

File tree

autoresearch/prefill/lean_gate.py

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def _signature_only(source: str) -> str:
5858
return source[:match.start()].strip() if match else source.strip()
5959

6060

61+
def lean_theorem_signature_hash(source: str) -> str:
62+
signature = " ".join(_signature_only(source).split())
63+
return hashlib.sha256(signature.encode()).hexdigest() if signature else ""
64+
65+
6166
def _run_lean(
6267
content: str,
6368
*,
@@ -212,8 +217,7 @@ def validate_lean_signature(
212217
status="TYPECHECK_FAILED",
213218
error="theorem signature must end with `:= by` proof scaffold",
214219
)
215-
signature = " ".join(_signature_only(source).split())
216-
signature_hash = hashlib.sha256(signature.encode()).hexdigest()
220+
signature_hash = lean_theorem_signature_hash(source)
217221
content = (
218222
"import KakeyaLeanGate\n\n"
219223
"set_option autoImplicit false\n\n"
@@ -289,3 +293,75 @@ def validate_lean_signature(
289293
elapsed_s=total_elapsed,
290294
output=output,
291295
)
296+
297+
298+
def validate_lean_proof(
299+
source: str,
300+
*,
301+
project_root: Path,
302+
timeout_s: float = 45.0,
303+
) -> LeanSignatureResult:
304+
"""Compile one complete theorem without sorry/admit or added axioms."""
305+
source = source.strip()
306+
if (
307+
not source
308+
or len(source) > 12_000
309+
or _FORBIDDEN.search(source)
310+
or re.search(r"\b(?:sorry|admit)\b", source)
311+
):
312+
return LeanSignatureResult(
313+
source,
314+
"",
315+
False,
316+
status="UNSAFE_REJECTED",
317+
error="Lean proof is empty, unsafe, oversized, or incomplete",
318+
)
319+
declarations = re.findall(
320+
r"^\s*theorem\s+([A-Za-z_][\w']*)",
321+
source,
322+
re.MULTILINE,
323+
)
324+
if len(declarations) != 1 or not re.search(r"\s*:=\s*by\b", source):
325+
return LeanSignatureResult(
326+
source,
327+
"",
328+
False,
329+
status="TYPECHECK_FAILED",
330+
error="expected exactly one complete theorem declaration",
331+
)
332+
proof_hash = hashlib.sha256(source.encode()).hexdigest()
333+
run = _run_lean(
334+
"import KakeyaLeanGate\n\nset_option autoImplicit false\n\n"
335+
+ source
336+
+ "\n",
337+
project_root=project_root,
338+
timeout_s=timeout_s,
339+
)
340+
if run.timed_out:
341+
return LeanSignatureResult(
342+
source,
343+
proof_hash,
344+
False,
345+
status="TYPECHECK_TIMEOUT",
346+
error=f"Lean proof timed out after {timeout_s:.1f}s",
347+
elapsed_s=run.elapsed_s,
348+
output=run.output,
349+
)
350+
if run.returncode != 0:
351+
return LeanSignatureResult(
352+
source,
353+
proof_hash,
354+
False,
355+
status="TYPECHECK_FAILED",
356+
error=f"Lean proof failed: {run.output[-2000:]}",
357+
elapsed_s=run.elapsed_s,
358+
output=run.output,
359+
)
360+
return LeanSignatureResult(
361+
source,
362+
proof_hash,
363+
True,
364+
status="PROVED",
365+
elapsed_s=run.elapsed_s,
366+
output=run.output,
367+
)

autoresearch/prefill/program.md

Lines changed: 143 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Prefill AutoResearch Program
22

3-
You are optimizing the two-Mac full-context RH proof research system.
3+
You are optimizing the two-Mac retained-interface RH proof research system.
44

55
## Ownership
66

@@ -36,7 +36,7 @@ Use a lexicographic objective:
3636
3. Modify only `candidate.py`.
3737
4. Verify Primary and allens health without restarting either service.
3838
5. Preserve all KV caches across decomposition iterations.
39-
6. Run the fixed full-context acceptance workload.
39+
6. Run the fixed retained-capacity certified-interface acceptance workload.
4040
7. Run `prepare.py` against the resulting report.
4141
8. Keep the candidate only if every hard constraint passes and it closes an
4242
obligation, falsifies a novel hypothesis, or creates a novel smaller
@@ -48,15 +48,55 @@ contain a falsifiable hypothesis plus distinct Generator and Critic directives.
4848
Normal iterations use the deterministic host candidate and do not call the
4949
Strategy model. Invoke Strategy Gemma only after three consecutive
5050
non-progressing runs, after a falsified branch, or via an explicit CLI/trigger
51-
file request.
52-
If an optional Strategy replan exceeds its lossless Prefill budget, defer the
51+
file request. A valid premise invalidation is also an immediate event-driven
52+
Strategy trigger. It is informative recovery, but does not reset mathematical
53+
stagnation as proof progress.
54+
If an optional Strategy replan exceeds its exact-interface retained budget, defer the
5355
replan and continue immediately with the deterministic host candidate. Never
5456
truncate the Strategy prompt and never stop the GAN proof loop for this
5557
control-plane admission failure.
5658
An unresolved Critic verdict must isolate one strictly smaller missing lemma;
57-
the host records that lemma as a deduplicated child obligation. Completed GAN
58-
runs, transcripts, checkpoints, and ledger updates remain durable even when the
59-
candidate strategy is reverted or fixed evaluation fails.
59+
that free-form text is only a trigger for certified decomposition and never
60+
creates a child directly. Completed GAN runs, transcripts, checkpoints, and
61+
ledger updates remain durable even when the candidate strategy is reverted or
62+
fixed evaluation fails.
63+
64+
## Certified decomposition
65+
66+
Certified decomposition is the authoritative and only child-persistence path.
67+
For an unresolved frontier, seven isolated fresh-session workers run in order:
68+
Definition Auditor, Counterexample Worker, Decomposer, Formalizer, Prover,
69+
Adversarial Proponent, and Judge. Every role uses allens Prefill and Primary
70+
decode with no shared session/KV state; only explicit host-packaged artifacts
71+
and hashes flow forward. Raw transcripts and parsed artifacts are persisted in
72+
one private atomic manifest. Any timeout, malformed binding, or role failure
73+
fails open without ledger mutation.
74+
75+
Every role artifact binds the exact target ID, parent statement hash, immutable
76+
root-goal hash, producer role/run ID, and all upstream artifact hashes.
77+
Decomposer labels are temporary: only the host assigns persistent IDs after
78+
the complete certificate passes. The proposed graph must be acyclic, all
79+
labels must exist, and the one-step certificate must contain exactly one child
80+
and reduction label. That child—including a definition obligation—must occur
81+
in the explicit reduction contract. Deeper graphs are discovered recursively
82+
across later certified iterations.
83+
84+
Formalizer must preserve an existing parent Lean signature/hash exactly, or
85+
propose a new parent signature only for an `UNFORMALIZED` parent. Parent and
86+
all child signatures must pass the pinned signature gate. The reduction
87+
signature may assume the child propositions and declared public assumptions,
88+
but Prover must provide a complete proof of that exact reduction theorem.
89+
`sorry`, `admit`, axioms, unsafe commands, placeholders, signature changes,
90+
disconnected children, semantic duplicates, and vague glossary tasks reject
91+
the entire bundle. Judge receives only the host-generated verification
92+
manifest and cannot override a failed host gate.
93+
94+
Lean certification proves only that the formal child propositions and public
95+
assumptions suffice for the exact formal parent proposition in the accepted
96+
reduction theorem. The mapping from mathematical prose to Math IR and Lean
97+
propositions remains model-authored semantic translation; host hashes,
98+
typechecking, and adversarial review make that translation explicit but do not
99+
prove it faithfully represents the intended informal mathematics.
60100

61101
Worker lifecycle and cache policy belong to the inference serving plane, not
62102
the proof experiment. `prefill_compute_chunk_tokens` is immutable during this
@@ -65,21 +105,107 @@ benchmark here. Model/tokenizer/quantization/rope/window/cache-format changes
65105
must be deployed outside this supervisor. Cold benchmarks are explicit,
66106
separate invocations of `scripts/benchmark_prefill_architecture.py`.
67107

68-
Prefill budgets are hard admission limits, never truncation instructions.
69-
Strategy input must fit 8448 tokens by carrying the complete active leaf
70-
ancestry and its exact experiment records. Generator and Critic inputs must fit
71-
6144 tokens; the Critic always receives the complete current Generator output.
72-
Repeated Strategy strings are interned once in `text_by_id`; `_ref` fields
73-
losslessly reference that exact text.
74-
If any complete semantic unit exceeds its budget, reject it before remote
75-
Prefill and preserve the checkpoint. Never slice, sample, summarize, or drop
76-
the tail of an over-budget input.
108+
Retained KV capacity—not nominal Prefill admission—is the hard model-call
109+
limit. The deployed default is sink 4 + window 2048 = 2052 tokens. Every
110+
Strategy, Generator, Critic, premise, and certified-role chat template is
111+
counted before append and must fit `min(configured prefill,
112+
max_retained_tokens)`, including explicit control/decode reserve where needed.
113+
No call may rely on evicted middle tokens.
114+
115+
Every active model call receives one exact `ProofStepInterface`: immutable root
116+
hash, exact target statement, exact formal target/parent certificate interface,
117+
public assumptions, immediate dependency interface, relevant active no-go
118+
premises, current target evidence, and archive hashes. Eleven-node prose
119+
ancestry and historical evidence are not active context. They remain durable
120+
and hash-addressed; this is state selection, not an LLM summary and not a claim
121+
of arbitrary natural-language full-attention equivalence.
122+
123+
Strategy proposes exactly one next proof step/question. Generator emits exactly
124+
one bounded ISSUE_RESPONSE. Before Generator decode, the host reserves enough
125+
retained capacity for Critic's fixed package plus the complete Generator
126+
output; Critic receives that output byte-for-byte with the same exact
127+
ProofStepInterface. Certified Decomposer proposes exactly one child per
128+
certificate; recursive later iterations perform deeper decomposition.
129+
130+
If an exact statement, structured artifact field, ISSUE block, dependency
131+
node, or Lean source is indivisible and too large, fail closed with
132+
`SEMANTIC_UNIT_TOO_LARGE`. Never slice tokens or strings, drop tails, or call a
133+
model summary lossless. Recursive decomposition preserves exact certified
134+
interfaces and reduction semantics, not arbitrary prose-history equivalence.
135+
136+
The concise stable `STRATEGY_CONTRACT` in `supervisor.py` is the authoritative
137+
deterministic projection of this human-owned program for Strategy inference.
138+
It includes the objective, event triggers, obligation/no-go/premise recovery
139+
rules, exact-target requirement, immutable candidate/runtime constraints, and
140+
the no-fallback/no-truncation contract. The full program remains authoritative
141+
for host behavior but is not serialized into every Strategy prompt.
77142

78143
Obligation IDs are host-owned. Treat IDs emitted by Generator/Critic as
79144
untrusted labels and bind verdicts to the exact current target. Never persist a
80145
model-invented ID. Reject a proposed child when it duplicates an existing
81146
statement or lemma name, is highly similar to an ancestor, or is too vague to
82-
be falsifiable. A rejected cyclic frontier is `INCONCLUSIVE`, not progress.
147+
be falsifiable. Also reject any child that canonically or semantically repeats
148+
a persisted no-go premise. A rejected cyclic frontier is `INCONCLUSIVE`, not
149+
progress.
150+
151+
Every `DISPROVED` ISSUE_VERDICT distinguishes
152+
`Invalidation: APPROACH|PREMISE_SUSPECTED`. Missing invalidation is legacy
153+
`APPROACH`; legacy transcript value `PREMISE` is only a suspicion. A suspicion
154+
must name `Premise refuted`, identify one evidence type, and provide a concrete
155+
one-line JSON artifact. It never directly closes or quarantines a branch.
156+
157+
The worker automatically runs two fresh, ordered inference roles for every
158+
structurally valid suspicion. The isolated Premise Auditor returns
159+
`PREMISE_AUDIT` with `CONFIRMED|NOT_CONFIRMED|INCONCLUSIVE`, evidence
160+
type/source, confidence, artifact, and analysis. The isolated Adversarial
161+
Proponent then receives only the immutable goal, host-packaged suspicion, and
162+
complete Auditor output and returns `PREMISE_DEFENSE` with
163+
`RESCUED|NOT_RESCUED|INCONCLUSIVE`, exact correction/failure, and evidence.
164+
Each inference uses a distinct session on allens-prefill/Primary-decode; only
165+
explicit text crosses role boundaries. Both complete outputs and parsed
166+
artifacts are durably persisted. Any timeout, malformed output, or worker
167+
failure is an `INCONCLUSIVE` review and can never invalidate a premise.
168+
169+
The host upgrades to `PREMISE_INVALIDATED` only on a structurally valid
170+
suspicion, Auditor `CONFIRMED` at confidence >= 0.8, Proponent `NOT_RESCUED`,
171+
and a deterministically verified artifact. Arithmetic evidence uses one
172+
host-normalized `FOR_ALL` claim object (`variables`, domain, lhs, claimed
173+
relation, rhs). The host hashes this exact schema at suspicion time. The
174+
Auditor must preserve the schema/hash, bind every quantified variable exactly
175+
once, and provide a finite witness for which the Critic's claimed relation
176+
evaluates false. Unknown variables, true-but-unrelated arithmetic, missing
177+
bindings, schema changes, or hash changes are rejected.
178+
179+
Lean evidence is bound to the target's host-recorded `lean_signature_hash` and
180+
must claim `NEGATION_OF_TARGET_SIGNATURE`. The current stored Lean signature
181+
format does not permit the host to safely synthesize an exact negation wrapper,
182+
so Lean artifacts are presently recorded but fail open to `INCONCLUSIVE` even
183+
if their standalone theorem compiles. Pinned theorem references are likewise
184+
untrusted until a local exact-assumption registry exists.
185+
186+
Before upgrade, descendants retain their statuses and only reversible
187+
`SUSPECTED`/temporary-quarantine metadata is recorded. After upgrade, the host
188+
marks the target `DISPROVED/PREMISE_INVALIDATED`, quarantines descendants,
189+
stores one bound-schema-hash no-go lesson with confidence/evidence/worker-run
190+
provenance, and backjumps to the nearest sound unresolved ancestor. A later
191+
Auditor `NOT_CONFIRMED` or Proponent `RESCUED` deterministically restores prior
192+
statuses and marks quarantine/no-go records `REVERSED`. `APPROACH` failure
193+
never quarantines descendants or siblings.
194+
195+
After a structurally valid suspicion completes review without verified
196+
upgrade (`NOT_CONFIRMED`, `RESCUED`, or `INCONCLUSIVE`), the host clears all
197+
temporary quarantine, restores descendants, preserves audit provenance, and
198+
closes only the attempted leaf as `DISPROVED/APPROACH_FAILED`. This fallback
199+
is allowed only when the original Critic DISPROVED evidence passed the existing
200+
strong closure gate. It creates no no-go lesson or premise quarantine.
201+
202+
Only a host-upgraded invalidation triggers supervisor `premise-invalidated`.
203+
Suspicion initiates worker audit but is neither proof progress nor permanent
204+
falsification. The exact Strategy interface carries only active relevant no-go
205+
records. New candidates must not assume, rename, or reconstruct them. Lean
206+
signature typechecking remains merely `FORMALIZED` and does not establish
207+
premise truth; only the separate complete-proof gate can validate Lean
208+
evidence.
83209

84210
`DECOMPOSED` is keepable only when the host actually persisted at least one
85211
new child that passed the ID, novelty, cycle, and falsifiability gates.

0 commit comments

Comments
 (0)