For a while, AI coding tools made me feel productive in a way that worried me. I'd describe a feature, get 200 lines of code in 30 seconds, skim it, ship it. A week later I'd be back fixing the edge cases I never thought about, because the model didn't either.
That's the gap Spec-Driven Development (SDD) fills.
What it actually is
Write the spec first. Code second. The spec defines goals, constraints, edge cases, and acceptance criteria, and it becomes the source of truth that AI agents (and humans) implement against.
A practical spec isn't a Word doc with three layers of headings. It's closer to a contract:
# Feature: Payments CRUD
## Goal
Allow internal users to create, view, update, and refund customer payments.
## Functional requirements
- Create payment with amount, currency, customer ID, and method
- List payments with pagination and filters (status, date range)
- Update payment metadata (description, tags)
- Issue full or partial refunds
## Non-goals
- Recurring billing (v1)
- Multi-currency conversion at checkout (v1)
## Edge cases
- Refund exceeds original amount
- Update on a payment already refunded
- Concurrent refund requests on the same payment
## Acceptance criteria
- All endpoints return 4xx on invalid input with a structured error
- Refunded payments are immutable except for metadata
- Audit log records actor and timestamp on every write
Short, structured, testable.
Why it's having a moment
SDD isn't new. BDD, formal methods, and design-first APIs all share its DNA. What changed is that AI can now execute against a spec at production speed. The bottleneck stopped being how fast we type and started being how clearly we describe what we want.
Without a spec, vibe-coding with an AI agent produces fast, confident, subtly wrong code. With one, the same agent has guardrails it can be measured against.
The benefits I've actually felt
Less rework. Most of my "the AI broke it" moments were really "I didn't tell it about the edge case" moments. Writing the spec surfaces those before any code exists.
Better PR reviews. Reviewers get the why alongside the what. Conversations move from "is this how you wanted it?" to "does this match the spec?"
Living documentation, for free. The spec lives in the repo, version-controlled, and it's the same artifact onboarding devs read on day one.
Better tests. Acceptance criteria translate directly into test cases. Coverage becomes a question of "did we cover the spec?" instead of "did we hit 80%?"
Cheaper AI calls. Counterintuitive but real. A tight spec means fewer correction loops, which means fewer tokens burned reprompting until something works.
The honest caveats
SDD isn't waterfall in a trench coat, but it can become that if you over-formalize. Specs that try to enumerate every case grind iteration to a halt. The goal is enough spec to remove ambiguity, not a 40-page design doc nobody reads.
It's also harder in brownfield codebases. Reverse-engineering specs from legacy behavior is its own discipline, and worth treating as a separate project.
Where to start
Pick one upcoming feature. Before opening your editor, write the spec: goal, requirements, non-goals, edge cases, and acceptance criteria. Hand it to your AI agent of choice. Compare the output to what you would have vibe-coded.
The win isn't writing more docs. It's thinking before you ship.
Top comments (0)