What to Actually Hand a Coding Agent
Coding agents are good at a narrower set of jobs than the marketing suggests and better at them than the scepticism suggests. Which tasks to delegate, how to write the brief, and why the handover matters more than the model.
Generation stopped being the hard part some time in the last two years.
Google’s CEO says three quarters of the company’s new code is now AI-generated, up from half in late 2025. Be careful with that number. It is a self-report from the company with the largest stake in the answer, and Google has never published a definition of what counts as new code. Discount it as heavily as you like and the direction still holds.
The interesting question is no longer whether an agent can write the code. It is which code is worth handing over, and what you have to give it so the result comes back reviewable.
Who This Is For
- Engineers who have tried an agent, got something plausible and unusable, and want to know what they got wrong
- Technical founders deciding how much of a backlog can genuinely be delegated
- Team leads who need a rule for what goes to an agent and what does not
- Anyone who has spent longer reviewing generated code than writing it would have taken
What You Will Need
- A codebase with tests, or a willingness to add them first
- Version control with cheap branching, which you already have
- One task you can describe precisely enough that a competent stranger could check the result
That last item is the whole method. If you cannot describe the finished state, you do not have a task to delegate yet. You have a decision to make first.
The Pattern
Every task splits on one question, and it is not difficulty. It is whether the finished state can be verified by something other than a human reading the diff.
flowchart TD
T[Task] --> Q{Verifiable end state?}
Q -->|Yes| A[Delegate to agent]
Q -->|No| H[Keep it yourself]
A --> V[Test, build or diff proves it]
V -->|Fails| A
V -->|Passes| R[Human review of intent]
H --> D[Decide, then delegate the mechanics]
Note where the human sits. Not at the code, at the intent. The machine checks whether the code does what the test says. You check whether the test says the right thing.
The Four Jobs Agents Are Genuinely Good At
Across the work I have delegated and the work I have taken back, four categories consistently pay.
Writing tests against code that already exists. This is the highest-value delegation in the set and the least glamorous. The behaviour is already fixed, so there is a right answer; the agent is describing reality rather than inventing it. Characterization tests over a module nobody wants to touch are close to free.
Reconnaissance. “Where does this value get set?” across an unfamiliar codebase is a search problem with a natural-language interface. An agent reads faster than you do and does not get bored on the fourth file. Ask for a map, not a change.
Mechanical migrations. A framework version bump, a deprecated call replaced everywhere, an import path moved. The end state is verifiable by the build and the test suite, and the work is tedious in exactly the way that makes humans careless.
Reproducing a bug from a report. Turning “it breaks when I upload a big CSV” into a failing test is a bounded, checkable task, and having the failing test is most of the fix.
What these share is not simplicity. A migration across 400 files is not simple. They share a cheap oracle: something fast and mechanical that says yes or no.
How You Brief It
The industry has settled into three registers, and they are not competing philosophies. They are appropriate at different stakes.
Vibe coding. Describe it, accept what arrives, do not read it closely. Legitimate for a throwaway prototype where the cost of being wrong is that you delete it. It is not a technique for software other people depend on, and the confusion between the two is where most of the horror stories come from.
Goal-based. State the outcome and let the agent choose the route. Right when you genuinely do not care about the route: a script, a one-off analysis, a spike.
Spec-driven. Write the acceptance criteria first, in enough detail to check the result mechanically. Thoughtworks classes this as a feedforward control in its v34 Radar: it constrains the work before it happens rather than catching problems afterwards. It is the register for anything that will be maintained.
A spec does not need to be a document. This is enough:
## Task
Replace the deprecated `client.query(sql)` calls with `client.execute(sql, params)`.
## Done when
- No occurrence of `.query(` remains under `src/` (grep is the check)
- `pytest tests/` passes with no new skips
- No call site changes behaviour: parameters that were interpolated into the
string are passed as bound parameters, not reformatted into it
- Diff touches no file outside `src/db/` and `tests/db/`
## Do not
- Add a compatibility shim
- Reformat unrelated lines
- Change the test assertions to make them passThe last section is doing more work than the rest. Left unconstrained, an agent asked to make tests pass will make tests pass, and editing the assertion is a perfectly rational way to do that.
The Long-Running Task Problem
Agents that work for hours are the current frontier, and people worry about the wrong part of it. The runtime is not the problem. The problem is that nobody sees the intermediate states, so a wrong turn in minute three is still being built on in hour two.
The fix is not a shorter leash. It is a checkpointed one:
# Bound the blast radius, not the runtime.
git switch -c agent/db-migration
# Commit on every green test run, so every checkpoint is a state you can return to.
while agent_step; do
pytest -q tests/ && git commit -am "checkpoint: $(date -Is)" || break
done
# The review unit is the branch, but the recovery unit is the checkpoint.
git log --oneline main..HEADA long-running task with a cheap verifier and a clean rollback is a good bet. The same task without either is a way to generate several hours of work you cannot evaluate.
This is the same control loop that makes AI agents useful for workflow automation rather than merely impressive. The agent is bounded by something that can say no.
Before and After
| Before | After | |
|---|---|---|
| Unit of work | A ticket | A ticket plus its acceptance criteria |
| What you write first | The code | The check |
| Where review time goes | Reading the implementation | Reading the intent and the test |
| Cost of a tedious migration | Days, done carelessly | Hours, done uniformly |
| Cost of an ambiguous task | Hours, done wrong | Hours, done wrong, faster |
| The bottleneck | Typing | Deciding what correct means |
The last row is the one that matters. Delegation does not remove work, it moves it earlier and makes it harder to skip.
Failure Modes to Avoid
- Delegating the decision instead of the mechanics. “Design the caching layer” is not a task. “Implement a read-through cache with these four invalidation rules” is.
- Accepting a diff you would not have written and cannot explain. If you cannot say why a line is there, it is not reviewed, whatever the pull request says.
- Letting the agent edit the test that catches it. Put the assertions out of scope in the brief, explicitly.
- Measuring the wrong thing. Lines produced is not throughput. The team shipping twice the code with the same review capacity has not doubled its output, it has doubled its queue.
- Handing over a codebase with no tests and expecting the agent to be careful. It has no way to be. Add the characterization tests first, which is itself a good task to delegate.
- Assuming the code compiles means the code is finished. Veracode’s 2026 benchmark across more than 100 models found a syntax pass rate near 100% against a security pass rate of 56%. It builds, therefore it looks done.
What to Build First
- Pick one tedious, verifiable task you have been avoiding. A deprecation, a rename, a version bump.
- Write the done-when list before you open the agent. Three to six bullets, each mechanically checkable.
- Run it on a branch with the test suite wired in, so failure is loud and free.
- Review the intent, not the typing. Read the tests first; if they assert the right thing, the implementation is a smaller question.
- Add one guardrail per surprise. Every time the result surprises you, that is a missing line in the brief. Put it there instead of remembering it.
- Only then try a long-running task, and only where a checkpoint gives you a clean way back.
Final Take
The model stopped being the variable a while ago. Every serious agent is competent enough now that what separates a useful session from a wasted afternoon sits on your side of the conversation: whether the task had a checkable end state, and whether you said so before you started.
That is a deflating answer if you came looking for a tooling recommendation. The skill being rewarded is specification, which is the same skill that has always separated the engineers who ship from the engineers who rework. Agents did not change what good looks like. They removed the excuse that writing it down would have taken too long.
Frequently Asked Questions
- What are coding agents genuinely good at?
- Four things, consistently: writing tests against code that already exists, reconnaissance in an unfamiliar codebase, mechanical migrations with a verifiable end state, and reproducing a bug from a report. All four share one property. The finished state can be checked by something other than reading the code.
- Is vibe coding a real technique or a joke?
- Both, depending on the stakes. Describing what you want and accepting whatever comes back is a legitimate way to explore a throwaway prototype. It is not a way to change software other people depend on, because nobody has read the result and no test asserts it. The distinction is not the technique, it is whether the output is going to be maintained.
- What is spec-driven development?
- Writing the acceptance criteria before the agent starts, in enough detail that the finished work can be checked against them mechanically. Thoughtworks classes it as a feedforward control, meaning it constrains the work before it happens rather than catching problems afterwards. In practice it is the difference between reviewing a diff and reviewing a decision.
- Should I let an agent run for hours unattended?
- Only on a task with a cheap verifier and a clean rollback. A long-running agent is not risky because it works for a long time; it is risky because nobody sees the intermediate states, so a wrong turn in minute three is still being built on in hour two. Bound the blast radius, not the runtime.
Enjoyed this article?
Get notified when I publish new articles on automation, ecommerce, and data engineering.
Get in touch