Thresholds live in the spec
Add atests: block, keyed by question:
prototype/examples/swe_agent/patch_eval.yml
hunch test checks each one, prints PASS or FAIL, and exits 1 if any fails. A check marked severity: warn prints WARN instead and never fails the build: for something you want to see on every run without blocking on it.
Here is a judgment that reads a coding agent’s patch and predicts whether it will pass the project’s tests, from the SWE-agent cookbook, run against the real test results:
min_accuracy, min_act_accuracy (accuracy among the answers acted on without a person) and order_stability for choices; the spec reference describes each. A question with no tests still gets its numbers printed; nothing can fail.
Two more kinds of check live in the same spec. Examples pin rows whose answers must not change. Metrics check a rule built from several answers, such as “stop the command if any question says yes”, against gold, with limits like max_missed.
Thresholds compare the point estimate, not the lower end of its interval. With 30 reviewed rows the interval is about ±15 points, so set
min_accuracy a little below what you measured.What CI needs
test compares answers with gold, so CI needs both.
Gold is your answer key column and your *.reviews.csv files. Commit them.
Answers come from the store. test asks the engine for any it lacks, which in CI would mean paying on every pull request. Two things keep that small:
- Cache the store between runs. Answers are stored by their exact input, so a restored store is always safe to reuse, and only changed rows or questions are asked again.
- Always pass
--max-cost. If the missing answers would cost more,testasks nothing and exits 1.
TYPESAFE_API_KEY for Jev, or your engine’s key (Environment).
A GitHub Actions workflow
.github/workflows/judgments.yml
test also adds a table to the run’s summary page: per question, accuracy, its range and any failed check, and a line for each metric and for the examples. The same numbers are in the results file for any other CI.
The cache key changes every run and restore-keys picks the newest store, so answers asked in one run are there for the next. hunch uses the nearest .hunch/store.sqlite at or above the spec’s folder, or creates one at the repository root. Set HUNCH_STORE to choose another path.
To see what a pull request does to the answers, add a step with hunch diff evals/ --against git:origin/main --max-cost 0.50. It reports and does not fail the build.
Reading a failure
Exit 1 has two causes, and the last line of the log tells them apart. Here is the quickstart’s guard tested with
--max-cost 0 on a fresh store, before any answers exist:
test writes its results to .hunch/target/, as JSON with a passed field; a stopped one writes nothing. See the results file.