“The spec is the contract” is one of those phrases everyone nods at. It sounds right, it sounds rigorous, and most of the time it means nothing, because a contract that no one signs, no one can breach, and no one enforces is not a contract. It is a wish with better formatting.
If you want the phrase to carry weight, you have to answer three questions a real contract always answers. Who signs it? Who can break it? And how does anyone find out it was broken? Skip those and “the spec is the contract” is just a nicer way of saying “we wrote something down once.”
A contract has parties
A contract binds parties to each other. So the first question is: between whom?
In spec-driven development the spec sits between product intent and implementation. On one side is whoever is accountable for what the software is supposed to do. On the other is whoever, or whatever, builds it, and increasingly that is an agent. The spec is the agreed statement of what “correct” means, written before the building starts so that both sides are pointing at the same target.
This is why the spec has to precede the code. A contract you write after the work is done is not a contract, it is a description. The whole value of defining the acceptance contract before implementation is that it exists as a commitment both parties can point to, not a summary of what already happened.
The signature matters too. Someone has to actually agree to the spec, on the record, before the agent builds against it. That signature is what ends the I never agreed to that argument three weeks later. Without a recorded moment of agreement, the spec is a draft, and drafts do not bind anyone.
A contract can be breached
Here is where most “spec as contract” talk falls apart. If nothing can break the contract, it was never a contract. So what counts as a breach?
Two things breach a spec, and they are different.
The implementation violates the spec. The agent built something that does not do what the contract says. It handles the happy path and ignores an invariant the spec explicitly protected. This is the breach everyone imagines, and it is the easier one to catch.
The world changes and the spec no longer describes it. Nobody violated the contract on purpose. A later change touched the same surface, the behavior moved, and now the code and the spec disagree. Neither party broke faith, but the contract is breached all the same, because it no longer matches reality. This is spec drift seen through a contractual lens, and it is the breach nobody assigns blame for, which is exactly why it festers.
A spec that can only be breached by the first kind and never notices the second is protecting you from the easy failure and leaving the common one wide open.
A contract is enforced, or it is decoration
A breach nobody detects is not enforcement. This is the part that separates a spec that governs from a spec that decorates.
Detection has to be mechanical, because human attention does not scale to the speed agents produce code. The spec’s acceptance criteria have to be executable against the real result, and something has to actually run them and attach the outcome to the contract. A passing test suite is not enough on its own, because a green build is not a correct feature: the build can be green while the specific behavior the contract promised was never exercised.
This is why acceptance criteria have to be written to be checked, not just read. Vague criteria like “handles errors gracefully” cannot be enforced, so they are not contract terms, they are hopes. Criteria an agent and a runner can both evaluate are the difference between acceptance criteria that get verified and a checklist someone ticks by feel.
And enforcement has to be continuous, because the second kind of breach happens after the ink is dry. Checking the contract once at merge time catches the implementation violation and misses every drift that follows. Enforcement is not a gate you pass through once. It is a standing question the system keeps re-asking: does the code still satisfy the contract?
Notice how much of this the person is doing by hand today. You are the party who signed. You are the enforcement mechanism, reading the diff and deciding whether it honors what was agreed. You are the drift detector, the one who eventually notices the spec no longer matches. A contract enforced entirely by one human’s attention is a contract that holds exactly as long as that human has attention to spare, which at agent speed is not long. The terms do not weaken. The enforcer just gets overwhelmed, and an unenforced contract is decoration again.
The contract has to travel with the goods
A contract is worthless if the parties lose their copy. When the spec lives in a chat transcript that gets cleared or a folder the next agent never opens, the contract effectively voids itself the moment the workflow changes.
For the spec to stay a contract, it has to move with the code and the evidence, not stay pinned to the tool that wrote it. This is the practical reason specifications should be portable: a contract only binds while both parties can still read it, and in an agent workflow the parties change constantly.
Where PaellaDoc fits
Making the spec a real contract is the job PaellaDoc is organized around. A spec is agreed and recorded, so there is an actual signature rather than an assumption. Its acceptance criteria stay connected to the runs that exercise them, so a breach of the first kind gets caught by evidence instead of trust. And because the spec stays linked to the code that implements it, a breach of the second kind, the drift, surfaces when the code moves instead of hiding until an incident finds it.
The spec is the contract only when someone signed it, something can break it, and something catches the break. Answer those three and the phrase means what it claims. Skip them and you have a document that looks like a contract right up until the moment you need it to hold.
FAQ
Who signs a spec-as-contract? Whoever is accountable for what the software should do, on the record, before the agent builds. That recorded agreement is what turns a draft into a commitment and settles later disputes about what was actually agreed.
Isn’t a passing test suite already enforcement? Not by itself. A green build proves some code ran and passed, not that the specific behavior the contract promised was exercised. Enforcement means the acceptance criteria are run against the real result and the outcome is attached to the spec.
How is spec drift a contract breach if nobody broke a rule? Because a contract is breached whenever it stops matching reality, not only when someone violates it on purpose. A later change can move the behavior and leave the spec describing a system that no longer exists. No one is at fault, and the contract is broken anyway.