An AI coding agent doesn't stop and ask "are you sure?" when a decision was never made. It picks a default, writes it into the diff, and moves on — because that's what execution engines do. When the resulting code turns out to be wrong, the failure almost never traces back to the model itself. It traces back to a gap: the gap between what product decided and what engineering built. That's the exact seam where AI coding agents go wrong, and it's why collaborative planning — product and engineering agreeing on scope together, in writing, before an agent opens a single file — isn't a process nicety. It's the only thing standing between "the agent built what we agreed on" and "the agent built what one person assumed."
Ambiguous requirements have always produced the wrong software. What's new is the speed at which ambiguity now turns into shipped code. A human developer who hits an unstated assumption usually stops and asks — in Slack, in standup, in a hallway conversation, and work waits for the answer. A coding agent doesn't stop. It infers the missing piece, commits to an interpretation, and opens a pull request in minutes, often before the person who could have caught the gap even knows work started. A missing decision used to cost a team a day of back-and-forth. Now it costs a merged branch built on a guess — and a much longer conversation about how it got there.
Why "the agent got it wrong" is usually a planning failure
When a shipped feature doesn't match what the business needed, the instinct is to audit the code. Check the logic, check the tests, check whether the model hallucinated an API that doesn't exist. Most of the time, none of that is the problem. The code does exactly what it was told to do. What's missing isn't code quality — it's a decision that two people needed to make together and didn't.
Coding agents are execution engines, not judgment engines. Given a well-scoped, unambiguous instruction, they're remarkably good at turning it into working code fast. Given an instruction with a gap in it — an edge case nobody specified, a boundary nobody drew, a tradeoff nobody weighed in on — the agent doesn't flag the gap and wait. It fills it. Usually with whichever interpretation is most literal, most locally convenient, or most common in its training data — which is rarely the interpretation the business actually needed.
That's the core mechanism behind almost every "the AI got it wrong" incident: unclear scope, not a bad model. The agent isn't the risk. Unclear scope is. And unclear scope isn't a documentation problem — it's a governance problem. It happens because nobody structured a moment where product and engineering had to look at the same plan and both say yes before building started.
The architectural assumption nobody signed off on
Take a concrete case. A fintech team is adding an "delete account" flow. Product writes the requirement in a single sentence: "Users should be able to delete their account and all associated data." That sentence is correct from where product sits — it's what the customer asked for, in plain language.
What it doesn't capture is that the company's compliance obligations require transaction records to be retained for a minimum period regardless of account status. Engineering knows this. Product, reasonably, doesn't — retention schedules live in a compliance doc nobody on the product side has read recently. Nobody flagged the conflict, because nobody put the requirement and the constraint in the same room before the agent started.
The agent takes the instruction literally. "Delete all associated data" becomes a hard delete: the user row, the transaction history, the audit records, gone. Clean implementation, passing tests, a ticket closed as done. It's also a regulatory violation that surfaces three months later when an auditor asks for records that no longer exist. The agent didn't make an error. It resolved an ambiguity nobody told it existed, in the only direction it had information for. A one-line comment in a shared spec — "soft delete, 90-day retention per compliance" — would have made this a non-event. That line only gets written if someone on the engineering side is looking at the same requirement, at the same time, before the build starts.
Scope changes don't stop for approval — they just route around it
The second failure mode isn't about what's missing at the start. It's about what changes mid-build, and who's in the room when it does.
A team is two days into building a notification digest feature. The original spec, approved by both PM and engineering lead, scoped it to daily email summaries. Midway through the sprint, a sales conversation surfaces an enterprise prospect who wants the digest available by Friday to close the deal, and wants it to include an in-app option, not just email. The PM, under deadline pressure, doesn't reopen the approved spec — there isn't time, and the change feels small. They drop an updated ask directly into the thread the coding agent is working from: "also add in-app notifications, same data, ship by Friday."
Nobody on engineering reviews that change before the agent picks it up. The agent adds an in-app notification path fast, reusing what it can from the email pipeline — which means it reuses a data query that was fine for a daily batch job and is not fine running on every page load. Nothing about this shows up as broken in review. The feature works in the demo on Friday. It starts showing up in the query monitor as a slow endpoint two weeks later, once real usage hits it.
The scope change itself wasn't the mistake — deadlines move, and priorities shift. The mistake was that the change bypassed the same approval path the original scope went through. A revised requirement that both sides sign off on gets engineering's read on feasibility and cost before it becomes an instruction to the agent. A revised requirement that goes straight from a Slack message to a coding agent gets neither, and the gap doesn't surface until it's already in production.
| Path the change took | What it skipped | Where the cost landed |
|---|---|---|
| PM → coding agent, direct | Engineering feasibility review | A slow endpoint found in production, not code review |
| PM → shared spec → engineering sign-off → agent | Nothing — same review as original scope | Caught before the agent wrote a line |
One team's small scope decision is another team's blast radius
Some gaps aren't about a missing detail inside one feature. They're about a decision that looks self-contained from where it was made and isn't self-contained at all once you see the whole system.
Consider a payments team adding automatic retry logic for failed transactions — a request that comes in sounding almost trivial: "if a charge fails, retry it once before showing the customer an error." From product's vantage point, this touches one thing: the checkout flow. From engineering's vantage point, retrying a charge safely means the retry has to be idempotent, which means it touches the billing service's idempotency-key handling, the reconciliation logic in the reporting pipeline that assumes one attempt per transaction ID, and the webhook consumer in a separate notifications repo that fires on every charge attempt, retried or not.
None of that is visible from inside the checkout repo, which is the only repo the coding agent assigned to this task has open. It implements the retry exactly as scoped — cleanly, correctly, for the one service it can see. Customers stop seeing spurious errors. They also, for about a week, occasionally see two charges for one purchase, because the retry wasn't idempotent-safe in the billing service the agent never touched and the team building it didn't know needed to be touched. This is the scenario that has nothing to do with the agent's code quality and everything to do with nobody having mapped, before the build started, which services a "small" change actually reaches. That mapping is a joint act — product frames the intent, engineering knows the blast radius — and it has to happen before an agent is scoped to a single repo, not after a customer notices the double charge.
Regulated teams need a record, not a recollection
For a consumer app, the failure modes above are expensive and embarrassing. For a regulated business — healthcare, financial services, anything with a compliance function that gets audited — they're a different category of problem, because the question an auditor asks isn't "did this work." It's "who approved this, and where's the record."
A Slack thread doesn't answer that question. Neither does a coding agent's commit history, which shows what changed but not who decided it should. When an auditor asks why a data access pattern changed, "the PM mentioned it in a DM and the agent picked it up" is not an answer that survives a compliance review — not because anyone acted in bad faith, but because there's no artifact showing the decision was reviewed by the people who needed to review it, or why.
An approved plan is that artifact. When a spec moves through explicit, section-by-section sign-off — Problem, User Stories, Architecture Overview, API Endpoints, each reviewed by both product and engineering before anything is built — the approval itself becomes part of the record. If scope changes mid-build, that change is traceable back to who approved it and why, the same way the original scope was. That's not a compliance feature bolted onto planning. It's what planning looks like once you accept that "we agreed on this" has to be provable, not just remembered.
What collaborative planning looks like in practice
None of this argues against using coding agents, or against moving fast. It argues against treating the moment before the agent starts as informal — a Slack thread, a half-read PRD, a decision one person made alone because asking felt slower than guessing.
Collaborative planning means product and engineering are looking at the same structured plan, section by section, before an agent writes code — not a document one side wrote and the other side skimmed. Context gets pulled from where decisions actually happened: the Slack thread where a customer complaint got discussed, the support ticket that explains why an edge case matters, the call where a scope tradeoff got made out loud. That context gets mapped to the services and repos it will actually touch, so the blast-radius question gets asked before the build, not after the incident. The plan gets built into a structured spec — Problem, User Stories, Architecture Overview, API Endpoints — and both sides sign off section by section, so nothing moves forward on a private assumption. The approved plan becomes the ticket in Jira or Linear and the brief the agent works from, so the thing that got approved is the thing that gets built. And if scope shifts mid-build, that shift is traceable back to who approved it, the same way the original plan was.
The gap between what product decided and what engineering built isn't a communication problem that better standups fix. It's a structural one, and it existed before AI coding agents showed up. What agents changed is the cost of leaving it open — a gap that used to surface in a code review now surfaces in production, because there's no longer a human in the loop slow enough to notice it first. Closing that gap before the agent starts isn't overhead on top of building fast. It's what building fast safely requires.
See how Enact closes the gap before the agent starts
Give every coding agent an approved plan to execute — signed off by product and engineering together.
Book a call →