Repository navigation
Verifier bake-off: no local verifier clears the second-gate bar (held-out NOT-RECOMMENDED) - #229
Conversation
…no longer poisons the file
…NOT-RECOMMENDED) Implements specs/verifier-bakeoff.md end to end: seeded sha256(id) dev/held-out split, per-verifier dev tau selection (max catch s.t. collateral <=0.05, ties -> higher tau), and a held-out verdict scored once at the dev-selected tau. V0 reuses Study B's cached OpenJev noul scores; V1 adds think/samples reasoning depth; V2 is the proxy's JudgeGate prompt mirrored verbatim against a local mlx-lm judge; V3 has the same local model write tests from the task spec alone (CodeT-style), scored in the fail-closed sandbox. V3 had the best dev catch rate and was the pre-registered selection, but its held-out catch rate (0.094) falls well short of the 0.30 bar -- NOT-RECOMMENDED, extending Study B's finding across a deeper/local-judge/generated-test search rather than just plain OpenJev. crates/firstpass-bench/src/decision_study.rs and dataset.rs: widen a few helpers to pub(crate) so verifier_bakeoff.rs can reuse Study B's sandbox labeling, HTTP-fetch-with-cache loop, and metric/verdict math instead of duplicating it.
🔎 Codex cross-audit (agent:audit)Blocking Findings
Not run: tests/lints, because this was an audit pass in a read-only workspace. |
|
🔒 Reviewer verdict: BLOCKING — Code and mirrors of judge.rs/decision_study.rs are consistent and well-tested, but the pre-registered spec's "memory use" metric is never collected or reported anywhere, an unmet Acceptance Criterion. |
🔷 Gemini cross-audit (agent:audit-gemini)Blocking Issues & Correctness Regressions
Non-Blocking Edge Cases & Deficiencies
|
…failed resumes - verifier_bakeoff::run creates scratch_dir up front and propagates every cache append failure (decision_study::append_jsonl now returns Result) instead of silently dropping writes. - V0 now errors loudly if decision-scores.jsonl is missing/empty, instead of silently scoring V0 at n=0 — points to `--decision-study` as the fix. - jev_replay's load_priors doc comment no longer inherits resumable_ids' # Errors section; the two are separated again with their own docs. - run_v2_scores/run_v3_tests/run_openjev_scores now retry failed records on resume (score None / zero parsed tests / raw_ok false) via a shared decision_study::resumable_ids helper, mirroring jev_replay's resumable_ids/last-record-wins fix for fetch-priors. - score_bakeoff's n_dev/n_held_out are now the labeled dataset's partition sizes, computed once, rather than whichever verifier iterates last (which could under-report if a verifier only scored a subset). - render formats tau via format_tau so small positive values (e.g. 8.39e-6) don't print as 0.0000 indistinguishable from a true zero (now "0"). Regenerated docs/benchmarks/verifier-bakeoff.md from the existing complete caches: only tau formatting changed (V1 0.0000 -> 8.39e-6, V2 0.0000 -> 0); every catch/collateral/AUC/verdict/selected-verifier number is identical to the previously committed report, so ADR 0013 and the CHANGELOG needed no changes. Co-authored-by: Claude <noreply@anthropic.com>
🔎 Codex cross-audit (agent:audit)Blocking
High
Verification I attempted a narrow test run, but the environment is read-only and rustup failed before compilation: |
|
🔒 Reviewer verdict: BLOCKING — V3's sandbox-scoring resume check uses stale contains_key instead of the PR's own resumable_ids pattern, so a candidate that abstained (empty tests) on a prior run never gets rescored after test-writer retries succeed — undermining this PR's stated goal. |
🔷 Gemini cross-audit (agent:audit-gemini)Blocking
Correctness & Methodology
Edge Cases & Configuration
|
… resume run_v2_scores/run_v3_tests/run_openjev_scores already retry a failed record on resume (previous commit); run_v3_scores still used contains_key, so a candidate whose test-writer call failed on one run (raw_tests: [], scored score: None) stayed permanently un-scored even after a later run successfully regenerated its tests. Flagged independently by both PR #229 review bots (Codex and Gemini cross-audits) as Blocking. Verified a no-op against the existing complete caches (no v3-scores.jsonl record has score: null), so docs/benchmarks/verifier-bakeoff.md needed no further regeneration — confirmed byte-identical before/after. Co-authored-by: Claude <noreply@anthropic.com>
🔎 Codex cross-audit (agent:audit)Blocking
Other Findings
Verification
|
|
🔒 Reviewer verdict: BLOCKING — Unmet spec acceptance criterion (specs/verifier-bakeoff.md:38): report must record memory use alongside latency/model, but neither verifier_bakeoff.rs's BakeoffReport/render(), docs/benchmarks/verifier-bakeoff.md, nor the ADR 0013 addendum include a memory-use figure or a disclosed reason it's missing; otherwise the diff is correct, well-tested, and matches the rest of the pre-registered protocol. (Could not post the PR comment or run cargo test/clippy — gh/cargo commands required approval that was unavailable in this session.) |
🔷 Gemini cross-audit (agent:audit-gemini)Audit Assessment: PASS (Non-Blocking Findings Only)Auditor: Below are non-blocking correctness edge cases, operational inefficiencies, and documentation gaps identified for hardening. 1. Blocking IssuesNone. 2. Correctness & Edge Cases (Non-Blocking)2.1 Fail-Late Prerequisite Check in
|
…ootprint) — closes the pre-registration gap
🔎 Codex cross-audit (agent:audit)Blocking
High
I did not run tests; this was a diff audit only. |
🔷 Gemini cross-audit (agent:audit-gemini)Audit Verdict: Non-Blocking / Approved with ObservationsNo security vulnerabilities or blocking regressions were identified. The sandboxing of generated tests is fail-closed, the pre-registered protocol is strictly adhered to, and the resume bug in Below are correctness edge cases, operational caveats, and non-blocking issues. 1. Correctness & Resumption Edge Cases
2. Operational & Configuration Rigidities
3. Security Audit
|
What
This is a pre-registered search for a verifier stronger than OpenJev
noulto use as a second gate (specs/verifier-bakeoff.md, committed before any scoring). Every candidate runs locally and needs no API key.sha256(id)into 488 dev and 486 held-out answers. The verifier and τ are chosen on dev; the verdict comes from held-out only.noul.noulwiththink: 1024andsamples: 4.JudgeGateprompt, mirrored verbatim and pinned by a parity test, sent to a local Qwen3-Coder-30B-A3B-Instruct (4-bit MLX, mlx-lm).Result: NOT-RECOMMENDED (the bar is catch ≥ 0.30 and collateral ≤ 0.05)
I checked that V2's zeros are genuine explicit
score: 0judgments; parse failures count as abstains, and there were none. It gives 0 to 17.1% of wrong answers and to 6.5% of right ones, so no τ clears the collateral cap. These candidates already passed Firstpass's gate, so the remaining wrong answers are the hard residual. A frontier-model judge hasn't been tried, because no key was available here.Also
--fetch-priorsnow retries failed calls on resume. Previously a keyless first run left every task recorded as done, so a rerun with a valid key skipped them all. Covered by a regression test, which was mutation-tested.Verification
-D warnings0.cargo test --workspace --no-fail-fast: 898 passed, 0 failed.proxy.rsfailed intermittently under heavy concurrent CPU load from the bake-off. They passed 15 of 15 isolated runs, and this PR doesn't touch them.verifier_bakeoff, and the resume fix.