How I Actually Work With Coding Agents

By: on Jul 8, 2026
A branching tree-like structure covered in glowing multicoloured lights

The Part Nobody Writes About

There is an enormous amount of writing about what AI agents can do. Benchmarks, demos, capability announcements, threads about how someone shipped a whole app in a weekend.

There is almost nothing about how to actually work with one productively. The habits. The session structure. The specific things you say to get good output instead of mediocre output.

That gap is most of what I write about here, one piece at a time. This post is the map: the whole loop from opening a session to merging, with pointers to the posts where I've dug into each piece properly.

Before the Session: Put Context Where It Can't Be Skipped

Every session starts with a prompt file. Not a long one, just one or two sentences setting context. What am I working on, what's the current state, what matters right now.

The critical distinction, and I got this wrong for months: the prompt file is not documentation. It's context for this session. Documentation is for humans over years; the prompt file is for one agent over one afternoon. Conflating them is how you end up with a 900-line instructions file the agent skims and you're afraid to delete anything from.

Which raises the obvious question. If the instructions file is disposable, where do the durable standards live? In the code. The agent always reads the code; the instructions file is optional. Putting your standards in the optional place and then being annoyed they got skipped is a self-inflicted wound, and there's a paper backing that up.

The corollary: whatever you work out during a session should end up somewhere the next session is forced to look. If you're going to burn the tokens, leave something to show for it. Eighty thousand tokens of reasoning through a nasty bug is worth nothing if it evaporates when you close the tab.

The Environment: Boring, and Worth Getting Right

I run agents in tmux, which sounds like a triviality and isn't. Sessions survive a dropped connection, I get panes for agent-plus-logs, and I can reattach from anywhere, including, when I'm being ridiculous about it, from my phone over Tailscale.

The first thing I do in an unfamiliar codebase is fire questions at every part of it simultaneously: what does this service do, what depends on it, where are the failure modes, what does the test suite actually cover. Tracer bullets, with the cost per shot near zero. The picture assembles faster than any sequential investigation would produce it, mostly because you stop having to guess what to ask next. It's the same move I use to get up to speed inside a whole organization, just pointed at one repo instead.

One habit that's paid off more than it should: steal the commands the agent uses. When it reaches for a flag or an invocation I didn't know existed, that goes into my own notes. The agent has perfect recall of ten thousand examples of CLI usage and I have none, which is the same reason it writes better Nix than I do. That's not a threat, it's a tutor that never gets bored of being asked.

During the Session, I'm the Meat Layer

I don't hand the agent a task and come back later. I read what it produces as it produces it.

The division of labor is lopsided in both directions:

  • The agent is fast and tireless. It generates code, tests, comments, diagrams, and refactors without getting bored or hungry.
  • I'm slow and judgment-heavy. I decide whether those artifacts are any good, what gets committed, and what gets encoded permanently.

Together that's faster than I'd be alone and considerably more focused than the agent would be alone. Neither half works without the other, which is a less exciting claim than most of what gets written about this, and closer to true.

The transactional alternative (write a detailed spec, hand it over, review the output) mostly produces work you then rewrite. Not because the agent is bad, but because the spec was wrong in ways neither of you could see until code existed. Watching it work catches that at minute five instead of hour two.

There's a subtler failure I have to actively defend against: shipping 400 lines I don't really understand because the tests passed and the PR merged. That's cognitive debt, the same shape as tech debt, except the fragile thing is you. Making the agent quiz me before I merge is how I pay it down.

When Something Breaks

This is where most of my actual technique lives, because it's where sessions go wrong.

The highest-leverage habit I have: when the agent finds a bug, don't ask it to fix the bug, ask it to write a test for the bug. One sentence of rephrasing turns an ephemeral fix into a permanent record of what was broken plus proof it isn't anymore.

When the same mistake reappears a third time, that test becomes a tripwire. Agents change and memory rots; the test suite is the only part of this that survives a model swap. For the failure modes I'd never think to write a test for, I let the agent fuzz, which is genuinely better than I am at imagining hostile inputs.

All of that is downstream of one economic shift: tests and docs are free now. Anything you skipped because it was tedious rather than difficult deserves reconsidering.

And when the model itself seems to be the problem, it's worth checking whether it actually is. A single run against a stochastic model isn't a test, and "the agent is being dumb today" is a hypothesis, not a diagnosis.

The Phrase I Use Most

When something needs to survive past this conversation, I say: "make this durable."

What's interesting is what happens next. The agent has to decide where the intention should live: an inline comment, a test name, a commit message, an assertion, a file name. Picking correctly requires understanding why the constraint matters, and that understanding is most of what makes the result durable rather than merely written down.

I've tried other framings. "Remember this" doesn't work, because the agent isn't remembering, it's processing. "Don't do X again" doesn't work either; it's a constraint without context, and constraints without context get dropped the moment they're inconvenient.

"Make this durable" names the property I want without prescribing the mechanism, and lets the agent do the thinking about where it goes.

Getting It Out the Door

Commit hygiene is a solved problem I refused to solve manually for years. Git hooks plus an agent means every commit gets a real message and passes the checks without me supplying the discipline.

Then the PR. If I haven't reviewed my own code before opening it, the PR isn't cool enough. Descriptions, diagrams, coverage flags, and changelogs are all processing work, which is precisely the kind to hand off. And it helps to be clear-eyed about what review is for: not finding bugs, but finding code that will be hard to maintain. Reviewers are unreliable at the first and uniquely good at the second.

Ending the Session

I update the prompt file with whatever needs to persist: findings, constraints, open questions, things I tried that didn't work.

That last category is underrated. "I tried X and it failed because Y" saves the next session, mine or the agent's, from walking the same dead end. Negative results are cheap to record and expensive to rediscover.

The Shape Underneath All of It

Step back far enough and the pattern never changes: something generates, something else judges, and the tension between them produces quality. That's GANs all the way down. Your coding agent plus a test suite is a GAN in your terminal, most people just don't call it that.

Which reframes every habit above. The prompt file, the tripwires, the self-review, the quiz: they are all ways of strengthening the judging half, because the generating half got cheap and the judging half didn't.

It's also why orthogonal design matters more now rather than less. When generation is nearly free, the bottleneck moves entirely to your ability to verify and change one thing without disturbing another.

Why I Write This Down

Because the workflow is the part nobody's writing about, and because writing it down is how I notice when it changes.

Every habit here came from a session that went badly. The tripwires came from explaining the same bug four times. The quiz habit came from being asked why my own code worked and having no answer. The durability phrase came from getting tired of re-teaching a lesson that had already been learned and then thrown away.

Those go in the blog. Or a project doc. Or a test.

Somewhere durable, anyway.

Header photo by Bhautik Patel on Unsplash.

Content on this blog was created using human and AI-assisted workflows described in my standards and workflow posts. Original ideas and editorial decisions by Justin Quaintance.