All Guides

07 / 25

Who Opens Pull Requests?

Core Questions

  • Can agents open PRs directly?
  • How are branches named and scoped?
  • How are tasks linked to specs?

A pull request is more than a diff. It's a proposal, a context bundle, a unit of review. When agents start opening PRs, the mechanics change. You need conventions for naming, scoping, linking, and tracking. Without them, you'll drown in a sea ofagent-fix-123 branches with no idea what they're for.

Can agents open PRs directly?

Yes. And they should. The alternative is to have agents produce diffs that humans manually turn into PRs, and that adds friction without adding safety. The PR is just a container for the change. The safety comes from review, not from who clicks the "Create PR" button.

That said, there's a spectrum of how much autonomy agents have in the PR workflow:

PR Autonomy Levels

Draft PRs only

Agent creates PR as draft. Human must mark it ready for review. Prevents accidental merges; good for early trust-building.

Conservative

Ready PRs, human merge

Agent creates PR ready for review. Human reviews and merges. This is the most common pattern for production workflows.

Standard

Auto-merge on CI pass

Agent creates PR with auto-merge enabled. If CI passes and no blocking reviews, it merges automatically. Requires high trust and strong CI.

Advanced

Avoid: Direct push to main

No PR at all. Agent commits directly to main. This is almost never necessary. It bypasses review, breaks the audit trail, and makes failures harder to reason about. Even for trivial changes, a PR is cheap and gives you the same workflow every time.

Bad practice

Most teams should start with draft PRs and graduate to ready PRs as trust builds. Auto-merge is powerful but requires excellent CI coverage; you're betting that your tests catch everything a human reviewer would.

The important consistency point: agent authors the commits and opens the PR. A human reviews and merges. See Who Writes Code? for recommended authorship and signing rules.

Technical setup

Agents need a Git identity and push access. Options:

  • GitHub App: Create a GitHub App for your agent. It gets its own identity, can open PRs, and permissions are scoped per-repo. This is the cleanest approach.
  • Machine user: A dedicated GitHub user for the agent. Works well for git-native workflows (SSH keys, commit identity), but treat it like a production identity with minimal permissions.
  • Personal access token: Use a human's PAT. The agent's commits appear as that human. Avoid this. It conflates identities and makes auditing impossible.

Prefer short-lived, scoped credentials (GitHub App installation tokens) over long-lived tokens. Agents should not impersonate developers.

# Using GitHub CLI with a short-lived token (prefer GitHub App installation tokens)
gh auth login --with-token < token.txt

# Create PR
gh pr create \
  --title "Fix null check in user service" \
  --body "Closes #42" \
  --head agent/fix-null-check-42 \
  --base main

How are branches named and scoped?

Branch naming is underrated infrastructure. Good naming conventions let you:

  • Instantly identify agent branches vs human branches
  • Link branches to tasks, issues, or charters
  • Automate cleanup of stale branches
  • Apply different CI rules to different branch types

Branch Naming Patterns

agent/<task-id>

Simple prefix + task identifier. Clear that it's agent-created. Easy to find all agent branches with git branch -r | grep agent/

Example: agent/issue-42, agent/task-abc123

agent/<agent-name>/<task-id>

Includes which agent created it. Useful when multiple agents work on the same repo.

Example: agent/claude/issue-42, agent/copilot/fix-typos

agent/<date>/<task-id>

Includes creation date. Makes it easy to find and prune old branches. Sort alphabetically and old branches cluster together.

Example: agent/2025-01-15/issue-42

<type>/<scope>/<description>

Conventional commits style. Works for both humans and agents. Type indicates the kind of change; scope is the component; description is human-readable.

Example: fix/auth/null-check-user-service

Whichever pattern you choose, encode the task identifier in the branch name. This is the link back to why the branch exists. Without it, you're reverse-engineering intent from commit messages.

Branch scoping

A branch should contain one logical change. This is true for humans and doubly true for agents. Why?

  • Reviewability: A PR that touches 15 files across 3 unrelated features is hard to review. Agents can produce these easily if not constrained.
  • Revertability: If something breaks, you want to revert one change, not five tangled together.
  • Parallelism: Multiple agents can work on multiple branches simultaneously. If changes are scoped well, they won't conflict.

Enforce scoping through your task definitions. A task should be: "Fix the null check in the user service," not "Fix all the bugs in the auth module."Small, specific tasks produce small, reviewable PRs.

How are tasks linked to specs?

Every agent PR should answer: why does this exist? The answer is a link back to the task, issue, or charter that authorized the work. Without this link, PRs are orphans. You can't trace them to requirements, and you can't verify the agent did what it was asked to do.

Linking Strategies

GitHub Issues

The simplest pattern. Task is an issue. PR references the issue with"Closes #42" or "Fixes #42" in the body. GitHub auto-links and auto-closes on merge.

Closes #42

This PR implements the null check fix requested in the issue.

Charter files

For larger tasks, the spec lives in a charter file in the repo. PR references the charter path. This keeps the spec versioned alongside the code.

Charter: charters/2025-01-auth-improvements.md
Task: Section 2.3 - Null check handling

External task systems

If tasks live in Linear, Jira, Notion, etc., include the external link. Use a consistent format so it's parseable.

Task: https://linear.app/company/issue/ENG-1234

Implements the fix described in the linked ticket.

Structured metadata

Add machine-readable metadata to PR descriptions. Makes it easy to build tooling that extracts and processes task links.

```yaml
task_id: task-abc123
charter: charters/auth-improvements.md
agent: claude-sonnet-4
requested_by: [email protected]
```

The metadata approach is most powerful but requires discipline. At minimum, always include a link to the task that spawned the PR, whether that's an issue number, a Linear ticket, or a charter file path.

PR templates for agents

Agents should follow a consistent PR format. This isn't just about aesthetics; it's about reviewability. When every agent PR has the same structure, reviewers know where to look for context, what changed, and how to verify it.

Recommended PR template

## Summary
[One-line description of what this PR does]

## Task
[Link to issue, charter, or task ID]

## Changes
- [Bullet list of what changed]
- [Keep it high-level, not line-by-line]

## Verification
- [ ] Tests pass locally
- [ ] [How the agent verified the change works]
- [ ] [Screenshots or logs if applicable]

## Metadata
```yaml
agent: claude-sonnet-4
task_id: task-abc123
requested_by: [email protected]
model_version: 20250514
```

## Notes for reviewers
[Anything the reviewer should pay special attention to]
[Areas of uncertainty or risk]

The Verification section is crucial. Agents should explain how they know the change works, not just "tests pass" but what specifically they checked. This gives reviewers confidence and flags when the agent couldn't verify something.

The Notes for reviewers section is where the agent can express uncertainty. "I wasn't sure if this error case should throw or return null; please verify." This calibration is valuable; it's like a human saying "I'm 80% confident in this part but want a second opinion on that part."

Branch lifecycle and cleanup

Agents can create a lot of branches. Without cleanup, your repo accumulates dead branches forever. Establish lifecycle rules:

Branch Lifecycle

On merge: delete immediately

GitHub has a setting to auto-delete branches after PR merge. Enable it. The branch served its purpose; the commits are in main.

On close (no merge): retain 7 days

If a PR is closed without merging, keep the branch briefly in case someone wants to resurrect it. Delete after a week.

Stale PRs: warn at 14 days, close at 30

Agent PRs that sit unreviewed become stale. Their base may have diverged. Warn the team, then auto-close if nobody acts.

Orphan branches: delete at 30 days

Branches with no open PR are orphans. If they're agent branches older than 30 days, delete them. The work is either done or abandoned.

# Example: Cleanup agent branches older than 30 days
git branch -r | grep 'origin/agent/' | while read branch; do
  last_commit=$(git log -1 --format=%ct "$branch")
  now=$(date +%s)
  age=$(( (now - last_commit) / 86400 ))
  if [ $age -gt 30 ]; then
    echo "Deleting stale branch: $branch ($age days old)"
    git push origin --delete "${branch#origin/}"
  fi
done

What goes wrong

PR avalanche

Agents open 50 PRs overnight. The team wakes up to an overwhelming review queue. Nobody can keep up. PRs go stale. Morale drops. Rate-limit your agents or batch work into larger chunks.

Orphan branches everywhere

Agents create branches, fail partway through, and don't clean up. Six months later you have 500 dead branches. Your branch list is useless. Implement aggressive cleanup automation.

Untraceable PRs

PRs don't link to tasks. Nobody knows why they exist. Reviewing is guesswork. When something breaks, you can't trace it back to a requirement. Enforce task links in PR templates and CI.

Merge conflicts pile up

Multiple agents work on overlapping areas. PRs sit in review. By the time they're approved, they conflict with each other. The last one to merge has a nightmare. Coordinate agent work to minimize overlap.

Tools that help

GitHub CLI (gh)

Create PRs, add labels, request reviewers, all from the command line. Perfect for agent automation. Handles auth cleanly.

CLI

GitHub Apps

First-class identity for your agent. Scoped permissions per repo. Shows up as its own entity in the GitHub UI. Better than bot accounts.

Identity
actions/stale

GitHub Action to warn on and close stale PRs/issues. Configure different rules for agent branches vs human branches using labels.

Cleanup

Branch protection rules

Require PRs for main. Require reviews. Require CI pass. These rules apply equally to humans and agents, which is the point.

Guardrails

Summary

  • Agents should open PRs directly. The safety comes from review, not from who creates the PR.
  • Use consistent branch naming that encodes the task ID. This enables linking and cleanup automation.
  • Every PR must link to its task. No orphan PRs. Enforce this in templates and CI.
  • Automate branch cleanup. Agent branches accumulate fast; stale branches pollute your repo.

Stay updated

Get notified when we publish new guides or make major updates.
(We won't email you for little stuff like typos — only for new content or significant changes.)

Found this useful? Share it with your team.