fix(bench-verify): Measure each recursion ref's guest cycles with a CLI built from that ref#856
fix(bench-verify): Measure each recursion ref's guest cycles with a CLI built from that ref#856nicole-graus wants to merge 3 commits into
Conversation
…facts at startup, and reject refs predating the execute --cycles counters
|
/bench-verify |
|
⏳ Benchmark started on the bench server. The recursion-guest cycle comparison adds guest builds on top of the verifier bench, longer on a cold runner. The bench server is occupied until it finishes. |
|
/ai-review |
Codex Code Review
|
Review — no significant issuesReviewed the per-ref measuring-CLI change ( Verified:
One thing worth stating explicitly (not a defect — I believe it's the correct tradeoff): each ref now counts cycles with its own VM rather than a single shared counter, so a delta reflects "total verifier work for each side's own proof." That's exactly what the header comment already frames, and it's the only scheme that survives a PR introducing/removing a syscall — the shared- |
Verifier benchmark —
|
| Metric | main | PR | Δ |
|---|---|---|---|
| Verify time | 3.483s | 3.478s | -0.13% ⚪ |
| Proof size | 204.30 MiB | 204.30 MiB | +0.00% ⚪ |
pairs: 20 mean A (PR): 3.478s mean B (main): 3.483s
[parametric] paired-t mean -0.13% sd 0.40% se 0.09%
95% CI: [-0.31%, +0.06%] (t df=19 = 2.093)
[robust] median -0.09% Wilcoxon W+=57 W-=133 p(exact)=0.1311 (z=-1.51)
run-to-run jitter: A CV 0.28% B CV 0.28% (lower = steadier)
within-session drift: -0.24% over the run, 1st->2nd half -0.11%
⚪ INCONCLUSIVE — effect not separable from 0 at n=20 (point estimate ~-0.09%). Add pairs to resolve.
Drift-free interleaved A/B/B/A measurement. - = PR faster. Trust the verdict when paired-t and Wilcoxon agree.
Recursion guest cycles (main vs PR)
=== Recursion-guest cycle comparison — single query (blowup=2, 1 query) — deterministic to ~±100k cycles ===
REF_B (baseline) origin/main 528a841 guest=recursion-min.elf
REF_A (PR) 05e2be0 05e2be0 guest=recursion-min.elf
| Metric | REF_B (baseline) | REF_A (PR) | Δ (A-B) |
|---|---|---|---|
| Guest cycles | 41.7M | 41.7M | -0.0M (-0.06%) |
| Keccak calls | 3025 | 3025 | 0 |
note: cycles reproduce to ~±100k (build codegen + proof nondeterminism); treat sub-100k deltas as noise, not signal.
raw (exact integer counts)
ref_b_sha=528a8411bb641a1290c0794cdd79c76eba76c739 ref_b_elf=recursion-min.elf ref_b_cycles=41749851 ref_b_keccak=3025 ref_b_execute_wall_s=2
ref_a_sha=05e2be02d63242cd38cbe56fd3f4d7a8e21cb50b ref_a_elf=recursion-min.elf ref_a_cycles=41726358 ref_a_keccak=3025 ref_a_execute_wall_s=1
delta_cycles=-23493 delta_keccak=0
(blowup2 regime unavailable for these refs — see the workflow log.)
(blowup4 regime unavailable for these refs — see the workflow log.)
=== Recursion-guest cycle comparison — 128-bit (blowup=4, 110 queries) — real ethrex block, 4 transfers — deterministic to ~±100k cycles ===
REF_B (baseline) origin/main 528a841 guest=recursion-cont-blowup4.elf
REF_A (PR) 05e2be0 05e2be0 guest=recursion-cont-blowup4.elf
| Metric | REF_B (baseline) | REF_A (PR) | Δ (A-B) |
|---|---|---|---|
| Guest cycles | 1470.1M | 1470.2M | +0.1M (+0.01%) |
| Keccak calls | 1755694 | 1755646 | -48 |
note: cycles reproduce to ~±100k (build codegen + proof nondeterminism); treat sub-100k deltas as noise, not signal.
raw (exact integer counts)
ref_b_sha=528a8411bb641a1290c0794cdd79c76eba76c739 ref_b_elf=recursion-cont-blowup4.elf ref_b_cycles=1470095496 ref_b_keccak=1755694 ref_b_execute_wall_s=22
ref_a_sha=05e2be02d63242cd38cbe56fd3f4d7a8e21cb50b ref_a_elf=recursion-cont-blowup4.elf ref_a_cycles=1470209700 ref_a_keccak=1755646 ref_a_execute_wall_s=23
delta_cycles=114204 delta_keccak=-48
AI ReviewPR #856 · 2 changed files Findings
Status column reflects the verdict from the verifier: deepseek-verifier (openrouter/deepseek/deepseek-v4-pro). AI-004: Keccak-counter preflight check greps a brittle source string
Claim The up-front compatibility check for the Evidence Line 290: Suggested fix Replace the source grep with a probe of the built CLI: either run Reviewer Lanes
Verification Lanes
Native Codex and Claude reviews run separately and post their own comments. They are not included in this structured provenance report. Discarded candidates (5) — rejected by the verifier
Raw lane outputs, candidates, final issues, and model metrics are uploaded as workflow artifacts. |
Motivation
/bench-verify's recursion cycle bench builds a single measuring CLI from the workflow checkout, which, in theissue_commentflow, is the default branch (main), and runs it against both the baseline and PR guest ELFs. That works only while every guest uses syscallsmainalready knows. The moment a PR's guest emits a new syscall the main executor aborts withExecutionError(UnknownSyscall(...))and the cycle bench fails, even though the PR is correct. PR #818 (wiring the recursion verifier's Fp3 mul-add through the FEXT accelerator) is the first to hit this: its guest emitsFEXT_LOAD (u64::MAX - 19 = 18446744073709551596), whichmaindoesn't recognize. It will recur for any future PR that adds an accelerator/syscall.Description
Build the measuring CLI per ref instead of once: the baseline guest is measured by a
clibuilt from the baseline ref and the PR guest by aclibuilt from the PR ref, each inside the worktree the script already creates for that ref's guest build. Each VM therefore understands exactly its own guest's syscall, robust for PRs that add or remove syscalls in either direction. This mirrors the existing per-side build inscripts/bench_verify.sh. The result-cache key drops its counter-SHA component (the ref SHA now identifies the counter) and the CLI build sharesHOST_TARGET_DIRwith the blob-dump build so deps stay warm. Onlyscripts/bench_recursion_cycles.shchanges behavior; the workflow gets a comment update.