1. The product memo pretending to be a spec
This antipattern describes the user problem, opportunity, and launch value, then stops before implementation truth begins. It may be a good PRD, but it is not a technical spec. Engineers and agents still need to know current behavior, affected systems, requirements, edge cases, and verification.
Fix it by adding the engineering boundary: current system, proposed behavior, data/API/UI changes, acceptance criteria, rollout risks, and commands. If those sections feel premature, the work probably still needs product or design clarification before a spec is written.
2. The code transcript
The opposite failure is a spec that narrates every future function and file before the implementation has met the real code. This creates brittle pseudo-code that reviewers debate line by line, even when the real system would suggest a simpler local pattern.
Fix it by specifying contracts, not imaginary code. Name the API behavior, data ownership, state transitions, invariants, and verification. Let implementation follow the codebase unless a specific technical choice is required for correctness.
3. The happy-path-only spec
Happy-path specs are attractive because they make a feature feel simple. They list what should happen when everything is valid, connected, authorized, and on time. Real systems fail in the gaps: expired records, duplicate events, retries, empty states, permission boundaries, partial outages, and stale clients.
Fix it with edge-case prompts: What if there is no data? What if the user is unauthorized? What if the request is repeated? What if the job is retried? What if the dependency times out? What if old data does not match the new assumption?
5. The unbounded refactor invitation
Phrases like "clean this up while you are there" and "modernize the flow" are dangerous in a spec. They blur the acceptance boundary and invite unrelated churn. This is especially risky with coding agents because a broad improvement instruction can trigger sweeping edits that are hard to review.
Fix it with non-goals. If a refactor is required, specify the refactor as its own scoped requirement. If it is not required, fence it out. A narrow feature spec can still improve code quality, but the improvement should serve the feature rather than become a hidden second project.
6. The testless definition of done
"Works as expected" is not a definition of done. It is a feeling. A spec must list the tests, manual checks, build commands, or operational signals that prove completion. Without verification, implementation quality depends on the memory and discipline of whoever happens to review the work.
Fix it by naming exact verification. If there is no automated test path, name the manual path and explain why automation is not practical. If the change affects risk-sensitive behavior, add a small targeted test before implementation expands.
"qualities of a good software requirements specification"
7. The stale decision record
Specs often rot when decisions move to chat, code review, or hallway conversation. The document still says one thing while implementation follows another. Future readers inherit a false source of truth.
Fix it by treating the spec like an engineering artifact. Keep the decision log current while the work is active. If implementation deliberately deviates, update the spec or record the deviation in the final report. Abseil's public chapter from Software Engineering at Google argues for documentation as part of the engineering workflow; specs should follow that standard.
"documentation is treated like code"
8. The prompt disguised as a durable artifact
A prompt can be conversational, but a spec has to survive review, implementation, and maintenance. If the document only says "please build X" and relies on the current chat context, it is not durable enough for future readers or different agents.
Fix it by making the spec self-contained: goal, current behavior, scope, non-goals, requirements, examples, verification, and open questions. Link to supporting materials rather than assuming the implementer saw the same conversation.
Review checklist
Before approving a spec, review it against these questions:
- Can a new implementer explain the current behavior after reading it?
- Are the scope and non-goals concrete enough to prevent adjacent work?
- Does every MUST map to an acceptance criterion or verification check?
- Are edge cases and failure modes listed, not implied?
- Does the spec distinguish product decisions from implementation decisions?
- Are migrations, permissions, privacy, and rollout risks handled if relevant?
- Could a reviewer tell whether the implementation is complete without asking the author?
- If an AI coding agent executed this, would it know where to stop?
For a more structured pass, use the Spec Review Checklist and run obvious language issues through the Ambiguity Checker.