Introducing Tenki's code reviewer: deep, context-aware reviews that actually find bugs.Try it for Free
GitHub Actions
Jul 2026

The AI Agent PR Playbook: GitHub Actions, Branch Policies, and Review Thresholds

Eddie Wang
Eddie Wangengineering

Share Article:

Your team adopted Copilot Workspace last quarter. Then someone added Cursor to the mix. Now Claude Code is opening PRs at 2 AM. The review queue that handled 15 human PRs a day is staring down 150 agent-generated ones, and your branch protection rules were never designed for this.

This guide covers the specific GitHub Actions configurations, branch protection rulesets, and review threshold settings that platform engineers need when AI coding agents are producing a significant share of the pull request volume. It's not theory. Every pattern here is something teams are running in production right now, and every anti-pattern is something that's already caused incidents.

Why 20-PR workflows break at 200 PRs

Human developers open PRs during working hours, in bursts, with natural gaps between them. Status checks finish before the next PR lands. Reviewers process the queue during the day and it's mostly empty by EOD. Agent PRs don't follow that pattern.

Three things break first:

  1. Review queue depth. Agents produce PRs around the clock. If you require one human approval per PR, your reviewers are underwater by Tuesday morning. The backlog creates pressure to rubber-stamp, which is the opposite of what branch protection is supposed to enforce.
  2. Status check latency. GitHub's concurrency limits on hosted runners mean 50 queued workflow runs can take an hour to clear. Agent PRs that depend on each other's merge state go stale, triggering cascading rebases. Each rebase re-triggers the full CI suite.
  3. Branch protection bypass pressure. When the queue grows long enough, someone with admin privileges starts bypassing required checks "just this once" to unblock the pipeline. GitHub's audit log will show the bypass, but by then the code is in production.

The fix isn't to remove safeguards. It's to restructure your workflow architecture so the safeguards actually hold under agent-scale volume.

The three PR archetypes agents produce

Not all agent PRs carry the same risk. Treating a dependency bump the same as a feature implementation wastes reviewer attention on the wrong things. In practice, agents produce three distinct PR types, and your workflow configuration should handle each one differently.

Feature PRs

These add or modify application logic. An agent like Copilot Workspace might scaffold an entire feature branch from an issue description, or Claude Code might implement a function based on a prompt. Feature PRs are the highest risk because the agent is making design decisions, not just updating values. They need full CI, automated review, and usually a human sign-off.

Dependency update PRs

Dependabot, Renovate, or an agent instructed to "update all outdated packages" will generate these. The diff is typically a lockfile change plus maybe a config tweak. The risk is supply chain compromise (malicious package version) rather than logic errors. These benefit from dependency review checks and SBOM validation but don't need the same depth of code review as feature work.

CI fix PRs

An agent sees a failing CI run, diagnoses the issue, and opens a PR to fix it. These are deceptively dangerous. The agent is responding to error output, which can be manipulated. If an attacker controls the test fixtures or error messages, they can steer the agent's fix toward introducing a vulnerability. CI fix PRs need the same scrutiny as feature PRs, plus explicit validation that the fix actually addresses the original failure and doesn't just silence it.

Workflow trigger patterns and their security implications

Agents interact with GitHub Actions through the same event triggers humans do, but the patterns they produce expose different attack surfaces. Two triggers deserve special attention.

pull_request_target: the privileged trigger

The pull_request_target event runs in the context of the base repository, not the fork. It has access to secrets and a write-capable GITHUB_TOKEN. If a workflow triggered by pull_request_target checks out the PR's head branch and runs build scripts, an attacker can exfiltrate every secret in the repository. This is the "pwn request" attack pattern, and it's been exploited at Fortune 100 companies.

Agents make this worse in two ways. First, they produce more PRs, which means more workflow runs with elevated privileges. Second, agents sometimes generate workflows that use pull_request_target without understanding why it's dangerous. They see examples in documentation, replicate the pattern, and ship a workflow that checks out untrusted code in a privileged context.

GitHub's November 2025 update now requires pull_request_target workflows to use the default branch as their source, which eliminates one class of exploit. But the core risk remains: if the workflow checks out PR code and executes it, secrets are exposed.

The rule: Use the standard pull_request trigger for all build, lint, and test workflows. It's sandboxed. It doesn't have access to secrets. It's what you want for agent PRs.

The pull_request + workflow_run split pattern

Sometimes you genuinely need a workflow that has write permissions or access to secrets after a PR's checks pass. The correct pattern is a two-phase split: the first workflow runs on pull_request (no secrets, sandboxed), and the second runs on workflow_run after the first completes. The second workflow has access to secrets but never executes code from the PR directly.

# Phase 1: Sandboxed checks (no secrets)
name: PR Checks
on:
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

---
# Phase 2: Privileged post-check (has secrets, never checks out PR code)
name: Post-PR Deploy Preview
on:
  workflow_run:
    workflows: ["PR Checks"]
    types: [completed]
jobs:
  deploy-preview:
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.workflow_run.head_branch }}
      # Deploy using secrets - but validate the artifact, don't run PR scripts

The critical detail: even in the workflow_run phase, don't execute build scripts or test suites from the PR branch. Use the artifacts produced by the sandboxed phase, or validate the checked-out code through static analysis before running anything.

Branch protection ruleset configuration

GitHub's repository rulesets (the newer replacement for classic branch protection rules) give you granular control over what can merge and under what conditions. Here's what each setting actually does in an agent-heavy environment, and where the gaps are.

Required status checks

This is your first line of defense. A required status check means the PR cannot merge until a specific CI job reports success. For agent PRs, you want at minimum:

  • Your standard test suite
  • Linting and type checking
  • An automated code review check (more on this below)
  • Dependency review (GitHub's built-in action or a third-party equivalent)

Enable "Require branches to be up to date before merging." Without this, an agent PR can pass checks against a stale base, then merge and break main. With agents producing PRs in parallel, stale-base merges are one of the most common causes of broken builds.

Dismiss stale reviews

This setting invalidates existing approvals when new commits are pushed. Turn it on. Agents frequently push follow-up commits to fix lint errors or test failures. Without stale review dismissal, an approval given before those fixup commits carries through to the final version, which may have changed substantially. The reviewer approved version 1; version 3 is what actually merges.

Merge queue integration

GitHub's merge queue batches approved PRs and tests them together against the target branch before merging. This is nearly mandatory for agent-scale volume. Without it, you get the classic merge skew problem: PR A and PR B both pass checks independently, but conflict when merged sequentially.

Configure the merge queue with a batch size that matches your CI capacity. If your full test suite takes 8 minutes and you have enough runner concurrency for 3 parallel merge groups, set the batch size to 3. Going higher creates longer feedback loops when a batch fails and has to be bisected.

What branch protection doesn't enforce

Branch protection verifies that checks pass and reviews are present. It does not evaluate the quality or depth of those reviews. A one-line "LGTM" comment counts the same as a thorough code review. It also can't distinguish between an agent PR that made a sound architectural decision and one that introduced a subtle race condition that passes all tests.

This is where automated code review tools fill the gap. Your status checks gate on CI correctness; automated review gates on code quality and security. You need both.

Setting review thresholds per PR source

Uniform review settings across all PR sources is the wrong default. A Dependabot patch bump carries different risk than a Copilot feature implementation, and your review infrastructure should reflect that.

The practical approach is to classify PRs by their source actor and archetype, then apply different review sensitivity to each combination. Here's what that looks like in practice:

Dependabot and Renovate PRs

Focus automated review on supply chain signals: is the new version flagged in any advisory database? Does the dependency review action report new vulnerabilities? Is the package still actively maintained? If the diff is purely a lockfile change and the dependency review passes, these can often auto-merge with just automated checks. The review threshold is lower for severity because the blast radius is constrained to known vulnerability databases.

Copilot and Cursor feature PRs

Run automated review with maximum sensitivity. Flag anything at Warning level or above. These PRs introduce new logic, and agents are prone to specific classes of mistakes: they hardcode values that should be configurable, skip error handling for edge cases, use deprecated APIs they saw in training data, and sometimes introduce subtle security issues like SQL injection in dynamically constructed queries. An automated reviewer like Tenki catches these patterns because it evaluates the diff against the repository's existing conventions, not just syntactic correctness. On the Tenki benchmark, it catches 68.9% of bugs in PR diffs, which matters a lot when you're reviewing 10x the volume you used to.

Claude Code and autonomous agent PRs

Same high sensitivity as Copilot feature PRs, but add an additional gate: require a human reviewer for any PR that modifies workflow files, security-sensitive configuration, or authentication logic. Claude Code and similar autonomous agents operate with less human oversight during generation than Copilot (which typically has a human in the loop). The approval requirement should reflect that reduced oversight.

Implementing source-based routing with labels

GitHub Actions doesn't natively support different workflow configurations per PR author. The cleanest workaround uses labels applied by a triage workflow, which then determines which review jobs run:

name: PR Triage
on:
  pull_request:
    types: [opened]
jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            const actor = context.actor;
            const labels = [];
            if (actor === 'dependabot[bot]' || actor === 'renovate[bot]') {
              labels.push('agent:dependency');
            } else if (actor.endsWith('[bot]')) {
              labels.push('agent:autonomous');
            } else {
              labels.push('author:human');
            }
            await github.rest.issues.addLabels({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              labels
            });

Downstream review and CI workflows then filter on these labels to decide which checks to run and what thresholds to apply.

Handling Critical flags with no human author

When a human-authored PR triggers a critical review finding, you ping the author and ask them to fix it. Agent PRs don't have that feedback loop. The bot that opened the PR isn't checking Slack. You need a different escalation path.

Three patterns that work:

  1. Auto-close with reason. If the automated review flags a Critical severity finding, the workflow closes the PR with a comment explaining what was found. The linked issue stays open. A human triages the issue and decides whether to re-run the agent with more specific instructions or fix it manually.
  2. Route to a CODEOWNERS team. Use GitHub's CODEOWNERS file to assign agent PRs that touch sensitive paths to a specific review team. When a Critical flag fires, the team gets notified through GitHub's standard review request mechanism. This works well for teams that already have CODEOWNERS configured but need to extend it to cover agent-authored changes.
  3. Block and notify the person who triggered the agent. If your agents are triggered by issue assignments or slash commands, there's usually a human who initiated the agent run. Map agent PRs back to the initiating human (via the issue assignee or the commit that kicked off the agent workflow) and notify that person when a Critical flag blocks the PR. They're the closest thing to an author and have the most context on what the agent was supposed to do.
name: Critical Finding Handler
on:
  check_run:
    types: [completed]
jobs:
  handle-critical:
    if: |
      github.event.check_run.conclusion == 'failure' &&
      contains(github.event.check_run.output.title, 'Critical')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            const pr = context.payload.check_run.pull_requests[0];
            if (!pr) return;
            
            // Close the PR with explanation
            await github.rest.pulls.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: pr.number,
              state: 'closed'
            });
            
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: pr.number,
              body: `This PR was closed automatically due to a Critical severity finding in automated review. The linked issue remains open for manual triage.`
            });

Putting it together: a reference configuration

Here's the complete set of settings for a team running 100+ agent PRs per day against a monorepo:

Repository ruleset for main:

  • Required status checks: test suite, lint, type check, automated review, dependency review
  • Require branches to be up to date: enabled
  • Dismiss stale reviews: enabled
  • Required approvals: 1 (automated review counts; require human for workflow file changes via CODEOWNERS)
  • Merge queue: enabled, batch size 3-5, minimum entries to merge 1
  • Block force pushes: enabled
  • Do not allow bypassing: no exceptions, including admins

Workflow architecture:

  • All CI on pull_request trigger (sandboxed, no secrets)
  • Deploy previews via workflow_run (privileged, artifact-based, no PR code execution)
  • PR triage workflow labels by source actor on open
  • Critical findings auto-close the PR and notify the initiating human
  • CODEOWNERS on .github/workflows/ requires human approval for any workflow changes

Review thresholds by source:

  • Dependabot/Renovate: automated review + dependency review; auto-merge if clean
  • Copilot/Cursor: automated review at max sensitivity + human approval for Warning+ findings
  • Claude Code/autonomous agents: automated review at max sensitivity + mandatory human approval
  • Human developers: standard automated review + team-defined approval rules

None of this requires exotic tooling. It's GitHub's native features (rulesets, merge queue, CODEOWNERS, workflow triggers) combined with an automated review check that can differentiate between severity levels. Tenki's code reviewer plugs into this architecture as a required status check at $1 per review. It reports severity levels that your workflow can act on, so you're not just gating on pass/fail but on how severe the findings are and who authored the PR.

The goal isn't to slow agents down. It's to let them move fast on low-risk changes while applying appropriate friction on the changes that actually need a human brain looking at them.

Tags

#ai-coding-agents#branch-protection#merge-queue#cicd-security#agentic-ci

Recommended for you

What's next in your stack.