Fix the prose-register eval failures: arguable keys and a per-skill floor - #68
nonreagent wants to merge 7 commits into
Conversation
The `after` variant read "completed in just 11 days". SKILL.md bans "just" as a modifier and lists it under Lint, so `before` (which has no "just") was a defensible pick. A keyed CI run chose it on exactly that ground and hard-failed disc-01, while the same case passed 3 of 3 in each of two local bare-HOME batches: an intermittent second right answer under a hard gate. Dropping the word leaves one answer. The upstream commit that purges it is c26cd1a; the source repo isn't available here, so the edit is by hand, and both the case's grading note and the file's provenance block say so. trans-01's reference and disc-08's `direct` variant keep the source wording. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
check-gate hard-fails any wrong discrimination choice. That fits a case with one right answer. Several prose-register cases carry grading notes that concede the key is one defensible reading among others, and a subject that picks another reading fails the whole job on a judgment call. A case can now set `arguable: true` in evals.json. check-gate then counts a wrong choice against the pass-rate floor instead of gating on it; a subject that returned no answer still gates. validateData accepts the flag only on discrimination cases (elsewhere there is no choice to soften) and requires a grading_note, so the flag always says why. The generator and the data land in the next commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Self-review before handing back. I ran an adversarial pass over the five commits (Opus, read-only, with the three result files), including mutation checks on the new tests. Findings and what I did with them: Fixed in this series
Left as is, and raised in Feedback
The |
Four cases carry a grading note that concedes another answer is defensible: disc-04 (the connective has nothing to join in isolation), disc-08 ("not a strict rule violation" in the direct opening), disc-09 (ranking `original` first "is not wrong") and disc-11 ("both readings defensible"). Across ten keyed runs (six local under a bare $HOME, four CI) the subject picked the key in 9 of 10 for disc-04, 7 of 10 for disc-08, 6 of 10 for disc-11 and 0 of 10 for disc-09, which it ranked `restored` last every time. disc-04 is flagged on its note and on the parent PR's report that it flipped once in four earlier runs.
disc-12 is flagged on evidence rather than its note: the CI subject picked the wrong answer on all four bare-runner runs, reading the recap triplet in `before` as a hard line with a breath, while all six local suite runs got it right. The cause of that gap is open (see the spec), so the key does not gate hard until it is understood. The case's grading note records the evidence; removing the flag is a one-line revert.
The generator copies `arguable` into the test metadata that check-gate reads. A wrong choice on these cases still fails the case and counts against the floor; it no longer fails the job on its own. The cases stay in the suite unchanged, so a reviewer can still re-key or revise them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
check-gate applied one 90% floor to every skill, and neither suite meets it reliably on the CI runner. Four CI runs of prose-register scored 12, 10, 12 and 10 of 22; code-comment-register scored 15, 15, 13 and 13 of 16, so its 90% default failed two of four runs on judge-rule and detection misses alone. prose-register's det-01 and det-02 fail on every run by design (exact-quote matching against a fixed list), which alone leaves 20 of 22 rows. A skill can now set `min_pass_rate` (a number in (0, 1]) at the top of its evals.json. check-gate resolves the floor as argv, then the skill's own value, then the 90% default. The values sit one row below each skill's worst CI run so far: 0.4 for prose-register (9 of 22) and 0.75 for code-comment-register (12 of 16). They catch a collapse, not a drift, and rest on four runs each. Local runs are not a valid source: a bare $HOME scored prose-register 59 to 73%, about 17 points above CI, and the cause of that gap is open. The resolution is defensive. Only the named skill's evals.json is parsed, so a sibling's broken file cannot fail the gate; an unreadable one warns and falls back to 90%. Results that mix skills get the default, and a floor that is empty, non-numeric or outside (0, 1] is an error rather than a floor of 0 or NaN. EVAL_REPO_ROOT points the gate at a throwaway skills tree so the tests do not depend on the real values. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…the eval spec Adds decisions 10 and 11 with the run data behind them, updates the pass criteria to name both exceptions, and replaces the "revise three cases" follow-up with what is still open: disc-09's key (every run ranked `restored` last), disc-10's rule key (every run cites the breath rule) and the unflagged choices that can still fail the job on one sample. Adds a "CI versus local" section: the CI runner scores about 17 points below a local bare $HOME under the same model, what was ruled out (inherited environment, CI variables, effort level) and what still needs the CI token to test. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The subject runs with the alias `sonnet` and nothing in the results says what it resolved to. Two CI runs of prose-register scored 54.5% and 45.5% while six local runs under a bare $HOME scored 59 to 73%. CI calls also averaged about 1,700 completion tokens and 19 to 21 seconds against about 600 tokens and 9.5 seconds locally, and a side-by-side of inherited and scrubbed local environments (all `claude-sonnet-5`, 500 to 970 tokens, correct on disc-12) ruled the developer's shell out. With no record of the model, the CI and local runs cannot be compared. runClaude now returns the keys of the CLI's `modelUsage` as `metadata.models`, which promptfoo writes to each row's `response.metadata` in the results file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The discrimination prompt said "End with exactly these two lines and nothing after", which a session can satisfy by writing only the verdict. The CI subject did: its discrimination rows averaged about 210 visible characters (the two lines) against about 640 locally, where the subject reasons in prose first. The terse form commits to a letter before comparing, and CI's disc-06 answered `A` while its rule line argued B was on-register. The prompt now asks for a few sentences of comparison first. In one CI run afterwards, discrimination output rose to about 700 characters and disc-06 passed. disc-12 still failed, with the reasoning now visible: the subject reads the recap triplet as a hard line with a breath, which is a judgment difference and not a format slip. The ANSWER line is still read from the end of the output, and the subject still never sees the answer key. This applies to every skill that has discrimination cases; one CI run is thin evidence that it helps. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6790f73 to
73a9271
Compare
|
Follow-up to the self-review above. The first What CI showed. Four runs put What changed in response.
Result. The tip passes both |
Stacked on #67.
Problem
The
run (prose-register)check on #67 scored 12/22 (54.5%) against a 90% floor, with hard failures ondisc-01,disc-09,disc-11anddisc-12. Some of that was eval-side:disc-01's correct answer contained the modifier SKILL.md bans,disc-09anddisc-11carry grading notes that call the alternative answer defensible, andprose-registercannot reach 90% becausedet-01anddet-02fail by design.Four CI runs (one on #67, three on this branch as it developed) then showed a larger problem. The CI runner scores the suite about 17 points below the same suite run locally under a bare
$HOME(prose-register: 45.5 to 54.5% in CI, 59 to 73% locally), with the same model (claude-sonnet-5).disc-12missed on all four CI runs and on none of six local ones. I could not reproduce CI's behavior locally, so this PR fixes what the evidence supports and records what it does not.Motivation
#67 aims for a check CI can run on every skill PR without teaching people to ignore it. A hard gate on a case whose key is contested, or a floor the suite misses half the time on unchanged code, turns sampling noise into red CI. Both wear down the signal the suite exists to give.
Proposed Solution
Seven commits, each green on its own (80 offline tests at the tip,
make preflightclean):disc-01's correct answer. The CI run that pickedbeforehad a skill-backed reason. The edit is by hand (the source essay repo is not available to me); the case's grading note and the provenance block say so.arguable: truemakes a wrong choice count against the floor instead of hard-failing the job. A subject that returns no answer still gates. Accepted only on discrimination cases, and it requires agrading_note.disc-04,disc-08,disc-09anddisc-11on their own notes;disc-12on CI evidence (0 of 4 in CI, 6 of 6 locally), with the evidence in its note. No key is changed.min_pass_rateoverrides the 90% default. Values come from CI runs only, one row below the worst so far:prose-register0.4 (9 of 22),code-comment-register0.75 (12 of 16). The gate also stops crashing on a malformed sibling file and rejects an empty or non-numeric floor.metadata.modelson every result row. This is how I established that CI and local use the same model.disc-06answeredAwhile its rule line argued B. After the change CI output rose to about 700 characters anddisc-06passed. This touches every skill with discrimination cases, on one CI run of evidence.CI on the tip: both
evalsjobs pass.prose-registerscored 10/22 (45.5%, floor 40%).disc-04,disc-09,disc-11anddisc-12all missed their choice again; with the flags those count against the floor, and without them the same run has four hard failures.code-comment-registerscored 16/16 (floor 75%). This is one run after calibrating on four, so it shows the gate no longer trips on typical CI results. It does not show the checks are stable:prose-registerhas now scored 10 of 22 on three of five CI runs, one row above its floor.Feedback
disc-12prompt: inherited shell environment,CI/GITHUB_ACTIONSvariables, every--effortlevel (31 of 34 correct against 0 of 4 in CI). Untested, because it needs the CI credential: authentication throughCLAUDE_CODE_OAUTH_TOKENrather than a credentials file, npm-installed CLI versus native, and a first-run$HOME. The next test is a local run with a token fromclaude setup-tokenexported asCLAUDE_CODE_OAUTH_TOKEN, or a check of which account the repo secret belongs to.disc-12flag are calibrated to CI, and both are your call. 0.4 and 0.75 catch a collapse, not a drift, and rest on four runs each.disc-12is flagged on evidence rather than on its author's note, which stretches whatarguablemeant in the first draft; removing the flag is a one-line revert. If the CI/local gap turns out to be a token or account artifact, both should be recalibrated.disc-06missed on two of four CI runs. Repeating each choice and gating on the majority would cost 2 to 3 times the sessions. Theevalsjob stays advisory (decision 7).disc-09: every run (0 of 10) ranksrestoredlast, against the key's worst stage.disc-10: every run cites the breath rule where the key names concrete nouns, and the judge rejects it, which costs one row per run. I did not re-key either, because a re-key needs text the source essay does not supply.disc-01edit against upstream. I removed "just" by hand on the strength of the case's own note that c26cd1a purges it.