Build the first version
With memory online and the architecture decided, build features one atomic task at a time. The PRD is the spec; the build loop elaborates it into a plan, then tasks, then code, verified per task.
Purpose: ship features against the spec, gated task by task, never in one big unverifiable dump.
Run: /sdd-init → /sdd-design → /sdd-tasks → /sdd-impl (in .claude/commands/).
Output: .specs/<feature>/{spec,design,tasks}.md + the shipped feature, each task checked off.
Feeds: Step 9 (deploy) ships the result; the memory bank logs progress for the next session.
Why it exists
"Build me the whole site" produces a pile of code nobody can verify. Spec-Driven Development inverts that: the spec is fixed first, then the agent plans the architecture, splits it into atomic testable tasks, and implements exactly one per pass through an implement → test → review loop. Every task maps to a checkable PRD Section 9 criterion.
The SDD loop
/sdd-init <feature>
Derive a spec.md for one feature from the PRD: problem, user stories (Given / When / Then), and numbered, testable acceptance criteria. No file paths, no "how". That comes next.
/sdd-init waitlist-form/sdd-design <feature>
A researcher subagent inventories reusable primitives, then a design.md is written: architecture, files to create / edit, the server / client boundary, route + SEO wiring (getSEOTags, renderStructuredData), API contracts, and env-gating / fail-soft behavior.
/sdd-tasks <feature>
A planner subagent breaks the design into ordered, atomic tasks (types → server action → server components → client islands → route + SEO → sitemap → inventory). Each task is a small diff and maps to a spec criterion.
/sdd-impl <feature> [n]
Implements exactly one task through implementer → tester → reviewer, with auto-debug capped at 2 retries. Then it marks the task complete and logs to .memory/50-progress.md. One task per invocation: per-task gating is the point.
/sdd-impl waitlist-form # next unchecked task/sdd-impl waitlist-form 3 # a specific taskVerification per task
The tester pass closes the loop on the PRD's checkable criteria. For each task it runs pnpm lint, npx tsc --noEmit, and a Playwright smoke check on the touched routes: the page renders, returns 200, and throws no browser console errors. Mechanical failures are auto-fixed; structural ones surface to you.
$pnpmlint$npxtsc --noEmit# Playwright smoke: route renders, 200, no console errorsBest practices baked in
- One task per
/sdd-impl. Per-task gating catches drift before it compounds. - Every acceptance criterion is checkable by a command, an HTTP probe, Lighthouse / INP, or a JSON-LD validator.
- Tests embedded in each task's plan, not deferred to the end.
- Never relax the zero-env build to make a task pass. A task that needs an env var to build is a design bug.
- Never auto-commit. You commit when you are ready.
pnpm build locally first: a clean local build is the fastest way to catch issues before Vercel does.