Background Coding Agents

10 min read

U12
Playbook · Coding & Computer-Use Agents

Background coding agents: the queue is the product.

A background coding agent that opens twelve pull requests a day adds nothing if your team merges four, and it subtracts something once the other eight go stale and start conflicting with each other. Detaching the agent from the editor moves the bottleneck from writing code to reviewing it, and every design decision that follows — task selection, environment reproduction, concurrency, failure handling — is either about making a run self-verifying or about keeping the review queue short enough that the work still lands.

STEP 1

No human in the loop means the run has to verify itself.

An interactive coding agent can ask. It shows a diff, waits, gets corrected, and continues. Every one of those exchanges is a repair the developer performs for free without noticing, and detaching the agent deletes all of them at once. What remains has to be enough to finish the job alone.

  • The selection criterion is machine-checkable completion, not difficulty. "Fix this flaky test" and "add the missing null check the linter flags" are good background tasks not because they are easy but because a command exits zero or non-zero at the end. "Refactor the payments module for clarity" is a bad one at any capability level, because nothing in the repository can tell the agent it is finished.
  • The test suite is the specification, and its coverage is your reliability ceiling. A background agent will happily produce a change that passes a suite which does not test the behaviour it broke. Teams find that the first serious investment a background agent forces is not prompting — it is the tests they had been meaning to write. See patch generation and tests.
  • Ambiguity resolution has to happen before dispatch. An issue that a human would clarify in one Slack message becomes, in a detached run, either a guess or a stalled process. Front-load it: a task description that a new contractor could execute without asking a question is the bar, and writing that description is the work you are actually paying for.
  • Give the run a way to fail loudly and stop. The failure mode you want is "abandoned with a written reason after four minutes". The one you get by default is "kept going for forty minutes and produced a large confident diff against the wrong assumption", which costs a reviewer far more than the abandonment would have.

The useful reframe: a background agent is not a faster developer, it is an asynchronous contractor with no communication channel. Every question it cannot ask must be answered in advance, in the task, in the tests, or in the repository conventions — and the tasks worth dispatching are the ones where you can do that in five minutes.

STEP 2

Most background runs fail on the environment, not on the code.

The single most common disappointment in the first month of running detached agents is not bad reasoning. It is a run that spends its entire budget failing to install dependencies, and then reports a plausible-looking summary of what it would have done.

  • The agent's sandbox is not your laptop and not your CI. It has no cached package store, no pre-authorised registry credentials, no running database, and none of the seventeen things your onboarding doc never got around to mentioning. Whatever your setup script does not cover, the agent will attempt to reinvent — badly, and on the clock.
  • Write the environment down as an artifact and test it independently. A checked-in setup script that a fresh container can run to green is the highest-return investment in this whole playbook. It benefits new hires too, which is a useful way to fund it.
  • Snapshot the prepared environment rather than rebuilding it per run. Dependency installation dominates the wall clock on most repositories, and it is identical every time. A pre-warmed image or filesystem snapshot converts a five-minute tax into a start-up cost you pay once, which matters more than raw sandbox cold-start numbers.
  • Decide egress deliberately, because the default is open. A background agent needs a package registry and probably your source host. It does not need arbitrary outbound access, and outbound access is the channel by which a poisoned dependency or an injected instruction in an issue comment turns into exfiltration. Default-deny with an allowlist is the highest-leverage control available here — see sandboxing and code execution and sandbox and isolation patterns.
  • Give it the narrowest credentials that let it finish. A token that can push a branch and open a pull request is not a token that can merge one, delete branches, or read production secrets. The scoping rules are the ones in scoped credentials for agents, and detached execution is exactly the setting where nobody is watching them get used.
  • Log setup failures as a separate category from task failures. If you cannot tell the two apart in your metrics, you will spend a quarter tuning prompts to fix a Docker problem.
STEP 3

Isolate every run, and treat wall-clock time as a correctness risk.

Detached runs are concurrent by nature, and the repository is shared mutable state. Isolation is straightforward; the non-obvious part is that latency itself degrades the output.

  • One run, one branch, one working tree. Never two agents in one checkout. This is cheap and it removes an entire class of confusing failure where run A's half-finished edit is read as context by run B.
  • Staleness is a function of elapsed time and repository velocity. A branch cut from main at 09:00 and reviewed at 16:00 has to survive a day of other people's merges. On a busy repository the probability that a diff still applies cleanly falls fast, and the reviewer pays for it — so an agent that takes an hour to produce a slightly better patch can easily net worse than one that takes six minutes.
  • Prefer many small runs over one long one. Shorter runs conflict less, review faster, fail cheaper, and give you a usable signal earlier. The instinct to batch related changes into one big autonomous session optimises the wrong variable.
  • Decide the rebase policy up front and automate it. Either the agent rebases and re-runs the suite when the base moves, or the pull request is closed and the task re-dispatched from current head. Both are fine; a stack of branches quietly diverging from main is not.
  • Serialise runs that touch the same surface. Three agents independently editing the same module produce three conflicting patches and a reviewer who has to reconcile them by hand. Route by ownership: one in-flight run per file cluster, queued behind the last.
  • Never let a background run merge itself. Opening a pull request is a proposal; merging is an irreversible action on shared state, and it belongs on the far side of a human decision — which is the placement argument in human in the loop, applied to a repository.
STEP 4

The review queue is the throughput limit. Cap the input.

This is the part that decides whether the whole programme pays back, and it is a queueing problem rather than an AI one. Merge throughput is set by reviewer capacity. Dispatching more agents raises the arrival rate, and an arrival rate above the service rate does not produce more merged code — it produces a growing queue of ageing branches.

  • Measure merged pull requests, never opened ones. Opened-PR count is the metric every background agent product will show you and it is the one that can rise while delivered value falls. If the ratio of merged to opened is drifting down, you are manufacturing review debt.
  • Cap work in progress explicitly. Pick a number of open agent pull requests the team can actually clear in a day and refuse to dispatch beyond it. A queue with a limit is a system; a queue without one is a landfill.
  • Constrain diff size at dispatch, not at review. Review time rises faster than linearly with diff size, and a 600-line agent patch is disproportionately likely to be skimmed rather than read — which converts your safety mechanism into a rubber stamp. If a task cannot be expressed as a small diff, split it before dispatch.
  • Make each pull request carry its own evidence. What was asked, what changed and why, the commands run and their output, and what the agent chose not to do. A reviewer who has to reconstruct intent from the diff spends the time you were trying to save; the cost model is in the cost of human review.
  • Route the mechanically-checkable work away from humans entirely. Formatting, lint, type checks, generated-file consistency and test results should be gates the agent must pass before a human sees anything. Every one of these that reaches a reviewer is review capacity spent on something a machine could have settled.
  • Watch for the reviewer becoming the bottleneck's owner. If one person reviews all agent output, they are now a single point of failure with the least interesting job on the team, and quality decays with volume in a way no dashboard shows.
STEP 5

Design the failure path, because you will not be watching.

Interactive agents fail in front of someone who corrects them. Detached agents fail into a log. The difference in cost between a well-designed failure and a badly-designed one is larger here than anywhere else in the coding-agent playbook.

  • Hard caps on steps, wall clock and spend, per run. A loop that cannot be interrupted by a human needs to be interruptible by arithmetic. Set them low enough that a pathological run costs less than a coffee, and alert on the rate of runs hitting the cap rather than on individual hits.
  • An abandoned run must produce a useful artifact. "Could not reproduce the failing test; the fixture at tests/conftest.py requires a database that was not reachable" is worth more than a silent absence and often more than the patch would have been. Make abandonment a designed output, not an error state.
  • Never retry a failed run unchanged. The same task, same environment and same model will usually fail the same way while charging you again. Retry only when something in the inputs has changed — and cap the attempts, because an issue that has defeated three runs is telling you the task description is the problem.
  • Treat issue and comment text as untrusted input. A background agent triggered by an issue is reading attacker-controllable text and then executing code with repository credentials. That is the canonical injection surface, and the defence is the boundary — narrow credentials, egress allowlist, no self-merge — not a better system prompt. See prompt injection.
  • Quarantine the flapping task. Tasks that get re-dispatched repeatedly consume budget and reviewer attention out of all proportion. Track dispatch count per task and pull the recidivists into a human's queue instead.

A run that ends with "I stopped, here is what I learned, here is what a human needs to decide" is a success. Judge the fleet on the fraction of runs that reach a clean terminal state — merged, or abandoned with a reason — rather than on the fraction that produce a diff. The runs that produce a diff nobody can evaluate are the expensive ones.

STEP 6

The five numbers worth a dashboard.

Background agent tooling reports activity. Activity is not the thing. These five say whether the programme is working, and four of them will look worse than the vendor's numbers, which is the point.

  • Merge rate — merged over opened. The headline. A healthy programme sits high because tasks are selected well, not because review is lax; watch it alongside the reject-rate signal from your review process.
  • Dispatch-to-merge time, median and p90. This is the number that determines staleness and conflict cost, and it includes queue time, which is usually most of it.
  • Setup-failure share. Runs that died before touching the task. If this is above a few percent, your next week's work is the setup script and the snapshot, not the prompt.
  • Reviewer minutes per merged pull request. The real unit cost. Compare it against what the task would have taken a developer outright; if the ratio is not comfortably favourable, narrow the task mix rather than expanding the fleet.
  • Post-merge revert and follow-up-fix rate. The quality signal that review cannot give you, because it measures what review missed. A rising number here means the diffs got too big or the suite is not testing what changed.

Start with one narrow, well-tested task class, a checked-in setup script that a fresh container runs to green, a snapshot so runs start in seconds, default-deny egress, a push-only token, and a hard cap on open agent pull requests. Then grow the fleet only when merge rate and dispatch-to-merge time both hold as you add load. The constraint is never how many pull requests the agents can open — it is how many your team can genuinely read, and every design decision here is worth making in the direction that shortens the review.

Related: coding agent architecture for the loop underneath, sandboxing and execution for the runtime, async agent UX for the interface a detached run needs, and code review agents for the other end of the same queue.