Pairing With an Agent: Granularity Is the Whole Game
Too many interruptions and you stop reading them. Too few and the decision you would have vetoed is already load-bearing.
Checking in is not the same as checking in usefully
An agent that pauses to ask questions is easy to prefer. It feels collaborative, it surfaces ambiguity, and it means you are never surprised by what arrives. Compared with a system that disappears for an hour and returns with a pull request, the pairing model reads as the safer one.
It is safer only if the questions arrive at the right moment. A check-in is valuable when it comes before a commitment that would be expensive to undo, and it is a tax when it comes in the middle of work that was going fine. Most frustration with pairing is not about the number of interruptions; it is about their placement.
The argument here is that granularity is the variable worth managing, and that both failure directions — too fine and too coarse — produce the same visible symptom, which is a developer who stops paying attention.
The two failure directions
Too fine: the agent confirms each file it is about to read, asks whether to proceed after each step, and narrates its way through work you would not have supervised if a colleague were doing it. The interruptions are cheap individually and they destroy the thing pairing was for, because you cannot hold a problem in your head while answering a question every ninety seconds.
Too coarse: the agent asks nothing, makes a structural decision forty minutes in that you would have vetoed, and continues building on it. By the time you see the result the decision is load-bearing, and the choice is between accepting it and discarding an hour.
Neither is a failure of the model. Both are a failure to say where the decision points are, which is information only you have.
The decision points are architectural, not procedural
The useful rule: interrupt on choices that constrain later work, not on steps that implement a choice already made.
Which library. Where a new module lives. Whether to change a shared interface. Whether this is a migration or a parallel implementation. What the data model looks like. Those are commitments — each one makes some futures cheap and others expensive, and reversing them later means unwinding everything built on top.
Which loop construct, what to name a local variable, whether to extract a helper, the order of the arguments: consequences that stop at the function boundary. Nothing downstream depends on getting them right the first time, so a question about them is spending your attention on something a review would have caught for free.
Say it once, at the start
The instruction that changes the interaction most is a short statement of where you want to be consulted, given before the work rather than as correction during it.
Work through this without checking in on implementation details.
Stop and ask me before:
- adding a dependency
- changing anything in src/api/types.ts (shared contract)
- creating a new top-level directory
- changing the database schema
- deleting a test
Everything else: decide, do it, and tell me at the end what you chose
and why. If you are unsure whether something is on that list, it is.
The last line matters more than the list. It converts an ambiguous case from a guess into a rule, and it is the sentence that stops the agent asking about variable names while barrelling through a schema change.
Ambiguity in the requirement is the one to always surface
One category deserves an unconditional interrupt: a question about what the software should do that the agent cannot answer from the code.
Should a deleted record be recoverable. Is this rate limit per user or per organisation. What happens when the external service is down. An agent encountering these will pick something reasonable and continue, and reasonable is not the same as correct, and the choice will be buried in an implementation nobody re-examines.
These are cheap to ask and expensive to guess wrong, which is exactly the profile that justifies an interruption. Ask for them explicitly, because the default behaviour is to resolve them silently.
Do not answer a question you have not thought about
The other half of the discipline is on your side. A question arriving mid-flow is easy to answer quickly and wrongly — you glance at it, recognise the shape, and say yes, because you were thinking about something else.
An answer given without attention is worse than no question, because it carries your authority. Everything downstream is built on a decision the agent believes you made deliberately. If you are not in a position to think about it, say so and come back — the agent will wait, and waiting is cheaper than the alternative.
Presenting intermediate steps is a separate lever
Showing you work is not the same as asking permission, and the two get conflated. An agent can narrate what it is doing without blocking on you, which gives you the option to intervene without imposing an obligation to respond.
That is often the right setting for medium-stakes work: visible progress, no forced turn-taking, and an interrupt available if something looks wrong. The skill of watching that stream and knowing when to stop it is its own thing, covered in interrupting an agent.
Pairing has a cost people do not count
Sustained supervision is expensive in a way that is easy to miss because the cost is yours rather than the system's. A pairing session occupies you completely: you cannot do other work, you cannot leave, and your attention is consumed by the fastest-moving thing in the interaction.
Two hours of pairing costs two hours of your day. Two hours of asynchronous work costs the twenty minutes you spend reviewing it, and the difference is not made up by the quality gain unless the task genuinely needed supervision.
So the honest question about any task is whether it needs you present, and the answer is often no. That decision — which work to supervise and which to hand off — is worked through in asynchronous task handoff.
Where pairing is clearly right
Unfamiliar code, where you are learning at the same time. Anything where the requirement is being discovered rather than implemented — you find out what you want by seeing something wrong. Debugging with a live system, where your judgement about what to try next is the scarce input. High-stakes changes where a wrong turn is expensive. And anything you cannot specify well enough to hand off, which is more work than people admit.
The common thread: pairing is right when the information needed to make progress is in your head and cannot be written down faster than the work proceeds.
Where pairing is a waste of a person
A mechanical refactor with a passing test suite. A well-specified bug with a reproduction. Adding a case to an established pattern. Anything where you could write the acceptance criteria down completely before starting — which is the test, and it is a good one, because if you can write the criteria you can hand off and check the result.
Supervising those feels productive and is mostly watching. The time is spent, the outcome is unchanged, and the reason it happens is that supervision is the default rather than a choice.
The check-in that is actually valuable is at the end
Underrated: the most useful conversation is usually a summary of decisions made, delivered when the work is done. Not a list of changes — the diff is the list of changes — but the four or five judgement calls, with the alternatives that were rejected.
That is a five-minute read, it surfaces exactly the things you would have wanted to be asked about, and it is retrospective rather than blocking. When one of them is wrong you find out at review time, which is far earlier than the alternative, which is finding out in three weeks.
Mode-switching mid-task
Granularity does not have to be fixed for a session. The natural pattern is tight at the start — while the approach is being settled — then loose through implementation, then tight again at integration.
Saying that explicitly works: "check with me on the approach, then run through the implementation without stopping, then let me look before you touch anything in the shared module." That is three granularities in one task, and it matches where the risk actually sits rather than applying one setting to work whose stakes change.
Asking clarifying questions is a skill you can request
One more asymmetry. Agents ask questions less than they should about requirements and more than they should about permissions, and both are adjustable by saying so.
"Before you start, tell me what you are assuming" is a prompt that surfaces the requirement ambiguity in one turn, at the cheapest possible moment. It produces a list of three or four assumptions, most of which are fine and one of which is usually wrong, and correcting that one costs a sentence instead of a rewrite.
What good pairing looks like from outside
Very few interruptions, each about a decision you actually care about. An opening exchange that surfaces assumptions before any code is written. A visible stream you can watch or ignore. A closing summary of judgement calls. And no moment where you approve something you have not read, because there were few enough prompts that reading each one was possible.
That is achievable with two sentences at the start of the session, which is the whole practical content of this article. The default granularity is someone else's guess about your risk tolerance, and replacing it with yours costs almost nothing.
The transcript is not a substitute for having been there
A small point with practical consequences. After a pairing session you have a transcript, and it is tempting to treat it as a record you can go back to. In practice nobody does: it is long, it is mostly mechanical, and the reasoning that mattered is distributed across forty exchanges.
So the durable output of a pairing session should be written deliberately — a paragraph in the pull request, a comment in the code, a note in the issue — rather than assumed to be recoverable from the log. The decisions you made together exist in your head and in a scrollback that will be gone next week.
Two people and an agent is a different arrangement
Worth flagging because it is increasingly common and it behaves badly by default. Two humans pairing with one agent produces a coordination problem: the agent responds to whoever typed last, the two people have different mental models of what it was asked, and corrections cross.
The arrangement that works is one driver at a time, explicitly, with the other person reading. That is the same rule as human pairing and it is easier to forget here, because the agent will happily accept instructions from both and produce something that is the average of two intentions.
Fatigue applies here too
The last practical caution. Pairing is cognitively demanding in a way that does not feel demanding while it is happening, because the pace is set by something that does not get tired. Two hours in, you are approving things you would have questioned at the start, and the interaction still looks identical.
That is the same mechanism as approval fatigue in a different costume, and the mitigation is the same: keep the interruption count low enough that each one is genuinely considered, and stop the session before your attention degrades rather than after you notice it has.
The value of a pairing check-in depends entirely on where it falls: interrupt on commitments that constrain later work — dependencies, shared interfaces, schemas, structure — and never on implementation details a review would catch anyway. State that list at the start, add "if you are unsure whether something is on it, it is", and always surface ambiguity about what the software should do. Then recognise that supervision costs your whole day, and that a closing summary of judgement calls is often worth more than any interruption.