Writing Skills
<activation>When This Skill Activates
- Creating a new skill (SKILL.md file)
- Editing or improving an existing skill
- Verifying a skill works before deployment
- Reviewing skill quality or effectiveness
Natural Language Triggers
- "create a skill", "write a skill", "new skill", "improve this skill"
Overview
Writing skills IS Test-Driven Development applied to process documentation.
Personal skills live in agent-specific directories (~/.claude/skills for Claude Code, ~/.codex/skills for Codex)
You write test cases (pressure scenarios with subagents), watch them fail (baseline behavior), write the skill (documentation), watch tests pass (agents comply), and refactor (close loopholes).
Core principle: If you didn't watch an agent fail without the skill, you don't know if the skill teaches the right thing.
REQUIRED BACKGROUND: You MUST understand shipyard:shipyard-tdd before using this skill. That skill defines the fundamental RED-GREEN-REFACTOR cycle. This skill adapts TDD to documentation.
What is a Skill?
A skill is a reference guide for proven techniques, patterns, or tools. Skills help future Claude instances find and apply effective approaches.
Skills are: Reusable techniques, patterns, tools, reference guides
Skills are NOT: Narratives about how you solved a problem once
<instructions>TDD Mapping for Skills
| TDD Concept | Skill Creation |
|---|---|
| Test case | Pressure scenario with subagent |
| Production code | Skill document (SKILL.md) |
| Test fails (RED) | Agent violates rule without skill (baseline) |
| Test passes (GREEN) | Agent complies with skill present |
| Refactor | Close loopholes while maintaining compliance |
| Write test first | Run baseline scenario BEFORE writing skill |
| Watch it fail | Document exact rationalizations agent uses |
| Minimal code | Write skill addressing those specific violations |
| Watch it pass | Verify agent now complies |
| Refactor cycle | Find new rationalizations -> plug -> re-verify |
The entire skill creation process follows RED-GREEN-REFACTOR.
When to Create a Skill
Create when:
- Technique wasn't intuitively obvious to you
- You'd reference this again across projects
- Pattern applies broadly (not project-specific)
- Others would benefit
Don't create for:
- One-off solutions
- Standard practices well-documented elsewhere
- Project-specific conventions (put in CLAUDE.md)
- Mechanical constraints (if it's enforceable with regex/validation, automate it -- save documentation for judgment calls)
Skill Types
Technique
Concrete method with steps to follow (condition-based-waiting, root-cause-tracing)
Pattern
Way of thinking about problems (flatten-with-flags, test-invariants)
Reference
API docs, syntax guides, tool documentation (office docs)
Directory Structure
skills/
skill-name/
SKILL.md # Main reference (required)
supporting-file.* # Only if needed
Flat namespace - all skills in one searchable namespace
Separate files for:
- Heavy reference (100+ lines) - API docs, comprehensive syntax
- Reusable tools - Scripts, utilities, templates
Keep inline:
- Principles and concepts
- Code patterns (< 50 lines)
- Everything else
SKILL.md Structure
Frontmatter (YAML):
- Only two fields supported:
nameanddescription - Max 1024 characters total
name: Use letters, numbers, and hyphens only (no parentheses, special chars)description: Third-person, describes ONLY when to use (NOT what it does)- Start with "Use when..." to focus on triggering conditions
- Include specific symptoms, situations, and contexts
- NEVER summarize the skill's process or workflow (see CSO section for why)
- Keep under 500 characters if possible
---
name: Skill-Name-With-Hyphens
description: Use when [specific triggering conditions and symptoms]
---
# Skill Name
## Overview
What is this? Core principle in 1-2 sentences.
## When to Use
Bullet list with SYMPTOMS and use cases
When NOT to use
## Core Pattern (for techniques/patterns)
Before/after code comparison
## Quick Reference
Table or bullets for scanning common operations
## Implementation
Inline code for simple patterns
Claude Search Optimization (CSO) — Quick Reference
| Element | Rule | Example |
|---|---|---|
| Description | Triggering conditions only, no workflow | "Use when tests hang waiting for async ops" |
| Keywords | Error messages, symptoms, tool names | "ENOTEMPTY", "flaky", "bats-core" |
| Name | Verb-first, hyphenated | condition-based-waiting not async-helpers |
| Token budget | <150 words getting-started, <500 words others | Compress, cross-reference |
| Cross-refs | Skill name + requirement marker, no @ links | **REQUIRED SUB-SKILL:** Use shipyard:foo |
Why no @ links: @ syntax force-loads files immediately, consuming context tokens you may not need yet.
Critical CSO rule — Description = When to Use, NOT What the Skill Does: When a description summarizes the skill's workflow, Claude follows the description instead of reading the full skill. A description saying "code review between tasks" caused Claude to do ONE review even though the skill showed TWO stages. Keep descriptions as triggering conditions only.
Flowchart Usage
Use flowcharts ONLY for:
- Non-obvious decision points
- Process loops where you might stop too early
- "When to use A vs B" decisions
Never use flowcharts for reference material, code examples, linear instructions, or labels without semantic meaning.
Code Examples
One excellent example beats many mediocre ones
Choose most relevant language (testing → TypeScript/JS, system debug → Shell/Python, data → Python).
Good example: complete, runnable, well-commented WHY, from real scenario, ready to adapt.
Don't: implement in 5+ languages, create fill-in-the-blank templates, write contrived examples.
File Organization
| Pattern | Structure | When |
|---|---|---|
| Self-contained | SKILL.md only | All content fits |
| With reusable tool | SKILL.md + example.ts | Tool is reusable code |
| With heavy reference | SKILL.md + ref.md + scripts/ | Reference too large for inline |
CSO Description Examples
<example type="good" title="Triggering conditions only, no workflow summary"> ```yaml description: Use when executing implementation plans with independent tasks in the current session ``` Just triggering conditions -- Claude reads the full skill to learn the workflow. </example> <example type="bad" title="Workflow summary in description"> ```yaml description: Use when executing plans - dispatches subagent per task with code review between tasks ``` Summarizes workflow -- Claude follows description instead of reading skill body, misses two-stage review. </example>Skill Content Examples
<example type="good" title="Well-structured skill with XML tags and clear activation"> ```markdown --- name: condition-based-waiting description: Use when tests need to wait for async operations, processes, or state changes instead of using arbitrary sleep/timeouts --- <activation> ## When This Skill Activates - Tests using sleep(), setTimeout(), or fixed delays - Flaky tests that pass/fail based on timing - Waiting for processes, servers, or async state </activation> <instructions> ## Core Pattern Poll for condition instead of sleeping... </instructions> <rules> ## Never - Use fixed sleep() in tests - Assume operation completes in N seconds </rules> ``` Clear activation, XML structure, rules separated. </example> <example type="bad" title="Missing structure, narrative style"> ```markdown # Waiting in TestsLast week I was working on a project where tests were flaky. I found t