SKILL.md
Spec-Driven Development
Code without a spec is guessing. The spec is the shared source of truth: what we build, why, and how we know it is done. Every misunderstanding it surfaces before code is hours of rework you skip.
The gated workflow
Four phases. The human reviews the output of each phase before you advance. No skipping.
| Phase | Output | Gate |
|---|---|---|
| 1. Specify | Spec file in the repo | Human approves the spec |
| 2. Plan | Technical plan (tasks/plan.md) | Human approves the approach |
| 3. Tasks | Task list (tasks/todo.md) | Human approves the breakdown |
| 4. Implement | Working code, task by task | Tests and review per task |
Phase 1: Specify
- List your assumptions first. Before writing spec content, print them and ask for corrections:
ASSUMPTIONS:
1. Web app, not native mobile
2. Auth is session cookies, not JWT
3. Database is PostgreSQL (existing schema suggests it)
Correct me now or I proceed with these.Silent assumption-filling is the most dangerous failure mode this skill exists to prevent.
- Reframe vague requirements as testable success criteria. "Make the dashboard faster" becomes "LCP under 2.5s on 4G, initial data load under 500ms, CLS under 0.1. Are these the right targets?"
- Write the spec covering six areas: objective, commands (full executable commands with flags, not tool names), project structure, code style (one real snippet beats three paragraphs), testing strategy, and boundaries. Boundaries use three tiers: always do, ask first, never do.
Read references/spec-template.md for the full spec skeleton and a worked boundaries example.
- Save the spec in the repo and commit it. A spec in chat scrollback is not a spec.
Phase 2: Plan
From the approved spec, produce a technical plan: major components and dependencies, build order, risks with mitigations, what can parallelize, verification checkpoints between phases. Save to tasks/plan.md. The bar: the human can read it and say "right approach" or "change X".
Phase 3: Tasks
Break the plan into tasks. Each task: completable in one focused session, explicit acceptance criteria, a verification step (test command, build, manual check), ordered by dependency, touches no more than ~5 files. Save to tasks/todo.md.
- [ ] Task: <description>
- Acceptance: <what must be true when done>
- Verify: <exact command or check>
- Files: <paths touched>Phase 4: Implement
Execute tasks one at a time. Follow test-driven-development for each. Load only the spec sections and files the current task needs, not the whole document.
Keep the spec alive
- Decision changes: update the spec first, then implement.
- Scope changes: added or cut features get reflected in the spec.
- Reference the spec section each PR implements.
An outdated spec is still better than no spec, but only barely. Update it.
Good vs bad
Bad: User says "add rate limiting". You pick a library, write middleware, and ask afterwards whether per-user or per-IP was intended. Half the work is wrong.
Good: User says "add rate limiting". You write a five-line spec: per-user, 100 req/min, 429 with Retry-After, Redis-backed, tested with a burst script. User corrects one number. You implement once.
Verification
Do this before entering Phase 4. Run ls tasks/plan.md tasks/todo.md and open the spec file. Expect: all three files exist, the spec covers all six areas, success criteria are testable, and you have an explicit human approval message for the spec. If any is missing, go back to the phase that produces it. No approval message means Phase 1 is not done, regardless of how good the spec looks.
Completion checklist
- [ ] Assumptions listed and confirmed before spec writing
- [ ] Spec covers all six areas and is committed to the repo
- [ ] Success criteria are specific and testable
- [ ] Boundaries defined (always / ask first / never)
- [ ] Human approved spec, plan, and task list at each gate
- [ ] Implementation followed the task list, nothing off-spec
Any box unchecked: not done. Fix or say so.
Footguns
- Spec written after the code. That is documentation, not specification. Its entire value is forcing clarity before code. If code exists first, stop, write the spec, and diff the code against it.
- Features creep in that no task mentions. Every implemented behavior must trace to a task. Untraceable behavior gets removed or the spec gets amended first.
- The two-line-spec dodge. Simple tasks do not need long specs, but they still need acceptance criteria. Two lines is fine. Zero lines is not.
Red flags
Stop when you catch yourself saying any of these:
- "This is simple, I don't need a spec"
- "I'll write the spec after I code it"
- "The spec will slow us down"
- "Requirements will change anyway"
- "It's obvious what to build"
- "Should I just start building?"
All of these mean the same thing: you are about to guess. Rephrasing the excuse does not license the shortcut; if code precedes an approved spec, the gate is blown.