Writing Skills
Author and maintain skills for this library. The canonical rule set lives in docs/AUTHORING.md — read it for descriptions, listing budget, frontmatter, dynamic context injection, and common mistakes. This skill adds the parts that must be applied, not just read: how to reproduce a skill's failure before fixing it, how to write a description that actually triggers, and how to pressure-test.
⛔ The Iron Law
Don't write a skill from imagination — reproduce the failure first, then write the minimum that fixes it.
Writing a skill is TDD applied to process documentation. If you're fixing a skill that under-triggers or that an agent rationalizes past, first reproduce that exact failure (the RED). A skill written to a problem you only imagined tends to over-explain things Claude already knows and miss the real failure mode.
The authoring loop (RED → GREEN → REFACTOR)
- RED — reproduce the failure. Run the target scenario against a fresh agent without the skill (or without the new section). Watch what goes wrong and capture the verbatim excuses it uses ("it's too simple to test", "I'll verify after"). See references/pressure-testing.md.
- GREEN — write the minimum that addresses those failures. Don't pad. Match the form of the fix to the form of the failure (table below).
- REFACTOR — re-test, capture new rationalizations, add counters. Repeat until the behavior holds under pressure. Stop when two consecutive runs pass.
When it doesn't pass, stop by rule, not by patience. Before each rewrite, name
the cause you believe is responsible and change only that. If the number doesn't
move, the hypothesis is dead — do not reword the same section a third time. Either
the assertion is unsatisfiable in this harness (see EVALS.md limitations 3 and 4:
reference-dependent and tool-dependent), or the behavior is a real cost of the
skill and belongs in the test's expected_behavior as an accepted trade with its
mechanism recorded. Both endings are results. Endless rewording is how a skill
grows to satisfy an instrument instead of a user.
Match the form to the failure
| Baseline failure | Right form in the skill |
|---|---|
| Skips or violates a rule under pressure | An Iron Law + a rationalization table + red flags |
| Output has the wrong shape | A positive recipe / template stating what the output is |
| Omits a required element | A structural requirement (named field or slot) |
| Behavior should depend on a condition | A conditional rule ("if X, do Y"), not a blanket rule + exceptions |
| Skill defers instead of delivering | The grounding instruction needs a delivery clause (below) |
| Behavior is documented but never appears | It is filed where the question doesn't reach — move it, don't restate it (below) |
| Behavior appears only as a handoff to another skill | The cross-skill reference is ceding it — say what stays in this skill's answer (below) |
Grounding instructions need a delivery clause
Any instruction of the form "read/inventory/verify X before you answer" degrades
into "ask permission to read X, deliver later" unless you say otherwise. This is
the most-repeated authoring failure in this library — eight occurrences across
three cycles, in architecture-design/data-modeling (Step 0's first draft),
project-documentation (twice), verification-before-completion,
git-workflow, tdd-workflow, api-design, and test-suite-design — and the
base model, having no such instruction, often scores better because it just
answers. The architecture-design Step 0 fix shape has now been applied eight
times and has never failed.
It also hides behind other diagnoses. test-suite-design looked like a naming
problem — an assertion about specification-style test names was failing — but the
judges recorded "no test names appear anywhere": the skill stopped at a behavior
map and an it.each table shape, so there was nothing to name. When an assertion
about the quality of some output fails, first check that the output exists at all.
Every grounding step must carry three things, and they are cheap:
- "This is not a gate on delivering." Say it in those words.
- An exit condition — the literal one-line sentence that closes the step, so the model has something concrete to emit instead of a question.
- "…in the same response." Plus the fallback: when the artifact can't be read, state the assumption and deliver anyway. A draft the user corrects beats a question they must answer.
architecture-design Step 0 is the reference implementation — copy its shape rather
than reinventing it. The tell in an eval is a GREEN reply that contains no artifact:
no message, no document, no recommendation, just a plan to produce one.
The library's stated position, so this stops being argued case by case: ask alongside, never instead. A skill may always ask — questions are often the most valuable thing it produces — but it must not make the answer conditional on a reply it cannot get. Deliver under stated assumptions in the same response, and put the open questions next to the draft rather than in place of it.
Two things follow. A skill that asks first is not thereby wrong — the failure
is withholding the artifact, not seeking context, and a skill whose whole job is
opening up a question (brainstorming) is behaving correctly when it converges
last. And an eval score partly measures this posture rather than knowledge: a
control arm that chooses to ask instead of produce scores as ignorant, so two
cases with the same margin can measure different things. Before reading a margin
as skill quality, check why the control failed.
Before adding content, check whether it is already there
A behavior can be documented and still never appear, because it is filed where the question never reaches. Adding it a second time makes the skill longer without making it reachable — move it, or file it where the prompt lands.
Three confirmed cases: accessibility-design documented submit-time focus in a
general focus table, but the Form Accessibility reference — the material a forms
prompt actually opens — omitted it, so the unaided model produced the behavior and
the skill did not; test-suite-design had its refactoring handoff buried inside a
step about untestable code, framed as "later", so a "where do I start" question never
hit it; api-design's YAGNI bullet licensed omitting the very pagination its own
step specified. Each was fixed by relocating, not by restating.
The check is cheap: grep the skill directory for the behavior first. If it is there, the bug is placement. But confirm before assuming — this pattern does not explain every miss. Two of three assertions investigated in one later pass turned out to be genuine content gaps where the behavior appeared nowhere in the skill at all, and the material an author would "relocate" did not exist.
A cross-skill reference can suppress the behavior it delegates
The mirror image of the above. When a handoff covers something this skill's own output is judged on, naming the other skill gives the model permission to hand the topic over instead of doing it.
Measured: cicd-pipeline gained a Step 3 bullet requiring a multi-stage cached
Docker build and a containerization reference that ceded "the Dockerfile itself
(multi-stage layout…)". Multi-stage went from 0 of 6 generations to 5 of 6 — but
almost never together with caching, because the reply pushed the build out of scope:
"the pipeline assumes a good one exists."
The delegation that worked, in test-suite-design, has four ingredients:
- A dedicated Cross-Skill References entry, not only a sentence inside a step.
- The delegation leads the list rather than sitting among peers.
- A bold imperative naming the trigger condition ("name this handoff whenever the goal of the coverage is a refactor").
- It says what to say, and cedes nothing — the skill still does its own work and names the successor for what comes after.
So: state explicitly what stays in this skill's answer. A reference that transfers the topic will transfer the behavior with it.
Description discipline (the highest-leverage line)
The description decides whether the skill ever runs. Agents follow the
description over the body, so get it right.
- Write WHEN to use, not WHAT it does. A description that summarizes the internal workflow ("reviews code in two passes") triggers worse than one that lists situations ("review this PR, check my code before commit").
- The listing is
description+when_to_use. TheTriggers:list is the when-to-use expressed as the phrases a user actually types — keep casting that net wide. New skills put it inwhen_to_use; existing skills migrate lazily (whenever next touched). A migration must be a pure move: triggers go towhen_to_use, the boundary/delegation instructions STAY indescription(they're what steers haiku routing — EVALS.md). The catalog builder concatenates both fields — check withnode scripts/build-plugins.mjs+git diff catalog.jsonthat content is unchanged (a trailing boundary reorders ahead of the triggers; that's fine). No re-baseline needed. - ~350 chars combined listing target (hard caps:
description1024, combined 1536 — the builder errors above either). Over the listing budget, the least-invoked skills' descriptions drop silently —/doctorreports it. See AUTHORING.md "Listing Budget". - Anti-pattern: describing mechanics/steps instead of triggering situations.
Structure and budget (brief — see AUTHORING.md for detail)
- Frontmatter:
name,description,when_to_use,allowed-tools— do NOT setmodel(inline pins are ignored at runtime; on forked skills they override the user's model choice and quota bucket — see AUTHORING.md "Frontmatter Fields"). Newer fields where they fit:context: fork+agent(heavy report-producing skills — must write the full report to a file and put anything needing user input in an "Open questions" section, since a fork returns only a summary and can't ask the user),paths(file-scoped),disable-model-invocation(deliberate-only workflows),effort. Dynamic injection (bang-prefixed backtick commands, inline or fenced): cheap--stat-style commands only,|| truefailure-tolerant — see AUTHORING.md's injection rules. Note the syntax executes even inside markdown code spans, so never write a runnable example of it in a SKILL.md — describe it, or the skill runs the command every time it loads. - Progressive disclosure: keep SKILL.md tight (aim < 300 lines); push deep
domain knowledge to
references/, output formats totemplates/. On compaction only a skill's first ~5k tokens are re-attached — front-load the Iron Law and workflow; write standing instructions, not one-time steps. - Exactly 3 evals (happy path / edge case / scope boundary) with specific,
verifiable assertions. For hardened skills, add an optional
pressureeval (seeverification-before-completionand the safety-critical skills for the pattern). - Register new skills in
skill-routerso they're discoverable.
When to harden vs. keep open-field
Apply rigor where mistakes are expensive; keep freedom where judgment matters.
- Harden (Iron Law + rationalization table + red flags): fragile, safety- critical workflows — tests, migrations, deploys, security, incidents.
- Keep open-field (explanatory, flexible): creative/advisory work — architecture exploration, UX, estimation, proposals. Rigidity there produces worse outcomes, not better ones.
Retiring skills (obsolescence review)
As base models improve, a skill can become pure overhead. Once per release cycle
— or on a major base-model update — re-run the skill's 3 evals RED on shipping
models via evals/workflow-runner.mjs; re-sample ×3 on borderline scores and
read the judge journal before calling a result variance (a "flaky" case is often
a real content gap the skill causes). The GREEN arm reads the skill's
references/ and templates/, so reference-heavy skills are judged against
their full depth — the old carve-out for them is retired. If RED ≈ GREEN across
all 3 evals (0/0 assertion pairs needing a real repo, a write, or an executed
command don't count — the harness can't provide those), slim first — cut what the model
does unaided; keep the Iron Law, boundaries, and cross-skill references — then
re-run GREEN (gate: GREEN ≥ RED per case). Retire only after a slimmed skill
stays RED ≈ GREEN a full cycle later, with a deprecation notice in
CHANGELOG/ROLES.md first (removal is user-visible to role and plugin consumers).
Full policy: docs/AUTHORING.md § Obsolescence review.
See also
- docs/AUTHORING.md — the canonical rules and common mistakes.
- references/pressure-testing.md — running baseline scenarios and the pressure levers.
docs/EVALS.md— the automated RED/GREEN harness that replays evals through subagents and gates regressions in CI.verification-before-completion— the discipline that proves a skill change works (run the eval, read the result).