code-anything.com
Log inStart free

Engineering

Why an AI Coding Agent Should Only Touch Your Repo Through a Reviewed Pull Request

Autonomy is not the same as access. The safest place for an AI agent to be powerful is inside a pull request you control.

· 15 min read

There is a tempting but dangerous mental model of AI coding agents: a smart entity with write access to your repository, quietly improving things. It is dangerous because it collapses two things that should stay separate — capability and authority. An agent can be extremely capable and still have no authority to change your main branch directly. The mechanism that keeps those separate is the same one you already trust for human engineers: the reviewed pull request.

This piece makes that case in detail, then walks through what has to be true underneath for the pull request to be worth reviewing rather than a formality.

Capability and authority are different axes

The most common framing error in discussions about AI agents is treating "how good is it" and "how much should it be allowed to do unsupervised" as the same question. They are not even correlated. Your most senior engineer is extremely capable and still does not push to main. A junior contributor with a one-line fix and a senior architect with a refactor go through the identical gate, because the gate is not a judgement about the person.

Once you separate the axes, the design question gets much easier. You want maximum capability — an agent that reads the whole codebase, runs the tests, iterates until it is green — combined with minimum standing authority. Those are not in tension. They live in different parts of the pipeline.

The trust boundary you already have

Mature engineering teams almost never push directly to main. Work happens on a branch, it is opened as a pull request, it runs through CI, and a human reviews it before it merges. This is not bureaucracy — it is a trust boundary. It means no single actor, however senior, can unilaterally change production code without a second set of eyes and an automated check.

An AI agent should sit on the same side of that boundary as every other contributor. The agent proposes; the pull request is the proposal; you decide. Anything less asks you to extend more trust to an automated system than you would extend to a human teammate, which is exactly backwards.

The goal is not an agent you have to trust blindly. It is an agent whose work you never have to trust blindly, because every change arrives as a reviewable diff.

What happens when you connect a repository

Before any of this matters, the agent has to understand the codebase it is being asked to change. Connecting a repository is a sequence rather than a single action, and each stage exists for a reason.

  1. Clone. The repository is cloned into an isolated environment. Access is requested only to clone and import, and the token stays server-side.
  2. Load. The code is loaded into the editor so you can see what the agent sees.
  3. Read. The codebase is indexed — this is the stage that determines how good every later change will be.
  4. Install. Dependencies are installed, because an agent that cannot run your code cannot verify its own work.
  5. Start. The live preview comes up, so behaviour can be observed rather than inferred.

You can point at a repository either by connecting your GitHub account and picking from the list, or by pasting a repository directly — both the full URL form and the shorter owner/repo form work. Private and archived repositories are labelled in the list so you do not open the wrong one by accident.

Two indexes, not one

Reading the codebase builds two complementary indexes, and the distinction between them is the single most useful technical detail in this whole article.

The first is semantic: an index of what the code does. This is what lets you describe behaviour without knowing file names. "Where do we calculate the cart total" is a usable instruction precisely because there is an index of meaning rather than only of text. Without it, you would be reduced to grepping for a function name you may not remember correctly.

The second is symbol-aware: an index of definitions and references. This is what lets the agent see what a change will ripple into. Renaming a function is trivial until you realise it is called in forty places. A symbol-aware index knows about all forty, so the agent can make a change that is complete — every caller updated — without the change being broad. Completeness and minimalism stop being in tension.

Both indexes serve the same end goal: a diff small enough to review honestly. A pull request is only safe to review if it is focused. Sprawling, scattershot diffs are hard to reason about, which defeats the entire purpose of review — a reviewer who cannot hold the change in their head will approve it on vibes.

What "edits in a sandbox" actually buys you

Before a pull request can be opened, the work has to happen somewhere. The right somewhere is a sandboxed clone of your repository — an isolated container where the agent can read, edit, and run code without any of it touching your real branches. This matters for two reasons.

  1. Containment: a mistake in the sandbox is a mistake in a throwaway copy. Nothing the agent does there can corrupt your history, leak into main, or break a teammate checkout.
  2. Verification: a sandbox is a place to actually run things. The agent can typecheck, run your tests, and produce a build — and prove the change works before proposing it, rather than hoping it does.

That second point is the difference between a suggestion and a verified change. An agent that edits in a sandbox and runs your checks is not guessing whether its diff compiles; it has watched it compile. This is also why the sandbox has to install dependencies and start your app: an environment that can only read code can only produce opinions.

The verification gate, in detail

Before a pull request is opened, the change runs a gate: typecheck, your test suite, and a full build, inside the sandbox. If any of them fail, that is signal, not noise — the agent keeps working there rather than handing you something broken. The pull request you receive is one that has already cleared the same bar you would expect from a careful human contributor.

Why all three checks, and not just tests

Each gate catches a different class of failure and none of them subsumes the others. Typecheck catches structural mistakes — a renamed field, a changed signature, a null that was not handled — instantly and across the whole project, including code paths no test exercises. Tests catch behavioural regressions, but only in the behaviour someone thought to write a test for. A full production build catches the things that only appear under real compilation and bundling, which is a genuinely distinct category from "the tests passed on my machine".

A change that passes all three is not proven correct — nothing proves correct — but it is proven not to be broken in any of the ways that are cheap to detect automatically. That is precisely the work you want machines doing, so that human review can spend itself on the things machines cannot judge: whether this was the right change to make.

The awkward case: a suite that was already red

Real repositories are not always green when you find them. If your test suite had failures before the agent touched anything, a verification gate will report them, and it can look like the agent broke something it did not. This is worth knowing in advance because the fix is conversational rather than technical: reply with the context. A test that was already failing, a convention the agent got wrong, an environment value it did not have — each of those turns a stuck run into a finishable one.

A run that cannot get to green is still recorded, with its verdict and what it consumed, so you can read what it did before it stopped rather than starting over blind.

The secrets problem nobody warns you about

Here is a failure mode that catches almost everyone the first time they connect a real repository, and it is not a bug: your local .env is gitignored, so it is never part of the clone. The agent gets your code and none of your credentials. An app that needs a database URL, an API key, or an auth secret to boot will therefore come up incomplete on the first import, and the preview will tell you so with a banner counting how many required keys have no value.

The fix is to fill them in on the environment surface, either key by key or by pasting a whole .env at once. Where a provider account can supply the values, attaching the connection is better than pasting, because then the value is sourced from the provider rather than from a copy you have to keep in sync.

This is worth internalising because it reframes what an import failure usually is. "The agent could not get my app running" is much more often a missing credential than a broken agent, and the diagnosis takes about ten seconds once you know where to look.

How to review an agent pull request

A pull request from an agent is an ordinary pull request: a diff scoped to the task, with the checks already run, sitting in GitHub exactly as one from a colleague would. Which means the review skill you already have transfers. But the failure modes are weighted differently than they are for human authors, so it pays to read in a particular order.

First pass: read for scope

Before judging whether the code is good, judge whether the change is the change you asked for. Look at the file list before the diff. Files you did not expect are the highest-value signal in the entire review — they are where an agent that misunderstood the task leaves its fingerprints. A request to change a pricing calculation that also touches your authentication middleware deserves a question, regardless of how clean the code is.

Second pass: read for correctness

  • Does the change handle the cases your tests do not cover? Automated gates prove the absence of known failures, not the presence of good judgement.
  • Are the edits idiomatic for this codebase specifically, or generically reasonable? An agent with a good index usually matches local conventions; where it did not, that is worth a comment so the convention gets stated.
  • Did anything get deleted? Removals are quieter than additions in a diff and deserve disproportionate attention.
  • Are new dependencies justified? A new package is a permanent decision hiding inside a temporary change.
  • Does it do more than asked? Unrequested improvements are the most common source of scope creep, and the easiest to ask to have removed.

Third pass: ask for the tweak

You do not have to accept or reject wholesale. The productive move for a nearly-right change is to name the specific thing you want different and let the rest stand. This is the same conversation you would have with a colleague, and it converges faster than starting over.

The lifecycle, end to end

The lifecycle of an agent change
connect repo   → grant access to a GitHub repository (clone + import only)
clone          → isolated sandbox container, never your working tree
index          → semantic (what it does) + symbol-aware (defs & refs)
install        → dependencies resolved so the code can actually run
secrets        → environment keys filled in or sourced from a connection
edit           → surgical changes scoped to the request
verify         → typecheck + tests + production build must pass
open PR        → a reviewed pull request is the only path to your repo
you review     → approve, request changes, or close
merge          → your call, your history, your attribution

Auditability as a first-class feature

Because the only way into your repository is a pull request, your Git history becomes a complete, honest record of what the agent did and when. There are no out-of-band changes to reconcile, no "wait, who edited this?" moments. Every agent contribution is attributable, reviewable, and revertible through the exact same tools you already use. If a change turns out to be wrong, you revert the PR — the same as you would for anyone.

  • No direct writes to protected branches — ever.
  • Every change is a diff you can read before it lands.
  • Typecheck, tests and a build run before the PR reaches you.
  • Each run is recorded with its verdict and what it consumed.
  • Full attribution and ordinary revert through normal Git workflow.

This also matters for anyone who has to answer questions about their software supply chain. "How do you control what automated tooling changes in your codebase" has a short, checkable answer when the answer is "it opens pull requests and a named human merges them."

The honest costs of this design

A design worth adopting is worth describing accurately, including where it charges you.

The first cost is latency. Cloning, indexing, installing and verifying take real time before you see anything. An agent with direct write access would appear faster because it would be doing less. That is not a trade most teams should take, but it is a trade, and pretending otherwise is dishonest.

The second cost is that you remain the bottleneck, on purpose. The pull request queue does not review itself. If your team already struggles to review human PRs promptly, adding a tireless contributor will make that queue longer, not shorter. The counterweight is that agent PRs arrive pre-verified and usually small, which makes them faster to review than the average human PR — but the review still has to happen.

The third is setup: connecting a repository, filling in environment values, and letting an import finish is more friction than pasting a snippet into a chat window. It buys an agent that can run your code, which is the entire difference between a suggestion and a verified change.

It is also worth saying plainly which plan this sits on. Connecting a GitHub repository and having changes arrive as pull requests is a paid-plan capability, not something available on the free tier — the free plan covers prompt-to-preview building rather than repository work.

The cultural payoff

When an agent is constrained to the pull-request workflow, adopting it does not require a leap of faith from your team. You are not being asked to let a robot into production. You are being offered a tireless contributor that follows your existing rules — branch, verify, propose, review. The fastest way to get an engineering team comfortable with AI assistance is to make the AI play by the same rules everyone else already follows.

It also means adoption is reversible, which is underrated. A team that decides the experiment is not working simply stops merging the PRs. Nothing has to be untangled, because nothing was ever entangled.

Speed and safety are usually framed as a trade-off. Here they are not. Sandboxed edits and automated verification make the agent fast; the reviewed pull request makes it safe. You get both because they live in different parts of the pipeline.

FAQ

Common questions

No. Repository changes happen only through a reviewed pull request. The agent edits inside a sandboxed clone and opens a PR; your protected branches are never written to directly.

Stop reading. Start shipping.

Describe what you want and watch it build — or connect a repo and ship a reviewed PR.

Why an AI Coding Agent Should Only Touch Your Repo Through a Reviewed Pull Request · code-anything.com