Skip to content

skills:eval cannot measure a skill reached from another skill #2204

Description

@cliffhall

scripts/skill-eval.mjs runs every case with --max-turns 1, so it measures whether a skill is the model's first tool call. That is the right thing to measure for a skill a user reaches directly, and #2202 tuned every committed case to that shape. It leaves one class of invocation entirely unmeasured: a skill reached from inside another skill.

The gap, measured

testing ends its body with "See /test-servers for picking and building one", and test-servers is model-invocable, so the hand-off is live rather than a dead pointer. It still does not happen:

  • Prompt: "Write an integration test that exercises tool listing against a real server."
  • testing loaded first, 2/2.
  • Across the next 9–12 tool calls in each run, test-servers was never loaded — the model went to Bash/Read/Glob instead.

The suite reports test-servers at 5/5, because all five of its cases ask for it directly. A skill that is only ever reachable through another would score a clean 100% while the hand-off silently never fires.

#2203 improves this particular hand-off two ways — test-servers' description now claims the "a change or a PR needs a real server to exercise it" situation, and testing's pointer moved from its last line into its lede — but neither is measured, and that is the point of this issue rather than a reason to close it.

There is also a task-prompt gap this would cover

"Can you smoke test this PR?" reaches no skill at all (0/3 before #2203's change, 0/3 after). That is arguably correct behavior: the model has to inspect the PR before it can know what fixture the change needs, so firing a skill on the first move would be firing blind. The realistic path for a prompt like that is a second-hop load once the investigation reveals a server is needed — exactly what nothing can currently observe.

What this would take

  • A second eval mode with a higher turn budget that asserts an ordered pair — skill A fired, then skill B — rather than a single name.
  • A decision about what its number means: a chain hit rate is not comparable to the first-move rate, so it probably wants reporting as its own column rather than folded into N/M cases at or above 80%.
  • Read-only tool restriction has to hold across the extra turns; the current harness leans on --max-turns 1 for much of that containment.

Acceptance

  • The suite can express and score "loading A should lead to loading B", with committed cases for at least the testingtest-servers hand-off.
  • The chained measurement is reported distinctly from the first-move rate.
  • docs/skill-authoring.md gains a section on when to write a chained case instead of a direct one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature requestv2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions