Repository navigation
[#3] Free checks on eval case structure and a cheaper eval cadence - #22
Merged
Merged
Conversation
…een on Linux checks/test_eval_cases.py, under make validate: every case carries its component's tag so its make target finds it, every grader parses with a known type and that type's required fields, and every scaffold is a regular executable file named by its case.yaml. evals/README.md, the Makefile header and the top-level README record the cadence: run only the component touched, iterate at one run, confirm at two when every grader is deterministic and three when any is an llm judge or the target mixes both; --case takes one glob and the last flag wins. The CI workflow comment describes the checks instead of listing them. The hook eval was run once under Linux in a scratch container and recorded on issue #4. Closes #3, #13 and #4. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
dansabin
approved these changes
Oct 14, 2026
This was referenced Oct 14, 2026
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
Closes #3, #13 and #4. A case that lost its component tag, a grader whose frontmatter did not parse, or a scaffold that was not a regular executable file was silently never run or never scored, and nothing free caught it. The eval README still said three runs was the confirmation and did not say that
--casetakes one glob. And the SubagentStart hook had only ever been seen firing inside a sub-agent on macOS, while CI runs on Linux.What
make validatenow fails on any eval case that cannot run or cannot be scored. The eval README, the Makefile header and the top-level README record a cheaper cadence: run only the component touched, iterate at one run, confirm at two for deterministic graders and three when an LLM judge is involved. The hook eval was run once under Linux and recorded on #4.Changes
checks/test_eval_cases.py,.github/workflows/validate.yml): a stdlib unittest module that finds every case, requires its component's tag, requires every grader to parse with a known type and that type's fields, and requires every scaffold to be a regular executable file named by itscase.yaml; the CI workflow comment describes the checks instead of listing them. The goal is to look for cases that cannot run or don't validate. A broken case at run time is not good and it can be prevented.--caserule (evals/README.md,Makefileheader,README.md): run only the component touched; iterate at--runs 1; confirm at two when every grader of the case is deterministic, three when any isllmor the target mixes both;--casetakes one glob and the last flag wins; the eval README names the check as what keeps cases valid and the top-level README points to it. The goal is to minimize unnecessary invocations. For things that are mostly deterministic, two invocations is enough on the plugin side; three for LLMs on the validate side, since there are two places where non-deterministic behaviour can be introduced, so we have more rigor. The rest is to make sure we keep things working and aligned, which is why the free checktest_eval_cases.pyis called out..claude/specs/eval-hygiene/): requirements, design and the ticked task list. We added the requirements that outlined this work; it's important to know how we got here.Testing
make validate: 15 checks OK, both plugin validations pass. The new check alone: 4 tests in 0.07 s. Broken-input proof, run twice on scratch copies of a case: a missing tag, an unknown grader type, a missingpattern, an empty llm body, a missingexists, a non-executable scaffold and an unwiredscaffold.sheach produce one problem line naming the file. All 29 existing cases pass the check unchanged.Hook eval under Linux, once, in a scratch
node:22-bookwormcontainer with Claude Code 2.1.296, recorded with the command on #4:Risk and rollout
Limited. The check runs in CI on every PR from now on, so a new case that is untagged, has a malformed grader or an unwired scaffold fails
make validate. Nothing else changes behaviour; the behaviour was validated and the goal is to increase testing robustness. Roll back by reverting the commit.Notes for reviewers
The only code is
checks/test_eval_cases.py; the rest is documentation. The fewer-variants item of #13 was dropped by decision and is recorded on the issue.🤖 Generated with Claude Code