The one doc to read before building a claude-mods skill. It sequences the whole lifecycle — is-it-warranted → frontmatter → body → resources → tests → repo wiring → ship — and points to the adjacent docs that own each layer. It restates none of them: each step cites its authority and adds only the repo-specific fact that lives nowhere else.
How to use this. Read top to bottom once. Follow the steps in order; skip a step only when there's a clear reason it doesn't apply. Where a step says "→ see X", X is the single source of truth for that layer — go there for detail, come back here for sequence.
Adjacent docs this protocol orchestrates:
| Layer | Authority | Owns |
|---|---|---|
| Authoring method | skill-creator skill (Skill tool) |
concrete-examples → plan → init → edit → package → iterate; description-as-trigger; progressive disclosure |
| Frontmatter fields | SKILL-SUBAGENT-REFERENCE.md | allowed top-level keys, metadata block, license/author rules |
| Naming & layout | naming-conventions.md | -ops suffix, kebab-case, the three subdirs |
| Resource contract | SKILL-RESOURCE-PROTOCOL.md | scripts/assets/references: streams, exit codes, --help, --json, staleness verifier |
| Terminal output | TERMINAL-DESIGN.md | TTY glyphs/panels via skills/_lib/term.sh |
When two sources disagree, this table decides which one wins for that layer. The
notable case: the bundled skill-creator says "name + description only, no other
frontmatter fields" — that is Anthropic's portable default. In this repo,
SKILL-SUBAGENT-REFERENCE overrides it (we require license + metadata.author).
→ method: skill-creator Steps 1–2 (work concrete usage examples first, then plan the
reusable contents).
Repo-specific gates before you scaffold anything:
uv"), it's a rule (rules/), not a skill.
If it's context-isolation/worker behaviour, it may be an agent (agents/). See
ARCHITECTURE.md for the skill-vs-rule-vs-agent split.skills/ first; prefer extending one.-ops suffix (→ naming-conventions).→ method: skill-creator Step 3 (init_skill.py).
The skill directory MUST contain scripts/, references/, and assets/ — create them
even if empty, with a .gitkeep (→ naming-conventions, "Directory Structure"). The
directory name is kebab-case and matches the frontmatter name exactly.
→ authority: SKILL-SUBAGENT-REFERENCE.md — read its "Allowed Top-Level Fields" table; it is the only legal field list.
claude-mods house rules layered on top (checklist, not a restatement):
license: MIT (exception: skill-creator keeps its custom license)metadata.author: claude-modsdepends-on / related-skills live under metadata as comma-separated
strings — never arrays, never top-level. Omit entirely if empty.name matches the directory.→ authority: skill-creator ("Progressive Disclosure", "What to Not Include").
The load-bearing rules it owns: the description is the trigger (put every "when to
use" cue there, never in the body); keep the body under 500 lines; split detail into
references/*.md (one concept per file, linked from SKILL.md); don't ship
README/CHANGELOG/INSTALL files inside a skill.
→ authority: SKILL-RESOURCE-PROTOCOL.md — its §10 compliance checklist is the gate for anything executable.
In one line: stdout is data-only, semantic exit codes, --help with an EXAMPLES section,
the first-comment-block contract, validate agent-supplied input. Every reference/asset
must be cited from SKILL.md or it's dead weight the router never finds. If the skill
encodes fast-moving external facts (model IDs, API params, action versions), ship the
--offline/--live staleness verifier (§7) so drift trips a tripwire instead of
rotting. TTY output → TERMINAL-DESIGN.md.
Add tests/run.sh — an offline, self-contained behavioural suite that exits nonzero
on any failure and prints a skip message (exit 0) on unsupported platforms. Pattern after
skills/supply-chain-defense/tests/run.sh.
No registration needed: tests/run-skill-tests.sh globs
skills/*/tests/run.sh and runs them all in CI. If the skill ships a verifier script,
also add an offline-mode assertion to tests/check-resources.sh
(PR CI, may block); its --live mode runs in the scheduled
freshness.yml, never blocking a PR.
tests/doc-drift.sh blocks CI unless docs match disk. Before you
commit:
skills/<name>/ must appear in README.md (the
gate requires one row per skill).README.md, AGENTS.md, and docs/PLAN.md (skills
total).tests/validate.sh passes (frontmatter + naming).claude plugin validate passes — gate on the official validator, never a
hand-rolled reimplementation.skill-creator Step 5 package_skill.py if a distributable .skill is needed.feat(skills): …).0 warranted? → skill-creator §1-2 + ARCHITECTURE (skill vs rule vs agent)
1 scaffold → skill-creator init_skill.py; 3 subdirs (naming-conventions)
2 frontmatter → SKILL-SUBAGENT-REFERENCE (+ license:MIT, metadata.author)
3 body → skill-creator (description=trigger, <500 lines, progressive disclosure)
4 resources → SKILL-RESOURCE-PROTOCOL (§10 gate; staleness verifier if external facts)
5 tests → tests/run.sh → run-skill-tests.sh; verifier → check-resources.sh
6 integrate → doc-drift.sh: README row + count bumps + no ghost links
7 ship → validate.sh + claude plugin validate + package + commit
This doc owns the sequence and the test/CI/counts bookend. Everything else is owned by the adjacent doc named at each step — read that doc for depth, this one for order.