Skip to content

Commit 9a395e7

Browse files
committed
chore: add spec driven development docs
1 parent db18e47 commit 9a395e7

2 files changed

Lines changed: 322 additions & 2 deletions

File tree

.agents/skills/writing-spec/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Collaborate on sections 4-6 of the template.
4949
Fill sections 7-10 of the template.
5050

5151
1. Break work into a **Task Breakdown** — ordered, independently testable tasks. Each task:
52-
- References building blocks from section 4
52+
- References building blocks from section 4 if any are involved
5353
- Traces to requirement IDs (R1, R2, …)
5454
- Includes target file paths
5555
- Is marked `[P]` (parallelizable) or `[S]` (sequential)
@@ -159,6 +159,6 @@ The spec is ready for implementation when:
159159

160160
## References
161161

162-
- `@docs/spec-template.md` — section structure and inline guidance
163162
- `.agents/skills/building-blocks/SKILL.md` — building block type dictionary (names, descriptions, when to use each)
163+
- `@docs/spec-template.md` — section structure and inline guidance
164164
- `@docs/architecture.md` — project structure, architectural decisions, conventions

docs/spec-driven-development.md

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
# Spec-Driven Development
2+
3+
This document describes how we use spec-driven development (SDD) in this codebase — what it is, why we use it, how the pieces fit together, and how to work within the system as a contributor.
4+
5+
## Why spec-driven development
6+
7+
AI coding agents are effective at writing code but unreliable at making design decisions. Without constraints, an agent will produce working code that doesn't fit the architecture, misses edge cases, or solves a different problem than intended. Spec-driven development addresses this by separating _what to build_ from _how to build it_.
8+
9+
The spec is a short document (80–150 lines) that captures intent, constraints, and sequencing _before_ any code is written. It serves three purposes:
10+
11+
1. **Reduces ambiguity** — the agent works from explicit behavioral requirements instead of inferring intent from vague prompts.
12+
2. **Creates traceability** — every requirement has an ID, every task traces to a requirement, so nothing gets lost or invented.
13+
3. **Keeps humans in control** — four review gates ensure the developer approves direction before implementation begins.
14+
15+
---
16+
17+
## When to use a spec
18+
19+
Not every change needs a spec. We use a three-tier complexity model:
20+
21+
| Tier | Trigger | Process |
22+
| ------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
23+
| **Quick fix** | Config edits, CSS fixes, helper functions, single-file changes, presentation-only changes | No spec. Just implement. |
24+
| **Plan mode** | 3+ steps or architectural decisions, but < 5 files and < 5 unconstrained decisions | Agent enters plan mode, outlines the approach, gets developer approval, then implements. No spec file created. |
25+
| **Full spec** | 5+ files, 5+ unconstrained decisions, or developer explicitly requests a spec | Use the `writing-spec` skill to collaboratively produce a `spec.md` before any code is written. |
26+
27+
The threshold is intentionally conservative — a spec adds 15–30 minutes of upfront work but prevents hours of rework when the agent builds the wrong thing.
28+
29+
---
30+
31+
## How the pieces fit together
32+
33+
The SDD system consists of six interconnected files:
34+
35+
```
36+
CLAUDE.md ← Agent behavior rules (plan mode, verification, self-improvement)
37+
docs/
38+
architecture.md ← Project structure, layers, dependency rules
39+
spec-template.md ← Section structure for spec documents
40+
specs/
41+
NNN-feature-name/
42+
spec.md ← Individual feature spec (produced by the workflow)
43+
lessons.md ← Accumulated learnings from past implementations
44+
skills/
45+
writing-spec/SKILL.md ← Four-phase gated workflow for writing specs
46+
building-blocks/
47+
SKILL.md ← Catalog index with short summaries
48+
rules/ ← One file per building block (full pattern + example)
49+
```
50+
51+
The flow between these files:
52+
53+
1. **CLAUDE.md** tells the agent _when_ to write a spec (5+ files or 5+ decisions) and establishes the plan-mode-first workflow.
54+
2. **writing-spec/SKILL.md** drives the _how_ — the four-phase collaborative process.
55+
3. **spec-template.md** provides the _structure_ — the section template that the spec fills in.
56+
4. **building-blocks/SKILL.md** provides the _vocabulary_ — typed building block names that the spec references in its Building Blocks Diff section.
57+
5. **architecture.md** provides the _context_ — project structure, layer rules, and state management patterns.
58+
6. **specs/lessons.md** provides _accumulated wisdom_ — patterns learned from past mistakes that feed back into future specs.
59+
60+
---
61+
62+
## The spec template
63+
64+
Every spec follows a fixed section structure defined in `docs/spec-template.md`. Here's what each section does and why:
65+
66+
### Meta (required)
67+
68+
Status tracking table — `draft``review``approved``implementing``done``archived`. Keeps the spec lifecycle visible.
69+
70+
### Section 1: Goal & Context (required)
71+
72+
2–5 sentences answering _what problem does this solve and why now_. Constrains intent, not approach. The agent reads this to understand the purpose — if it can't explain the goal, the feature isn't well enough defined.
73+
74+
### Section 2: Requirements (required)
75+
76+
Behavioral requirements using **EARS notation** (Easy Approach to Requirements Syntax). Each requirement follows the pattern:
77+
78+
```
79+
WHEN [condition] THE SYSTEM SHALL [behavior].
80+
```
81+
82+
Each requirement gets a stable ID (R1, R2, R3, …) used for traceability — tasks in Section 7 reference these IDs.
83+
84+
**Why EARS?** Traditional requirements are often vague ("the form should validate properly"). EARS forces requirements into unambiguous, testable statements that constrain exactly one observable behavior. The agent can't misinterpret "WHEN the login form is submitted with an empty email field, THE SYSTEM SHALL display an inline validation error without making an API call."
85+
86+
EARS was developed by Alistair Mavin at Rolls-Royce and is documented in the paper [_Easy Approach to Requirements Syntax (EARS)_](https://ieeexplore.ieee.org/document/5328509). The five EARS patterns are:
87+
88+
| Pattern | Template | Use when |
89+
| ----------------- | ----------------------------------------------- | ----------------------------------- |
90+
| Ubiquitous | THE SYSTEM SHALL [behavior] | Always-on behavior |
91+
| Event-driven | WHEN [event] THE SYSTEM SHALL [behavior] | Response to a trigger |
92+
| State-driven | WHILE [state] THE SYSTEM SHALL [behavior] | Ongoing behavior during a condition |
93+
| Unwanted behavior | IF [condition] THEN THE SYSTEM SHALL [behavior] | Error handling, fallbacks |
94+
| Optional | WHERE [feature] THE SYSTEM SHALL [behavior] | Configurable behavior |
95+
96+
In practice, most frontend requirements use the event-driven pattern (WHEN/SHALL).
97+
98+
### Section 3: Non-Goals (required)
99+
100+
Explicit list of what the feature will NOT do. Prevents scope creep and stops the agent from "helpfully" adding unrequested capabilities.
101+
102+
### Section 4: Building Blocks Diff (required)
103+
104+
The core of the spec. Lists every building block that is **added**, **modified**, or **deleted** — referenced by name and type from the building blocks catalog. No implementation details. The agent reads the relevant building block rule file to understand the pattern.
105+
106+
Example:
107+
108+
```markdown
109+
### Added
110+
111+
- `loginMutation` (mutation) — handles POST /auth/login
112+
- `LoginForm` (component) — form with email/password fields
113+
114+
### Modified
115+
116+
- `AppRouter` (route) — add /login route
117+
- `authStore` (store) — add `isAuthenticated` derived state
118+
```
119+
120+
### Section 5: Design Decisions (required for non-trivial features)
121+
122+
Key choices with brief rationale — what you chose, what you rejected, and why. Kept short (2–4 decisions max). If you need more, the feature should be split.
123+
124+
### Section 6: Boundaries (required)
125+
126+
Three-tier classification controlling what the agent can do autonomously:
127+
128+
-**Always** — proceed without asking (e.g., create files in `src/features/auth/`)
129+
- ⚠️ **Ask first** — needs human approval (e.g., modify API contracts, add dependencies)
130+
- 🚫 **Never** — hard stops (e.g., modify core auth internals, remove tests, commit secrets)
131+
132+
This pattern comes from [GitHub's analysis of 2,500+ agent configuration files](https://github.blog/ai-and-ml/github-copilot/how-to-write-a-great-agents-md-lessons-from-over-2500-repositories/), where "Never commit secrets" was the single most impactful constraint.
133+
134+
### Section 7: Task Breakdown (required)
135+
136+
Ordered list of independently testable tasks. Each task:
137+
138+
- References building blocks from Section 4
139+
- Traces to requirement IDs (R1, R2, …)
140+
- Includes target file paths
141+
- Is marked `[P]` (parallelizable) or `[S]` (sequential)
142+
143+
### Section 8: Error & Edge Cases (optional but recommended)
144+
145+
Uses **GIVEN/WHEN/THEN** format (from BDD) for precision:
146+
147+
```
148+
GIVEN the user is already authenticated,
149+
WHEN they navigate to /login,
150+
THEN redirect to dashboard.
151+
```
152+
153+
If you skip this section, expect the agent to guess — and guess wrong.
154+
155+
### Sections 9–11
156+
157+
- **Acceptance Criteria** (optional) — high-level "done" checklist, often redundant if requirements are precise.
158+
- **Open Questions** (optional) — unresolved decisions blocking specific tasks.
159+
- **References** (optional) — links to related specs, mockups, API docs.
160+
161+
---
162+
163+
## The writing workflow
164+
165+
The `writing-spec` skill guides the developer through a four-phase process. Each phase ends with a human review gate — the agent does not advance without explicit approval.
166+
167+
### Phase 1 — Goal & Scope (Intent)
168+
169+
The developer describes the feature. The agent drafts Goal & Context, Requirements (EARS), and Non-Goals. Before drafting, the agent asks 3–5 clarifying questions about scope boundaries, error scenarios, and unstated assumptions.
170+
171+
**Key principle:** The agent never invents requirements. If the developer hasn't specified a behavior, the agent asks about it.
172+
173+
### Phase 2 — Design (Approach)
174+
175+
The agent proposes a Building Blocks Diff and, for non-trivial features, two plausible designs with tradeoffs. The developer chooses. The winner and rationale go into Design Decisions. Boundaries are drafted.
176+
177+
**Key principle:** Building blocks reference name + type only — no implementation details in the spec. The spec describes a _change to the status quo_, not the code itself.
178+
179+
### Phase 3 — Spec (Sequencing)
180+
181+
Tasks are broken down, traced to requirements, and ordered. Error & edge cases are documented in GIVEN/WHEN/THEN. Open questions are captured.
182+
183+
### Phase 4 — Review & Finalize
184+
185+
The agent runs a structured self-audit and presents findings:
186+
187+
- **Coverage matrix** — each requirement ID mapped to implementing tasks. Flags requirements with zero tasks.
188+
- **Orphan tasks** — tasks that don't trace to any requirement.
189+
- **EARS compliance** — flags requirements missing WHEN/SHALL or using vague language.
190+
- **Boundary specificity** — flags boundary items referencing vague categories instead of file paths.
191+
- **Building block references** — flags blocks not found in the catalog.
192+
- **Line count** — reports total; identifies bloated sections if >150 lines.
193+
194+
Issues are fixed before presenting the final spec for developer sign-off.
195+
196+
---
197+
198+
## Building blocks
199+
200+
Building blocks are typed, named patterns that form the project's architectural vocabulary. When a spec says `loginMutation (mutation)`, that name maps to a specific pattern with defined constraints, layer placement, and a canonical code example.
201+
202+
### The catalog
203+
204+
The building blocks catalog lives in `skills/building-blocks/`. It uses progressive disclosure:
205+
206+
- **SKILL.md** — summary index table with block name, layer, and one-line description. The agent reads this to know _which_ blocks exist.
207+
- **rules/{block-name}.md** — full description, constraints, and canonical example. The agent reads these _only when implementing_ a specific block.
208+
209+
### Block categories
210+
211+
| Category | Blocks | What they cover |
212+
| ------------------ | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
213+
| Data Fetching | `mutation-hook`, `query-options-factory`, `query-keys-factory`, `dto-model` | Server reads/writes, cache keys, API response types |
214+
| State Management | `store`, `provider` | Zustand stores, React Context dependency injection |
215+
| App Orchestration | `use-case-hook` | Feature-level operations composing mutations + notifications |
216+
| Component Patterns | `notification-hook`, `pure-component`, `compound-component`, `hoc`, `page`, `facade-hook`, `named-effect` | UI components, hooks, and composition patterns |
217+
| Data Modeling | `frontend-model`, `value-object` | Domain types, value-based logic grouping |
218+
219+
### How specs reference building blocks
220+
221+
In the spec's Section 4 (Building Blocks Diff), each entry references a block by name and type:
222+
223+
```markdown
224+
- `addToCartMutation` (mutation-hook) — handles PUT /carts/:id
225+
```
226+
227+
The agent then reads `rules/mutation-hook.md` to understand the implementation pattern — error handling conventions, cache invalidation approach, return tuple shape, etc.
228+
229+
---
230+
231+
## Architecture integration
232+
233+
The spec system works within the project's feature slice architecture documented in `docs/architecture.md`. Key architectural constraints that affect spec writing:
234+
235+
**Feature layers:** Each feature has four layers — `components/`, `application/`, `providers/`, `models/`. Building blocks map to specific layers (e.g., `mutation-hook``providers/`, `use-case-hook``application/`).
236+
237+
**Dependency rules:** Components and application import from models and providers. Providers and models have no internal feature dependencies. Library-specific code (React Query, etc.) stays inside providers — never leaks beyond.
238+
239+
**API layer:** All HTTP logic starts in `src/lib/api/` (query options factories, mutations, DTOs by resource), then gets exposed through the relevant feature's `providers/`.
240+
241+
**State management:**
242+
243+
| Tool | Use case |
244+
| ----------- | -------------------------------------------------------------------- |
245+
| XState | State orchestration with explicit states and constrained transitions |
246+
| Zustand | Complex local state (auth, modals, etc.) |
247+
| React Query | Server state and caching |
248+
| React state | Simple component state |
249+
250+
---
251+
252+
## Self-improvement loop
253+
254+
After every implementation, the agent captures lessons learned in `specs/lessons.md` — patterns that caused rework, misunderstandings, or repeated mistakes. This file is reviewed at the start of each session so the same mistake doesn't happen twice.
255+
256+
This creates a feedback loop: specs improve over time as lessons accumulate, and the agent's behavior becomes more aligned with the team's expectations.
257+
258+
---
259+
260+
## Anti-patterns
261+
262+
These are common failure modes the system is designed to prevent:
263+
264+
**Spec that's actually a task list.** "First create the model, then add the service" constrains sequencing but not intent. The agent follows every step and still builds the wrong thing. Fix: write requirements first, derive tasks from them.
265+
266+
**Over-specification that becomes code.** If the spec includes TypeScript interfaces, database DDL, or code snippets, it has crossed from "what" into "how." Implementation details belong in building block patterns and existing code, not the spec.
267+
268+
**Under-specification that forces guessing.** "Handle errors gracefully" without specifying _which_ errors and _what_ "gracefully" means guarantees the agent will guess. Fix: use GIVEN/WHEN/THEN for every error scenario.
269+
270+
**Auto-generated specs without human input.** LLM-generated context files have been shown to reduce task success rates. The developer drives content; the agent structures and challenges it.
271+
272+
**Specs exceeding 150 lines.** If the review cost exceeds the value, the spec fails its purpose. Split the feature or compress the spec. If a section is long, it likely contains content that belongs in architecture docs or coding standards instead.
273+
274+
---
275+
276+
## Quick reference for contributors
277+
278+
**Starting a new feature:**
279+
280+
1. Describe the feature to the agent.
281+
2. If it spans 5+ files or involves 5+ design decisions, the agent will initiate the spec workflow.
282+
3. Collaborate through four phases — review and approve each before moving on.
283+
4. Once the spec is approved, implementation begins task by task.
284+
285+
**Working on an existing spec:**
286+
287+
- Specs live in `specs/NNN-feature-name/spec.md`.
288+
- Check the `Status` field in the Meta table.
289+
- The task breakdown in Section 7 shows what's done and what remains.
290+
- Open questions in Section 10 may block specific tasks.
291+
292+
**Adding a new building block:**
293+
294+
1. Create `skills/building-blocks/rules/{block-name}.md` following the format of existing blocks.
295+
2. Add the block to the catalog table in `skills/building-blocks/SKILL.md`.
296+
3. Use the block name in future specs.
297+
298+
---
299+
300+
## References
301+
302+
### Project files
303+
304+
- `CLAUDE.md` — agent behavior rules and workflow principles
305+
- `docs/architecture.md` — project structure, layers, dependency rules
306+
- `docs/spec-template.md` — spec section structure with inline guidance
307+
- `skills/writing-spec/SKILL.md` — four-phase spec writing workflow
308+
- `skills/building-blocks/SKILL.md` — building block catalog index
309+
- `specs/lessons.md` — accumulated learnings from past implementations
310+
311+
### External references
312+
313+
- [GitHub Spec Kit](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/) — GitHub's open-source SDD toolkit
314+
- [Addy Osmani: How to write a good spec for AI agents](https://addyosmani.com/blog/good-spec/) — five principles for effective AI specs
315+
- [Matt Rickard: The Spec Layer](https://blog.matt-rickard.com/p/the-spec-layer) — specs as a constraint layer between humans and AI
316+
- [Birgitta Böckeler: Understanding Spec-Driven Development](https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html) — comparative analysis of SDD tools (Thoughtworks/Martin Fowler)
317+
- [Birgitta Böckeler: Harness Engineering](https://martinfowler.com/articles/harness-engineering.html) — guides vs. sensors framework for AI agent constraints
318+
- [EARS: Easy Approach to Requirements Syntax](https://ieeexplore.ieee.org/document/5328509) — the requirements notation we use (Alistair Mavin, Rolls-Royce)
319+
- [GitHub: Lessons from 2,500+ agent configurations](https://github.blog/ai-and-ml/github-copilot/how-to-write-a-great-agents-md-lessons-from-over-2500-repositories/) — data-driven findings on effective agent constraints
320+
- [Eng Leadership: How to Do AI-Assisted Engineering](https://newsletter.eng-leadership.com/p/how-to-do-ai-assisted-engineering) — survey of 15 engineering leaders on SDD practices

0 commit comments

Comments
 (0)