Build your spec
One path or glob per line (or comma-separated).
spec.md
# Add password reset flow
**Type:** Feature
## Context
Users who forget their password currently have to email support. We want a self-serve reset flow: request a reset link by email, set a new password from the link. Support tickets about lockouts are our #1 category.
## Scope
The agent may create or modify files only within:
- `src/app/api/auth/**`
- `src/components/auth/**`
## Out of scope
- Do not modify the session model or billing code
Anything not listed under Scope is out of bounds. If the task appears to require touching other files, stop and ask instead of widening the diff.
## Acceptance criteria
The story is done when every box is checked:
- [ ] POST /api/auth/reset returns 200 and sends an email for a known address
- [ ] returns 200 (not 404) for unknown addresses — no user enumeration
- [ ] reset link expires after 60 minutes
## Verification
```bash
npm test
```
Run `npm test` after implementing. If anything fails, fix and re-run until the suite is green — do not open the PR with failing tests.
## Deliverable
Open a pull request from a dedicated branch (suggested: `feat/add-password-reset-flow`). Include this spec in the PR description and reference each acceptance criterion. Keep the diff limited to the Scope above — one story, one PR.
## Approval
Do not start implementation until this spec is approved.
Approved by: ____________ on ____________
Why agents need specs, not prompts
A prompt tells an agent what to start. It says nothing about when to stop, what not to touch, or how anyone will know the work is correct. That gap is where most AI coding pain lives: the agent “finishes,” you open a 40-file diff, and the review becomes an archaeology dig for what it decided on your behalf.
A spec closes the gap by writing down four things before any code exists: why the change is needed, which files are in bounds, what observable behavior counts as done, and what artifact you expect back. None of it is bureaucracy — it is the exact information you would give a new teammate, and the exact checklist you will review the diff against. The full argument lives in our guide to spec-driven AI development; this page gives you the template. If you would rather start from worked examples for features, bugfixes, and refactors, grab the story & spec templates.
Anatomy of a good acceptance criterion
Acceptance criteria are the load-bearing section — they are the definition of done your AI agent gets measured against. A good criterion has three properties: it is observable (describes behavior you can see from outside the code), machine-checkable (a test or a command could verify it), and it covers exactly one behavior (so it can pass or fail independently).
| Weak criterion | Strong criterion | What changed |
|---|---|---|
| “Password reset works properly” | POST /api/auth/reset returns 200 and sends an email for a known address | Named the endpoint, the status code, and the side effect — a test can assert all three. |
| “Handle errors gracefully” | returns 200 (not 404) for unknown addresses — no user enumeration | One specific failure case, with the security reason for the surprising status code. |
The weak versions are not wrong — they are unfalsifiable. An agent can claim “works properly” about almost anything, and a reviewer has no way to disagree without re-deriving the requirements. Write each criterion so that a stranger with the diff and a terminal could mark it pass or fail in under a minute.
Scope is damage control
The scope and out-of-scope sections exist because agents are eager. Given “add password reset,” an unscoped agent may reasonably decide your session model needs refactoring, your email helper needs a rewrite, and your lint config is wrong. Each edit is defensible in isolation; together they turn a one-hour review into an afternoon.
Scope caps the blast radius
Out-of-scope removes ambiguity
Per-story beats repo-wide
Standing conventions belong in a rules file the agent reads on every task — our AGENTS.md generator builds one — while the spec carries the boundaries that are true only for this story.
The approval line is the cheapest review you will do
The template ends with an approval line for a reason. Reviewing a spec takes two minutes: skim the scope, sanity-check the criteria, cross out what is wrong. Reviewing a finished diff built on a wrong assumption takes an hour — and rejecting it costs the whole implementation. The spec is the last moment where “wrong” is cheap to fix, which is why it deserves a signature, even a symbolic one.
Approval also changes what happens downstream. When the PR arrives with the spec attached, review stops being “is this good code?” and becomes “does this diff satisfy these checkboxes?” — a faster, fairer question. That handoff, from approved spec to reviewable PR, is the backbone of a sane AI PR automation workflow: the human gates sit at the two cheap points (spec approval, PR merge), and the agent runs unattended in between.