docs: tune skill eval cases and document how to write them - #2203
Open
cliffhall wants to merge 2 commits into
Open
docs: tune skill eval cases and document how to write them#2203cliffhall wants to merge 2 commits into
cliffhall wants to merge 2 commits into
Conversation
`skills:eval` was at 38/46 with several skills measuring 0-33%. The low scores were mostly bad eval cases rather than bad descriptions, for two reasons that were nowhere written down: - The harness runs each case with `--max-turns 1`, so the skill has to be the model's FIRST tool call. A prompt asking "how does X work here", or naming a concrete file, sends the model to Read/Grep first — a better answer to the question, scored as a miss. Every 0% case was one of these. - `AGENTS.md` is resident on every turn, so a prompt it already answers is answered without any skill and the case can never pass. Replace the cases that measured the wrong thing, expand every model-invoked skill from 3 to 5 positives (negatives kept) so one flake cannot cross the threshold, and reshape `local-dev`'s description to the action-first form. Add `docs/skill-authoring.md` with the case shapes that fire, the ones that cannot, and the probe-then-measure loop. RUNS=5 npm run skills:eval: 63/63 at or above threshold, 60 at 100%, all 18 negatives clean. Closes #2202 Signed-off-by: cliffhall <cliff@futurescale.com>
…g cases Adds a multi-name filter to `npm run skills:eval` so a set of related skills can be iterated together, and makes an unknown name a hard error rather than an empty run — a typo would otherwise report a green 0/0 that reads exactly like a clean pass of the skill that was meant. Re-aims two `local-dev` cases and one `test-servers` case that partially overlapped `AGENTS.md`. Partial overlap oscillates across runs rather than sitting at zero, so it reads as eval noise instead of a defect in the case; `docs/skill-authoring.md` now records that failure mode and the observed scores. Widens the `test-servers` description to the "Use when …" shape and points the `testing` skill at it, since anything needing a real server to run against is a procedure `testing` does not carry. That growth moves the skill listing from 2,921 to 3,144 of 4,000 characters, so the figure recorded in AGENTS.md is updated to match. Signed-off-by: cliffhall <cliff@futurescale.com>
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.
Closes #2202
npm run skills:evalwas at 38/46, with several model-invoked skills measuring 0–33% on situations they exist to cover. The low scores turned out to be mostly bad eval cases rather than bad descriptions — and the reasons why were nowhere written down, so the next person to add a skill would have rediscovered them.The two root causes
1. The harness runs each case with
--max-turns 1, so the skill has to be the model's first tool call. A prompt phrased as "how does X work here", or one naming a concrete file or helper, sends the model toRead/Grepfirst — a better answer to the question, scored as a miss. Every 0% case in the suite was one of these. Probing the same questions reshaped confirms it:BashSkill✅BashSkill✅ReadSkill✅2.
AGENTS.mdis loaded in full on every turn, so a case it already answers can never pass. Three committed cases were in that category — including "Which package owns the OAuth secret storage backends?", whose answer is a verbatim line of the directory tree, and which had measured 0% across every run. I then wrote a fourth one myself mid-investigation ("What should I run before I push?", 40%), which is fair evidence the trap is easy to fall into even while documenting it.Changes
AGENTS.mdor invited aReadare replaced with "how do I…", "does X belong in A or B", "<stage> failed, how do I diagnose it" shapes.local-devdescription reshaped to the action-firstUse when …; when …form.project-structure's reshape was reverted: it measured no improvement, so it was 110 characters of listing budget for nothing.docs/skill-authoring.md(new) — how the eval measures, the first-move rule, the shapes that fire and the ones that cannot, why anAGENTS.md-answerable case is unpassable, the probe-then-measure loop, and a checklist. Linked from the README table and fromAGENTS.md's skill-maintenance rules.AGENTS.md— listing-cost figure refreshed (2,834 → 3,144 of 4,000, after thetest-serversreshape below) and a pointer to the new page.Two smaller findings, also captured
board-ops3/3 as anissue-createcase —board-opsis the correct answer, so the case was replaced rather than the description broadened onto another skill's ground.Verification
RUNS=5 npm run skills:eval— 63/63 at or above threshold, 60 of them at 100%, all 18 negative cases clean, script exits 0 (was 38/46).The three that sat at 80% —
local-dev's dependency-resync case,pr-flow's Copilot-review case, andproject-structure's Node-backend placement case — are revisited in the follow-up below.npm run local:gatepasses (GATE_EXIT=0).No UI change, so no screenshots.
Follow-up (commit
a344225e)Chasing the three cases that had been sitting at 80% turned up a fourth failure mode, plus one gap in the harness.
Partial overlap with
AGENTS.mdreads as flakiness, not as a missA case
AGENTS.mdanswers outright sits at 0% and is easy to spot. A case it answers half of oscillates — and looks like eval noise rather than a defect in the case:AGENTS.md; only the diagnosis is the skill'sAGENTS.mdsays a single rootnpm installis all you needBoth stabilised at 100% once re-aimed at what only the skill holds — "what do I check" instead of "where should it have gone", and the worktree install trap instead of the install command.
docs/skill-authoring.mdnow records this as its own section, with the rule: if a case keeps moving between runs while its neighbours hold steady, suspect the case before you suspect the noise.test-serversreshaped, andtestingpointed at ittest-serverskept its noun-phrase description ("Covers the stale-build hazard"). Reshaped to the action-firstUse when …; when …form that worked elsewhere, and its stale-build case — whichAGENTS.mdpartly answers — re-aimed at "I need a real server to exercise this change against by hand."Since integration and smoke tests here drive a real server rather than a mock,
testingnow carries an explicit pointer to/test-serversfor anything needing one — that is a proceduretestingdoes not hold.This is what moves the listing from 2,921 to 3,144 of 4,000 characters, and
AGENTS.md's recorded figure is updated in the same commit per its own maintenance rule.skills:evalaccepts several skill namesIterating on two related skills meant either one skill at a time or the full suite.
npm run skills:eval -- testing test-serversnow works.An unknown name is a hard error rather than an empty run — a typo would otherwise enqueue zero cases and report a green
0/0, which reads exactly like a clean pass of the skill you meant. Two new tests inscripts/skill-eval.test.mjscover the multi-name form and that error; the single-name form is unchanged.Narrowing never narrows what a negative case is scored against — a focused run still fails a negative that fires any model-invoked skill, since "no skill of ours fired" is the property being asserted. Documented alongside a warning that a focused run cannot see displacement, so the full suite is still what you take before pushing.
Verification (this round)
RUNS=5 npm run skills:eval— 63/63 at 100%, including all 18 negatives clean and all three previously-80% cases. No displacement of untouched skills.npm run local:gate— passes, all 34 stages (GATE_EXIT=0).