← Back to Blog

AI coding agents expose the real bottleneck: unfinished decisions

When an agent can implement a ticket in an hour, every unanswered product and technical decision becomes visible in the diff. The teams that ship faster learn to make those decisions explicit before they ask for code.

AI coding agents expose the real bottleneck: unfinished decisions

The bug is often written before the code

An agent gets a ticket: "Add plan-based access to exports."

It can find the billing code, add a check, update an endpoint, write tests, and open a tidy pull request. The diff looks productive. Then someone asks the questions that were missing from the ticket. Is an existing customer grandfathered in? Does an export that started before a downgrade finish? Does a team owner get an exception? What should support see when a request is blocked?

None of those are coding questions. They are product and operating decisions. Yet the code had to choose an answer for each one.

That is the part of AI-assisted development I think teams still underestimate. Agents do not create ambiguity. They make it expensive much sooner. A developer used to fill gaps quietly from experience, ask a colleague, or leave a corner case for the next iteration. An agent fills every gap at once and turns its guesses into a large, plausible diff.

The resulting review is slow for a strange reason. Nobody is reviewing code first. They are reverse-engineering decisions that should have been made before the work began.

Faster implementation changes where the bottleneck sits

For years, the expensive part of a software change was implementation. A rough ticket could be good enough because the engineer who picked it up had time to discover the missing context while writing the code.

That trade has changed. When an agent can produce a first implementation in an hour, the unanswered questions become the limiting factor. A team does not get a faster delivery system by making the build step faster while leaving decisions scattered across Slack, old tickets, somebody's memory, and a meeting that happened last Tuesday.

This is why measuring generated lines of code tells you very little. A larger diff may mean the agent helped. It may also mean it made many more decisions than anyone intended to delegate.

The measure I care about is simpler: how long does it take to move from a clear decision to a production change that the team trusts? If that time does not fall, faster coding has mostly moved the queue into review, QA, and production support.

Vague tickets worked better when humans were doing the guessing

This is not an argument for turning every ticket into a 20-page specification. Most work does not need that. It is an argument for being deliberate about what is still open.

Humans are good at noticing uncertainty. A senior engineer sees "plan-based access" and immediately knows there is a pricing model, an existing customer base, and probably an ugly edge case in billing. They know which person to ask. They can decide that one small detail is safe to leave for later.

An agent cannot reliably make that distinction unless you give it the context. It will often produce a reasonable-looking answer. That is exactly what makes the failure mode dangerous. The code compiles. The tests it wrote for itself pass. The missing decision only appears when a customer, support person, or reviewer sees the behaviour in context.

So the job is not to make prompts more clever. The job is to make the decisions that matter visible enough for an agent, a reviewer, and a product owner to see the same thing.

Write a decision packet, not a bigger ticket

Before giving an agent meaningful implementation work, I would ask the person owning the change to write five short things.

  1. The user behaviour that must change. Write it in a way support or QA could recognise.
  2. What must stay unchanged. This often prevents the most expensive regression.
  3. The systems and boundaries involved. Include the service, data owner, and integrations that the agent may touch.
  4. The decisions still owned by a person. Pricing exceptions, policy choices, acceptable risk, and any trade-off that has not been made.
  5. The evidence required before merge. That may be a test, a migration rehearsal, a screenshot, a before-and-after metric, or a named reviewer.

This does not need to be a new ceremony. For a bounded change, it can fit in ten lines. What matters is that a reviewer can tell the difference between a deliberate choice and an accidental inference.

For the exports example, the packet might say that users on the Pro plan can create new exports, exports already queued must finish, and a downgrade takes effect for new requests immediately. It might state that billing remains the source of truth and that the endpoint must return the same error shape as the existing report-download endpoint. It might leave the question of grandfathered contracts explicitly with the product owner.

Now the agent has a useful job. It can trace the relevant code, make a narrow change, add the cases the team already agreed on, and flag what it could not determine. Reviewers spend their time checking implementation, not discovering the business model hidden inside it.

Put agents where they reduce uncertainty

The most useful agent work often happens before and after the code change, not just in the middle.

Before implementation, an agent can collect the relevant code paths, past incidents, API contracts, and similar pull requests. This gives the engineer a faster way to build a mental model of a system they do not touch every day. It should return sources and uncertainty, not pretend it made the product decision.

During implementation, give it a boundary. "Change this endpoint and the shared access helper. Do not change billing. Add tests for these three cases." That is far more reliable than "implement plan-based access."

After implementation, use another pass to look for missing cases, unintended callers, migration risk, or a mismatch between the packet and the diff. A separate review step matters because the agent that produced the change is not the right system to judge whether it followed the intent.

This is not about creating a busy assembly line of agents. It is about putting assistance at the handoffs where teams normally lose context.

A five-day test for your own team

Pick a recurring kind of change that currently causes rework. It might be a permission change, a pricing rule, a customer integration, or a production bug that keeps returning.

For five working days, require a short decision packet before an agent starts implementation. Keep a record of three things: questions found after the first diff, changes requested during review, and work reopened after release.

Do not compare the agent against a theoretical tenfold productivity gain. Compare this workflow with how the team normally works. If the packet removes review churn and clarifies ownership, keep it. If it turns into paperwork with no visible effect, make it smaller or stop.

You will probably find that some tasks remain too ambiguous to delegate. That is useful information. It tells you where a product decision or system boundary needs attention before more automation will help.

AI does not remove the need to decide

AI can write a surprising amount of code before anyone has agreed on what the system should do. That looks like progress until the uncertainty returns in review or production.

The teams that get more from coding agents do something less glamorous first. They decide what must be true, what may change, and who owns the remaining calls. Then they use the agent to move that decision through the system faster.

That is a more demanding way to work. It is also the one that gives faster code a chance to become faster delivery.

Source

This article develops a point raised in "AI Is Redesigning the Software Development Lifecycle": AI gains come from changing the full delivery system, not from attaching a coding model to one stage.

Book a call