Skills Engineering
This skill teaches an agent how to author, evaluate, and iteratively improve Agent Skills. It follows a rigorous TDD lifecycle with nine phases. Each phase has one job. Each phase's output feeds the next phase's red state.
Do not reference this file for phase instructions. Call scripts/generate.sh — the script output is the guidance.
Phase routing
| # |
Phase |
TDD state |
Job |
| 1 |
spec |
— |
Declare intent, boundaries, and script contracts in spec.md |
| 2 |
behavioral |
Red |
Write BDD contracts: Given X, When skill activates, Then agent does Y |
| 3 |
script-test |
Red |
Write acceptance tests for every script before the scripts exist |
| 4 |
script |
Green |
Write scripts AC-by-AC until tests pass |
| 5 |
skill |
Green |
Write SKILL.md + references to pass behavioral tests |
| 6 |
adversary |
Red |
Write boundary attacks now that the skill's surface is known |
| 7 |
eval |
Assert |
Full run: script tests → behavioral → adversarial. Grade and aggregate. |
| 8 |
improve |
— |
Fix failures from eval, loop back to eval |
| 9 |
refactor |
— |
Clean up internal structure without changing behavior (optional) |
How to invoke
bash skills/skills-engineering/scripts/generate.sh \
--phase <spec|behavioral|script-test|script|skill|adversary|eval|improve|refactor> \
--skill-path .agents/skills/<skill-name>
The script emits a targeted prompt and the next phase name. Follow its output — it handles tier detection, test set selection, and phase sequencing. The LLM never sees cross-phase content.
Skill directory layout
<skill-name>/
├── SKILL.md # Required: YAML frontmatter + instructions
├── spec.md # Lightweight intent + script contracts
├── references/ # Documentation loaded on demand
├── scripts/ # Executable code (Bash, Python)
├── assets/ # Templates, images, data files
└── tests/
├── behavioral-tests.json # BDD: Given/When/Then behavioral contracts
├── adversarial-tests.json # Boundary attacks
├── smoke-tests.json # Fast subset for trivial changes
└── test-<script>.sh # Acceptance tests for each script
Progressive disclosure in skill design
- Metadata (name + description) — loaded at startup. Teaches the agent when to use the skill.
- SKILL.md body — loaded on activation. Route to references for detail, don't embed everything.
- References — loaded on demand. Encyclopedic knowledge, schemas, detailed procedures.
Complexity tiers
The phase router detects change scope and selects the appropriate test level:
| Tier |
Trigger |
Tests |
| Smoke |
Typo, wording change, single-line non-structural edit |
smoke-tests.json |
| Behavioral |
Adding references, modifying workflows, changing phase instructions |
behavioral-tests.json |
| Full |
Routing table changes, phase additions/removals, spec.md changes, structural rework |
behavioral-tests.json + adversarial-tests.json |
Key design principles
- Every script gets TDD. Write acceptance tests first (script-test phase), then implement AC-by-AC (script phase). Scripts are code — same discipline as
.py or .sh.
- Code-based pre-grading catches deterministic failures. Test JSON supports
assert_sh — shell assertions that run before LLM grader dispatch. If any assertion fails, the test fails immediately without a subagent call.
- Adversarial tests come after the skill exists. You can't write effective boundary attacks against a skill you haven't read. The adversary phase studies the concrete skill and crafts targeted attacks.
- The context window is the API. Phase isolation protects context. Authoring never sees eval criteria. Eval never sees authoring instructions.
- Skills are code. Skill files are markdown syntax. Non-trivial edits require worktree isolation.
- Description is the trigger. The
description field is the primary discovery mechanism. Write it to describe both what the skill does and when to use it.
- Behavioral expectations live in the skill, not in agent memory. When a user gives feedback about how a skill should behave (output format, required sections, mandatory steps, prohibitions), that requirement MUST be encoded in
SKILL.md, a referenced file, or a script/template inside the skill directory. NEVER store it as agent memory — memory is invisible to other consumers of the skill (other users, other sessions, CI runs). If you find yourself reaching for the memory tool to record a skill's required behavior, stop and update the skill instead. Memory is for cross-skill, cross-project preferences about how the operator wants to collaborate; skills carry their own behavioral contracts.
- Shaped outputs get a Jinja2 template. When a skill produces structured/formatted output (summaries, reports, documents, serialized data), place a Jinja2 template in
assets/ that declaratively defines the output shape — variable slots ({{ var }}), conditionals ({% if %}), and loops ({% for %}). Agents default to manually writing output that follows the template, without requiring a full data-collection-and-render pipeline.
1---2name: skills-engineering3description: Author, evaluate, and iteratively improve Agent Skills (SKILL.md protocol) using a rigorous TDD lifecycle. Handles spec declaration, BDD behavioral contract authoring, script TDD (red-green per acceptance criterion), SKILL.md authoring, adversarial boundary testing, full eval with subagent-driven grading, improvement loops, and optional refactoring. Use when creating a new skill, evaluating an existing skill, improving a skill from eval feedback, or engineering the SKILL.md structure.4license: MIT5---67# Skills Engineering89This skill teaches an agent how to **author, evaluate, and iteratively improve** Agent Skills. It follows a rigorous TDD lifecycle with nine phases. Each phase has one job. Each phase's output feeds the next phase's red state.1011Do not reference this file for phase instructions. Call `scripts/generate.sh` — the script output is the guidance.1213## Phase routing1415| # | Phase | TDD state | Job |16|---|-------|-----------|-----|17| 1 | **spec** | — | Declare intent, boundaries, and script contracts in spec.md |18| 2 | **behavioral** | Red | Write BDD contracts: `Given X, When skill activates, Then agent does Y` |19| 3 | **script-test** | Red | Write acceptance tests for every script before the scripts exist |20| 4 | **script** | Green | Write scripts AC-by-AC until tests pass |21| 5 | **skill** | Green | Write SKILL.md + references to pass behavioral tests |22| 6 | **adversary** | Red | Write boundary attacks now that the skill's surface is known |23| 7 | **eval** | Assert | Full run: script tests → behavioral → adversarial. Grade and aggregate. |24| 8 | **improve** | — | Fix failures from eval, loop back to eval |25| 9 | **refactor** | — | Clean up internal structure without changing behavior (optional) |2627## How to invoke2829```bash30bash skills/skills-engineering/scripts/generate.sh \31 --phase <spec|behavioral|script-test|script|skill|adversary|eval|improve|refactor> \32 --skill-path .agents/skills/<skill-name>33```3435The script emits a targeted prompt and the next phase name. Follow its output — it handles tier detection, test set selection, and phase sequencing. The LLM never sees cross-phase content.3637## Skill directory layout3839```40<skill-name>/41├── SKILL.md # Required: YAML frontmatter + instructions42├── spec.md # Lightweight intent + script contracts43├── references/ # Documentation loaded on demand44├── scripts/ # Executable code (Bash, Python)45├── assets/ # Templates, images, data files46└── tests/47 ├── behavioral-tests.json # BDD: Given/When/Then behavioral contracts48 ├── adversarial-tests.json # Boundary attacks49 ├── smoke-tests.json # Fast subset for trivial changes50 └── test-<script>.sh # Acceptance tests for each script51```5253## Progressive disclosure in skill design54551. **Metadata** (name + description) — loaded at startup. Teaches the agent *when* to use the skill.562. **SKILL.md body** — loaded on activation. Route to references for detail, don't embed everything.573. **References** — loaded on demand. Encyclopedic knowledge, schemas, detailed procedures.5859## Complexity tiers6061The phase router detects change scope and selects the appropriate test level:6263| Tier | Trigger | Tests |64|------|---------|-------|65| **Smoke** | Typo, wording change, single-line non-structural edit | smoke-tests.json |66| **Behavioral** | Adding references, modifying workflows, changing phase instructions | behavioral-tests.json |67| **Full** | Routing table changes, phase additions/removals, spec.md changes, structural rework | behavioral-tests.json + adversarial-tests.json |6869## Key design principles7071- **Every script gets TDD.** Write acceptance tests first (script-test phase), then implement AC-by-AC (script phase). Scripts are code — same discipline as `.py` or `.sh`.72- **Code-based pre-grading catches deterministic failures.** Test JSON supports `assert_sh` — shell assertions that run before LLM grader dispatch. If any assertion fails, the test fails immediately without a subagent call.73- **Adversarial tests come after the skill exists.** You can't write effective boundary attacks against a skill you haven't read. The adversary phase studies the concrete skill and crafts targeted attacks.74- **The context window is the API.** Phase isolation protects context. Authoring never sees eval criteria. Eval never sees authoring instructions.75- **Skills are code.** Skill files are markdown syntax. Non-trivial edits require worktree isolation.76- **Description is the trigger.** The `description` field is the primary discovery mechanism. Write it to describe both what the skill does and when to use it.77- **Behavioral expectations live in the skill, not in agent memory.** When a user gives feedback about how a skill should behave (output format, required sections, mandatory steps, prohibitions), that requirement MUST be encoded in `SKILL.md`, a referenced file, or a script/template inside the skill directory. NEVER store it as agent memory — memory is invisible to other consumers of the skill (other users, other sessions, CI runs). If you find yourself reaching for the memory tool to record a skill's required behavior, stop and update the skill instead. Memory is for cross-skill, cross-project preferences about *how the operator wants to collaborate*; skills carry their own behavioral contracts.78- **Shaped outputs get a Jinja2 template.** When a skill produces structured/formatted output (summaries, reports, documents, serialized data), place a Jinja2 template in `assets/` that declaratively defines the output shape — variable slots (`{{ var }}`), conditionals (`{% if %}`), and loops (`{% for %}`). Agents default to manually writing output that follows the template, without requiring a full data-collection-and-render pipeline.