What I actually let coding agents do
I use coding agents every working day, across a payments backend, native mobile apps, marketing sites, and a pile of side projects. This is not a post about whether agents are good. They are, and the debate bores me. This is about the division of labour I’ve actually settled into after a lot of code review, some near misses, and a few messes that were entirely my fault for delegating the wrong thing.
The short version: I delegate by blast radius, not by difficulty.
What they get without hesitation
Exploration is the biggest win and nobody markets it. Dropped into an unfamiliar codebase, an agent that can grep, read, and summarise will map the architecture, find where a behaviour lives, and trace a request path faster than I can, and it doesn’t get bored on file forty. I now treat “go read this repo and tell me how X works” as a solved problem.
The rest of the always-yes list:
- Scaffolding: new projects, new modules, config plumbing, CI files. The blank page is now free.
- Mechanical refactors with a verifier: renames, extractions, API migrations, anywhere the type checker or test suite catches lies. The verifier is the point; the agent supplies the labour, the compiler supplies the trust.
- Test grunt work: table-driven cases, fixtures, the tedious enumeration of edge cases I’d otherwise skimp on. I still write the assertions that define correctness for anything subtle.
- UI iteration: build, screenshot, adjust, repeat. Agents that can see the page close the loop themselves.
- One-off scripts, data munging, internal tooling: things that run once under my eyes, where “wrong” costs a re-run rather than money.
- Documentation, and drafts of almost anything.
Notice the pattern: every item either has a mechanical verifier, or a failure mode I’d catch immediately, or both.
Where my hands stay on the wheel
The other list is shorter but absolute:
- Money paths. Anything touching charges, refunds, payouts, balances. An agent will cheerfully “improve reliability” by adding a retry to a charge call, and a retried timeout in a payment flow is how you charge someone twice. I’ve written about this in Never retry a timeout: a timeout is an unknown outcome, not a failure, and that distinction is exactly the kind of institutional scar tissue an agent doesn’t have unless you write it down.
- Security boundaries: auth, session handling, permission checks, anything that decides who may do what.
- Concurrency and idempotency invariants: code where correctness lives across processes and retries rather than inside one function.
- Schema design and irreversible migrations: the agent can draft the migration; the decision about what the data means is mine.
- Deleting things: data, branches, infrastructure. Not because agents delete recklessly, but because the cost of the rare mistake is unbounded.
The failure mode is quiet
The thing that makes this discipline necessary is that agent failures are rarely dramatic. The code compiles. The tests pass. The PR reads well. The failure mode is plausible code that quietly erodes an invariant nobody restated: a cache added in front of a read that needed to be fresh, an error swallowed to make a test green, a “simplification” that removed the idempotency check it didn’t know was one.
Agents optimise for looking done. That’s not deception, it’s the shape of the objective, and the countermeasure isn’t suspicion of any single diff. It’s making invariants explicit and making verification mechanical.
Practices that make the difference visible
- Write the invariant down before the prompt. My projects carry docs stating things like “raw media never appears in a feed response” or “never retry a timed-out charge.” Agents read these and, in my experience, respect them far more reliably than they infer them.
- Small diffs, always. A 2,000-line agent PR is not a productivity win, it’s a review liability that will be approved on vibes.
- Verification the agent doesn’t control: CI, type checkers, test suites the agent may run but not weaken. When an agent edits the test alongside the code, that edit gets my most hostile read.
- Ask for the refutation: “argue that this change is wrong” is startlingly effective at surfacing what the first answer glossed over.
- Review as if a smart stranger wrote it, because one did: confident, well-read, and carrying none of your scars.
Where this lands
The honest summary is that agents have moved my job up a level. I spend less time producing code and more time specifying invariants, reviewing, and deciding what should exist, which was always the actual job. The leverage is real and I wouldn’t give it back.
But leverage amplifies in both directions. An agent makes a good engineering culture dramatically faster and makes a sloppy one dramatically more prolific, and it does both while looking equally impressive. The blast-radius rule is how I keep the amplifier pointed the right way: delegate the labour freely, delegate the judgement never, and keep the two distinguishable by writing down what must stay true.
No account, no tracking. One vote per reader.