Someone always asks whether spec-driven development replaces test-driven development. The question assumes they compete for the same slot, that you pick one methodology and the other becomes redundant. That assumption is the mistake, and it leads people to drop one of two things they both need.
Tests and specs answer different questions. A test asks “does the code do this specific thing?” A spec asks “is this the thing the code was supposed to do?” You can pass every test and still have built the wrong feature, and you can have a perfect spec and still ship code that violates it. These are not two answers to one problem. They are two different problems that happen to sit next to each other.
What each one actually fixes
Test-driven development fixes behavior. You write a failing test, make it pass, refactor. The test is an executable claim about what the code does at a concrete point, and its great virtue is that it runs. A test does not have opinions or forget. It either passes or it does not, and it keeps checking forever. That is a real form of truth, and it is why tests remain load-bearing no matter how the code was written.
Spec-driven development fixes intent. The spec states what must change, what must stay true, and how you will recognize a correct result, and it does this before the building starts. Its virtue is that it captures the decision, not just the behavior. A spec can say “coupons must never stack, this is a business rule, not an accident,” which is the kind of thing a test enforces but never explains.
Here is the gap between them. A test can be perfectly green and enforce the wrong behavior, because the test only knows what someone told it to check. It cannot tell you that the behavior it is protecting is itself a misunderstanding of what the product needed. The spec is where that judgment lives. Tests verify against a target. The spec is what set the target.
Why agents make the layering non-optional
With a human writing every line, you could sometimes get away with only tests, because the intent lived in the developer’s head and leaked into reasonable defaults. An agent has no such head. It has the prompt, the context you gave it, and whatever it can infer, and it will confidently fill any gap you left with a plausible guess.
This is where tests alone stop being enough. An agent can write code, write tests for that code, and make them pass, and the whole loop can be internally consistent and still wrong, because the agent tested its own interpretation. Nothing checked that interpretation against your intent. This is the trap behind a green build that is not a correct feature: the build proves the code agrees with its own tests, not with you.
The spec breaks that loop. It is the one artifact the agent did not author, the fixed intent the tests get measured against. Give an agent a spec and its tests have something to be right or wrong about. Give it none and its tests are just a mirror.
They plug into each other
Once you stop framing them as rivals, the connection is obvious. The spec’s acceptance criteria are where tests should come from. A criterion like “an expired coupon is rejected before the total is calculated” is one sentence in the spec and one test in the suite, and the test exists precisely to prove that clause of the contract.
This is how you get acceptance criteria an agent can actually verify: the criteria are written to be executable, so each one becomes a test rather than a vague hope. The spec sets the intent, the criteria translate it into checkable claims, and the tests do the checking on every run. Each layer does the job the other cannot.
And it runs in both directions. A test that is hard to write usually means a criterion is vague, which usually means the intent was never really pinned down. The friction of writing the test surfaces a hole in the spec. That feedback is one of the quiet reasons the two disciplines are better together than either is alone.
The sequencing matters as much as the pairing. The spec comes first, then the criteria, then the tests, then the code, and each step constrains the next. If you let the agent write code first and generate tests afterward, the tests inherit whatever the code happened to do, including its mistakes, and you are back to a mirror. Writing the checkable criteria before the code exists is what keeps the tests independent of the implementation, so they measure the code against the intent instead of against itself. TDD gave the industry that ordering discipline for behavior. Spec-driven development pushes the same discipline one layer up, to intent.
What still changes about testing
Layering the two does not mean testing is untouched by agents. When code arrives faster than anyone can read it, the tests carry more of the trust than they used to, so what you test and how you trust it both shift. That is its own subject, covered in testing AI-generated code: what changes and what doesn’t, but the short version is that tests become more load-bearing, not less, precisely because a human reviewed fewer of the lines.
The spec does not save you from that. It aims the effort. Without the spec, you are testing whatever the agent decided to build. With it, you are testing whether the agent built what was agreed. The tests are the same mechanism either way. The spec decides whether they are pointed at the right target.
Where PaellaDoc fits
Treating the two as layers is the model PaellaDoc is built on. The spec holds the intent and stays linked to the code that implements it. Its acceptance criteria connect to the runs that exercise them, so the tests are not a separate island of trust but the enforcement arm of the contract. When the code drifts, you can see which criteria, and therefore which tests, are now checking against an intent that moved.
Spec-driven and test-driven were never fighting for one seat. Tests tell you the code does what it does. The spec tells you that is what it was supposed to do. Drop either and you are trusting a loop that only checks itself.
FAQ
Does spec-driven development replace TDD? No. They operate on different questions. TDD verifies that code does a specific thing; the spec fixes what that thing was supposed to be. Removing tests loses your behavioral safety net; removing the spec loses the intent the tests are supposed to serve.
If I have good tests, why do I also need a spec? Because tests can enforce the wrong behavior perfectly. A test only checks what someone decided to check, and with an agent that someone is often the agent itself. The spec is the independent intent your tests get measured against.
Where do the tests come from in a spec-driven workflow? From the spec’s acceptance criteria. Each criterion written to be checkable becomes a test, so the suite exists to prove specific clauses of the contract rather than the agent’s own interpretation of the task.