Skip to content
8 min read

AI pair programming needs a working agreement

AI pair programming works when teams define session boundaries, review every change, record decisions, and test whether humans retain the knowledge.

AI pair programming needs a working agreement
Table of Contents

AI pair programming fails quietly when the agent writes code faster than the human can explain it. The pull request may pass, yet nobody can say why a boundary moved, which assumption the test encodes, or what to inspect when production behaves differently. That is not pairing. It is unattended delegation with a person still sitting at the keyboard.

A useful pairing practice makes three things visible: the session's contract, the evidence behind each accepted change, and the knowledge the human keeps afterward. Speed matters, but speed without those records creates a debt that appears during review, onboarding, and incidents. I have seen teams celebrate a large agent-generated change on Tuesday and spend Friday reconstructing what it did. The etiquette below prevents that waste without turning every prompt into a ceremony.

Pairing starts with a written contract

Every session needs a small written contract before the agent touches the repository. State the outcome, the permitted area, the constraints, and the proof of completion. A prompt such as fix the billing bug gives the agent room to redefine the task while it works. A contract gives both partners a stable object to challenge.

I use a session brief that fits on one screen:

Outcome: Reject a renewal when the stored payment token is expired.
Allowed: billing/renewal, tests/billing
Do not change: public API, database schema, retry policy
Evidence: failing test first, focused suite passes, diff reviewed
Stop when: a schema change or policy decision appears necessary

The Allowed line is a boundary, not a prediction. The agent can inspect related code when needed, but it must ask before editing outside that area. The Do not change line protects decisions that look incidental in code but carry product or operational consequences. The stop condition matters most. It tells the agent which discoveries belong to the human.

The human should also name the decision owner. One engineer can drive while another reviews, but a machine cannot accept accountability for a pricing rule, a data migration, or a security tradeoff. If the session uncovers one, pause and record the choice instead of hiding it inside an implementation.

A good contract stays narrow enough to verify in one sitting. It may cover one bug, one refactoring seam, or one endpoint. It should not say modernize authentication or improve performance. Those are programs of work. Split them into observable changes with explicit constraints, then open a fresh session when the first result changes what you know.

Short sessions beat heroic context windows

End a pairing session when the task changes shape, the evidence becomes hard to hold in memory, or the agent starts revisiting settled decisions. A large context window does not make a long session coherent. It only lets the model carry more text, including stale assumptions and rejected approaches.

Forty-five to ninety minutes is a useful operating range for many code tasks, not a law. The stronger rule is one outcome per session. If a bug fix reveals a missing abstraction, close the bug session with its findings. Start a separate design session for the abstraction. That boundary makes the history readable and prevents a local repair from turning into a repository tour.

Watch for three reset signals. First, the agent proposes the same failed idea in new words. Second, you can no longer summarize the current diff without rereading it. Third, the session brief no longer describes the work on screen. At any of those points, preserve the useful state and restart with a clean brief. Continuing usually feels faster because the conversation is already open, but it produces more review work.

A restart packet should contain facts, not a transcript dump. Include the current goal, files changed, tests run, decisions accepted, approaches rejected with reasons, and the next unresolved question. Five precise paragraphs beat fifty pages of dialogue. The transcript can remain available for audit, but it should not become the next agent's primary context.

This discipline also makes switching agents less risky. A session that depends on one model remembering its own conversational path cannot be reproduced. A session whose state lives in the repository, test output, and a concise handoff can continue with another engineer or another agent. Reproducibility is a stronger form of continuity than conversational memory.

Grant context by relevance and risk

Give the agent the smallest context that lets it reason correctly, then expand access when a concrete question requires it. Dumping an entire repository into a prompt can expose secrets, bury local conventions, and encourage changes across unrelated modules. Starving the agent is also bad: it will invent the missing contract from nearby code.

Start with the session brief, the target file, its tests, and the nearest interface or call site. Add architecture records, operational constraints, or data examples only when they affect the decision. For sensitive work, replace production values with representative fixtures. An agent needs the shape of a token record to write validation logic; it does not need a real token.

Separate reading permission from editing permission. Many tools make both feel like one broad grant, but the difference is operationally important. The agent may need to read a shared type or deployment file to understand a constraint. That does not authorize it to rewrite those files. Record edit boundaries in the brief and inspect the final changed-file list before looking at line-level details.

Secrets require a harder rule. Do not paste credentials, customer records, private incident notes, or unredacted production logs into a session because the agent asks for more context. Create a sanitized reproduction. If the bug cannot be reproduced without sensitive data, use approved internal tooling and the organization's actual data-handling policy. Convenience is not consent.

Context also has a time dimension. Build output from twenty minutes ago may describe a different diff. A design note may predate the interface now in production. Label evidence with the command and commit that produced it. When an agent cites a comment as authority, check whether tests, types, or current behavior contradict it. Comments explain intent; executable evidence shows what the repository enforces today.

Agent output stays a proposal until a human proves it

Treat every generated patch as an untrusted proposal, even when it compiles and looks idiomatic. The reviewer must understand the behavioral change, inspect the diff, and run evidence appropriate to the risk. Accepting a patch because the agent says tests pass is not review.

Use a fixed review order so polished code cannot distract from a wrong premise:

  1. Restate the requested behavior in your own words.
  2. Inspect the changed-file list for scope drift.
  3. Read the tests before the implementation.
  4. Trace error paths, state changes, and external calls.
  5. Run focused checks, then the broader suite required by the repository.

The sequence starts with intent because an agent can solve the wrong problem cleanly. Reading tests before implementation exposes whether the test proves the requirement or merely mirrors the generated code. A test that calls a new helper and asserts its return value may say nothing about the production path that was supposed to change.

Ask the agent to explain the diff, but do not accept the explanation as evidence. Compare each claim with the patch. If it says the change preserves backward compatibility, identify the old input and run it. If it says an error is impossible, locate the guard. Generated explanations often sound more complete than the code because prose does not face a compiler.

Git provides a cheap first pass that teams skip too often:

git status -s
git diff
git diff HEAD

The Git manual separates changes in the working tree from changes staged for commit. Review both views because an agent can leave an intended file unstaged or stage an unrelated edit. These commands reveal scope and content, but a clean diff does not validate behavior, security, or operational fit.

For high-risk paths, require a second human reviewer or a separate verification session that starts without the original agent's explanation. Authentication, authorization, money movement, destructive migrations, and concurrency deserve independent reasoning. The point is not distrust of AI as a category. These areas already deserved stronger review when humans wrote every line; generation speed increases the amount of code that can reach the gate.

Review the negative space around the diff

Put an owner on agent work
Fractional CTO leadership sets accountable engineering ownership around Claude Code, Codex, and multi-agent pipelines.

The dangerous part of an agent-authored change often sits outside the lines it edited. Review what should have changed but did not, what caller now receives different behavior, and which operational signal would reveal a failure. Line comments alone cannot answer those questions.

Consider a renewal bug. The agent adds an expiry check to the card adapter and writes a unit test. The focused suite passes. During production rollout, renewals using a second payment provider still accept expired tokens because that provider bypasses the adapter. The patch is locally correct and systemically incomplete. A reviewer who searches for all implementations of the payment interface catches the omission; a reviewer who reads only the patch does not.

Use an impact pass after the line review. Search for other implementations of changed interfaces, callers of changed functions, duplicated validation logic, metrics tied to the old outcome, and runbooks that name the old failure. Keep the search tied to the behavior. A repository-wide cleanup in the same pull request makes the proof harder, not better.

Review deletions with particular care. Agents remove code confidently when it appears unused in the visible graph. Reflection, configuration, migration tooling, scheduled jobs, and external consumers may not appear in ordinary references. Ask what invoked the deleted path, how you know it no longer does, and what rollback would restore it. If the answers depend on production observation, stage the removal behind the organization's normal release controls.

Check absent tests as well as present ones. Boundary values, retries, cancellation, permissions, partial failure, and idempotency often vanish from the happy path. Do not demand every category mechanically. Choose the failure modes implied by the changed behavior. A retry test matters when the patch moves an external call; it adds noise when the code only formats a local message.

This is where small pull requests earn their keep. Google Engineering Practices argues that reviewers can respond faster and inspect small changes more thoroughly. I agree, with one qualification: a small diff can still hide a wide behavioral radius. Size the change for comprehension, then inspect the radius separately.

The human owns every accepted line

Authorship records who produced text; ownership records who can defend and maintain the result. Teams blur those ideas when they label a pull request AI-generated and treat the label as a waiver. It is only provenance. The engineer who approves the patch owns its behavior exactly as if they typed it.

That rule changes pairing etiquette. The human should interrupt when the agent makes a decision that cannot be explained from the brief, repository evidence, or an explicit product choice. The human should reject sprawling changes even if they look clever. The human should also give precise feedback: preserve the public error code because mobile clients branch on it teaches the session more than try again.

Do not make the agent perform agreement. Asking Are you sure? invites another confident answer. Ask for falsifiable work: identify the call sites, show the failing test before the fix, compare two approaches against the stated constraint, or produce the exact command output. Evidence can still be incomplete, but it gives the reviewer something concrete to challenge.

Pairing also does not excuse unsigned decisions. Record who approved a schema change, security exception, or product behavior and where the rationale lives. The conversation transcript is a poor decision record because readers must reconstruct the final choice from proposals and corrections. Put durable decisions in the repository's normal design record, issue, or pull request description.

Managers must protect the engineer's right to slow down. If output targets reward merged volume while incidents and review effort remain invisible, people will accept agent patches they do not understand. That is an incentive failure, not an etiquette failure. Measure completed outcomes, escaped defects, review delay, and ownership health together. Generated line count tells you almost nothing.

Interrupt the agent at decision boundaries

Price the verification work
A Team & AI Audit puts review effort beside payroll savings so the decision uses complete economics.

Good pairing includes interruption. Stop the agent when it crosses a decision boundary, not every time it chooses a variable name you dislike. Constant stylistic correction wastes attention and encourages the human to supervise keystrokes while missing behavioral choices. A repository formatter can settle spacing; only the team can settle a compatibility promise.

A decision boundary appears when several plausible implementations carry different consequences. Choosing whether to retry a payment, change a public error, add a dependency, broaden data access, or alter a migration order belongs there. The agent can present options and evidence. The human must connect the choice to product behavior and operational risk. If the brief already settles the choice, point back to the constraint and require a smaller patch.

Use comments that state the violated constraint and the observable correction. This is wrong gives the agent no stable direction. Keep retries at two because the provider may charge on each accepted request; add a test that counts calls identifies both the reason and the proof. The same comment helps a human partner and leaves language suitable for the pull request record.

Do not negotiate with a patch that has drifted far beyond the task. Revert the proposal within the session, restate the allowed files and outcome, and ask for the smallest change that satisfies them. Once a sprawling refactor becomes the conversational baseline, each correction tends to preserve parts of it. Starting again from the last accepted repository state is usually cheaper than editing an invented architecture back into shape.

The agent should surface uncertainty directly. Ask it to distinguish repository facts, inferences, and unresolved questions in its plan. A fact might be that both providers implement the same interface. An inference might be that they share the same expiry semantics. The unresolved question is whether a product rule permits rejection before the provider call. Those categories demand different treatment, and prose that blends them creates false confidence.

Silence also communicates during pairing. When the agent finishes a patch and immediately offers another improvement, pause. Read the current work before accepting more scope. Tools often make continuation effortless, but each extra change increases the surface you must understand. The polite response to an attractive bonus refactor is often to record it as separate work.

Agents can critique one another, but that does not create human approval by accumulation. A verifier agent may find an untested branch, compare the patch with the brief, or challenge a dependency choice. Its output is another proposal for the human to assess. Two confident model responses that agree can share the same missing context. Independent prompts help only when the verification path uses different evidence rather than the first agent's narrative.

Pairing etiquette applies to the human side of the team as well. Tell reviewers which parts came from agent exploration, where you intervened, and which assumptions deserve special attention. Do not dump the transcript on them and call it transparency. Give them the accepted decisions and the evidence, then remain available to answer for the change.

When a reviewer rejects a generated approach, preserve the reason in the ordinary code review. Future sessions can then see the constraint without relying on one person's memory. Do not preserve every failed suggestion. Record the ones another reasonable engineer or agent might propose again, especially when the rejection rests on product policy, an external contract, or a production failure that the code cannot reveal.

The session should feel like a technical conversation with unequal typing speed, not a command queue. The human defines success, challenges assumptions, and owns acceptance. The agent searches, drafts, compares, and revises. Confusing those roles either reduces the agent to expensive autocomplete or promotes it into a decision maker that cannot carry responsibility.

Close with a record another engineer can use

A session is not complete when the code works on the driver's machine. It ends when another engineer can see what changed, why it changed, how it was checked, and what remains uncertain. The closing record should live beside the team's ordinary work, not inside a private chat history.

Use a compact closeout block in the pull request description or work item:

Outcome: Expired renewal tokens are rejected before provider calls.
Changed: renewal validator, both provider paths, boundary tests
Verified: billing unit suite; provider contract suite; manual expired fixture
Decisions: retained public error code for existing clients
Unresolved: alert threshold still uses the old failure category
Human owner: initials or team role

Write the block from observed evidence. Tests pass is too vague; name the suites or commands. Refactored billing hides behavior; name the path and invariant. The unresolved line is not an embarrassment. It prevents the next person from mistaking a bounded change for a complete system repair.

Then perform a teach-back without the agent. The driver explains the new behavior, the main alternative rejected, one failure mode, and the rollback path to a colleague or into a short voice note. If the explanation collapses without reopening the chat, the team did not retain enough knowledge. Reopen the diff and fill the gap before merging.

Do not archive full transcripts by default. They may contain sensitive context, repeated dead ends, and statements the team rejected. Follow the organization's retention and privacy policy. Preserve the brief, decisions, evidence, and final closeout because those artifacts describe the accepted work. Keep a transcript only when audit or investigation needs justify it.

A clean close also improves the next session. The agent receives established facts instead of a conversational fossil. The next human reviewer can distinguish settled constraints from open questions. Documentation becomes a byproduct of disciplined work rather than a reconstruction scheduled after everybody has forgotten the details.

Test whether knowledge survived the pairing

Check the savings before scaling
The fixed $5,000 audit identifies at least $50,000 yearly savings or it is free.

Knowledge retention needs observable checks because self-reported understanding is generous. Ask whether the team can modify, debug, and operate the changed code without replaying the original conversation. If only the driver and the chat transcript can explain it, the organization has rented an answer rather than gained capability.

Use delayed checks instead of quizzes immediately after the session. At the next review or planning cycle, ask another engineer to locate the invariant, explain the failure signal, or make a small adjacent change using the closeout record. Friction reveals where the record or code structure is weak. The goal is not to catch people out; it is to find knowledge that never left the session.

Track a few operational measures over several weeks:

  • Time a reviewer spends understanding an agent-assisted change.
  • Rework caused by missed scope or wrong assumptions.
  • Changes that only the original driver can safely modify.
  • Incidents where the team cannot explain generated behavior.
  • Closeout records that omit verification or an owner.

Do not turn these measures into individual scorecards. People will hide agent use, split work artificially, or overdocument harmless changes. Review patterns at team level and sample actual pull requests. A rising review burden can erase generation gains even while delivery dashboards look busy.

Rotation is the best retention test I know. Move drivers and reviewers across a bounded area while keeping a knowledgeable owner available. If every agent-assisted module becomes the private territory of the person who prompted it, the pairing practice has recreated the silo it was meant to reduce. If another engineer can take the next change from the recorded constraints and tests, the knowledge has become team property.

Training should focus on judgment, not prompt tricks. Engineers need to define behavior, read unfamiliar code, design tests, reason about failure, and write decisions. Prompt fluency helps them communicate those skills to an agent. It cannot replace the skills. A team that teaches only tool syntax produces fast operators who still need somebody else to verify the work.

Scale the practice only after the review system holds

Scale agent pairing when review capacity, repository controls, and knowledge records can absorb the extra output. Adding more agents before those controls work increases the queue of plausible patches. The cost moves from writing to verification, and founders often discover it only after senior engineers become full-time reviewers.

Start with bounded work where outcomes are easy to test: adding coverage around existing behavior, routine migrations with reversible steps, internal tooling, or a small feature behind established interfaces. Keep high-risk decisions with experienced owners. Expand scope when the team can show clean closeouts, manageable review time, and successful ownership rotation.

Set repository rules that do not depend on memory. Protect main branches, require the checks appropriate to each area, keep secrets outside agent context, and make code owners visible. These controls help human-only work too. Agent speed simply makes weak gates fail more often.

The economics deserve a complete calculation. Count subscription and compute costs, reviewer time, rework, incident exposure, and the time saved in implementation. Then compare completed, operated outcomes rather than generated output. A team can produce three times as many patches and ship no faster if review and product decisions remain constrained. It can also become much smaller and faster when senior engineers own narrow outcomes and agents handle well-specified execution.

For founders who cannot see where the constraint has moved, a Team & AI Audit from oleg.is can map the work, review load, agent setup, and savings case before a larger transformation. The useful deliverable is a decision about team design and controls, not a pile of generic prompts.

Before broad rollout, sample a finished change without warning and ask the current owner to reconstruct its path from request to production signal. They should locate the contract, show the decisive test, identify affected callers, explain the accepted tradeoff, and name the rollback action. This exercise tests the whole system at once. If the answer depends on searching a private transcript or summoning the original driver, fix the record before increasing agent volume. Repeat the sample after team rotation and after a real incident, when documentation weaknesses become easier to see. The practice has matured when this reconstruction feels ordinary, not when agents produce impressive patches during a demonstration.

Good AI pair programming etiquette is visible in the repository after the chat closes. You can find the contract, trace the evidence, name the owner, and hand the next change to someone else. If any one of those is missing, generate less code until the team can prove what it already accepted.

Frequently Asked Questions

How long should an AI pair programming session last?

Aim for one verifiable outcome, which often fits into 45 to 90 minutes. End sooner when the task changes shape, the brief becomes stale, or neither partner can summarize the diff without rereading it.

Should every AI-generated change get human review?

Yes. A human must understand the behavior, inspect the scope, and verify evidence before accepting it. Automated checks support that decision, but they do not own it.

What context should I give a coding agent first?

Start with the outcome, edit boundaries, target code, nearby tests, and the relevant interface. Add more context to answer a specific question instead of dumping the repository into the session.

Is it safe to paste production logs into an AI coding session?

Do not paste unredacted logs unless your organization's approved tooling and data policy explicitly permit it. Build a sanitized reproduction with the same structure and failure condition whenever possible.

Who owns code written by an AI agent?

The engineer who accepts the patch owns its behavior and maintenance. An AI-generated label records provenance; it does not reduce the reviewer's responsibility.

Should teams save complete agent chat transcripts?

Not by default. Preserve the brief, accepted decisions, verification evidence, and closeout record, then follow your retention policy for transcripts that may contain sensitive or rejected material.

How do I know whether developers retained the knowledge?

Ask another engineer to explain or modify the code later using the repository record, without replaying the chat. If that fails, improve the tests, decision record, or code structure before expanding agent use.

Can an agent approve its own pull request?

No. A second agent can find issues or run an independent check, but a named human still makes the acceptance decision. High-risk changes deserve an independent human reviewer as well.

What belongs in an AI session closeout?

Record the outcome, changed areas, exact verification, accepted decisions, unresolved risks, and human owner. Keep it short enough that the next engineer will actually read it.

How should a startup measure AI coding productivity?

Measure completed outcomes alongside review time, rework, escaped defects, and ownership concentration. Generated lines or patch counts can rise while delivery slows, so they are poor management measures.

Related Posts