writing-skills · git:20260916.b8baf3a · 2026-09-16 · sha256 2f2f1ae5e6500b00
writing-skills git:20260916.b8baf3aA
Immutable. This exact content never changes and is served at /api/v1/blob/2f2f1ae5e6500b00.
--- name: writing-skills description: Use when creating new skills, editing existing skills, or verifying skills work before deployment. --- # Writing Skills _Adapted from the MIT-licensed superpowers plugin by Jesse Vincent. See NOTICE.md._ ## Overview **Writing a skill is Test-Driven Development applied to process documentation.** Watch an agent fail without the skill (baseline), write the skill, then watch a fresh agent comply. If you never watched the failure, you don't know whether the skill teaches the right thing — or whether there was anything to teach at all. A skill is a reusable technique, pattern, or reference — not a narrative about how you solved something once. Don't create one for a one-off fix or a project-specific convention (put that in the project's own instructions file instead). ## Start from the template Copy `templates/SKILL.template.md` as the starting structure for a new skill. It carries the required frontmatter shape and the section skeleton (When to use / Process / Red flags) — fill it in rather than improvising frontmatter from scratch. ## Rules this plugin's test suite enforces These are checked mechanically by `tests/skills.test.mjs` and `tests/skill-contracts.test.mjs` on every skill under `skills/` — get them wrong and the suite fails, not just a reviewer: - **`name` matches the containing folder exactly.** `skills/writing-skills/SKILL.md` must declare `name: writing-skills`. - **`description` starts with `Use when`.** It states triggering conditions, not what the skill does — see "Write the description as a trigger" below. - **Every CLI subcommand named in the body must actually exist.** Only `init-run`, `gate`, `digest`, `claim`, `unclaim`, and `workflow` are real subcommands of the CLI entrypoint. Naming a subcommand that doesn't exist fails the suite, not just the reader. - **Every `tm-*` agent named in the body must actually exist.** Only `tm-implementer`, `tm-reviewer`, and `tm-integrator` exist under `agents/`. - **The CLI is always invoked through `<fleetmates root>`**, never a relative path: `node "<fleetmates root>/scripts/cli.mjs" <subcommand> --root <project root>`. A relative invocation works from the author's shell and breaks for everyone else. ## Write the description as a trigger, not a summary The description is what a future agent reads to decide whether to load the skill at all — it answers "should I read this right now?", not "what will I learn if I do?" Name concrete situations: symptoms, error messages, the moment in a workflow where the need arises. Don't summarize the skill's process or steps in the description — an agent that reads a workflow summary in the description will sometimes act on the summary and skip the body, which is worse than not finding the skill at all. ```yaml # BAD: abstract capability, not a triggering situation description: Use when working with async tests # GOOD: concrete symptom description: Use when tests have race conditions, timing dependencies, or pass/fail inconsistently # BAD: summarizes the workflow instead of the trigger description: Use when executing plans - dispatches one implementer per task with review between tasks # GOOD: trigger only description: Use when you have a written implementation plan to execute in a separate session with review checkpoints ``` ## A skill must be verified to trigger Writing a skill and shipping it without confirming it fires is not done. Start a fresh session, give it a prompt that matches the situations named in the description, and confirm the skill actually loads and is followed — don't just re-read the description and judge by eye whether it sounds like it would match. **A skill that never triggers is worse than no skill.** It sits in the directory creating false confidence that a process is covered, while every real invocation silently falls through to default behavior. No skill at all is at least honestly absent. ## Match the form to the failure A rule's shape has to match the shape of the failure it prevents. - **Failure is doing a forbidden thing** (claiming done without running tests, committing without the failing test first) — a prohibition works, because obeying it tells the reader exactly what not to do and there's nothing else to get right. - **Failure is producing the wrong shape of output** (a plan with inconsistent task sizing, a digest missing a required field) — a prohibition backfires, because forbidding the wrong shape doesn't tell the reader what the right shape is. Use a positive form instead: a template, a worked example, a required structure to fill in. To tell which you're facing, ask: if a reader obeyed this rule perfectly, would they then know what to produce? If yes, a prohibition is fine. If no — obeying it only tells them what to avoid — the rule is the wrong form; replace it with a template or example. ## Pressure-test discipline skills with a subagent A skill that reads as compelling in calm review can still collapse under the pressure it exists to withstand — time pressure, a plausible-sounding shortcut, an authority claim that "this case is different." Reading your own skill and agreeing with it proves nothing; you already agreed with it before you wrote it. For a **discipline skill** — one whose job is to hold under pressure, like TDD, systematic debugging, or verification-before-completion — dispatch a subagent with the skill plus a scenario engineered to make skipping it look attractive. Then judge by what the subagent *did*, not by what it said it would do. If it rationalized its way out of the rule, the skill's wording is the defect, not the subagent — go fix the wording and retest. This step is overkill for purely informational skills (reference docs, how-to guides) — there is no pressure to resist, only information to find. It applies specifically to skills that exist to hold a line under pressure. ## Red flags | Thought | Reality | |---------|---------| | "The description is close enough, no need to test triggering" | Close enough to you is not close enough to the matcher. An untested description is an unverified claim that the skill will ever run. | | "This is a small edit, I don't need to re-verify" | An edit that changes the description or the triggering conditions can silently break discovery. Re-verify triggering after any change to those sections. | | "I'll skip the template, my frontmatter is fine" | The template's frontmatter shape is exactly what the suite checks. Freehand frontmatter is how a missing field or a name/folder mismatch slips through. | | "It reads fine, that's enough for a discipline skill" | Reading fine under no pressure proves nothing about holding under pressure. Pressure-test it with a subagent before trusting it. | ## Applying this Both authoring a brand-new skill and editing an existing one under `skills/` go through this cycle: start from `templates/SKILL.template.md`, write to the rules the suite enforces, write the description as a trigger, and verify the skill actually fires in a fresh session before calling it done.