Pular para o conteúdo principal

Auto-Commit Background Agents: Draft-PR Handoff

Avançado

On July 1, 2026 Claude Code shipped v2.1.198 and quietly closed the last manual step in the agent loop: background agents launched from claude agents began auto-committing, auto-pushing, and auto-opening a draft PR when they finished code work in a worktree. You went from "here's a task" straight to "here's a reviewable draft" — no keystrokes in the middle.

The reaction was immediate and split. Some users loved it; others filed anthropics/claude-code#73197 the next day asking for an off switch so their propose-only workflows (agent proposes, human commits) still worked. Five weeks later, on August 4, 2026, v2.1.221 walked the default back: background sessions now always commit and push to preserve work, but only open a draft PR when the task calls for one. Same primitive, softer default.

If you run agents unattended — nightly triage, a /loop on /code-review, a fleet of /forked sessions — this is the workflow you're already inside. Here is what it does end-to-end, what fires when, and how to shape it for your team's trust bar.

What you'll learn
  • The exact end-to-end flow from `claude agents` launch to draft PR — commit, push, notification, all of it
  • What v2.1.198 shipped, what v2.1.221 tuned, and why the default softened
  • How `/fork`, `/resume`, `/background`, and (new in v2.1.221) `/subtask` fit around the auto-PR flow
  • The Notification hook payload — `agent_needs_input` vs `agent_completed` — and how to page yourself instead of Claude
  • A propose-only pattern that survives every release by using permissions, not settings, as the enforcement point

The four shipping events, in order

The auto-PR flow did not arrive fully-formed — it landed across five releases in six weeks. Reading them in order tells you what each layer of the current behavior is actually for.

DateVersionChange
2026-07-01v2.1.198Subagents run in the background by default. Background agents launched from claude agents auto-commit, auto-push, and auto-open a draft PR on completion. Notification hook fires agent_needs_input and agent_completed for background sessions.
2026-07-15 (approx.)v2.1.212/fork copies your conversation into a new background session (its own row in claude agents) while you keep working. /resume opens a picker of past sessions, including deleted ones.
2026-07-20 (approx.)v2.1.216Fix: resumed background sessions restore the agent's prompt and tool restrictions instead of dropping to the default agent.
2026-07-22 (approx.)v2.1.218/code-review runs as a background subagent by default — review no longer fills the conversation.
2026-08-04v2.1.221Default tuned: background sessions always commit and push to preserve work, but open a draft PR only when the task calls for one. In-session subagent that /fork used to launch is now /subtask.

Two things worth noticing about that arc:

  1. Every step is more autonomy, not less. v2.1.221 did not disable auto-commit or auto-push — it just made the draft PR opt-in-per-task instead of always-on. The runtime still wants your work out of an ephemeral worktree and onto a branch before it forgets.
  2. /fork and the auto-PR flow compose. Once a fork is its own row in claude agents, it is a background session — which means when it finishes, the same commit → push → maybe-PR sequence fires. A single /fork launched at lunch can come back as a branch on origin by afternoon.

What actually happens when a background agent finishes

The end-to-end sequence for a claude agents background session on v2.1.221, once its final tool call returns:

Guided walkthrough1 of 6
  1. The runtime keeps the isolated worktree (default location under `~/.claude/worktrees/`) alive as long as the working tree is dirty. If the agent made zero changes, the worktree is pruned automatically — no ghost branches.

The sequence never rolls back. If the push fails (auth, protected branch), the runtime keeps the local commit and surfaces the failure through the same notification — but it will not delete your work.

The Notification hook — page yourself, not Claude

The two events v2.1.198 added to the Notification hook are the seam where you keep humans in the loop without ever attending the session.

Two payload shapes on the same hook

# agent_needs_input — session paused waiting for approval or clarification
{ "event": "agent_needs_input", "session_id": "...", "agent": "code-review", "reason": "..." }

# agent_completed — session finished; branch pushed, PR maybe opened
{ "event": "agent_completed", "session_id": "...", "agent": "feature-x",
"branch": "claude/feature-x-2026-08-04", "pr_url": "https://github.com/..." /* or null */ }

The pr_url field is the single most useful bit: it is null when the runtime pushed-but-did-not-PR (the v2.1.221 default for exploratory work), and populated when it did. Routing on that field is how you build "only ping me for reviewable work" without a second config layer.

A minimal hook that pings a Slack channel only for completions that produced a PR:

{
"hooks": {
"Notification": [
{
"matcher": "agent_completed",
"hooks": [
{ "type": "command", "command": "jq -e '.pr_url' >/dev/null && jq -r '\"<\" + .pr_url + \"|Draft PR ready> — \" + .agent' | curl -X POST -H 'content-type: application/json' -d @- $SLACK_WEBHOOK_URL" }
]
}
]
}
}

The jq -e '.pr_url' gate is the whole trick: -e exits non-zero when the field is missing or null, short-circuiting the rest of the pipeline. Sessions that only committed-and-pushed don't page. Sessions that opened a PR do.

Why #73197 mattered — and why the fix wasn't a settings key

Issue anthropics/claude-code#73197, filed July 2, 2026 — one day after v2.1.198 — asked for a backgroundAgents.autoCreatePr: false in settings.json, or at least separate knobs for commit / push / PR. The reasoning was reasonable: in a "propose-only" workflow the human is the only one allowed to push to origin or open PRs, and a default-on publish step needs an off switch.

Anthropic's answer was different in shape. Instead of a new setting, v2.1.221 tuned the default itself (PR only when the task calls for one) and pointed at the existing permission system: a Bash(git push:*) deny rule blocks the push, and a Bash(gh pr create:*) deny rule blocks the PR. The permission layer is authoritative for both interactive and background sessions — it's how the runtime enforces the ban regardless of what the agent decides to do at the end.

Watch out
  • There is still no `backgroundAgents.autoCreatePr` key in `settings.json` — 'disable the feature' is spelled with permissions, not settings.
  • A permission deny on `Bash(git push:*)` also blocks the final auto-push, not just interactive pushes. If your only concern is the PR, deny `Bash(gh pr create:*)` instead and let the push through so `/resume` can pick up the branch cleanly.
  • v2.1.221 is the default *today*. If you pin an older Claude Code (2.1.198 – 2.1.220), you get the always-PR behavior — and the permission gate is your only real defense.

The propose-only pattern that survives every release

Build the policy at the permission layer, not the settings layer. Then it applies to every session (foreground, background, /fork, /subtask, /loop) and does not care which version of v2.1.x you're on.

settings.json — propose-only project policy

{
"permissions": {
  "deny": [
    "Bash(git push:*)",
    "Bash(gh pr create:*)",
    "Bash(gh pr edit:*)"
  ],
  "allow": [
    "Bash(git commit:*)",
    "Bash(git add:*)"
  ]
}
}

Under this policy:

  • The background agent still commits inside its worktree — your review has the diff exactly as the agent produced it.
  • The push at end-of-session fails. The runtime surfaces the failure through agent_completed with pr_url: null.
  • Nothing reaches origin until you git push the branch yourself from the worktree path the notification handed you.

This is the pattern the community asked for in #73197, expressed in tools that already exist. It also happens to be the shape the v2.1.221 default is converging on — the runtime just accepts you as the source of authority on which agents can publish.

/fork, /subtask, /resume — where they fit

v2.1.212 and v2.1.221 reshuffled what these three commands do around the auto-PR flow. Read them together:

CommandWhat it startsRuns whereAuto-PR flow applies?
/backgroundNew background sessionIts own row in claude agentsYes
/fork (v2.1.212+)Copy of the current conversation into a new background sessionIts own row in claude agentsYes
/subtask (v2.1.221+, was /fork in-session)Ephemeral subagent inside the current sessionIn-conversationNo — the parent owns the outcome
/resumeReattach to any prior session in claude agentsWherever it wasWhatever that session's config was
/code-review (v2.1.218+)Review as a background subagentIts own rowYes — but reviews rarely produce PRs, so v2.1.221 usually pushes-without-PR

The rename in v2.1.221 (/fork/subtask for the in-session case) is the important cleanup: /fork now means "hand this conversation to a new background worker and get out of my way," which is the shape the auto-PR flow was designed around. /subtask is what you use when you want a scoped helper in your existing session and don't want the finish-and-publish sequence to fire.

Cost, race conditions, and the two gotchas nobody documents

Three real-world details that don't show up in release notes:

  • Background agents count against the concurrency cap. Since v2.1.198, subagents default to background — which means a claude agents list of 25 running sessions will start refusing new spawns with Concurrent subagent limit reached. See Subagent Fleet Limits for the four env vars.
  • The auto-commit is not amend-safe. If two /forks off the same conversation both finish and both push to their own branches, you get two branches, two commits, and (on v2.1.198 – v2.1.220) two PRs. Fine when you meant it as a race; not fine when you thought only one would win. Put a plan step in your agent prompt if you need serialization.
  • A watcher that auto-commits can double-commit. If you also run a repo watcher (a common script that auto-commits changes it sees on disk), it can race the agent's own end-of-session commit — you end up with an empty commit or a merge conflict on push. The safe topology is: the agent owns the worktree, the watcher owns the main clone, and never the twain.

Check yourself

0/3
  1. On v2.1.221 defaults, a background agent finishes a research task with `/subtask`. What happens on completion?
  2. You want to block draft-PR creation but keep the push so `/resume` can pick up the branch. What do you configure?
  3. The `Notification` hook fires `agent_completed` with `pr_url: null`. What does that mean on v2.1.221?
Auto-PR flow — flip each card
Pressione Enter ou Espaço para virar o cartão. Use as setas esquerda e direita para navegar entre os cartões.Termo exibido.
1 / 6
Key takeaways
  • The auto-PR flow lives at the runtime layer, not the settings layer — there is no `backgroundAgents.autoCreatePr` key, and there won't be. Use permissions.
  • v2.1.221 (today's default) always commits and pushes; it opens a draft PR only when the task frames a reviewable change. Read the notification's `pr_url` field to tell which happened.
  • `/fork` now means 'hand this conversation to a background worker'; `/subtask` is what you reach for when you want an in-conversation helper without the finish-and-publish sequence.
  • The propose-only pattern is a permission deny on `Bash(gh pr create:*)`. It survives every version of v2.1.x and every command that produces a background session.
  • Background agents still count against `CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS`. A fleet of 25 half-finished sessions in `claude agents` will start refusing new spawns.

Next

Sources & further reading