All Recipes

Skills library: SKILL.md for the agent (Phase 6)

Phase 6 of the Harness Engineering series: a skill is a SKILL.md encoding a repeatable procedure ('how to do a recurring task') that the agent auto-loads via the trigger in its description field. You learn to tell a skill apart from the lessons-ledger (which stores 'what NOT to repeat'), to mine skill candidates from commit history, to write the make-or-break description field with trigger phrases, to structure SKILL.md (When to use / Steps / DoD / Anti-patterns / Examples), and to wire the library into the agent's context file. Stack-agnostic, with a copyable template.

IntermediateAI DevOps20 minClaude Code, SKILL.md, CLAUDE.md, git
1

A skill is a procedure — not documentation, not a one-off prompt

If you catch yourself pasting the same long prompt into a chat for the third time — 'here's how we write a test for a component: first…' — that's the signal it's time to make a skill. A skill is a SKILL.md that encodes a REPEATABLE PROCEDURE: 'how to do a recurring task on THIS project'. Not theory, not a reference — a step-by-step action recipe. The thing that sets a skill apart from a plain file in docs/: the agent loads it ITSELF. A SKILL.md has a description field with a trigger; when the user's task matches the trigger, the agent automatically pulls the skill's body into context. So a skill is not documentation (which the agent reads only if you give the path) and not a one-off prompt (that lives in one thread's history and is lost). The scope boundary is honest: a skill describes a PROCEDURE, it doesn't enforce it. If a rule must always hold (import boundaries, strict types), it belongs in a Phase 3 barrier, not a skill. A skill shines where there's a stable sequence of steps but the trigger is contextual: 'when you add a new endpoint — do it like this'.

🟩 Skill (SKILL.md)

  • A repeatable procedure: "how to do X"
  • The agent auto-loads it via a trigger
  • Lives in the repo, reused in every thread

🟦 Documentation

  • Explains "what exists", not "how to do"
  • The agent reads it only if given the path
  • Describes a system, not an action

🟨 One-off prompt

  • A long text pasted into one chat
  • Lost together with the thread history
  • Re-typed from scratch every time
The 'skill or not' test: if you've already explained the same sequence of steps to the agent twice, almost word for word — that's a skill candidate. Explained it once for a unique task — it's not.
2

Skill vs lessons-ledger: "how to DO" vs "what NOT to repeat"

A skill is easy to confuse with the lessons-ledger from Phase 5.5 — both are 'accumulated knowledge about the project', both are text. But they store opposite things and aren't interchangeable. A skill stores a positive procedure: 'how to DO a recurring task' — a stable sequence of steps you want to repeat the same way. The lessons-ledger stores the negative: 'what NOT to repeat' — corrections of specific agent mistakes accumulated after the phrase 'no, not like that'. You write a skill proactively, having noticed a task repeating; a ledger entry appears reactively, after a mistake. They complement each other. Often the ledger tells you it's time to make a skill: if the same correction — 'forgot step X in this procedure again' — keeps surfacing, the procedure has no skill; create one, and step X becomes part of Steps. And if a correction is deterministic ('an across-layer import again'), it belongs neither in a skill nor in the ledger but in a Phase 3 barrier. Three different homes for three different kinds of knowledge.
Kind of knowledgeWhat it storesWhere it lives
Skill (SKILL.md)"How to DO" — a positive procedure.claude/skills/, triggered by description
Lessons-ledger"What NOT to repeat" — error correctionsA lessons file, read at session start
Barrier (Phase 3)A deterministic rule, machine-enforcedLinter / test / script in pre-commit + CI
Ask yourself: does the rule fire on a task trigger or after a mistake? On a 'when you do X' trigger — a skill. After 'no, not like that' — the ledger. And if a machine can check it, it isn't text at all — it's a barrier.
3

Where to find candidates: mine the repeats from commit history

The headline rule of this phase: skills are NOT invented 'by best practice' — they're mined from REAL repeats on this project. The goal is to find 3–5 recurring tasks the project has already done many times. The source isn't imagination, it's the commit history and the shape of the code. How to mine: scan git log and group commits by type of work. Which tasks recur month after month? 'add … endpoint', 'add … page', 'test for …', 'bump … to v…' — those are the skeletons of your skills. In parallel, look where the code has an obvious pattern-by-example: a folder with twenty same-shaped modules means 'create a new module by pattern X' is a recurring task with an established procedure. Below are universal candidate shapes, stack-agnostic. But don't take them as a ready list: your real candidates are the intersection of these shapes with what ACTUALLY repeats in your git log. A skill for a task that happened once is dead weight the agent will load into context for nothing.

Universal candidate shapes (take ONLY those that actually recur)

Write a test for a component / function / module
Create a new module by pattern X
Add a new endpoint / page / scenario
Refactor by pattern X (migrate to a new pattern)
Triage a production bug: from report to repro
Release procedure / bump a dependency with breaking changes
A task that happened EXACTLY once
The bar for a skill: the task has recurred 3+ times AND has a stable sequence of steps. Recurs but differs every time — too early: the procedure must settle first, or you'll freeze noise.
4

SKILL.md structure: a template the agent reads as a recipe

A SKILL.md has a fixed shape: frontmatter with two fields (name in kebab-case and description) plus a body of five sections. Each section carries weight, no filler. When to use — the concrete situations the skill applies in (this echoes and sharpens the trigger for a human reader). Steps — the step-by-step procedure with no waffle, exactly the actions you got tired of repeating. Definition of Done — the signs by which the task counts as closed (the same DoD vocabulary as in Phase 1 and Phase 3). Anti-patterns — what NOT to do: this is where corrections from the lessons-ledger relevant to this procedure collect. Examples — a REAL example from this repo, with concrete file paths: that's what turns an abstract recipe into 'do it by analogy with this'. The key move is Examples with real paths. Without a live example from the repo the agent interprets the skill however it likes; with a 'see how it's done in <real-path>' reference it gets an anchor, and the result becomes predictable. Below is a copyable template; replace the paths with your own.
---
name: add-endpoint                 # kebab-case, уникально / unique
description: >
  Use when adding a NEW HTTP endpoint / route / handler to the API.
  Triggers: "add an endpoint", "new route", "create a handler for",
  "expose ... over the API", "добавь эндпоинт", "новый роут".
---

# Add a new endpoint

## When to use
- A new public route/handler is needed (CRUD, action, webhook).
- NOT for: changing an existing handler's logic (that's a normal edit).

## Steps
1. Create the handler next to its siblings (see Examples for the folder).
2. Wire validation of the request shape at the boundary.
3. Register the route where the router is assembled.
4. Add a test mirroring the nearest existing endpoint test.
5. Update the API list/docs if the project keeps one.

## Definition of Done
- Route reachable; request/response shapes validated.
- A test exists and passes; existing tests untouched (no .skip, no loosened asserts).
- Boundary linter + type check are green (Phase 3 barriers).

## Anti-patterns
- Business logic inside the handler (keep it in the domain layer).
- Copy-pasting a sibling without renaming its identifiers.
- Skipping the test "because it's trivial".

## Examples
- Reference handler:  <path/to/handlers/get_user>      # adapt to your repo
- Reference test:     <path/to/handlers/get_user_test> # adapt to your repo
- Router assembly:    <path/to/router>                  # adapt to your repo
The Anti-patterns section is the bridge to the lessons-ledger: when a recurring correction belongs to a specific procedure, its home is here, next to Steps, not in the general registry. That way the lesson lands in context exactly when the task triggers it.
5

The description field is make-or-break: the trigger decides everything

You can write a perfect SKILL.md and never once fire it — if the description field is vague. This field isn't for humans: the agent decides from it whether to pull the skill's body into context. A vague description never triggers; a sharp one with characteristic trigger phrases fires reliably. The difference by example. 'Helps with API work' is a failure: it fits anything and nothing specific, the agent can't tell when it's relevant. 'Use when adding a new HTTP endpoint/route/handler. Triggers: "add an endpoint", "new route", "expose … over the API"' is a hit: a precise situation AND the literal phrases a user will say. Include both languages if you work in two. The writing rule: describe the trigger situation + list 3–5 characteristic phrases a user actually uses to state the task (not what you call it internally). Think like a search query: what words will a person utter the moment this skill is needed? Put those into the description. This field is worth more than the whole body — tune it experimentally: state the task in a natural phrasing and check whether the skill was pulled in.

✅ Sharp trigger — fires

  • A precise trigger situation: "when you add an endpoint"
  • 3–5 literal phrases the user will say
  • Both languages if you work in two

❌ Vague trigger — stays silent

  • "Helps with API work" — fits everything
  • Team's internal jargon instead of the user's words
  • A perfect body that never gets loaded
Debug the description like a search query: phrase the task the way an outside colleague would, and check whether the skill was pulled in. It wasn't — add the missing phrase to the trigger, don't rewrite Steps.
6

Wiring into the context file + place in the series

Skills must be visible to the agent. One line in the Phase 1 context file is enough: add to CLAUDE.md / AGENTS.md 'Available skills: see .claude/skills/, triggered automatically by description'. For agents that don't auto-trigger on description, the same SKILL.md body works as a saved playbook/prompt — you just feed it by hand when a When-to-use situation arises. The procedure being in a file, not in your head, is what's portable across agents. The phase's Definition of Done: ≥3 SKILL.md in the repo, each referencing REAL project paths in Examples, and the context file updated with a line about the skill library. No more: three working skills built on real repeats beat fifteen 'for later' ones that clutter the agent's choice. Where this sits in the series. Skills are the positive side of accumulated knowledge (how to DO); they complement the lessons-ledger (what NOT to repeat) and the Phase 3 barriers (what a machine enforces). The truly universal skills (bug triage, release) become material for the migration capsule in Phase 8 — the template repo new projects start from; project-specific ones ('a new module by our pattern') stay in the project. Next is Phase 7: workflow and worktrees. And the map of all phases and how they connect lives in the series hub.

Definition of Done — Phase 6

≥3 SKILL.md mined from real repeats (git log), not invented
Each has a sharp description with trigger phrases
Examples references REAL paths of this project
Context file (CLAUDE.md/AGENTS.md) updated with the library line
Universal skills flagged as migration-capsule candidates (Phase 8)
Fifteen "for later" skills with no real repeats
Tag a skill 'universal' or 'project-specific' right as you write it. It's free now and saves hours in Phase 8: the migration capsule is assembled from the universal skills in one pass, not by archaeology across the whole repo.

Result

Phase 6 is assembled: you stopped re-pasting long prompts into every thread and built a library of skills — SKILL.md files encoding repeatable procedures the agent auto-loads via a trigger. You can tell a skill ('how to DO') from the lessons-ledger ('what NOT to repeat') and from a Phase 3 barrier (what a machine enforces), mine candidates from real repeats in git log (rather than invent them), structure a SKILL.md (When to use / Steps / DoD / Anti-patterns / Examples with real paths), and — above all — write the make-or-break description field with trigger phrases, without which even a perfect skill never fires. DoD: ≥3 SKILL.md on real paths, the context file updated. Next is Phase 7 (workflow and worktrees); the universal skills ride into the migration capsule in Phase 8.