Skip to content

test(recursion): memory-bounded execute/prove smoke tests; wire CI#750

Merged
jotabulacios merged 6 commits into
mainfrom
pr/recursion-guest
Jul 2, 2026
Merged

test(recursion): memory-bounded execute/prove smoke tests; wire CI#750
jotabulacios merged 6 commits into
mainfrom
pr/recursion-guest

Conversation

@Oppen

@Oppen Oppen commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Stream the execute-only path via Executor::resume() and read the committed marker straight off Memory (Executor::finish), dropping the run()+Traces build that OOM'd. Prove the outer recursion guest memory-bounded via prove_and_verify_continuation (2^20-cycle epochs) instead of a monolithic ~125 GB prove.

CI: build the recursion guest ELFs (cache + conditional setup-rust + make compile-recursion-elfs) in the comprehensive prover jobs, and add test(test_recursion) to the comprehensive filter.

Oppen added 4 commits June 30, 2026 15:41
Stream the execute-only path via Executor::resume() and read the committed
marker straight off Memory (Executor::finish), dropping the run()+Traces
build that OOM'd. Prove the outer recursion guest memory-bounded via
prove_and_verify_continuation (2^20-cycle epochs) instead of a monolithic
~125 GB prove.

Un-ignore the three execute-only tests (now sub-minute); the full-prove
tests stay #[ignore]d (>60s) and run in the comprehensive CI job.

CI: build the recursion guest ELFs (cache + conditional setup-rust +
make compile-recursion-elfs) in both the per-PR and comprehensive prover
jobs, and add test(test_recursion_prove) to the comprehensive filter.
@Oppen

Oppen commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

/ai-review

@github-actions

Copy link
Copy Markdown

Codex Code Review

Findings:

  1. Medium - Unignored tests still require prebuilt recursion ELFs
    prover/src/tests/recursion_smoke_test.rs
    The three execute-only recursion tests are now normal tests, but they still read executor/program_artifacts/recursion/*.elf at runtime. make test-prover and make test-fast do not run make compile-recursion-elfs, so a fresh checkout will fail these documented test targets with the “run make compile-recursion-elfs” panic. Either keep these tests ignored, or update the affected test targets to build the recursion ELFs first.

  2. Low - New recursion cache is not seeded for merge queue
    .github/workflows/pr_main.yaml
    The workflow adds recursion ELF caches to the prover jobs, but seed-elf-cache still only seeds ASM/Rust artifacts. The comment says merge-group refs can only restore caches from main, so the new recursion cache will miss in merge queue and recompile the recursion guests there. Add the same recursion cache/compile steps to seed-elf-cache if the cache is intended to help merge-group runs.

I did not find safety/security issues in the changed Rust code. Static review only; no builds/tests run per instructions.

Comment thread .github/workflows/pr_main.yaml Outdated
@claude

claude Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review: test(recursion) — memory-bounded execute/prove smoke tests; wire CI

Verified the core behavioral changes against their dependencies. The PR is sound; one CI caching gap worth addressing.

Correctness (OK):

  • execute_outer_and_commit (run()+Traces -> resume()/finish()): the new path drains Executor::resume() to completion, then reads finish().memory_values. finish() returns Memory::read_return_value() = public_output.clone(), which memory.rs explicitly documents is kept in sync with the trace builder public_output_bytes. So dropping the Traces build is semantically equivalent and removes the OOM-prone trace materialization. The borrow from resume() is released before finish() consumes the executor — no conflict.
  • prove_outer_and_commit (prove+verify -> prove_and_verify_continuation): signature/return types line up (Result<Option<Vec>>, double-expect); epoch_size_log2 u32 = 20 and crate::GoldilocksCubicProofOptions / crate::continuation are valid re-exports. Memory-bounding the verifier-in-VM prove via continuations is the right fix for the ~125 GB monolith.
  • Un-ignoring the three test_recursion_execute* tests is consistent with the streaming path; full-prove tests correctly stay ignored for the comprehensive job, and the -E filter adds test(test_recursion_prove) there.

Findings:

  • Medium — recursion ELF cache key is under-specified (see inline comment). The key omits prover/stark/executor, which the verifier guest depends on via the lambda-vm-prover path dep; a prover-internal PR can get an exact-key cache hit on a stale verifier ELF and fail the now-always-on execute tests spuriously. Fails safe (false red, not false green) but noisy.

CI conditional logic (OK):
The added Setup Rust Environment (recursion ELFs) step (recursion cache miss AND rust-elf cache hit) correctly covers the only case where the rust-elf compile step own Setup Rust would not have run. The other branches (both miss / both hit) are already handled.

Nothing else flagged.

Comment thread .github/workflows/pr_main.yaml Outdated
@github-actions

Copy link
Copy Markdown

AI Review

PR #750 · 2 changed files

Findings

Status Sev Location Finding Found by
candidate high .github/workflows/pr_main.yaml:426 seed-elf-cache does not seed recursion ELFs, so every merge-queue entry recompiles them minimax
minimax/MiniMax-M3
candidate medium prover/src/tests/recursion_smoke_test.rs:257 test_recursion_execute_* now run on every test-prover shard and may time out minimax
minimax/MiniMax-M3
candidate low Makefile:144 Makefile comment claims recursion tests are #[ignore]d but execute_* tests no longer are minimax
minimax/MiniMax-M3

Status column reflects the verdict from the verifier: deepseek-verifier (openrouter/deepseek/deepseek-v4-pro).

AI-001: seed-elf-cache does not seed recursion ELFs, so every merge-queue entry recompiles them
  • Status: candidate
  • Severity: high
  • Location: .github/workflows/pr_main.yaml:426
  • Found by: minimax:minimax/MiniMax-M3
  • Verified by: -
  • Rejected by: -

Claim

Adding a recursion ELF cache to test-prover/test-prover-comprehensive is undermined because the seed-elf-cache job (the only job that writes caches on main) doesn't seed recursion ELFs. Per the comment block above the seed job, caches are branch-scoped and merge_group branches only read from main, so the new recursion cache will always miss on merge runs and compile-recursion-elfs will run every time — the very problem seed-elf-cache was added to solve.

Evidence

The seed-elf-cache job (lines 426-466) only adds ASM and Rust cache/compile steps; it has no 'cache-recursion-elfs' or 'make compile-recursion-elfs' steps, unlike the test-prover/test-prover-comprehensive jobs which the PR newly adds them to. The job's own comment says "without this job no ELF cache is ever saved on main and every merge-queue entry recompiles" — that is now literally true for the recursion ELFs.

Suggested fix

Add the same recursion cache/compile (and conditional Setup Rust) steps to the seed-elf-cache job that the test-prover job now uses, with the same cache key and path, so the recursion artifacts are persisted on main and available to merge-queue runs.

AI-002: test_recursion_execute_* now run on every test-prover shard and may time out
  • Status: candidate
  • Severity: medium
  • Location: prover/src/tests/recursion_smoke_test.rs:257
  • Found by: minimax:minimax/MiniMax-M3
  • Verified by: -
  • Rejected by: -

Claim

The PR removes #[ignore] from test_recursion_execute_empty / test_recursion_execute_1query / test_recursion_execute. These tests previously documented tens of GB and were excluded from CI; the streaming resume() path avoids the trace OOM but the executor still runs the full STARK verifier in-VM (the verifier's cycles are unchanged), so wall time stays high. With the same #[ignore] still present on test_recursion_prove_* but not on the execute_* tests, only ONE of the two tiers is in CI now — likely an unstated intent — and the new CI test load is now on every shard.

Evidence

Diff removes #[ignore = "needs prebuilt recursion guest ELF + tens of GB RAM (execution trace)"] from three tests (lines 257, 271, 287 in current file). All three still call run_recursion_pipeline which executes the recursion guest program (which calls verify_with_options in-VM). The OldComment even said tens of GB; this change relies on the docs' claim that streaming resume() now keeps footprint bounded to touched memory + instruction cache, but no per-cycle cap is added, so the worst case (a long inner proof still drives a long in-VM verifier) remains essentially unbounded.

Suggested fix

Either keep the execute-only tests #[ignore]d until they are confirmed fast in CI (matching the still-ignored prove tests), or add an explicit cycle timeout / step bound to resume()/execute_outer_and_commit so the test cannot hang a shard for hours. If intentional, also keep the Makefile/SPEC docs in sync — see next finding.

AI-003: Makefile comment claims recursion tests are #[ignore]d but execute_* tests no longer are
  • Status: candidate
  • Severity: low
  • Location: Makefile:144
  • Found by: minimax:minimax/MiniMax-M3
  • Verified by: -
  • Rejected by: -

Claim

The Makefile comment block at line 144-147 states "the recursion smoke tests are #[ignore]d (not run by make test / test-executor) because they're too slow for CI today; only test-prover-all runs them. We still compile their guest ELFs on every build so they keep compiling until the tests are fast enough to run in CI." This is now stale for the execute-only tests after the PR removed their #[ignore].

Evidence

Grep in prover/src/tests/recursion_smoke_test.rs shows #[ignore] only on test_recursion_prove_empty, test_recursion_prove_1query, test_recursion_prove (and the separate roundtrip test), while the three test_recursion_execute_* functions have no #[ignore]. The Makefile comment from the diff base still says all of them are #[ignore]d.

Suggested fix

Update the Makefile comment to reflect the split: the execute-only tests now run in CI shards, the prove-tier tests still only run via make test-prover-all.

Reviewer Lanes

Lane Model Prompt Status Findings
glm openrouter/z-ai/glm-5.2 general error: opencode failed (provider/auth/runtime error) and no findings were submitted 0
kimi openrouter/moonshotai/kimi-k2.7-code general error: opencode failed (provider/auth/runtime error) and no findings were submitted 0
minimax minimax/MiniMax-M3 general success 3
moonmath zro/minimax-m3 general error: agentic lane timed out after 1800s 0
nemotron openrouter/nvidia/nemotron-3-ultra-550b-a55b general error: opencode failed (provider/auth/runtime error) and no findings were submitted 0

Verification Lanes

Lane Model Status Confirmed Rejected Uncertain
deepseek-verifier openrouter/deepseek/deepseek-v4-pro error: opencode failed (provider/auth/runtime error) and no verifications were submitted 0 0 0

Native Codex and Claude reviews run separately and post their own comments. They are not included in this structured provenance report.

Raw lane outputs, candidates, final issues, and model metrics are uploaded as workflow artifacts.

… epochs

The prove tier's continuation bundle retains every epoch's STARK proof in
RAM, so it OOMs CI runners. Narrow the CI selector to test_recursion_execute
(streaming, bounded) and leave the prove tier manual-only with a 2^16 epoch
to cap the per-epoch trace+LDE spike.
@jotabulacios
jotabulacios added this pull request to the merge queue Jul 2, 2026
Merged via the queue into main with commit a482ec2 Jul 2, 2026
13 checks passed
@jotabulacios
jotabulacios deleted the pr/recursion-guest branch July 2, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants