Repository navigation
evals: split the v2 sweep across three CI runners - #25
Merged
Merged
Conversation
At trials=5 the sweep is ~6.3 h on one machine, past GitHub's hard 6 h per-job ceiling -- a platform limit no timeout-minutes can raise, and `fastskill eval run` 0.9.212 has no concurrency flag, so trials are sequential. The three suites share nothing until the scorecard, so put each on its own runner: the longest (consultation) is ~4.4 h. run.sh takes optional suite names and validates them before any side effect. A subset run deliberately does NOT score itself: every metric in metrics.toml is scoped to a case prefix and a metric matching nothing is a hard error (EVAL_SCORECARD_EMPTY_METRIC), so scoring `restraint` alone would fail on the two judge_score metrics rather than measure anything. scorecard.sh is the fold, extracted so it can run against a directory it did not produce -- in CI, the reassembled artifacts of three jobs. It refuses a root missing a suite and names which one, instead of letting the scorecard blame a metric for a gap in the inputs. live-eval stays dispatch-only. Nothing schedules it and nothing should. Docs: correct the sweep's cost and wall clock. The old "~$6, ~1 h" was an Anthropic-rate token estimate, which is fiction against a self-hosted gateway; 76 min at trials=1 is measured (run 33914096408). Also refresh the CI section, which still said no CI job runs a v2 sweep. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DobwJ8YTnfowwqwhspU1kQ
aroff
enabled auto-merge (squash)
September 4, 2026 22:52
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.
Why
The
trials=1preflight (run 33914096408) took 76 minutes wall clock. Attrials=5that projects to ~6.3 h sequentially — past GitHub's hard 6-hour per-job ceiling, which is a platform limittimeout-minutescannot raise.fastskill eval run0.9.212 exposes no concurrency flag (only--trials), so trials run one after another.The three suites share nothing until the scorecard, so they can run at the same time. Longest job becomes
consultationat ~4.4 h, comfortably under the ceiling.What changed
evals/v2/run.shtakes optional suite names:run.sh <agent> <out-dir> [trials] [suite...]. Names are validated beforemkdirand before the vacuity guard, so a typo costs nothing and leaves nothing behind.A subset run deliberately does not score itself. Every metric in
metrics.tomlis scoped to a case prefix, and a metric matching no case is a hard error (EVAL_SCORECARD_EMPTY_METRIC) — so scoringrestraintalone would fail on the twojudge_scoremetrics rather than tell you anything. A subset run says so and points at the fold.evals/v2/scorecard.sh(new) is that fold, extracted so it can run against a directory it did not produce — in CI, the reassembled artifacts of three jobs. It refuses a root missing a suite and names the missing suite, instead of letting the scorecard blame a metric for a gap in the inputs..github/workflows/skill-evals.yml:live-evalbecomes afail-fast: falsematrix over the three suites with per-suitetimeout-minutes(330 / 180 / 90, sized from the measuredtrials=1times) and per-suite artifacts. A newscorecardjob (needs: live-eval,!cancelled()) downloads them withmerge-multiple: trueand applies the gates. That job needs no secrets and no Tailnet.live-evalstays dispatch-only. Noschedule:, nocron:— verified by parsing the workflow. A sweep that runs for hours with nobody waiting on it is a sweep nobody reads.Docs
Corrected two stale claims while in there:
trials=1and the units that actually meter (agent runs, judge calls).evals/README.mdstill said "No CI job runs a v2 sweep" and describedlive-evalas v1-only. Both stopped being true when the sweep landed.Verification
bash -nandshellcheckclean on both scripts.run.shexercised with a stubbedfastskillonPATHacross all four argument shapes (no suite / trials only / one suite / two suites) plus a bad suite name →exit 2with no directory created.restraintalone correctly does not demandAIKIT_LLM_URL/JUDGE_API_KEY.scorecard.shagainst a partial root → exit 1 namingrestraint; complete root → exit 0; nonexistent root → exit 2.guard_vacuity.pypasses;build.pyproduces no diff, so no suite content moved.validate, validate-v2, score-fixtures, live-eval, scorecard; triggers arepush, pull_request, merge_group, workflow_dispatch— no schedule.🤖 Generated with Claude Code
https://claude.ai/code/session_01DobwJ8YTnfowwqwhspU1kQ