If you asked me for the one rule of spec-driven development (SDD) that does the most work, it would not be "write it precisely." It would be evidence over inference. Every requirement in the spec traces to a source: an interview, a comment on a document, a sample of real data, a decision someone actually made and recorded. Nothing is inferred, nothing is assumed, nothing is filled in because it seemed likely. I gave the principle one paragraph in How I Work. This post is the long version, following one small problem through every artifact it touched.
The Gap
The problem was ordinary. A consumer needed a field that our pipeline did not carry for part of the universe it covered. A coverage gap, the kind every data team has a backlog of. The old way to handle it is a ticket that says "add the field" and an engineer who fills in everything the ticket did not say: which source, which population, what to do when the source is empty, what the consumer sees in the meantime. Under SDD, the engineer is an agent, and the things the ticket did not say are not gaps to be filled by judgment. They are defects.
Four Artifacts, One Chain
| Artifact | What it asserts | What it has to cite |
|---|---|---|
| Product requirements document (PRD) | The problem, who has it, what done looks like | The interview where the consumer described the gap, and the sample rows that showed it |
| Mapping spec | Field by field, source to target, with every transformation | The source system's schema and the code that produces the value, not a belief about the column |
| Data contract | The promise to the consumer: shape, rules, availability | The mapping spec, and the quality query that was run against real data |
| Code | The implementation and its tests | The contract's example rows, used as the test fixtures |
Each artifact cites the one before it, and the first one cites the world. That is the chain. When it holds, the merged code can be traced back to a sentence a person said, and every step in between can be checked by opening the thing it points at.
What "Cite" Means in Practice
Not footnotes. A link to the message. The row number in the sample file. The entry in the decision log with a date and a name. The point is that a reader, or an auditor, or an agent verifying the implementation against the requirements one by one, can open the source and see that the requirement says what the source says.
Two of the operating principles are really this one principle applied to specific temptations. Never infer a status from a date: the field that "should have been" populated because the job ran that morning is a belief, and the query that shows it was populated is a fact. Validate data before asserting it: the coverage number in the PRD came from a query I wrote and ran, and the query is in the document, so anyone can rerun it. When the number in the spec is the number the query returned, there is nothing to argue about later.
Why the Agent Needs This More Than the Engineer
An engineer with an unsourced requirement walks over and asks. An agent builds what is written. If the requirement says "populate the field for all instruments" and the source only covers some of them, the agent will do something plausible with the rest, and plausible is the problem. I wrote about this failure mode a few weeks ago in It Fails Plausibly, Not Loudly. Traceability is the prevention. A requirement that cites its source cannot silently cover more ground than the source does, because the source is right there and it does not.
This is also why SDD demands more product depth, not less, a point I made in the first post in this series. Finding the source for every requirement is slow, unglamorous work. It is also exactly the work that separates a product manager who understands the domain from one who is describing a feature they heard about.
The Chain Is Also the Audit
Six months later something is wrong. With a prose ticket you have an argument about what was meant. With the chain you walk it backward: which artifact made the false claim, and what did it cite. Either the source was misread, which is a fixable process error, or the source was wrong, which is a fixable data error. Both are better than a meeting.
The mechanical version of all this is a source column. Every requirement table I write has one, and a requirement with a blank source is not a requirement. It is a wish, and the agent will grant it.