Open pull requests pile up faster than maintainers can route them. Most of that delay is mechanical (which area is this, who owns it, which reviewer is least swamped) and machine-friendly. A PR triage agent does the mechanical work, surfaces what humans should see, and stays out of code review entirely.
This walkthrough covers the setup most maintainers end up with after a fortnight on a small team's repo. The agent labels by changed paths, requests reviewers via CODEOWNERS, posts a diff summary as a comment, and tracks stale PRs. The line it does not cross is the substance of the review.
What this agent does
On every PR open, sync, and review event, the agent computes a label set, requests reviewers via CODEOWNERS, drafts a diff summary, and updates a daily stale-PR digest. It does not approve PRs, does not merge, does not push commits.
It is a maintainer multiplier, not a maintainer replacement.
For broader patterns, see what an AI agent can actually do. For the related code-debug pattern, see how to debug an agent that did the wrong thing.
App permissions
Use a GitHub App with least-privilege scopes.
- Read scopes day one. Pull requests, issues, contents (read-only), members (read-only).
- Write scopes for triage. Pull requests (to add labels, post comments, request reviewers), checks (if posting status checks).
- Never granted. Administration, secrets, workflows, code (write).
Install on the specific repos that need triage, not the whole organisation. For broader credential and scope hygiene, see how to give agent access to email safely (the same principles apply to source-control credentials).
Labels and routing
Labels are deterministic. The agent computes them from observable signals, not vibes.
- Area labels. Map changed file paths to area labels using a config (paths in
frontend/getarea: frontend,db/migrations/getshas: database-migration). - Size labels. Lines changed buckets: S (<50), M (50-200), L (200-1000), XL (>1000).
- Risk labels. Touches a migration directory, touches a security-sensitive file (auth, payments), touches a critical config.
- Test signals. Has tests added, lacks tests, broke CI.
Subjective labels (priority, good-first-issue, ready-to-merge) require an explicit human signal; the agent does not assign them.
Reviewer assignment
CODEOWNERS is the contract. The agent reads it, intersects with the PR's changed paths, and requests the relevant teams or individuals. If multiple owners apply, the agent picks based on a configured policy:
- Least-recently-assigned. Distribute review load evenly.
- Fewest open reviews. Route around busy reviewers.
- Round robin. Simple and predictable.
The agent does not request reviewers who are out of office (uses GitHub's busy/away signal where available, or a maintained schedule). It does not request the PR author. It does not bypass CODEOWNERS.
Diff summaries
The agent posts a diff summary as a comment on every PR over a size threshold (M and above). The summary captures:
- What changed (areas, files, key new functions).
- What did not (likely-impacted areas the diff did not touch).
- Linked issues mentioned in the body.
- CI status snapshot.
The summary lives as a comment, not as the PR description. Authors can copy useful parts; the agent does not overwrite human-authored intent.
For more on the boundary between drafts and direct edits, see how to limit agent actions.
Stale PR handling
Stale handling is a graduated sequence, not a binary close.
- Day 7 of inactivity. Agent posts a comment asking for an update.
- Day 14. Agent pings author and reviewer in a daily digest issue or Slack channel.
- Day 30. Agent labels the PR as
staleand posts a comment proposing close, rebase, or revival. - Never. The agent does not auto-close PRs. A maintainer decides.
Stale is configurable per repo. A library repo's stale window is much longer than a feature-velocity repo's.
Common mistakes
- Mixing triage with code review. The agent posts ten low-signal comments per PR; reviewers tune them out.
- Auto-merging on green CI. Beyond the scope of triage and beyond the trust the agent has earned.
- Bypassing CODEOWNERS. Breaks team contracts; reviewers stop using the labels.
- Auto-closing stale PRs. Loses contributor goodwill and sometimes useful work.
- Subjective labels without a human trigger. Priority labels assigned by an agent are noise.
Frequently asked questions
Should an AI agent review code in pull requests?
Triage and review are different jobs. A triage agent labels PRs by area, requests the right reviewers via CODEOWNERS, summarises the diff for the description, and surfaces stale PRs. Code review (judging correctness, suggesting changes) is a separate decision and a separate tool. Mixing them tends to flood PRs with low-signal comments. Pick triage as the first deployment.
How does the agent decide who to request as reviewer?
GitHub's CODEOWNERS file is the source of truth. The agent reads which paths the PR changed, looks up the owner in CODEOWNERS, and requests the relevant team or individual. If multiple owners apply, it picks based on a round-robin policy you configure (least-recently-assigned, fewest open reviews, etc.). It does not request reviewers outside CODEOWNERS.
What labels should the agent apply automatically?
Area labels (frontend, backend, infra, docs) derived from changed paths. Size labels (S, M, L, XL) by lines changed. Risk labels (database-migration, security-sensitive, has-tests, breaking-change) by files touched and CI signals. Avoid subjective labels (good-first-issue, priority) unless an explicit human signal triggers them.
Can the agent write the PR description for me?
It can draft a description from the diff plus the linked issue, and add it as a hidden comment for the author to copy. Auto-overwriting the description tends to backfire because authors include intent the diff does not show. The right pattern: agent posts a draft summary as a comment, the author lifts it (and edits it) into the description if useful.
How does the agent handle stale PRs?
Stale is a function of last activity, not absolute age. After 7 days of no activity, the agent posts a comment asking for an update. After 14 days, it pings the author and reviewer in a daily digest. After 30, it labels the PR as stale and proposes closing or rebasing. The agent does not auto-close PRs; that is a maintainer call.
Three takeaways before you close this tab
- Triage is mechanical. Code review is judgement. Keep them separate.
- CODEOWNERS rules. The agent does not invent reviewers.
- Stale is graduated. Comment, digest, label, propose. Never auto-close.
Sources
- GitHub Docs, "About code owners (CODEOWNERS)", retrieved 2026-05-10, docs.github.com/about-code-owners
- GitHub REST API, "Pulls and Reviews endpoints", retrieved 2026-05-10, docs.github.com/rest/pulls
- GitHub Docs, "GitHub Apps and least-privilege permissions", retrieved 2026-05-10, docs.github.com/apps/permissions
- Aryan Agarwal, "Gravity PR-agent guardrails", internal v1, May 2026, About