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.
Ready PRs, human merge
Agent creates PR ready for review. Human reviews and merges. This is the most common pattern for production workflows.
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.
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.
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.
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.
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.
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.
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
doneWhat 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
Create PRs, add labels, request reviewers, all from the command line. Perfect for agent automation. Handles auth cleanly.
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.
GitHub Action to warn on and close stale PRs/issues. Configure different rules for agent branches vs human branches using labels.
Branch protection rules
Require PRs for main. Require reviews. Require CI pass. These rules apply equally to humans and agents, which is the point.
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.
Related Guides
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.