Skip to content

Capture the repo's hard-won skill-authoring lessons as guidance - #979

Merged
Evangelink merged 5 commits into
mainfrom
dev/amauryleve/extract-skill-authoring-guidance
Aug 3, 2026
Merged

Capture the repo's hard-won skill-authoring lessons as guidance#979
Evangelink merged 5 commits into
mainfrom
dev/amauryleve/extract-skill-authoring-guidance

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Why

Our skills score well, but the reasons live in PR bodies and in a handful of engineers' heads. This mines ~35 merged PRs (#830#976), issue #899, and eng/eval-quality/README.md into guidance contributors can actually follow, and fixes two latent traps found along the way.

What

New: .agents/skills/improve-skill-quality — a triage playbook for an eval that regressed, returned no verdict, or failed to activate. Its core claim is the one lesson the history repeats loudest: classify before you rewrite. Broken fixtures, underpowered trial counts, forced tools, stale spec keys and harness errors have all masqueraded as skill regressions. Two reference docs carry the content patterns (writing-for-baseline-delta.md) and the symptom → cause → fix catalogue with PR citations (eval-triage.md).

Rewritten: .agents/skills/create-skill-test — it documented a pre-Vally schema (scenarios: / assertions: / setup.copy_test_files) that no longer loads. All 97 eval specs in tests/ use stimuli: / graders: / environment. Anyone following the skill today authored a broken eval. The rewrite also folds in the trial floor, the dormancy-guard rule, and the fixture rules (tracked by git, buildable, self-consistent, actually reproduces its bug).

Extended: .agents/skills/create-skill — description-as-router rules (trigger words, sibling partitioning, exclusion audit, menu budget) and a "write for delta over the baseline model" section.

CONTRIBUTING.md — a "what consistently separates a passing skill from a failing one" playbook, eval sizing with the sign-test arithmetic, a corrected eval snippet, and a fix to the stale "raise runs in dotnet-skills.experiment.yaml" advice — an experiment-level runs overwrites every eval's own value rather than defaulting it.

.gitignore.agents/skills/ was silently swallowing the repo's own authoring skills; the new one only landed because I checked. Replaced with .agents/skills/* plus negations for the five owned directories, so installed third-party skills stay ignored. (This is the same defect class as the .gitignore-swallowed coverage fixture in #945.)

Validation

  • markdownlint-cli2 — 0 errors
  • python eng/eval-quality/check_eval_quality.py — no errors
  • All relative links resolve; frontmatter parses; descriptions under 1,024 chars; bodies under 500 lines
  • A separate review pass fact-checked every schema, arithmetic and command claim against the repo. It found five inaccuracies (a numbering gap, the stale runs advice, an over-absolute disable-model-invocation rule that filter-syntax contradicts, a wrong "8 trials tolerates a loss" row, and run-command's required config) — all fixed before this was pushed.

No files under plugins/ change, so no evaluation is triggered.

Mines ~35 merged PRs (#830-#976), issue #899 and eng/eval-quality/README.md
into reusable guidance so contributors do not have to rediscover it.

- Add .agents/skills/improve-skill-quality: a triage playbook for evals that
  regress, return no verdict, or fail to activate. Classify before rewriting -
  broken fixtures, underpowered trial counts, forced tools, stale spec keys and
  harness errors have all masqueraded as skill regressions. Two reference docs
  carry the content patterns and the symptom/cause/fix catalogue with citations.
- Rewrite .agents/skills/create-skill-test. It documented a pre-Vally schema
  (scenarios:/assertions:/setup.copy_test_files) that no longer loads: all 97
  eval specs use stimuli:/graders:/environment. Anyone following it authored a
  broken eval. Also folds in the trial floor, dormancy-guard and fixture rules.
- Extend .agents/skills/create-skill with the description-as-router rules and a
  "write for delta over the baseline model" section.
- CONTRIBUTING.md: add the quality playbook, document eval sizing, and correct
  the eval snippet and the stale "raise runs in dotnet-skills.experiment.yaml"
  advice - an experiment-level runs overwrites every eval's own value.
- .gitignore: .agents/skills/ was silently swallowing the repo's own authoring
  skills. Replaced with .agents/skills/* plus negations for the five owned
  directories, so installed third-party skills stay ignored.

Validated: markdownlint clean, check_eval_quality.py clean, all relative links
resolve, frontmatter parses, descriptions under 1024 chars, bodies under 500
lines. Claims fact-checked against the repo by a review pass.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 771c704d-9ac9-4d5f-8ccb-54c62066630f
Copilot AI review requested due to automatic review settings July 31, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR consolidates repository-specific “skill authoring” and evaluation hard-earned lessons into first-class guidance, updating contributor docs and the repo’s own authoring skills to reflect the current Vally eval schema and common failure modes.

Changes:

  • Adds a new .agents/skills/improve-skill-quality triage playbook plus reference docs for baseline-delta writing and eval failure diagnosis.
  • Updates .agents/skills/create-skill and rewrites .agents/skills/create-skill-test to emphasize routing-by-description, Vally stimuli/graders/defaults, statistical power, and fixture hygiene.
  • Updates CONTRIBUTING/AGENTS and adjusts .gitignore so the repo’s own authoring skills aren’t accidentally ignored.
Show a summary per file
File Description
CONTRIBUTING.md Refreshes eval authoring guidance (Vally schema, defaults vs config, power sizing, and experiment runs caveat).
AGENTS.md Documents the repo’s intended “use the authoring skills + run eval-quality gate” workflow.
.gitignore Stops ignoring the repo-owned .agents/skills/* directories while still ignoring installed third-party skills.
.agents/skills/improve-skill-quality/SKILL.md New triage workflow for diagnosing regressions/no-verdict/no-activation/cost issues before rewriting content.
.agents/skills/improve-skill-quality/references/writing-for-baseline-delta.md Reference patterns for writing skill content that beats baseline.
.agents/skills/improve-skill-quality/references/eval-triage.md Symptom → cause → fix catalogue for harness/fixtures/power/design/activation issues.
.agents/skills/create-skill/SKILL.md Extends skill scaffolding guidance (description-as-router, baseline-delta writing patterns, validation).
.agents/skills/create-skill-test/SKILL.md Rewrites eval authoring guidance to the current Vally schema and codifies power/fixture/overfitting rules.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Suppressed comments (1)

.agents/skills/create-skill/SKILL.md:117

  • Same path issue as the earlier directory snippet: this optional-layout example should point at plugins/<plugin>/skills/<skill-name>/ rather than skills/<skill-name>/ to match the repo layout.
skills/<skill-name>/
  • Files reviewed: 7/8 changed files
  • Comments generated: 2

Comment thread .agents/skills/improve-skill-quality/SKILL.md Outdated
Comment thread .agents/skills/create-skill/SKILL.md Outdated
@github-actions github-actions Bot added the waiting-on-author PR state label label Jul 31, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 @Evangelink — this PR has 2 unresolved review thread(s). When you're ready, please address the feedback and push an update; the triage bot will pick up the next state automatically. (Add the no-stale label to silence further pings.)

… exceptions

Three review rounds (Copilot, Claude Opus 4.8, GPT-5.6 Sol/Terra) against the
implementation in eng/vally-adapter/adapt.mjs.

Statistics. The docs conflated the gate's two independent bars. adapt.mjs gates
on (1) counted trials >= 5, else `underpowered`, and (2) p <= 0.05 on a sign
test over the *discordant* (non-tie) trials. So "at 5-7 trials one tie makes a
pass unreachable" was wrong: at 6 trials 5W/1T/0L is 5 discordant and passes at
p = 0.031, and at 7 trials two ties are survivable. Every trial table is now
keyed on discordant trials. eng/eval-quality/README.md carried the same
over-generalisation and is corrected too, since these docs restate it.

Eval coverage. "Every skill needs an eval" and "no direct eval for a
disable-model-invocation skill" contradicted each other. Reference skills are
now explicitly exempt and covered through their consumers, and filter-syntax is
no longer described as the sole answer-graded exception - platform-detection
uses the same pattern.

Fixtures. "Every buildable fixture must build" forbade the intentionally broken
fixtures the same document demonstrates. Now: healthy fixtures build,
deliberately broken ones fail only for the reason their stimulus is about.

Triage routing. The first-match classifier sent fixture failures to the harness
row before the fixture row could match, and treated any positive-but-failing
record as a power problem even though adapt.mjs requires `conclusive` first.
Added an inconclusive row, moved the fixture row up, and scoped "quote a losing
trial" to content fixes so it no longer blocks the no-results path.

Also: expect_tools does not assert activation (the harness reports it
separately); CONTRIBUTING claimed evaluations run automatically on plugin
changes when a maintainer must trigger /evaluate against a bound commit; the
minimal eval example is labelled as a sub-floor skeleton; create-skill scaffolds
into plugins/<plugin>/skills/ rather than a non-existent top-level skills/.

Validated: markdownlint clean, check_eval_quality.py clean, adapt.test.mjs 21
pass, links and anchors resolve.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 771c704d-9ac9-4d5f-8ccb-54c62066630f
Copilot AI review requested due to automatic review settings August 2, 2026 22:40
@Evangelink
Evangelink requested a review from JanKrivanek as a code owner August 2, 2026 22:40
@Evangelink

Copy link
Copy Markdown
Member Author

Review rounds

Ran three independent review passes over the diff, each pointed at the implementation rather than the prose: Copilot, Claude Opus 4.8, and GPT-5.6 (Sol + Terra). All findings verified against eng/vally-adapter/adapt.mjs, eng/eval-quality/check_eval_quality.py, .github/workflows/evaluation.yml, and the 97 real specs under tests/. Everything below is in cdba3aa.

Accepted (10)

The statistics were wrong, and both Copilot and Opus caught it independently. The docs conflated the gate's two independent bars. adapt.mjs gates on underpowered = directions.length < 5 (counted trials) and signTestPValue(wins, losses) <= 0.05 (discordant trials). So "at 5-7 trials one tie makes a pass unreachable" is false: 5W/1T/0L over 6 trials is 5 discordant and passes at p = 0.031. Opus then caught the residual error in my own fix — at 6 trials two ties leave 4 discordant and fail, so "one or two ties are survivable" only holds at 7. Every table is now keyed on discordant trials.

# Finding Source
1 Trial arithmetic conflated counted vs discordant trials Copilot, Opus
2 "one or two ties survivable" wrong at 6 trials Opus
3 filter-syntax described as the sole answer-graded eval — platform-detection uses the same pattern Opus
4 "every skill needs an eval" contradicted the disable-model-invocation exception GPT
5 Minimal eval example declares 1 trial and would be rejected by the gate GPT
6 "every buildable fixture must build" forbade the intentionally broken fixtures the same doc demonstrates GPT, Terra
7 "do not proceed until you can quote a losing trial" blocked the no-results and underpowered paths this skill exists to handle GPT
8 expect_tools presented as an activation assertion — it checks tool usage; the harness reports activation separately GPT
9 CONTRIBUTING claimed evaluations run automatically on plugin changes; a maintainer must trigger /evaluate bound to a commit GPT
10 First-match triage table routed fixture failures to the harness row, and treated any positive-but-failing record as a power problem although adapt.mjs requires conclusive first Terra

Also corrected outside the original scope

eng/eval-quality/README.md carried the same over-generalisation this PR was reproducing ("at 5, 6 or 7 trials the only record that passes is every trial a win"). Since the new docs restate that section, leaving it would have put the two in conflict — so the blockquote under check 8 and the "Evals parked at the floor" paragraph are corrected. Happy to split that out if the owners prefer.

Rejected (2)

  • eng/version/nuget.config is invalid XML (Terra, High). Real bug, but not this PR: it shows up only under a two-dot git diff origin/main, which includes upstream drift. The three-dot PR diff does not touch the file, and main has already fixed it — this branch simply predates that commit. Nothing to do here.
  • Local-run prerequisites omit Bash (GPT). Correct that eng/run-skill-evals.sh needs Bash and that the prerequisites list only mentions Node and gh. Pre-existing, unrelated to any line this PR touches, and fixing it properly means either a cross-platform wrapper or a documented WSL/Git Bash requirement — a separate change rather than something to bury in a docs PR.

Validation

markdownlint-cli2 0 errors - check_eval_quality.py no errors - adapt.test.mjs 21/21 pass - all relative links and the new in-page anchor resolve - step numbering sequential in both rewritten skills.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (2)

.agents/skills/create-skill-test/SKILL.md:174

  • The run-command row lists stdout_matches as an optional config key, but existing evals also use stdout_contains (e.g. tests/dotnet-test-migration/migrate-xunit-to-mstest/eval.yaml:51-56). Including stdout_contains here would prevent readers from missing a commonly-used (and often more stable) assertion option for run-command graders.
| `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 |

eng/eval-quality/README.md:183

  • This callout correctly explains that ties at 6–7 counted trials can still pass (because the sign test is over discordant trials), but the current check_eval_quality.py warning text for 5–7 trials still says “every trial a win with no ties… one tie makes them unwinnable” (eng/eval-quality/check_eval_quality.py:406-412). That mismatch will confuse contributors when the gate prints the warning. Consider updating the gate’s warning message to match the discordant-trials explanation here (or adjusting the wording here until the warning copy is updated).
> **Landing on 5 exactly is a trap, and the gate now warns about it.** The table
> above is the *best possible* record. A pass needs **five discordant (non-tie)
> trials with no losses**, so at exactly 5 trials a single tie is fatal — it
> leaves 4 discordant, back below the floor. At 6 trials one tie is survivable
> (5W/1T/0L is 5 discordant and passes at p = 0.031) and at 7 trials up to two
  • Files reviewed: 8/9 changed files
  • Comments generated: 0 new

@AbhitejJohn

AbhitejJohn commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Review — PR #979

Thanks for putting this together, Amaury — this is a thorough extraction of lessons that were previously scattered across PR bodies and a few people's heads.

What I verified

Claim Result
Sign-test arithmetic (p = 0.031, 0.035, ≥ 0.0625) Confirmed. Computed: 0.5^5 = 0.03125, (C(8,7)+C(8,8))/256 = 0.03516, 0.5^4 = 0.0625
.gitignore swallowed repo-owned skills Confirmed. Old pattern was bare .agents/skills/; new pattern .agents/skills/* + 5 negations matches exactly the 5 directories in the repo
check_eval_quality.py passes Confirmed. 0 errors, 97 specs checked
selftest_eval_quality.py passes Confirmed. All 22 self-tests pass
All relative links resolve Confirmed. All 7 cross-referenced paths exist on the PR branch
Description lengths < 1024 chars Confirmed. 456, 447, 476 chars
Body lines < 500 Confirmed. 319, 246, 208 lines
Old CONTRIBUTING.md eval snippet used config: Confirmed. Line 253 was config: — following the old "add defaults: runs:" advice would silently break the spec
Old "raise runs in experiment yaml" advice was wrong Confirmed. Experiment yaml comments out runs and explains it would overwrite every eval's own value

Findings

1. Agent eval path guidance gap (worth addressing)
The rewritten create-skill-test/SKILL.md says "for a skill or agent" and mentions the agent. prefix convention, but agent evals are explicitly excluded from the canonical experiment (dotnet-skills.experiment.yaml evals: glob skips agent.*), and run-skill-evals.sh can't pull them in. The old doc had some agent-specific evaluation coverage. A brief note in Step 10 or Common Pitfalls saying that agent.* evals are excluded from the sign-test flow (and explaining how to validate them instead) would help agent-eval authors.

2. Pre-existing terminology drift in eng/eval-quality/README.md (nit, not introduced by this PR)
Line 154 still says trials = scenarios × defaults.runs while the new authoring skills consistently use stimuli × runs. Worth aligning in a follow-up.

3. .gitignore maintenance note (nit)
The negation list is exactly correct today (5 dirs, 5 negations). A one-line comment noting that new repo-owned authoring skills need a negation added here would help the next person.

4. InvestigatingResults.md reference (nit)
improve-skill-quality/SKILL.md Step 1 links to eng/vally-adapter/InvestigatingResults.md, while AGENTS.md references eng/skill-validator/src/docs/InvestigatingResults.md. If these are different docs for different audiences, a brief note clarifying which is which would help.

Summary

This is excellent work. The create-skill-test rewrite fixes genuinely dangerous documentation (the old pre-Vally schema would produce broken evals), the .gitignore fix closes a real bug, the CONTRIBUTING.md corrections prevent silent spec-load failures, and the new improve-skill-quality triage playbook is the kind of guidance that prevents the most common misdiagnosis in this repo. The only actionable finding is the agent-eval gap (#1).

(Copilot, commenting on Abhitej's behalf.)

Abhitej's review found one actionable gap plus three nits; all four are small
enough to land here rather than as follow-ups.

Agent evals. create-skill-test told authors to write tests/<plugin>/agent.<name>/
eval.yaml, size it for the trial floor, and validate with run-skill-evals.sh --
none of which applies. The canonical experiment declares
`evals: tests/*/!(agent.*)/eval.yaml`, so agent specs are excluded: no verdict is
computed, the floor does not apply, and the runner drops them even when named
explicitly because --eval-filter is intersected with that glob. Step 1 now says
so, Step 10 shows the EXPERIMENT_FILE route for actually exercising one, and the
checklist and pitfalls are scoped accordingly.

Nits: aligned eng/eval-quality/README.md check 8 on "stimuli" (it still said
"scenarios" while every authoring doc says stimuli); added a .gitignore comment
so the next repo-owned authoring skill gets a negation instead of being silently
untracked; and noted in improve-skill-quality that
eng/skill-validator/src/docs/InvestigatingResults.md documents the retired
skill-validator evaluate schema, so the vally-adapter one is the guide to read.

Validated: markdownlint clean, check_eval_quality.py clean, 22/22 eval-quality
self-tests, gitignore negations still exact.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 771c704d-9ac9-4d5f-8ccb-54c62066630f
Copilot AI review requested due to automatic review settings August 3, 2026 07:55

@AbhitejJohn AbhitejJohn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together.

Comment thread .agents/skills/improve-skill-quality/references/eval-triage.md Outdated
Comment thread .agents/skills/improve-skill-quality/references/eval-triage.md Outdated
@Evangelink

Copy link
Copy Markdown
Member Author

Thanks @AbhitejJohn — all four are addressed in c8b60e8. No follow-up tickets needed; each turned out to be a few lines in files this PR already touches.

1. Agent eval gap — fixed, and it was worse than a doc gap

You were right that this needed addressing. Confirmed the mechanism:

# dotnet-skills.experiment.yaml
evals:
  - tests/*/!(agent.*)/eval.yaml

and eng/run-skill-evals.sh:20-22 intersects --eval-filter with that glob, so naming an agent eval explicitly still drops it silently — the runner exits successfully having run nothing. So the doc was not merely incomplete: it told authors to size an agent.* eval for a trial floor that never applies and to validate it with a command that is a no-op.

Three changes:

  • Step 1 states that agent.* sits outside the verdict flow — no verdict, no floor, dropped by the runner even when named.
  • Step 10 gives the route that does work: widen the evals: glob in a copied experiment file and pass it via EXPERIMENT_FILE, then read the trajectories rather than a verdict.
  • Checklist and pitfalls scoped: stimuli × runs clears 5 now says "for a skill eval", plus rows for sizing an agent eval for the floor and for expecting run-skill-evals.sh to run one.

2. scenarios vs stimuli drift — fixed here

Aligned check 8 in eng/eval-quality/README.md (trials = stimuli × defaults.runs, and the sentence above it). It is a two-word change in a file this PR already edits, so carrying it as a follow-up seemed like more overhead than the fix.

3. .gitignore maintenance note — added

# Adding a new repo-owned authoring skill? Add a negation for it here too, or it
# will be silently untracked.

4. InvestigatingResults.md — they are not parallel docs

Worth recording, because the answer is cleaner than "two audiences": eng/skill-validator/src/docs/InvestigatingResults.md opens with a banner saying the LLM eval pipeline no longer uses skill-validator evaluate, that it documents the legacy schema, and that readers should use eng/vally-adapter/InvestigatingResults.md instead. I also confirmed skill-validator no longer ships an evaluate verb at all.

So the triage skill links the correct one. AGENTS.md's reference is also correct in its own context — that repo instruction is about keeping the validator's own bundled doc in sync when the validator changes. I added a line to the improve-skill-quality references section naming the legacy doc explicitly, so nobody reads the retired schema by mistake.

Validation

markdownlint 0 errors - check_eval_quality.py no errors - selftest_eval_quality.py 22/22 - .gitignore negations re-verified with git check-ignore (repo-owned skills tracked, a stranger skill still ignored).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (1)

.agents/skills/create-skill-test/SKILL.md:146

  • In the environment skeleton, the comment on environment.skills says these are "extra skills loaded in the isolated arm only", but there’s nothing in this YAML shape that would scope them to only the skilled/isolated arm. In the canonical skill-vs-baseline experiment, environment.skills is supplied by the experiment variants; in agent.* evals, environment.skills is the set of skills the agent may invoke. This wording is likely to mislead authors into thinking they can safely add skills without contaminating the baseline arm.
  skills:
    - binlog-failure-analysis                    # extra skills loaded in the isolated arm only
  • Files reviewed: 8/9 changed files
  • Comments generated: 0 new

The triage catalogue is meant to apply to every plugin, but two rows stated
their rule in dotnet-test terms, so an author on another plugin would read past
them:

- the split-brain fixture row was framed entirely around Cobertura `line-rate`;
  the rule is that a fixture must never state the same fact twice in two places
  that disagree, whatever the format. Cobertura is now the named example.
- the volume-comparison row said "both arms write tests" / "do not reward test
  count"; the rule is that when both arms produce the same kind of artifact the
  judge falls back on comparing quantity.

Also generalized the one-line summary of the first rule in SKILL.md Step 4 so
the detail and the summary do not disagree.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 771c704d-9ac9-4d5f-8ccb-54c62066630f
Copilot AI review requested due to automatic review settings August 3, 2026 08:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Suppressed comments (2)

.agents/skills/improve-skill-quality/SKILL.md:56

  • The sentence says a fixture-related failure "also matches the two rows above it", but the Fixture row is the first row in the table. This reads as a direction error and makes the classification guidance confusing.
fixture belongs in the Fixture row even though it also matches the two rows above it.

.agents/skills/create-skill-test/SKILL.md:146

  • In the Vally-based evaluation harness, environment.skills entries are treated as paths to skill directories (each must be a directory containing a SKILL.md, e.g. plugins/<plugin>/skills/<skill>). Using a bare skill name like binlog-failure-analysis in this example is likely to produce a spec that doesn't load the dependency as intended.
  skills:
    - binlog-failure-analysis                    # extra skills loaded in the isolated arm only
  • Files reviewed: 8/9 changed files
  • Comments generated: 0 new

Two suppressed findings from the Copilot review summaries, both real.

environment.skills. The Step 5 skeleton documented it as "extra skills loaded
in the isolated arm only", which is wrong in both halves. The experiment
declares `vary: /environment/skills` and supplies the value for each arm itself
(`[]` for baseline, `plugins/<plugin>/skills/<skill>` for skilled), so whatever
a skill eval declares is replaced in every arm -- it cannot add a skill to one
arm, and in a skill eval it does nothing at all. The key is meaningful only in
`agent.*` evals, which the experiment does not vary. Removed it from the generic
skeleton, documented where it does apply, and pointed at an existing agent eval
to copy rather than reproducing a spelling: the three agent specs in this repo
disagree about whether entries are bare names or relative paths, so the doc
should not assert one.

Stale cross-reference. Moving the fixture row to the top of the triage table
last round left the sentence below it still saying a fixture failure "also
matches the two rows above it", when it is now the first row. Reworded to say
why it leads.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 771c704d-9ac9-4d5f-8ccb-54c62066630f
Copilot AI review requested due to automatic review settings August 3, 2026 08:12
@Evangelink

Copy link
Copy Markdown
Member Author

Acting on two suppressed findings from the Copilot review summaries — flagging here because one of them changed documented guidance after your approval, @AbhitejJohn.

environment.skills was documented wrongly. The Step 5 skeleton called it "extra skills loaded in the isolated arm only", and both halves of that are false:

# dotnet-skills.experiment.yaml
vary:
  - /environment/skills
variants:
  baseline: { environment: { skills: [] } }
  skilled:  { environment: { skills: [plugins/${eval.grandparent}/skills/${eval.parent}] } }

The experiment supplies that key per arm, so anything a skill eval declares is replaced in every arm. It cannot add a skill to one arm, and in a skill eval it does nothing at all. It is meaningful only in agent.* evals, which the experiment does not vary. Removed from the generic skeleton, documented where it does apply, plus a pitfall row.

While checking, I noticed the three agent specs in this repo disagree on how those entries are spelled — tests/dotnet-msbuild/agent.msbuild/eval.yaml uses bare names (binlog-failure-analysis) while agent.test-quality-auditor and agent.test-migration use relative paths (../../plugins/dotnet-test/skills/...). Rather than assert a resolution rule I could not verify from the repo, the doc now tells authors to copy an existing agent eval. Worth a look separately — one of those two forms is likely not loading what its author intended.

Stale cross-reference: moving the fixture row to the top of the triage table last round left the sentence beneath it saying a fixture failure "also matches the two rows above it". Reworded.

Both in 13e67d1. markdownlint and check_eval_quality.py clean.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 8/9 changed files
  • Comments generated: 0 new

@Evangelink
Evangelink merged commit 38bf797 into main Aug 3, 2026
33 checks passed
@Evangelink
Evangelink deleted the dev/amauryleve/extract-skill-authoring-guidance branch August 3, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on-author PR state label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants