feat(coin-gym): LOCAL COIN Gym harness scaffold — baseline-vs-team + overfit gate (#2713 Phase 4)#2740
Open
rysweet wants to merge 1 commit into
Conversation
…overfit gate (#2713 Phase 4) Phase 4 of the LOCAL COIN Gym goal (issue #2713): a Rust `coin_gym` module and `coin-gym` CLI that run the COIN benchmark shape locally, score reach/precision against the published leaderboard, and A/B a single-model baseline vs. a multi-agent team — mirroring skwaq's failure-analysis + overfitting-reviewer gating. The whole pipeline runs offline against a mock oracle so it is exercised without a VM. Real `coin evaluate` grading (Docker/VM) is Phase 3; the live self-improvement verify/rollback loop is Phase 5 (both unchecked on #2713). Components (design doc Part 3.3): - target loader (pinned + held-out fresh slice; JSON snapshot manifest) - agent runner: baseline + team (reacher/skeptic/synthesizer threshold gate) - harness executor: mockable HarnessExecutor delegating to `coin evaluate` (CoinEvaluateExecutor.build_argv; Phase-3 gated) + MockHarnessExecutor - scorer: reach rate + precision, family split, R/W/A/T/N/E histogram - leaderboard comparator (published targeted-track numbers; material-deviation) - offline failure-analyst + overfitting-reviewer gate (the anti-overfit crux) - profiles: isolated per-model run state - CLI: coin-gym run|score|compare|improve|profiles Rust (not Python): the repo enforces a Rust-only policy (#2155) and the design calls the harness a Simard crate; `coin evaluate` stays an external oracle the harness delegates to via the mockable executor, never re-implemented. Docs: docs/howto/run-the-coin-gym-harness.md (wired into mkdocs nav); research doc phase table + CLI sketch reconciled. Test: 73 unit tests + gadugi scenario tests/gadugi/coin-gym-harness.{sh,yaml}. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📊 Coverage Summary
Coverage data from CI run. Test files matching |
Owner
Author
CI status (merge-ready gate #4)All code-validating CI jobs are green on the PR-event run (28829091204): The only red checks are
Not self-merging while these supply-chain gates are red. Once the fleet-wide advisory is addressed, this PR is clean-mergeable ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 4 of the LOCAL COIN Gym goal (issue #2713): a Rust
coin_gymmodule +coin-gymCLI that run the COIN benchmark shape locally, score reach/precision against the published leaderboard, and A/B a single-model baseline vs. a multi-agent team — mirroring skwaq's failure-analysis + overfitting-reviewer gating (design:docs/research/coin-benchmark-and-skwaq-study.md, Part 3, landed via #2712).The whole pipeline runs offline against a mock oracle, so it is fully exercised without a VM. Real
coin evaluategrading (Docker/VM) is Phase 3; the live self-improvement verify/rollback loop is Phase 5 — both remain unchecked follow-ups on #2713.Why Rust (not a Python
coin-gym/package)CI enforces a Rust-only policy (#2155,
scripts/check-rust-only-gate.sh— the first CI gate), and the design doc itself calls the harness a "Simard crate"; the repo already shipssimard-gym/simard-rust-gym. COIN's owncoin evaluate(Python/uv/Docker) stays an external oracle the harness delegates to via a mockable executor — never re-implemented (exactly the executor contract in the task/design).Components (design Part 3.3)
TargetSourcetrait; fixture + in-memory impls; bundled sample).AgentStrategyinterface:BaselineStrategy(single model) andTeamStrategy(reacher/skeptic/synthesizer with athreshold_hintsubmit-or-abstain gate). Reasoning abstracted behind a mockableReasoner.HarnessExecutortrait;CoinEvaluateExecutorbuilds thecoin evaluatedelegation argv (Phase-3 gated, unit-tested) +MockHarnessExecutordeterministic test double. The oracle is never re-implemented.R/W/A/T/N/Ehistogram.coin-gym run|score|compare|improve|profiles.The baseline-vs-team trade-off is demonstrable on the bundled sample: identical reach (60%) but the team's abstention gate lifts precision from 60% → 100% (baseline
R:3/W:2, teamR:3/A:2).Merge-ready evidence
1. qa-team / gadugi scenarios —
tests/gadugi/coin-gym-harness.{yaml,sh}: outside-in coverage of the full pipeline (run/score/compare/improve/profiles), the baseline-vs-team precision trade-off, the overfitting gate, offline-scaffold labelling, and usage-on-error. Hermetic, network-free.gadugi-test validate -f tests/gadugi/coin-gym-harness.yaml→ ✓ valid.gadugi-test run -d tests/gadugi -s coin-gym-harness→ ✓ Passed: 1 / Failed: 0 (command exit 0).2. Docs —
docs/howto/run-the-coin-gym-harness.md(new, wired into mkdocs nav under How-To Guides); research doc phase table + §3.5 CLI sketch reconciled to the implemented CLI.mkdocs build --strict→ clean (no orphan/dead-link warnings).3. Quality-audit — 3 SEEK→VALIDATE→FIX cycles, ended clean.
score/compare, run-id collisions, and profile-isolation gaps → all fixed (manifest validation,print_offline_note,RUN_SEQ+ no-overwritesave_run, per-modelensure_profilerejection,--profile/run-id path-traversal hardening).Nhollow run) → fixed + test added. Final cycle: no high-confidence findings.4. CI-equivalent, 100% green locally:
cargo test --lib coin_gym→ 73 passed, 0 failed.cargo test --all-features --locked→ green in a clean env (the only local failures were pre-existing/environmental: the sandbox setsSIMARD_SCALING=auto, which overridesOodaConfig::max_concurrent_actionsin unrelated ooda tests, and redirectsCARGO_TARGET_DIRso the e2e test's hardcodedtarget/debug/simardpath is absent — both pass in clean CI and are untouched by this diff).cargo clippy --all-targets --all-features --locked -- -D warnings→ clean.cargo fmt --check→ clean. Rust-only gate → passed.cargo build --bin simard --no-default-featurescompiles. Pre-commit + pre-push hooks passed on push.6. Focused diff — additive: new
src/coin_gym/module +coin-gymbin +pub mod/2 re-exports inlib.rs+ one[[bin]]inCargo.toml+ docs + gadugi scenario. No unrelated edits.Scope / follow-ups (unchecked on #2713)
azlinVM + Docker, pull a COIN snapshot, wire the realcoin evaluateexecutor (HIGH-RISK, operator-gated).Closes part of #2713 (Phase 4 only).