Writing

Why AI agents make scope the bottleneck, and how we write acceptance criteria

Anurag Das · 22 September 2026 · 6 min read

Agents removed the cost of typing. They did not remove the cost of deciding what to type. On every team we have worked with since coding agents became usable, the slowest step in delivery moved from writing code to writing down what the code must do. This piece explains why that happens, and shows the exact format we use for acceptance criteria so the bottleneck stays small.

What changed

A senior engineer given a two-line ticket used to spend the first hour asking questions. That hour was invisible in most plans, but it was where scope got fixed. The engineer read the surrounding code, found the integration nobody mentioned, and either narrowed the ticket or pushed back on it.

An agent does not do that hour. It reads the ticket, reads what it can of the codebase, and produces a complete implementation in minutes. If the ticket said "add retries to the payment webhook", it will add retries. It will not ask whether the webhook handler is idempotent, and it will not notice that the downstream ledger service treats a repeated event as a second payment. The tests it writes will pass, because they test the retries.

The failure is not that the agent is careless. It is that the ticket was never a specification, and the human who used to turn it into one has been removed from the loop.

Where the time goes now

We measured this on a retainer client during their first month with agents in the loop. The chart below is the share of the Technical Lead's week by activity, before and after.

ActivityBefore agentsWith agents
Writing and refining scope10%35%
Writing code45%5%
Reviewing diffs15%40%
Production and incidents20%15%
Meetings and status10%5%
Share of a senior engineer's week on one client engagement, first month with agents.

Scope and review now take three quarters of a senior person's week. That is the right shape, but only if the scope step is done well. Done badly, the review step catches the mistakes and the week is spent rejecting work. Done well, most diffs are approved on the first read.

The five parts of an acceptance criterion

Every backlog item we work on has a criterion in this shape before an agent sees it. The format is deliberately plain. It lives in the ticket, not in a separate document, and it is versioned with the code when it changes.

1. Context

Two or three sentences on why the change exists and what it touches. Name the services, the tables and the external systems. If the agent needs to know that the ledger service is not idempotent, this is where it is said.

2. Behaviour

Numbered, observable statements. Each one is something a reviewer can check without reading the implementation.

  1. A webhook that fails with a 5xx from the ledger is retried up to three times with exponential backoff.
  2. A webhook that fails with a 4xx is not retried and is written to the dead-letter table with the response body.
  3. A retried webhook carries the same idempotency key as the first attempt.
  4. Duplicate delivery of the same event id produces exactly one ledger entry.

3. Non-goals

What the change must not do. This is the section teams skip, and it is the one that stops an agent from being helpful in the wrong direction.

  • Do not change the ledger service.
  • Do not alter the shape of the dead-letter table.
  • Do not add a new queue.

4. Verification

How the behaviour will be proven. Usually three lines: which existing tests must still pass, which new tests must exist, and what the reviewer will check by hand.

  • Existing: the full payments suite in CI.
  • New: a test per behaviour statement above, including one that replays the same event id twice.
  • By hand: replay a captured production webhook against staging and read the ledger.

5. Review window

How long the client has to accept after the lead marks the item done. Agreed once at scoping, then written on every item so nobody has to remember it.

What this looks like in the agent's hands

The criterion above is roughly two hundred words. Writing it takes a senior person twenty to forty minutes, because most of that time is spent reading the code the change will touch. That is the hour the engineer used to spend anyway, moved to before the work instead of during it.

The agent receives the criterion and the codebase. Because the non-goals are explicit, it does not touch the ledger. Because the behaviours are numbered, its tests map one to one. Because the verification section names the suite, it runs it before declaring the work complete. The diff that comes back is reviewable in minutes, because the reviewer is checking four statements rather than reverse-engineering intent.

Objections we hear

This is just a good ticket. Yes. The difference is that it is now mandatory, because the person who used to compensate for a bad ticket is no longer in the loop.

It is too slow for small changes. A small change gets a small criterion: one context sentence, two behaviours, one non-goal, one verification line. Five minutes. The habit is what matters, not the length.

Our product people cannot write this. They do not have to. The Technical Lead writes the criterion; the product owner reads it and says yes or no. Reading two hundred words is a much smaller ask than reviewing a four-hundred-line diff.

What we ask of a new client

Before a pilot starts we ask for the eight to ten items you most want shipped, in whatever form they exist today. We turn them into criteria in the first two days. You read them and correct us. Then the agents start. Most clients tell us afterwards that the criteria were the first time the backlog had been written down properly, and that alone was worth the pilot.

Next step

A 20-minute scoping call. A fixed quote within 48 hours.

Bring the backlog, the system, or the question. We will tell you on the call whether it is a fit.

Scoping call, 20 min

Email hello@unocode.ai with two or three slots that suit you (SGT). We reply within one working day.

Email to book