Best for
- Creating a new eval.yaml for a skill or agent
- Adding stimuli to an existing eval
- Sizing an eval so the pass gate can actually be reached
dotnet/skills/.agents/skills/create-skill-test/SKILL.md
Scaffolds eval.yaml evaluation specs for agent skills in the dotnet/skills repository. Use when creating skill tests, writing evaluation stimuli, defining graders and rubrics, sizing an eval for statistical power, or setting up test fixture files. Handles the Vally eval.yaml schema, fixture organization, and overfitting avoidance. Do not use for running or debugging existing evals (use improve-skill-quality) nor for skills authoring (use create-skill).
Decision brief
Scaffold an evaluation spec (eval.yaml) for a skill or agent so it conforms to the Vally schema, passes skill-validator check and checkevalquality.py, is powerful enough to return a verdict, and does not overfit to the skill's own wording.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/dotnet/skills --skill ".agents/skills/create-skill-test"Inspect the Agent Skill "create-skill-test" from https://github.com/dotnet/skills/blob/1b896e91feb0f613cb54a914f1efd2897810ae02/.agents/skills/create-skill-test/SKILL.md at commit 1b896e91feb0f613cb54a914f1efd2897810ae02. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Verify the target exists at plugins//skills//SKILL.md or plugins//agents/.agent.md, and read it.
Verify the target exists at plugins//skills//SKILL.md or plugins//agents/.agent.md, and read it.
The spec is Vally format. Every eval in this repo uses stimuli: and graders:; scenarios: and assertions: are a pre-Vally format that no longer loads.
The gate gives each distinct stimulus one vote. Repeated runs for one stimulus collapse to one majority-direction vote and remain available as reliability evidence.
Name describes what is tested, not how.
Permission review
The documentation asks the agent to run terminal commands or scripts.
| `run-command` | `command` (plus optional `expected_exit_code`, `timeout`, `stdout_matches`) | Verify produced code actually builds/runs |The documentation asks the agent to read local files, directories, or repositories.
Did not open or analyze the dump fileThe documentation asks the agent to run terminal commands or scripts.
python eng/eval-quality/check_eval_quality.pyEvidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 5,248 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Scaffold an evaluation spec (eval.yaml) for a skill or agent so it conforms to the Vally schema,
passes skill-validator check and check_eval_quality.py, is powerful enough to return a verdict,
and does not overfit to the skill's own wording.
eval.yaml for a skill or agentimprove-skill-qualitySKILL.md files — use create-skill| Input | Required | Description |
|---|---|---|
| Skill or agent name | Yes | Must exist under plugins/<plugin>/skills/ or plugins/<plugin>/agents/ |
| Plugin name | Yes | e.g. dotnet-msbuild |
| Skill content | Yes | Read it — you cannot write non-overfitted rubric items without it |
| Failure modes to discriminate | Recommended | Each becomes one stimulus |
tests/<plugin>/<skill-name>/eval.yaml # skills
tests/<plugin>/agent.<agent-name>/eval.yaml # agents (the agent. prefix disambiguates)
Verify the target exists at plugins/<plugin>/skills/<skill-name>/SKILL.md or
plugins/<plugin>/agents/<agent-name>.agent.md, and read it.
Agent evals sit outside the verdict flow. The canonical experiment declares
evals: tests/*/!(agent.*)/eval.yaml, so agent.* specs are excluded: no verdict is ever computed
for them, the stimulus floor does not apply, and ./eng/run-skill-evals.sh drops them even when you
name one explicitly (its --eval-filter is intersected with that glob). The distinct-stimulus
floor therefore applies to skill evals only. Author agent evals for the
scenario coverage and the deterministic graders, and run them as described in Step 10.
Be careful with a skill that sets disable-model-invocation: true. The model cannot invoke it,
so the skill is absent from the model-facing skilled arm and any direct eval compares two identical
arms. Answer-content graders do not create a difference between those arms. The honest coverage for
such skills is dependency-level — through the outcome evals of the skills that load them, and through
the plugin arm.
The spec is Vally format. Every eval in this repo uses stimuli: and graders:; scenarios: and
assertions: are a pre-Vally format that no longer loads.
name: <skill-name>
description: Evaluates the <plugin>/<skill-name> skill
type: capability
defaults:
timeout: 5m
runs: 1
stimuli:
- name: <what the agent must accomplish>
prompt: <natural developer request>
environment:
files:
- src: fixtures/<case>/Project.csproj
dest: Project.csproj
graders:
- type: output-matches
config:
pattern: (root cause|underlying issue)
- type: exit-success
- type: prompt
rubric:
- <outcome the agent should have reached>
defaults:replacesconfig:— it does not join it.configis a deprecated alias for the same block and vally throws on a spec declaring both. Some existing evals still open withconfig:; when you change settings, replace it with onedefaults:block. The failure is invisible otherwise: the job exits 0 with no verdicts and the PR comment blames "transient infrastructure".
The gate gives each distinct stimulus one vote. Repeated runs for one stimulus collapse to one majority-direction vote and remain available as reliability evidence.
underpowered — never a pass, never a regression.| discordant stimulus votes | records that pass | p |
|---|---|---|
| ≤ 4 | none | ≥ 0.0625 |
| 5–7 | zero losses only (5W/0L) | 0.031 |
| 8 | one loss survivable (7W/1L) | 0.035 |
At exactly 5 stimuli, one tie is fatal because it leaves 4 discordant votes. At 6 stimuli one tie is survivable; at 7, up to two are. A loss is not. Five is an eligibility floor, not adequate power. For example, 80% power needs 8 discordant votes only for a true 90% conditional win rate; it needs 18 at 80%, 37 at 70%, and 158 at 60%. Size for the effect and tie rate you need to detect.
Use runs for reliability, not task breadth. Vally recommends 3 runs in CI and 5–10 nightly for
pass rate, pass@k, pass^k, and flakiness. Extra runs never clear the five-stimulus floor.
Do not set runs in dotnet-skills.experiment.yaml; experiment overrides overwrite every eval's
own value rather than defaulting it.
name. Vally pairs comparison trajectories by
(stimulus name, trial index); duplicate names make slot identity ambiguous.environment:
files:
- src: fixtures/broken-build/App.csproj # path relative to eval.yaml
dest: App.csproj # path in the agent's working directory
- src: fixtures/broken-build # a directory
dest: .
commands:
- dotnet build -bl || exit 0 # guard intentional failures
Do not set environment.skills in a skill eval. The experiment declares
vary: /environment/skills and supplies the value itself — [] for the baseline arm and
plugins/<plugin>/skills/<skill> for the skilled arm — so anything the eval declares is replaced,
in every arm. It cannot add a skill to one arm only. environment.skills is meaningful only in an
agent.* eval, which the experiment does not vary; there it is the set of skills the agent may
invoke. Copy the shape from an existing agent eval such as
tests/dotnet-test/agent.test-quality-auditor/eval.yaml rather than reproducing a remembered form —
the specs in this repo are not consistent about how they spell those entries.
Fixture rules — each one has already cost a real result:
.gitignore (e.g. coverage*.xml) has
silently swallowed a committed fixture: the eval passed locally and failed at setup in CI. Verify
with git ls-files, not by looking at the working tree.line-rate, summary totals (lines-covered/lines-valid), and <line> elements disagree lets
the two arms read different truths, and the loss is the fixture's fault. Update any rubric item or
prompt that quotes a figure in the same change.n; rename leftovers add trials without evidence.|| exit 0), or vally drops the trial.SKILL.md — the staged
skill lives there, and deleting it aborts only the skilled arm.Graders are hard pass/fail checks evaluated on every arm.
| Type | Required config | Purpose |
|---|---|---|
output-matches / output-not-matches | pattern | Regex over agent output |
output-contains / output-not-contains | substring | Literal text in output |
file-exists / file-not-exists | path | Glob against the work directory |
file-contains / file-not-contains | path, value | Content of a produced file |
run-command | command (plus optional expected_exit_code, timeout, stdout_matches) | Verify produced code actually builds/runs |
exit-success | — | Agent produced non-empty output |
prompt | — | Runs the LLM judge against the rubric |
Rules:
config is absent or missing its required key parses fine and enforces nothing.
The usual cause is an indentation slip during an edit; check_eval_quality.py blocks it.(root cause|primary error|underlying issue).Recommendation: line can silently stop doing so while the eval still passes.file-not-contains / file-not-exists to prove the agent avoided an incorrect action.Rubric items are judged pairwise (baseline vs. skilled). The overfitting judge classifies each item:
| Classification | Description | Goal |
|---|---|---|
| outcome | Whether the agent reached a correct result — WHAT, not HOW | Target this |
| technique | Whether the agent used a skill-specific procedure | Minimize |
| vocabulary | Whether the agent used the skill's terminology | Avoid |
dotnet build /flp".SKILL.md phrasing.Good:
rubric:
- Correctly identified the missing NuGet package as the root cause of the build failure
- Recognized that downstream failures cascaded from that root cause
- Suggested a concrete fix that resolves it
Overfitted:
rubric:
- Replayed the binary log using 'dotnet build /flp:v=diag' # technique
- Measured cold, warm, and no-op build scenarios # vocabulary
- Used the template-comparison skill # rewards activation
constraints:
expect_tools: [bash]
reject_tools: [edit, create]
reject_skills: [some-skill]
expect_tools: [bash] on an advisory question forces a restore or build and converts an
answer into a timeout with no quality benefit. Only require tools when the task genuinely needs
them.reject_tools is the right way to keep a read-only stimulus read-only.A dormancy guard proves the skill stays dormant on an off-target request that superficially matches it. Add one per real "when not to use" boundary: wrong input format, out-of-scope request, incompatible project type, wrong framework version, prerequisite absent.
- name: Decline dump analysis request
prompt: |
I already have a .dmp crash dump from my .NET app. Can you help me
analyze it to find the root cause of the crash?
expect_activation: false
graders:
- type: output-matches
config:
pattern: (out of scope|not cover|does not|cannot|only.*collect)
- type: prompt
rubric:
- Stated that dump analysis is out of scope
- Did not open or analyze the dump file
- Did not install analysis tools such as dotnet-dump analyze, lldb, or windbg
- Suggested the correct alternative
Never combine
expect_activation: falsewithconstraints.reject_skills. That forces the skilled arm to run skill-free, making it identical to the baseline; the score is then pure judge noise. Across four evals the same guard scored −0.4, +0.4, +0.4 and 0, and twice cost a skill its pass.expect_activation: falsealone is the repo convention.
Guard rubrics verify three things: recognition (why it does not apply), restraint (no workflow, no file changes, no installs), redirection (the correct next step).
dotnet run --project eng/skill-validator/src/SkillValidator.csproj -- check --plugin ./plugins/<plugin>
python eng/eval-quality/check_eval_quality.py
./eng/run-skill-evals.sh <plugin> <skill-name>
For an agent eval, the third command is a no-op: agent.* is outside the experiment's evals:
glob. Exercise one by pointing the runner at an experiment file whose glob includes it:
# copy dotnet-skills.experiment.yaml, widen its evals: glob to tests/*/agent.*/eval.yaml
EXPERIMENT_FILE=my-agent.experiment.yaml ./eng/run-skill-evals.sh <plugin>
Read the trajectories rather than the verdict — there is no sign-test result for an agent eval.
check_eval_quality.py blocks eleven structural defect classes that can corrupt a result:
missing or untracked fixtures, self-contradicting coverage fixtures, empty grader configs, dormancy
guards with reject_skills, sub-floor stimulus counts, duplicate YAML keys or stimulus names, and
config:/defaults: collisions. Do not add a new eval to
eng/eval-quality/underpowered-allowlist.txt — the gate rejects
allowlist entries that are new relative to the base branch.
For the official run, submit a PR review containing /evaluate so it binds to the reviewed commit.
tests/<plugin>/<skill-name>/ or tests/<plugin>/agent.<agent-name>/stimuli: / graders:, and exactly one of defaults: or config:git ls-filesconfig keyexpect_activation: false aloneskill-validator check and check_eval_quality.py pass| Pitfall | Solution |
|---|---|
Writing scenarios: / assertions: | That format no longer loads; use stimuli: / graders: |
Adding defaults: runs: beside an existing config: | Merge into one defaults: block |
| Landing an eval at exactly 5 stimuli | A single tie makes a pass unreachable; size for the effect and tie rate |
Raising runs to clear the floor | Repeats measure reliability for one task; add stimuli |
| Prompt mentions the skill or agent by name | Rewrite as a natural developer request |
| Rubric rewards using the skill | Drop the item — the harness reports activation separately; rubrics measure outcomes |
| Fixture present but ignored by git | Verify with git ls-files; CI setup will fail otherwise |
| Fixture that does not build, or breaks for the wrong reason | Fix the fixture before blaming the skill |
Dormancy guard with reject_skills | Use expect_activation: false alone |
expect_tools: [bash] on an advisory question | Drop it; it causes timeouts, not quality |
| Timeout too short for code generation | Use ~360s; empty output fails every grader |
| Duplicate YAML key left behind by an edit | It overwrites the next stimulus field by field — delete the stray block |
| Duplicate stimulus names | Vally uses names as comparison identity — give every stimulus a stable, unique name |
Direct eval for a disable-model-invocation: true skill | Remove it and cover the reference through consumer outcomes |
| Agent eval sized for the stimulus floor | agent.* evals get no verdict; size them for scenario coverage instead |
Agent eval "run" with ./eng/run-skill-evals.sh | The glob drops it — use a widened EXPERIMENT_FILE |
Agent eval missing environment.skills | Declare the skills the agent routes to, or it cannot invoke them |
environment.skills set in a skill eval | The experiment varies that key and replaces it in every arm; the declaration does nothing |
Frequently asked questions
Scaffold an evaluation spec (eval.yaml) for a skill or agent so it conforms to the Vally schema, passes skill-validator check and checkevalquality.py, is powerful enough to return a verdict, and does not overfit to the skill's own wording.
The source record exposes this install command: npx skills add https://github.com/dotnet/skills --skill ".agents/skills/create-skill-test". Inspect the command and pinned source before running it.
Static rules flagged exec-script, read-files in the source; the page lists the matching lines and excerpts.
Alternatives
garrytan/gbrain
End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
dotnet/skills
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing
vipshop/cache-dit
High-level guide for integrating a new DiT model into cache-dit: Cache (BlockAdapter/ForwardPattern), Context Parallelism, Tensor Parallelism, Text Encoder Parallelism (TE-P), VAE Parallelism (VAE-P), generate CLI, installation, testing workflow, and detailed references. Use when adding support for a new diffusion transformer model in cache-dit.