PR review procedure for AI agents. Use when instructed to review a PR. Triggers: "review", "pr", "code review"
First some general considerations:
Start all your comments with the 🤖 emoji.
All comments go into a pending review that is private until the human submits it. Never submit or complete the review yourself.
All comments must be posted to a pending (draft) review that you create. First, check that no pending review already exists:
OWNER=... REPO=... NUMBER=...
EXISTING=$(gh api repos/$OWNER/$REPO/pulls/$NUMBER/reviews \
--jq '[.[] | select(.state == "PENDING")] | first | .node_id // empty')
If $EXISTING is non-empty, stop and inform the user: "A pending review already exists." Do not
proceed.
Otherwise, create a new pending review. A body must be supplied at creation time; without one, the body becomes permanently uneditable via the API.
REVIEW_NODE_ID=$(gh api -X POST repos/$OWNER/$REPO/pulls/$NUMBER/reviews \
-f body='🤖 Review in progress' --jq '.node_id')
Never submit the review. Never delete a review. The human decides when to make it visible.
Add each comment as a new thread on the pending review via GraphQL:
gh api graphql -f query='
mutation($reviewId: ID!, $path: String!, $body: String!, $line: Int!) {
addPullRequestReviewThread(input: {
pullRequestReviewId: $reviewId
path: $path
body: $body
line: $line
side: RIGHT
}) {
thread { id }
}
}' -f reviewId="$REVIEW_NODE_ID" -f path="relative/path/to/file" -f body="🤖 Comment" -F line=42
Rules:
line is the absolute line number in the new version of the file.side: RIGHT always (commenting on the new version).path is relative to the repo root.To set or update the review body (overall summary):
gh api graphql -f query='
mutation($reviewId: ID!, $body: String!) {
updatePullRequestReview(input: {
pullRequestReviewId: $reviewId
body: $body
}) {
pullRequestReview { id }
}
}' -f reviewId="$REVIEW_NODE_ID" -f body="🤖 Overall summary"
NEVER use POST /repos/{owner}/{repo}/pulls/{pr}/comments for individual comments — those create
orphaned single-comment reviews that bypass the pending review.
Use gh to determine the state of the PR. If no PR exists or it is closed, stop and tell the user.
The PR MUST correspond to the currently checked out branch in the current local repository, because you are going to use the local repository to gather context for the PR review. If it does not, STOP and tell the user. Do NOT proceed with the review under any circumstances, even if you think you would be able to do the review task adequately.
Make sure you understand the purpose of the repository and have an appropriate amount of context.
Try to create a pending Review using the instructions above.
Use gh pr diff to read the full diff. Then read all changed files completely for full
context — understand the surrounding code, not just the diff lines.
Do you understand the intent of the PR? Is the intent what it should be? Is it basically doing what it intends?
Review the parts of the diff that change documentation and docstrings. Comment on individual lines as you see fit.
Review the parts of the diff that change test coverage, commenting on individual lines as you see fit. In general, a test suite should be passing if and only if the implementation defines correct behavior of the feature. Consider the following as possible reasons to comment:
Review error messages, commenting on individual lines as you see fit. These should be concise, well-written, and should instruct the user both what went wrong and how to address it, while avoiding verbosity. Consider the following as possible reasons to comment:
Review the actual implementation. Consider the following as possible reasons to comment:
Set the review body to an overall comment regarding the PR. Comment on whether you think what it is trying to do is what it should be trying to do. Comment on the extent to which it has achieved those two things: what more is needed? If there are any serious problems with the PR, or it appears to be going in an inappropriate direction then say so. If there is anything unusually good about the PR then say so, but do this only in exceptional cases.