How do I know engineering built what the PRD said?
Mostly, you don't. The PRD is prose, and code review checks code, not intent. The fix is to turn each requirement into a short, checkable constraint when the PRD is ratified, keep that list where engineers work, and demo against the constraints, not the ticket list, before anything ships.
By Naman Jain
The honest answer: unless you've done something deliberate, you find out at launch, from users. The PRD gets read once at kickoff, translated into tickets, and never consulted again, while the build quietly negotiates with reality for six weeks.
Why the PRD and the build drift apart
The mechanism is translation loss, not bad faith. A PRD is prose; work is tickets. Somewhere between the two, requirements get split, merged, rescoped, and reworded. Each translation is reasonable. The sum is a build that satisfies the board and not the document.
Then review compounds it. Code review checks that the code is good: correct, safe, idiomatic. It does not check that the code matches an intent stated in a doc the reviewer has never read. There is no moment in the standard pipeline where anyone holds the diff up against the PRD.
The result is spec drift: not one big miss, but a dozen small reinterpretations, each defensible, none surfaced. By the time the demo happens, the PRD describes a product that doesn't exist.
What actually works
Ratify constraints, not prose. At kickoff, extract the PRD into a numbered list of short, testable sentences: "free-tier users hit a hard cap at 3 projects," not "we should limit free usage." Systems engineers have done this for decades under the name requirements traceability: every requirement gets an identifier and a trace to the work that satisfies it. You don't need the matrix ceremony. You need the numbered list and the signature.
Get an explicit sign-off from engineering. Not on the PRD, but on the constraint list. Disagreement at this stage is cheap and productive. Disagreement discovered at the demo is neither.
Demo against the list, not the tickets. Run acceptance by reading each constraint aloud and showing it. This is the single highest-leverage half hour in the process, because it makes the comparison (build versus requirement) that no tool renders by default.
Keep a change log on the PRD. When scope genuinely changes mid-build (it will), the change gets written as a decision: what changed, why, who agreed. Otherwise the PRD becomes a document about the past, and checking against it stops meaning anything.
Surface deviations at PR time, not demo time. Ask engineers to flag any diff that reinterprets a constraint. This works exactly as well as the constraint list is short and findable, which is the real argument for keeping it that way.
Where Lockstep fits
This flow is the core of what Lockstep does for product teams: a PRD goes in, comes back as a set of constraints the owner ratifies, and pull requests that drift from a ratified constraint get caught at review time, with the constraint quoted, not vibes. Capture works from Slack and Notion today; Jira, Confluence, and Google Docs are newer. We're at design-partner stage. See how it works.
Related questions
- Why doesn't the ticket board tell me whether the PRD was built?
- Because tickets are a lossy translation of the PRD. Requirements get split, merged, deferred, and reworded on the way to the board, and 'all tickets done' only proves the translation was completed, not that it was faithful. The comparison you need is build against requirements, and nobody's tool renders that view by default.
- What is spec drift?
- The gap that accumulates between what a spec says and what the software actually does, one small reasonable-at-the-time deviation at a time. It's rarely one big miss. It's a dozen quiet reinterpretations that nobody surfaced back to the PRD.
- What's the lightest-weight way to check a build against a PRD?
- Extract every requirement into a numbered list of testable sentences at kickoff, get engineering to sign it, and run the demo from that list: the person demoing reads each constraint aloud and shows it. Thirty minutes, and misses surface before launch instead of after.
Keep reading