Skip to content

build-claude-skill

build-claude-skill

buildwriteshands-on

Use this when: you're adding or renaming a skill

Problem it solves — New skills drift off-convention — wrong verb, vague trigger, duplicated scope. This authors or renames a skill to the project's taxonomy: the right verb, a sharp trigger description, the per-skill contract, and the trigger wiring, so the set stays coherent.

Used in workflows: Grow the harness

Build a Claude skill

Skills live in .claude/skills/<name>/SKILL.md. The bar is docs/agents/skill-quality.md — read it. This skill is the house convention layer on top of it.

First: is this skill yours to touch?

Only ever create or rename owned skills — hand-authored, no upstream. The tell is frontmatter:

  • Owned — no metadata.author. Safe to name, rename, restructure.
  • Boost-managed — has metadata.author (e.g. laravel) + a license. Never rename or hand-edit thesephp artisan boost:update (wired into the composer post-update hook) regenerates them from source, so a rename just spawns a duplicate under the original name and orphans your copy. Leave them at their upstream names; treat them as read-only.

Check before touching anything: grep -l 'author:' .claude/skills/*/SKILL.md.

Naming taxonomy

Pick the prefix from what the skill does — its verb. Six workhorse verbs:

PrefixForBehaviourExamples
build-create / scaffold / forward workproduces complete work (pair with be-complete)build-crud-in-tempo, build-claude-skill, build-sprint
qa-audit a concrete artifact (code / tests / docs / skills)surfaces findings; confirm before any writeqa-code, qa-tests, qa-philosophy, qa-skills
optimise-make a thing faster / leanersurfaces opportunities; applies on confirmoptimise-code, optimise-ci, optimise-context
find-divergent discovery — what's missingsurfaces candidates / gaps (read-only)find-untracked-work, find-learnings
source-convergent acquisition — the best known X for a needshortlist → vet → adoptsource-a-skill
check-meta — reasoning + orchestrationred-team / sweepcheck-reasoning, check-everything

Plus incidental prefixes (1–2 skills each, not a system to learn): be- (a manner of working — be-complete), tidy- (housekeeping — available, currently unused), fyi- (reference, no actionfyi-tempo-domain). And a few standalone single-word skills whose name is the verb (or the actor it names): vet, debug, brainstorm, wrap-up, janitor.

App-specific builders take the -in-tempo suffix. Names are kebab-case, self-describing, and read as the thing you'd type — discoverability over terseness, because these surface in /-autocomplete. (Boost-managed skills sit outside the taxonomy.)

The contract — every skill declares it

In the body (or implicitly in a tight skill), make four things unambiguous — without them an expressive verb decays into a well-named but vague slogan:

  1. Task class — what kind of job (the verb answers this).
  2. Allowed tools — the default tool scope it works within.
  3. Direct vs fork — does it run in-thread, or dispatch a subagent to gather (heavy read-only research, an independence gate)?
  4. Verifiable artifact — what must exist or be true once it's done (the result you can check).

Surface-then-confirm is tiered by irreversibility: writes / deletes / filing issues / saving to memory / git always confirm; pure-read skills (find-, qa-, check-reasoning, fyi-, vet) just report — no confirm tax.

Frontmatter rules

  • name: MUST equal the directory name. Claude Code keys the invocation and /-autocomplete off the directory name — there is no alias field. name is a display label; keep it identical to the dir to avoid confusion. So renaming a skill = git mv the directory, then set name: to match.
  • description: is the trigger — and it has a budget. It drives auto-invocation, so pack it with the cues: Use when… / Use AFTER… / BEFORE…, the NOT cases, and how it differs from sibling skills. Lead with the verb. Cap: 1,536 chars combined with when_to_use — over-budget text clips in the listing and silently degrades routing.
  • Declare model: explicitlyclaude-fable-5 for the rare, highest-leverage harness writes whose output loads everywhere (authoring skills, trimming always-on context: occasional cadence × compounding blast radius justifies the 2× opus cost); opus when the skill reasons or writes harness-important artifacts (rules, specs, plans, audits); sonnet for mechanical task execution; inherit when unsure. Valid values are bare aliases (opus/sonnet/haiku/fable), full versioned ids (claude-fable-5), or inherit — a bare prefixed alias like claude-opus is not a model id; the runtime rejects it (harness:check --fix strips the prefix). Never leave the choice implicit.
  • Renamed? Keep (formerly old-name) at the start of the description, so older notes and muscle memory still resolve.
  • No metadata.author on owned skills — that field is the marker that a skill is upstream-managed.
  • The full field list is references/frontmatter.mdwhen_to_use, paths (native glob-scoped auto-load), argument-hint/arguments, invocation control (disable-model-invocation also blocks agent skills: preload), context: fork + agent, allowed-tools/disallowed-tools, effort, per-skill hooks. Skim it before writing frontmatter — reach for a field instead of re-inventing it in prose.
  • Ships with an agent? Same explicit-model rubric, plus color by role — green writes · red gates · yellow diverges · purple converges · cyan researches (table in references/frontmatter.md).

Body — house style

  • Terse, optimise for the next reader. Why-not-what comments (.claude/rules/code-quality.md).
  • Name the heart: mark the one step that carries the skill — "This is the skill." — and say where to spend disproportionate effort. Exception: fyi-/reference skills are deliberately flat.
  • Any skill that writes or acts outward (files issues, saves to memory, pushes, posts) is surface-then-confirm: propose candidates, let the user pick, never act unprompted. Mirror find-untracked-work (issues) and find-learnings (memory).
  • Cross-reference sibling skills by name; on a rename, update every reference (next section).

Wiring the trigger — when should Claude run it?

Three layers, strongest determinism first:

  1. description — sharp Use when… phrasing for auto-invocation. Always do this.
  2. .claude/hooks/suggest-skills.sh — for "after/before tool X" boundaries, add a branch keyed on a PreToolUse/PostToolUse event, boundary-anchored (at_boundary) so it fires on a real invocation, not the phrase appearing as data. Register the tool matcher in .claude/settings.json. The hook only nudges; Claude still applies judgment.
  3. Skill-chaining — for phase handoffs with no clean event (e.g. brainstorm → issues), have the upstream skill end by pointing at this one.

Joining the check-everything sweep

A sweep-eligible skill (qa- / optimise- / find- / check-) should usually join check-everything. When you create one:

  1. Ask the category — Work / Thinking-Planning / Brain / Housekeeping, or none (a genuinely targeted-only check). Add it to that category's list in check-everything.
  2. Show the current run order as a numbered list and ask where it slots. check-everything runs in a fixed, dependency-aware order (not category order), so position matters — e.g. an optimisation pass runs after its conformance check; a context-trim runs after the docs are aligned. Insert it and renumber.
  3. Add an applicability note (the needs a diff / merged branches / a plan / … gate) so the sweep skips it when it doesn't apply.

Skip this only if the skill genuinely shouldn't run in a full health sweep — and say why.

After creating or renaming

  1. Run the gates. A standalone / taxonomy-exempt / over-cap name must be allow-listed in config/harness.php (standalone_skills / taxonomy_exempt / line_cap_exempt); any config/harness.php edit then needs php artisan harness:export-config (the committed dashboard snapshot is sync-tested). Finish with php artisan harness:check green locally — CI's Harness-integrity job runs exactly this and fails the PR otherwise.
  2. Update every cross-referencegrep -rn '<old-name>' .claude docs CLAUDE.md harness-dashboard/philosophy (mind that a new name can contain the old token, e.g. fyi-tempo-domaintempo-domain — filter those out). The harness-dashboard/philosophy/* pages are hand-authored and link skills/agents by name — the dashboard drift-check fails the build on a stale wiki link, so fix them in the same change. A new skill rarely needs a narrative mention, but if it introduces a concept a philosophy page should cover, run qa-wiki to catch that drift.
  3. Update the docs it appears in — docs/learnings/README.md, docs/agents/skill-quality.md, the hook nudges, and CLAUDE.md if referenced. If the skill is authored on an external base / adapted from a source, add a row to docs/agents/sources.md (alongside the (formerly upstream/<name>) provenance marker).
    • Glossary: write the skill in the harness's pinned vocabulary (docs/agents/glossary.md) — reuse existing terms, don't coin a synonym. If the skill introduces a genuinely new harness concept, add it to the glossary here.
  4. Verify: name: == dir; the /-menu lists it; it triggers on its phrases.
  5. Keep the set tight. A skill you never fire is debt — prune before you accrete (we cut 11 unfitting packs for this reason). Don't add a near-duplicate of an existing skill.

Scaffold

.claude/skills/<prefix-name>/
  SKILL.md            # required — frontmatter + body
  references/         # optional — long reference material the body links to

Start from the closest existing owned skill of the same prefix and mirror its shape rather than inventing structure.