· specs · ai-assisted-delivery
Why your specs get bounced back (and what AI changes about it)
Dev teams bounce specs for the same five gaps, every time: unsourced rules, untestable criteria, missing refusals, two-way sentences, undefined contract detail. AI fixes two of them and quietly makes three worse. Here is the review loop that catches all five.
A bounced spec never costs just the rewrite. It costs the refinement slot it burned, the sprint that started without the story, and a little of the team’s default trust in the next document with your name on it. Do it three times and you stop being “the PO who writes the specs” and start being “the PO whose specs we check.”
The good news, if you can call it that: specs don’t get bounced for exotic reasons. Across teams, stacks, and industries, the bounce reasons are the same five gaps — consistent enough to check for mechanically. The complication is that AI-assisted drafting, which is how more and more specs get written now, fixes two of the five and makes the other three quietly worse.
The five gaps dev teams actually bounce specs for
1. Rules asserted without a source. The spec says “expired quotes can no longer be booked” — and in refinement someone asks: expired after how long? Measured from creation or from the last price update? Says who? If the answer is “I’ll check,” the story just left the sprint. A rule that has no source isn’t a requirement, it’s a rumor with formatting.
2. Untestable acceptance criteria. “The system handles the error appropriately.” “Performance should be acceptable.” “The booking works correctly.” Every one of these reads fine and verifies nothing — there is no observable outcome a tester can check, so the developer either asks (bounce) or decides for you (worse). The test is brutal and simple: if two people could disagree about whether the criterion passed, it isn’t a criterion.
3. The missing refusals. The happy path is fully specified: the coordinator books the shipment, the label is produced, the confirmation goes out. And then a developer asks what a finance viewer sees if they hit that same endpoint, or what happens to the booking that’s attempted on a quote that expired mid-session — and the spec goes silent. Half of a system’s real behaviour is what it must refuse to do, and specs systematically document the other half.
4. Sentences with two readings. “The user can update the shipment.” Which user — the coordinator who created it, or any coordinator? Update which fields — the reference and notes, or the parcels themselves? Until when — any time before pickup, or only before the label exists? A developer under deadline doesn’t flag the ambiguity; they pick the reading that’s cheapest to build. When it’s the wrong one, the bounce arrives weeks later, dressed as a bug.
5. Contract detail that doesn’t exist yet. The spec mentions a field the API doesn’t expose, an error code nobody has defined, an upstream system that “provides” data no one has confirmed it provides. Integration points are where specs write cheques other teams have to cash — and a dev team that has been burned once will bounce any spec that name-drops a contract without pinning it.
Five gaps. Every experienced developer reading this list just nodded at a specific memory.
What AI-drafted specs get wrong by default
Paste your notes into a model and ask for a spec, and something interesting happens to those five gaps: the two visible ones improve, and the three invisible ones get worse.
The improvements are real. Models are genuinely good at gap 2 — ask for Given/When/Then with observable outcomes and you get tidy, checkable criteria instead of “works correctly.” They help with gap 4 too: fluent, structured prose has fewer accidental two-way sentences than notes typed between meetings.
But gaps 1, 3, and 5 share a property that makes them dangerous with a model in the loop: they are gaps of missing knowledge, and a language model does not leave gaps — it fills them. Plausibly.
Give a model “quotes expire” and it won’t ask after how long. It will write “quotes expire 72 hours after creation” — confident, specific, and invented. Ask it for the refusal scenarios and it will generate refusals for the roles it imagines your platform has, not the ones it actually has. Mention the carrier integration and it will produce field names and error codes with perfect formatting and zero existence.
Here is the mechanism that makes this worse than the old problem, and it’s worth being exact about: vagueness gets bounced, specificity gets built. The hand-written spec that said “quotes expire” triggered a question in refinement — annoying, but the gap surfaced. The AI-drafted spec that says “72 hours” triggers nothing. It sails through review wearing the same confident tone as the parts you actually decided, gets built exactly as written, and surfaces six weeks later as a production behaviour nobody chose. The bounce was the immune system. Fluent invention is how a spec defeats it.
So the honest summary of “AI for specs” is: it converts loud failures into quiet ones. That’s a bad trade unless you change how you review — which you can.
The review loop that catches both
The fix is not “review the AI’s output carefully” — under deadline, nobody reviews an 800-word document carefully against an unbounded list of possible inventions. The fix is three finite passes, each with a definition of done, run before the spec leaves your desk.
Pass 1 — the rule audit. Walk the spec and find every conditional behaviour: every expiry, limit, threshold, and permission. For each one, ask a single question: where did this come from? Either it traces to a source you can name — a decision, a wiki page, a person — or it gets tagged. The tag discipline is the whole trick, and you should impose it at drafting time, in the prompt itself:
Mark every business rule, limit, error case, or field you introduced that was not present in the material I gave you with
[ASSUMED — confirm]. Do not silently promote an assumption to a requirement.
Now the review is finite: find the tags, and for each one either confirm it with the rule’s owner or delete it. Done when the tag count is zero.
Pass 2 — the refusal walk. Take every role your platform has — including the ones the story isn’t about — and every state the resource can be in, and walk them against the spec’s operations: what must each combination be unable to do, and what exactly happens when they try? This is mechanical enough to delegate to the model, with one guardrail: any role or state it infers rather than receives gets tagged, because the role you forgot to mention is exactly the one with the hole in it.
Pass 3 — the hostile read. Hand the finished spec to the model with instructions to read it as a literal-minded implementer who cannot ask questions: explain back what will be built, step by step, marking every place it had to guess. Then diff its explanation against what you meant. Every mismatch is a refinement question you just answered at your desk for free, instead of live in front of six developers. An explanation with zero guesses on a spec you know is thin means the reader was being polite — tighten the instruction, not the spec.
Fifteen minutes, three passes, each with a stopping condition. That is the difference between a spec that gets bounced, a spec that gets built wrong politely — and a spec that survives first contact with the team.
Get the system
The three passes above exist as full documented prompts — assumption surfacing, the negative and permission scenario generator, the “explain it back” verifier — in the free slice: 10 documented AI prompts for POs, drafted from a production AI-assisted specification pipeline. Each ships with when to use it, what to paste in, a worked example on Parcelio (the fictional logistics platform in every example on this site), and its documented failure modes. Email-gated, free, no listicle.
Subscribe and get the free slice →
— Pierre K.