|
| 1 | +# Skill authoring patterns |
| 2 | + |
| 3 | +Conventions every fleet skill follows. Reference from new-skill scaffolds and from auditor agents. |
| 4 | + |
| 5 | +## Modular structure |
| 6 | + |
| 7 | +A skill's `SKILL.md` is the **orchestrator**, not the encyclopedia. When a skill grows past ~300 lines or covers more than one phase / tool / domain, push the depth into siblings: |
| 8 | + |
| 9 | +``` |
| 10 | +.claude/skills/ |
| 11 | +├── _shared/ |
| 12 | +│ ├── <topic>.md # shared prose loaded on demand by multiple skills |
| 13 | +│ └── scripts/ |
| 14 | +│ └── <helper>.mts # shared TS helpers used by per-skill run.mts files |
| 15 | +└── my-skill/ |
| 16 | + ├── SKILL.md # ≤ 300 lines, table of contents + decision flow |
| 17 | + ├── reference.md # long-form prose Claude reads (single file, growable to a dir) |
| 18 | + ├── scans/<type>.md # one file per scan type / phase / tool (when many) |
| 19 | + ├── templates/ # file scaffolding copied verbatim by install/setup modes |
| 20 | + │ └── <name>.tmpl |
| 21 | + └── run.mts # skill-specific executable runner |
| 22 | +``` |
| 23 | + |
| 24 | +Two naming conventions are load-bearing: |
| 25 | + |
| 26 | +- **`lib/` vs `scripts/`** matches the fleet's public-vs-private convention. `lib/` names a public, importable, stable surface (think `@socketsecurity/lib`); `scripts/` names private, internal automation that's not consumed outside the host repo. Skill helpers under `_shared/scripts/` are internal automation — no external consumers — so `scripts/` is the right name. (No `_shared/lib/` exists in this tree.) |
| 27 | +- **`reference.md` vs `reference/`** — single file by default; grow to a directory only when a skill genuinely has multiple distinct reference docs. Don't preemptively wrap a single doc in a dir. |
| 28 | +- **`templates/`** is reserved for file scaffolding (`.tmpl` files copied verbatim by `install` / `setup` modes). Don't mix templates into `reference/` — readers can't tell prose from scaffolding by directory name alone. |
| 29 | + |
| 30 | +The same File-size rule from CLAUDE.md applies — soft cap 500, hard cap 1000 — but for skills the trigger is usually **shape**, not lines: as soon as the SKILL.md is "this and also that and also the other thing," extract. |
| 31 | + |
| 32 | +What goes where: |
| 33 | + |
| 34 | +| Path | Purpose | |
| 35 | +|---|---| |
| 36 | +| `<skill>/SKILL.md` | Orchestrator: when to use, modes, phase list, links to deeper files. Reads top-to-bottom in one screen. | |
| 37 | +| `<skill>/reference.md` | Long-form depth: bash blocks, full validation rules, sample outputs, recovery procedures. Loaded by the orchestrator when a phase needs it. | |
| 38 | +| `<skill>/scans/`, `phases/`, `tools/` | One file per discrete unit when the skill enumerates many (e.g., `scanning-quality/scans/<type>.md`). Adding a new unit = one new file, no SKILL.md touch. | |
| 39 | +| `<skill>/templates/<name>.tmpl` | File scaffolding (`.tmpl` files copied verbatim by `install` / `setup` modes — gate scripts, allowlist starters, etc.). Distinct from `reference.md` which is prose, not scaffolding. | |
| 40 | +| `<skill>/run.mts` | Skill-specific executable runner. Inline prompts so prompts and code can't drift. Per CLAUDE.md _Tooling — Runners are `.mts`, not `.sh`_. | |
| 41 | +| `_shared/<topic>.md` | Shared **prose** (variant-analysis discipline, compound-lessons workflow, multi-agent backends). Cross-skill load surface. | |
| 42 | +| `_shared/scripts/<helper>.mts` | Shared **TypeScript** helpers imported by per-skill `run.mts` (default-branch resolution, report formatting, spawn wrappers). Internal automation — not a public library, hence `scripts/` not `lib/`. Use `@socketsecurity/lib/spawn` for subprocesses, never raw `node:child_process`. | |
| 43 | + |
| 44 | +## Auditor agents |
| 45 | + |
| 46 | +Skills that author other artifacts (skills, hooks, slash commands, subagents) should ship an auditor sibling. The pattern: |
| 47 | + |
| 48 | +1. The authoring skill emits a draft. |
| 49 | +2. An auditor agent (separate prompt, narrower tool surface) reviews against a checklist. |
| 50 | +3. The authoring skill applies the auditor's feedback before shipping. |
| 51 | + |
| 52 | +Three audit dimensions per artifact: |
| 53 | + |
| 54 | +| Artifact | Auditor checks | |
| 55 | +|---|---| |
| 56 | +| Skill | frontmatter complete, when-to-use unambiguous, tool surface minimal, no buried opinions | |
| 57 | +| Hook | matcher tight, command exits fast, doesn't depend on session state, can't deadlock | |
| 58 | +| Slash command | argument shape clear, idempotent, doesn't touch shared state without confirmation | |
| 59 | +| Subagent | prompt self-contained (no "based on the conversation"), tool surface matches the task, return shape documented | |
| 60 | + |
| 61 | +A fleet skill that does this well is the canonical reference; the auditor is a `Task` agent spawned by the authoring skill, not a long-running daemon. |
| 62 | + |
| 63 | +## Compound-lessons capture |
| 64 | + |
| 65 | +When a fleet skill discovers a recurring failure mode — a lint rule that catches the same kind of bug, a hook that blocks the same antipattern, a review pass that flags the same regression — codify it once: |
| 66 | + |
| 67 | +1. Open a follow-up to add the rule to CLAUDE.md, the hook, or the skill prompt. |
| 68 | +2. Reference the original incident (commit, PR, finding ID) in a one-line `**Why:**` so future readers know the rule is load-bearing. |
| 69 | +3. Resist the urge to write a full retrospective doc — the fleet rule **is** the retrospective. |
| 70 | + |
| 71 | +This is the fleet's equivalent of a post-mortem: every recurring bug becomes a rule, every rule earns its place by closing a class of bugs. The principle is _compound engineering_: each unit of work makes the next unit easier. |
| 72 | + |
| 73 | +## When to NOT extract |
| 74 | + |
| 75 | +- One-off skill (≤ 100 lines, single phase, single tool) — keep it monolithic. |
| 76 | +- Code unique to one repo that can't be shared — keep it in that repo's `unique` skill. |
| 77 | +- Prompt that's tightly coupled to its caller — inline, don't split. |
| 78 | + |
| 79 | +The principle: **a reader should be able to predict what's in a skill from its name, and find what they need without scrolling past three other concerns.** Same as the File-size rule, applied to skills. |
| 80 | + |
| 81 | +## Frontmatter requirements (from upstream) |
| 82 | + |
| 83 | +The Anthropic docs codify several rules; honor them: |
| 84 | + |
| 85 | +- `name`: ≤ 64 chars, lowercase letters / numbers / hyphens only. No `anthropic` / `claude` substring. |
| 86 | +- `description`: ≤ 1024 chars, third-person voice (`"Manages X"`, not `"I help with X"` or `"You can use this to X"`). Include both **what** and **when to use**. |
| 87 | +- Prefer **gerund form** for the name (`processing-pdfs`, `scanning-quality`); noun-phrase (`pdf-processing`) and verb-imperative (`process-pdfs`) are acceptable alternatives, but pick one and be consistent across the fleet. |
| 88 | +- Use forward slashes in any path the skill references — never backslashes, even in docs that target Windows users. |
| 89 | + |
| 90 | +## References |
| 91 | + |
| 92 | +Authoritative upstream docs — keep these as the source of truth, mirror their guidance here only when fleet specifics demand it: |
| 93 | + |
| 94 | +- [Anthropic — Skill authoring best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) — frontmatter rules, progressive disclosure, evaluation-driven development. |
| 95 | +- [Anthropic — Claude Code best practices: writing an effective CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md) — CLAUDE.md scope, pruning discipline, when to push knowledge into a skill instead. |
| 96 | +- [Anthropic — Prompt engineering best practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices) — model-tuning, response-length calibration, examples-over-descriptions. |
| 97 | + |
| 98 | +Real-world plugin reference (not fleet-canonical, useful as a worked example of skills + hooks + templates working together): [`arscontexta`](https://github.com/agenticnotetaking/arscontexta) — knowledge-system plugin that derives skills/hooks/templates from a conversational setup. Useful as a study of the "skills compose into a system" pattern. |
0 commit comments