Skip to content

Record when a skill should fire, and what each runner measures - #26

Merged
cmj0121 merged 1 commit into
mainfrom
docs/record-firing-criterion
Sep 16, 2026
Merged

cmj0121 merged 1 commit into
mainfrom
docs/record-firing-criterion

Conversation

@cmj0121

@cmj0121 cmj0121 commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Addresses #24's first and third boxes. The relabelling and the agent-page correction are a separate PR.

Two findings from the first real make eval run, neither written down anywhere

1. When a skill should fire at all

A skill should fire when the request needs something the assistant cannot do unaided — persist state to a file, run a tool, coordinate other agents, emit a machine-readable verdict. Where the assistant can simply comply in the current turn, nothing fires, and that is the right outcome rather than a defect: a trigger-eval positive expecting one is mislabelled, and no description edit will fix it.

The evidence sits inside a single plugin's own results, which is what makes it more than plausible:

lingua case result why
restate my question before you answer it 3/3 complying means writing refine_question into a config file
stop refining my questions 0/3 complying means not doing something, in this turn

Same skill, same vocabulary, opposite results. The discriminator is not how near the wording sits to the description — it is whether anything has to happen that the assistant cannot do alone. The same reading covers three of the other four failures: briefing's two cases and agent-hale's the plan is agreed — write it all ask for something the assistant just does.

2. The two runners answer different questions, so a disagreement is not a tie

The blind router shows a model only the 19 name + description pairs and makes it pick one skill or none. Free, offline, all 380 queries — but a forced choice: given nineteen candidates it returns the nearest description even where a real session would invoke nobody, so its "skill A steals from skill B" verdicts overstate. make eval instead observes whether the Skill tool was invoked at all, at $0.142 a run over 13 of the 380.

The measurement that separates them: in all five failing cases the fires grader reported Skill called 0x, and in every case carrying an exclusion grader the rival reported 0x too and the exclusion passed. The blind router had compactor taking both of briefing's queries 3/3 and spec-writer taking the plan is agreed -- write it 3/3. In a real session neither fires at all.

So: a blind-router miss is a hypothesis; a make eval miss is an observation. Do not edit a description on the former alone when a case can be written for the latter. And the blind router's noise floor is about two queries per plugin at three samples — plugins nobody touched moved that much between runs — so a swing smaller than that is not a finding either.

Where it went

Two bullets appended to the "What that means for edits here" list in ## Checks, directly after #20's case-anatomy bullet, which already ends on "A bare query does not fire a skill" — the nearest thing in the file to finding 1. The list now reads as one progression: what the cheap 380 are → what make eval costs and covers → what a case looks like → when a skill should fire at all → which runner's verdict to trust. Neither new bullet restates #20's cost derivation, its 13-of-380 scoping, or the grader syntax.

What this deliberately does not say

#24 currently calls agent-page "the clearest case for a description edit". That claim is wrong — agent-page's Phase 1 says "Page reviews the change, not the codebase", requires a git diff, and stops outright without a __REVIEW_VERDICT__; its nine other positives are all review-of-a-change and its own set already carries fix the slow query as a negative. It is a mislabel. This PR does not argue that one case — finding 1's clause "no description edit will fix it" states the general rule that makes it wrong, and the label itself is fixed in the companion PR.

agent-page is not named in CLAUDE.md, before or after.

Versions

Nothing moves. CLAUDE.md is neither a plugin body nor catalogue copy, and no check reads it — grep -rn "CLAUDE.md" scripts/ Makefile .pre-commit-config.yaml returns nothing.

One note for the next editor of this file

Prettier de-indents any line where a backtick span straddles a line break, breaking the bullet's alignment, and it normalises *emphasis* to _emphasis_. Treat backtick spans as unbreakable tokens when wrapping. Prose here wraps at 95 characters against the file's existing 96 — and awk length miscounts, because em-dashes are three bytes.

Checks

make test — all four pass. bash scripts/validate-fixtures — all 67 fixtures pass. Pre-commit green on the commit.

🤖 Generated with Claude Code

…easures

A skill fires when the request needs something the assistant cannot do
unaided. Where it can just comply in the turn, nothing fires and the label
was wrong, not the description — lingua passes the query that writes a
config file and fires nothing for the one that asks it to stop.

And the blind router is a forced choice among 19 plus none, so it names a
thief where a real session invokes nobody: every failing case reported
Skill called 0x with its exclusion grader passing. A blind-router miss is
a hypothesis; a make eval miss is an observation.

Refs: #24

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cmj0121
cmj0121 merged commit 0e75fe4 into main Sep 16, 2026
2 checks passed
@cmj0121
cmj0121 deleted the docs/record-firing-criterion branch September 16, 2026 06:55
cmj0121 added a commit that referenced this pull request Sep 16, 2026
Four of the five failing cases were mislabels under the criterion recorded in #26, and one was
not. The one that was not is the point of the change.

agent-page was verified in its body rather than assumed: Page reviews the change after a git
diff, its performance phase is a checklist over that diff, and it stops outright when no
verdict arrived -- a live latency regression supplies none of the three. Both #24 and #25 read
its repeatable 0/3 as a description gap; it is a mislabel, and the set already drew the same
line with `fix the slow query`.

briefing's real reason turned out not to be the standing-versus-one-turn distinction that #25
guessed -- both prompts were already standing instructions. It is that briefing holds no state
at all: Read alone, no config file, no hook. Nothing it offers is beyond the session's reach.

lingua's stop-refining positive stands, decided against the rule on evidence: its body names
"stop refining" as a mid-session change that writes the config file, and the SessionStart hook
reloads that file, so a stop that is not persisted does not stop anything past this session.
Swapping in `lingua off` would have been worse on both counts -- it carries the magic word, and
the body has it suspend without writing. The case is left failing on purpose; that asymmetry is
what the criterion rests on.

compactor's clause stands too. The 0x measurement was taken with it in place, so reverting
trades one unmeasured state for another, and "cannot be distinguished from doing nothing" is an
absence of evidence.

Every relabel spent a negative that had asserted the same line by hand, so four boundaries are
now drawn by measurement instead of assertion.

Closes: #25

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant