Nightshift Dev
Agent Ops

Let AI review and merge pull requests safely

By Albert Nahas, 8 min read, updated

You can let AI review and auto-merge pull requests safely if two things are true. The reviewer is independent of the author, and every PR gets one of four grades: A merges, B gets fixed and reviewed again, C gets closed, and X (money, data-destroying migrations, auth, secrets, new dependencies, paid-API spend) always waits for a human. Claude Code's review tools post findings but don't merge anything, so the grade-and-merge step is a policy you write and a loop you run.

I run exactly this on OpenWhen, a product I built alone and run with scheduled Claude Code agents, and I review only the critical PRs. Here's the rubric, why the reviewer has to be a stranger to the code, and the mechanics.

What you get out of the box

As of October 2026, these are the main ways to get an AI review on a GitHub PR:

OptionWhat it doesMerges?
Claude Code ReviewSeveral agents review each PR on Anthropic's infrastructure, verify findings, and post inline comments plus a check run named "Claude Code Review". Team and Enterprise plansNo. It never approves or blocks
/code-reviewRuns in your own Claude Code session, on any planNo
anthropics/claude-code-action@v1Claude Code in your own GitHub Actions runners, on any event, with whatever tools you grantOnly if you give it a merge tool
Cursor BugbotReviews PRs and comments with fixes. Included on Cursor's Premium plan and aboveNo
Cursor PR Routing & ApprovalRoutes PRs to reviewers and can approve low-risk changesCan approve low-risk changes

Claude's Code Review is careful about this on purpose. Its check run doesn't conclude as a failure, and its docs say the decision to merge stays with your team. That's the right default for a product sold to many teams. If you want merges without a human, you have to define "safe to merge" yourself. That definition is the rest of this guide.

The four grades

This is the rubric from my global CLAUDE.md. Each project copies it, with its own X list, into its ops charter, and that charter is the single source of truth every loop defers to:

  • A, merge. Correct, verified, and fully undone by a revert. Squash-merge.
  • B, fix then merge. Real but fixable findings: a bug, a console error, a visual flaw, a stale assumption. Fix it on the branch, verify, review again, merge. Never park a PR on a B.
  • C, close. Superseded or moot. Close it with a comment naming the commit or the reason.
  • X, founder. Critical and hard to undo. Leave it open with a founder label, the reviewer's findings as a PR comment, and one line in the daily report.

The test for X is "hard to undo", not "important". A copy change on the pricing page is important, and a revert fixes it in a minute. A migration that drops a column can't be fixed by a revert. So X covers:

  • money movement: checkout, webhooks, purchases, prices, refunds
  • migrations that rewrite or drop data
  • user identity, auth and secrets
  • new dependencies
  • paid-API spend
  • deleting user data

I also write down what is not X: seasonal looks, product limits, copy, UI, admin and analytics pages, and edits to the agent charters. If you skip that list, the reviewer plays it safe and escalates everything. Then the real X items get lost in the noise.

Why the reviewer must be independent

An agent that reviews its own PR has already decided the PR is good. If you give a reviewer the author's reasoning, you get the same result: it judges whether the argument is convincing, and a well-written argument usually is.

So the reviewer is a subagent with fresh context. It reads only three things:

  1. the merge policy section of the charter
  2. the PR body
  3. the diff

It never sees the author's conversation, its plan or its test output. It judges the code. That's the design decision that makes everything else here safe, and Claude Code subagents make it cheap, because each one starts with an empty context window.

Here's the definition I use:

---
name: pr-grader
description: Independent reviewer. Grades one PR A, B, C or X against the merge policy.
tools: Read, Grep, Glob, Bash
model: opus
maxTurns: 40
---

You review pull requests you did not write. Read only:
1. The "Merge policy" section of docs/OPS_LOOP.md
2. gh pr view <N> (title and body)
3. gh pr diff <N>, plus any file you need for context

Do not trust the PR body's claims. Check them against the diff.
First line: the grade. Then each finding as file:line, what is wrong,
and the evidence. Grade X if the diff touches any X surface, even if
the change looks correct.

The last instruction matters. An X surface goes to a human even when the code is perfect, because what it costs if the reviewer is wrong is the reason it's X in the first place.

What "verified" means

Grade A requires "verified", so the policy defines it:

  • lint, typecheck, build and tests pass
  • the deploy preview is green
  • anything that renders was rendered at phone width and looked at, with a clean console

The last line is there because of a real failure. On 31 October 2026, a PR passed every automated check while an envelope's artwork sat hidden behind its wax seal and some SVG attributes failed hydration. Tests passed because nothing tested what a person would see. Since then the policy names the incident in the same paragraph, so no reviewer can grade a UI change A without opening the preview at phone width and reading the console.

If your agent can't render, it can't verify UI. In that case grade UI changes B at most and have a human look before merging.

The sweep: every run, before new work

My daily agent starts every run by sweeping all open PRs, whatever their author or branch, before it writes anything new:

for n in $(gh pr list --state open --json number --jq '.[].number'); do
  gh pr checkout "$n"
  git fetch origin main && git rebase origin/main   # keep both sides of any conflict
  git push --force-with-lease
  # spawn the pr-grader subagent on PR $n, then act on its grade
done

Acting on the grade:

# A
gh pr merge "$n" --squash --delete-branch

# C
gh pr close "$n" --comment "Superseded by abc1234."

# X
gh pr edit "$n" --add-label founder
gh pr comment "$n" --body-file grader-findings.md

Two rules keep the sweep safe:

  • Merge one at a time. Merging deploys. Rebase the next PR on the result before grading it, or you're reviewing a diff against a main branch that no longer exists.
  • Only X stays open. A B gets fixed in the same run, never parked. An X open more than 14 days goes to the top of the report so I can't ignore it.

On a private repo on GitHub's free plan you get no branch protection and no native auto-merge, so the loop merges with gh pr merge --squash directly. Turn on delete-branch-on-merge in the repo settings and create the founder label once.

Doing it in GitHub Actions instead

If you'd rather grade in CI than in a scheduled agent, claude-code-action runs in automation mode whenever the workflow passes a prompt. My own grading runs in a scheduled agent, so treat this workflow as a starting point and run it on a test PR before you trust it:

name: Grade PR
on:
  pull_request:
    types: [opened, synchronize, ready_for_review]
jobs:
  grade:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
      id-token: write
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: "Use the pr-grader agent on this PR (git diff origin/main...HEAD). Post the grade and each finding as inline comments."
          claude_args: '--max-turns 40 --allowedTools "Read,Grep,Glob,Bash(git diff *),mcp__github_inline_comment__create_inline_comment"'

The inline-comment tool is the one Anthropic's own review example uses, and the action only starts it when --allowedTools names it. Two more details from the docs bite people. First, the action rejects bot actors unless you list them in allowed_bots. If your coding agent opens PRs as a bot account, the grader won't run on them until you allow it. Second, GitHub won't trigger workflows on commits made with the default GITHUB_TOKEN, so B fixes pushed that way never get re-graded.

I left merging out of this workflow on purpose. I keep the merge in the scheduled loop, where merges happen one at a time and in order. Parallel CI jobs merging into the same branch is how you deploy a combination nobody reviewed.

What it changed

The obvious change is time: I read X PRs and nothing else. The bigger change is that I trust the history. Every merged PR has a grade, findings and a verification record, written by an agent that had no stake in the PR. When something breaks, I can see whether the reviewer missed it or the policy didn't cover it. Then I fix the reviewer or the policy, which fixes it for every future PR.

What I'd do next

Put the rubric in a charter file first, with your own X list, then have the agent that opens PRs defer to it. The agent charter guide shows where it goes, and the subagents guide covers how to brief the reviewer so it stays independent.

Questions people ask

Can AI auto-merge pull requests safely?

Yes, for changes a revert fully undoes, if an independent reviewer grades each PR and verification includes builds, tests and a rendered check of UI. Anything touching payments, data-destroying migrations, auth, secrets, new dependencies or paid-API spend should still wait for a human.

Does Claude Code Review approve or merge pull requests?

No. Claude Code Review posts inline findings and a check run, but it never approves or blocks a PR. The decision to merge stays with your team or with a merge loop you build.

How do I get Claude Code to review pull requests?

On Team and Enterprise plans an Owner can turn on Code Review for GitHub repositories. On any plan you can run /code-review in a session, or add anthropics/claude-code-action@v1 to a GitHub Actions workflow with a review prompt.

Why should the AI reviewer be a separate agent from the author?

An agent that shares the author's context tends to accept the author's reasoning. A fresh subagent that reads only the policy, the PR body and the diff judges the code itself.

Which changes should never be auto-merged?

Changes that are hard to undo: money movement, migrations that rewrite or drop data, user identity, auth and secrets, new dependencies, paid-API spend and deleting user data.