Skip to content

Pair Programming With a Model: A Working Method

5 min read · updated August 3, 2026

The phrase suggests two peers. It is nothing like that, and the method that works comes from taking the difference seriously rather than pretending it away.

The roles are inverted

In human pairing the driver has the keyboard and the context; the navigator has the perspective. Here the driver is fast, tireless, extremely well read, and has no stake in the outcome, no memory of last week, and no knowledge of anything you did not put in front of it. You hold all the context and none of the typing.

That inversion sets the division of labour. You own the goal, the acceptance criterion, the constraints and the judgement about when to stop. It owns transcription, recall of API surface, enumeration of cases, and the first draft. A session goes wrong when you delegate upward — asking it to decide what “done” means — or hoard downward, typing things it could have typed while you supervise character by character.

The loop, six steps

  • 1. State the acceptance criterion in one sentence, first. Ideally as a test that does not yet pass. “issueInvoice called twice with the same idempotency key creates one invoice.” If you cannot write that sentence, the session will not go well, and discovering that now costs nothing.
  • 2. Ask for a plan, not code. Five bullets and the files it intends to touch. Explicitly: no code yet.
  • 3. Correct the plan. This is the step people skip and it is where the entire value of the method sits. See below.
  • 4. One change at a time, small enough to read. If the diff is longer than a screen, the scope was too big — say so and split it rather than reading it badly.
  • 5. Run the test yourself. Not “does this look right”, not a report from the model that it passes. Your terminal, your eyes, every time.
  • 6. Commit at every green. Small commits, squashed later if you like. The commit is the undo, and having a cheap undo is what makes step 4 of the stopping rules possible.

Why the plan is where the leverage is

Correcting a plan is four sentences of reading and one sentence of reply — call it thirty seconds. Correcting the same misunderstanding after it has become 300 lines means reading the diff, identifying which parts are wrong, explaining, and re-reading the revision: twenty minutes, optimistically, and you may miss a piece.

The ratio is roughly forty to one, and it applies to the same information either way. Everything about how a session feels — smooth and productive, or a grinding sequence of “no, not like that” — is determined by whether the correction happened at step 3 or step 5.

What to look for in a plan, specifically: files it intends to touch that surprise you (it has misunderstood the architecture), files it has not mentioned that you know must change (it cannot see them — fix the context, not the plan), a step that says “update the tests” when the tests should be driving, and any step that is vague where the difficulty is. Vagueness in a plan is where the model has nothing and is deferring.

One phrasing earns its place in every session: before you write anything, tell me what you would need to know that you do not. The answers are frequently the missing constraint, and supplying it is cheaper than watching it be guessed.

Five triggers for stopping

“Know when to stop” is useless advice. These are observable events; when one fires, stop, git reset --hard to the last green commit, and either re-scope or do it yourself.

  • Two consecutive fixes that do not move the failing test. The same condition as the no-progress rule for an automated loop, and it applies identically to a human-driven one. Two failed attempts means the model’s model of the problem is wrong, and a third attempt from the same understanding will also fail.
  • A fix you cannot explain. The test is green and you do not know why. This is not success; it is an unexplained state change in your codebase. Either get the causal chain in one sentence or revert.
  • The diff grows while the test stays red. Additions accumulating without the failure moving means it is trying things. Trying things is expensive and it does not converge.
  • It asks you something it should already know. “What does the Invoice type look like?” when you gave it the file. That is a context problem — the file is buried, the transcript is too long, or the session has drifted — and no amount of re-prompting fixes a context problem.
  • The third agreement without a behaviour change. Enthusiastic acceptance of your correction followed by materially the same code. The model has no way to signal “I do not know how to do this”, and this is what it looks like when it does not.

The reason these are worth writing down is sunk cost. At minute 25 of a task you estimated at 15, continuing feels closer to done than restarting. It is not: the expected time from here is set by whether the current approach can work, and the twenty-five minutes are gone either way. What you gained is real, though — you now know the failure mode, the files involved and the shape of the wrong answer. Reverting and restarting with that knowledge is usually faster than continuing, and it is only cheap because you committed at every green.

Session hygiene

  • New session when the topic changes. A transcript carries stale premises — a file you already changed, an approach you abandoned, a constraint that no longer holds — and the model keeps honouring them, which is one of the mechanisms behind a long session getting worse. It is also quadratic in cost.
  • Do not delegate the acceptance criterion, the security boundary, or the decision to merge. These are the three things where being wrong is expensive and where the model has no stake.
  • Say what you tried and rejected. Without it you will be offered it again, confidently.
  • Keep the repo instruction file as the durable memory. Anything you find yourself explaining in a third session belongs in the file every session reads, not in this transcript.

A last honest note: this is a method, not a claim. It makes sessions less frustrating and it makes the failures visible earlier, which is worth having on its own. Whether it makes you faster depends on which band of work you are in, and the evidence on that is genuinely mixed — including one randomised trial in which experienced developers were slower while believing they were faster. The method above will not settle that for you. What it will do is make the moment where it is not working arrive in five minutes instead of fifty.

Pair Programming With a Model: A Working Method · Multigrid