git-pr
Skill7 starsChanged 21 days agoMITView on GitHub
PR and MR workflows for GitHub (gh) and GitLab (glab). Creation, review comment handling, thread resolution, review state queries, merging (including stacked PRs), cost-aware bot review rounds (GitHub: Copilot, CodeRabbit), and Copilot code review configuration (rulesets, custom instructions, billing). Use when creating PRs/MRs, addressing review feedback, resolving threads, looping bot reviews, checking approvals, querying PR data, stacking PRs or merging a stack, configuring Copilot reviews, or configuring gh/glab read-only allowlists. Not for git commits (git-commit), CI/CD status (git-ci), local pre-push CodeRabbit CLI reviews (coderabbit), or general git ops
- Commits and pushes
14 other projects use a version of this.
Adopted by
Most recently taken up by
- Markssuave/Markssuave-Agent-skillstheir own version, first seen Nov 8, 2026
- stuff4ai/skillstheir own version, first seen Nov 8, 2026
- Zenobia000/agent-skills-startertheir own version, first seen Nov 1, 2026
- eliasjnior/claude-skillstheir own version, first seen Oct 20, 2026
- klauswg/sasuketheir own version, first seen Oct 15, 2026
- AI-Cultivation/cultivation-world-simulatortheir own version, first seen Oct 8, 2026
Other versions14 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 14
- AI-Cultivation/cultivation-world-simulator★ 2.1ksame name
- 4thfever/cultivation-world-simulator★ 2.1ksame name
- diodeme/Gold-Band★ 164same name
- klauswg/sasuke★ 17same name
- khangpqvn/SDDADD★ 12same name
- Zenobia000/agent-skills-starter★ 4same name
- mattstruble/skills★ 2same name
- NaveenGumaste/keyskills★ 2same name
- Markssuave/Markssuave-Agent-skills★ 1same name
- CarpeWu/claude-git-skills★ 0same name
4 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- bun-apiSkill
- bun-cliSkill
- coderabbitSkill
- deps-upgradeSkill
- git-ciSkill
- git-commitSkill
- git-projectSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 2 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 24
Before starting any PR workflow, detect the current state.
- Very specific: line 65
glabhas no--json field1,field2equivalent: Use -F json | jq '{fields}' to filter output for token efficiency. - Distinctive: line 88
If ambiguous or both present, ask the user.
- Very specific: line 256
Commit the fixes (as many commits as the change needs) and push once for the whole round -- the message describes the change itself, never …
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PR and MR Workflows
Primary skill for pull request and merge request workflows across GitHub and GitLab. Covers the full lifecycle: creation, review queries, comment handling, line-specific comments, and merging. All recipes use minimal field sets for token efficiency.
Verified against gh v2.103.2 (2026-10-27): every gh subcommand and flag used here, against its --help on v2.102.0 (2026-09-30), then the pkg/cmd sources of v2.102.0 and v2.103.2 diffed (2026-10-27), since --help is generated from them: no flag of a subcommand used here changed. glab: not verified -- no pinned version yet; check glab <cmd> --help before relying on a glab flag. If gh --version is newer, read the release notes since v2.103.2 before relying on flag details. The CodeRabbit CLI pin lives in the coderabbit skill.
Context Check (Do This First)
Before starting any PR workflow, detect the current state. This determines the right action:
# Check if a PR exists for the current branch (allowlisted, zero approval)
gh pr view --json number,state,reviewDecision,reviewRequests,title 2>/dev/null| Result | Next action |
PR exists, CHANGES_REQUESTED | Fetch unresolved threads (see Review Comment Handling) |
PR exists, REVIEW_REQUIRED or has pending reviewRequests | Check review state or wait for reviewers |
PR exists, a bot review in flight: pending in REST requested_reviewers (Copilot shows as Copilot), or HEAD's CodeRabbit check is still running | Auto-review in flight -- wait for it the way the host allows (Critical Rule 9); do NOT re-request |
| PR exists, unresolved review comments | Address the comments first (Review Comment Handling); never request a new review over outstanding ones |
PR exists, no unresolved CodeRabbit threads, and coderabbitai itself resolved every thread of its newest round after answering, with no review running (bot_status exit 7) | Round closed in the threads -- run the body-only completeness check (Critical Rule 6), then report it done and request no review (Critical Rule 10) |
PR exists, APPROVED | Check CI status, then merge -- after the stack check (Critical Rule 11) |
| PR exists, no review decision yet | On an auto-review repo, read the bot round's outcome first (bot_status, Bot Review Loop) -- a clean or rate-limited round shows nothing in this query; then check CI status, review state, or push more changes |
| No PR for current branch | Create a PR (see PR/MR Creation) |
This avoids offering to create a PR when one already exists, and immediately surfaces pending review work. The reviewDecision field reliably indicates whether a reviewer has requested changes without needing to fetch individual threads.
Auto-review is an optional setting -- never assume it either way (GitHub): automatic Copilot code review comes from either a repo/org ruleset or the author's personal Copilot setting, so its presence varies between accounts, orgs, and even repos of the same owner. When enabled it requests Copilot on every non-draft PR at creation (and when a draft is marked ready for review), so a freshly created PR may already have a pending bot request or bot comments minutes later -- and on other repos nothing fires at all. The ruleset source is detectable read-only (the copilot_code_review rule via gh api repos/{owner}/{repo}/rules/branches/{branch}; see references/copilot-review-config.md), but the personal setting has no API -- so an empty ruleset check still means detect, don't assume: check for a pending request or an existing bot review first, and only request one if neither shows up; otherwise you get a duplicate round. Gotcha: the pending bot request is only visible via gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers (login Copilot) -- gh pr view --json reviewRequests omits bot reviewers and stays empty.
Bot reviews cost money (Copilot) or quota (CodeRabbit) -- budget rounds deliberately. Every Copilot review, including each re-request, bills fully: 13 premium requests on legacy annual plans (up to ~23 reviews/month on Pro -- the pool is shared with all premium features), or token-metered AI credits + Actions minutes on current plans. CodeRabbit PR reviews draw from an hourly per-plan bucket that is per developer, not per PR -- all of a developer's open PRs contend for the same review windows. Check the project's Code Review Policy (below) before requesting anything billable; prefer local CodeRabbit CLI reviews (see the coderabbit skill) to iterate cheaply before the PR-side review.
When to Use
- Creating PRs or MRs -- draft workflows, fill patterns, title format
- Addressing PR/MR review feedback -- "fix PR comments", "address review", "handle feedback", "resolve review threads"
- Responding to code review -- evaluating reviewer comments, replying, resolving threads
- Checking review state -- approvals, pending reviewers, review decisions
- Querying PR/MR data -- files changed, commits, labels, linked issues
- Posting comments on PRs/MRs -- line-specific comments, thread replies
- Stacked PRs -- opening a PR on another PR's branch, merging a stack without closing the child or running the deploy twice
- Looping bot review rounds (GitHub only; Copilot, CodeRabbit) -- re-request the bot, wait for the async review, address comments, repeat until no valid comments remain ("loop the Copilot review", "loop 3 rounds")
- Configuring Copilot code review -- auto-review rulesets, review effort, custom instructions, billing/quota checks
- Configuring tool allowlists -- auto-approval patterns for read-only commands
Critical Rules
- Prefer CLI subcommands over raw API calls. Subcommands handle pagination, error formatting, and repo detection. Only use
gh api/glab apifor operations not covered by subcommands (line comments, thread resolution, GraphQL). - Use
--json field1,field2withghto filter output. This IS the efficiency mechanism -- no--jqneeded for basic queries. Only request fields you actually need. glabhas no--json field1,field2equivalent. Use-F json | jq '{fields}'to filter output for token efficiency.- Use commands exactly as shown in this skill. The commands below are designed to match auto-approval allowlist patterns. Improvising flag order or adding unexpected flags may trigger permission prompts.
- Push only finished work -- one push per round. Where auto-review and
auto_incremental_revieware on (both default),git pushis the review request and it reviews whatever is on the branch at that moment. Do every task of the round first -- all fixes, tests, docs, local checks (coderabbit review --committed), everything committed -- then push once. A progress push spends a scarce per-developer review window on code you already intend to change. While the change is still moving, keep the PR a draft (drafts are not auto-reviewed, so pushes to them are free); marking it ready is the review request. Full gate:references/bot-review-loop.md(One Push Per Round). - A review is not handled until its body-only findings are. Bot findings that never become threads (CodeRabbit nitpick, outside-diff-range, duplicate and failed-to-post buckets) live in the review body and are invisible to thread queries -- triage them too, and reconcile the claimed comment count before declaring a round done.
- A passing bot check is not a completed review. CodeRabbit records each round as a check run named
CodeRabbit(the default since its review progress reports) or, wherereviews.commit_statuskeeps it, a commit status. Neither one fails on a refused round: the check run issuccessorneutral, the status issuccesseither way. The outcome is only in the verdict (Review completedvsReview rate limited) -- the check run's first summary line, or the statusdescription-- and a rate-limited round often posts nothing else at all: no review, no threads, no comment.gh pr checksreturns nodescriptionfor a check run andgh pr view --json statusCheckRollupdrops the verdict on both surfaces, so read it withbot_check(references/bot-review-loop.md, The Status Check Nobody Reads) before reporting a PR as reviewed. - The local CodeRabbit command is exactly
coderabbit review --committed --base {base}, plus--agentfor JSON-lines output. Plain text is the default -- never pass--plain: CLI v0.7 through v0.9.0 reject it (error: unknown option), and v0.9.1 accepts it again as a hidden no-op.--type <scope>is not gone but hidden: it still starts a review, and fails next to--committed. Never improvise an output or scope flag from memory: thecoderabbitskill owns the CLI surface. On v0.7 a wrong flag printed the usage text with exit0, so a wrapper that tails the output read it as a clean review (v0.8 exits1). - Never end a turn on an in-flight bot round without a way back to it. A non-draft PR on an auto-review repo starts a round at creation; wait for it the way the host allows. Where polling is allowed, run the
bot_tickloop. Where the host forbids self-polling but offers a PR monitor (Claude Code desktop app: Auto-fix), ask the user to switch it on and name what it misses: a clean CodeRabbit round posts no review comment, and a rate-limited one only leaves aCodeRabbitcheck with the verdictReview rate limited, so the monitor may never wake the session -- then the user re-invokes/git-pr, which reads the round's outcome. Where neither exists, say plainly that the round is pending and unprocessed, and that re-invoking/git-prafter it lands processes it. Full detail:references/bot-review-loop.md(Waiting for an In-Flight Round). - When CodeRabbit resolves the threads you replied to, the round is closed. Never request a review to confirm it. Its chat answer re-checked each fix at HEAD, or accepted each reason, before it resolved the thread. That is the confirmation, and it spent no review. Do not post
@coderabbitai revieworfull reviewafter it, and do not ask the user whether to. A later push stampedReview skipped: incremental reviews are disabledis that design working, not a missing round, and aReview rate limitedstatus on HEAD does not reopen the round either. Only two things follow: commits the fixes added (or that landed after the answers) go through the local CLI lane, and on a large PR you may offer one@coderabbitai full review, posted only on a yes. This holds under "loop until clean" too:bot_statusexit7is the loop's clean exit (references/bot-review-loop.md, Fixes Confirmed in the Thread). - Never merge a PR in a stack without asking how. Before every merge, check
gh pr list --base {its head branch}, and check whether its own base is the default branch. Deleting a parent's branch (--delete-branch, or the repo's auto-delete) can close the child PR instead of retargeting it. Each merge into the default branch also re-runs whatever a push there starts (deploys, releases), so merging the stack one PR at a time runs those pipelines once per PR. Tell the user both, list what a push to the default branch starts, and ask: merge as one (top-down, one push) or one by one (bottom-up, child retargeted first). Recipes and the pipeline check:references/stacked-prs.md.
Provider Detection
git remote get-url origin| Remote URL contains | Provider | CLI | PR term |
github.com | GitHub | gh | PR |
gitlab.com or self-hosted GitLab | GitLab | glab | MR |
If ambiguous or both present, ask the user.
The glab recipes follow GitLab's documentation and are not exercised against a live instance -- the GitHub ones are. Treat flags and JSON shapes on the GitLab side as documented-but-unverified: check glab <command> --help before relying on one in an unattended flow, and prefer -F json | jq over assuming a field exists.
Read-Only vs Write Classification
- Read-only (safe to auto-approve):
view,list,status,diff,checks,search - Write (require user approval):
create,edit,merge,close,reopen,comment,review,approve
Reference: See
references/allowlist.mdfor tiered auto-approval patterns.
PR/MR Summary (Current Branch)
GitHub:
gh pr view --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefNameGitLab:
glab mr view -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'PR/MR Summary (By Number)
GitHub:
gh pr view {number} --json number,title,state,isDraft,reviewDecision,mergeable,baseRefName,headRefNameGitLab:
glab mr view {iid} -F json | jq '{iid:.iid,title:.title,state:.state,draft:.draft,merge_status:.merge_status,target:.target_branch,source:.source_branch}'Review State
Reference: See
references/review-queries.mdfor advanced review queries: per-reviewer state, approval checks, pending reviewers.
GitHub:
gh pr view --json reviews,reviewRequests,latestReviewsGitLab:
glab mr view -F json | jq '{upvotes:.upvotes,reviewers:[.reviewers[]?.username]}'For detailed approval info (GitLab):
glab api projects/{project_id}/merge_requests/{iid}/approvals | jq '{approved:.approved,approvers:[.approved_by[]?.user.username]}'Files Changed
GitHub:
gh pr diff --name-onlyGitLab:
glab mr diffFile Stats
GitHub:
gh pr view --json filesGitLab:
glab api projects/{project_id}/merge_requests/{iid}/changes | jq '[.changes[] | {path:.new_path,added:.diff | split("\n") | map(select(startswith("+"))) | length,removed:.diff | split("\n") | map(select(startswith("-"))) | length}]'List Open PRs/MRs
GitHub:
gh pr list --json number,title,author,reviewDecision,updatedAtGitLab:
glab mr list -F json | jq '[.[] | {iid:.iid,title:.title,author:.author.username,updated:.updated_at}]'PR/MR Commits
GitHub:
gh pr view --json commitsGitLab:
glab api projects/{project_id}/merge_requests/{iid}/commits | jq '[.[] | {sha:.short_id,title:.title}]'Search PRs/MRs
GitHub:
gh pr list --search "review-requested:@me" --json number,title,urlGitLab:
glab mr list --reviewer=@me -F json | jq '[.[] | {iid:.iid,title:.title,url:.web_url}]'Create PR/MR (Write -- Manual Approval)
| Action | GitHub | GitLab |
| Create draft | gh pr create --draft --fill | glab mr create --draft --fill |
| Create with title | gh pr create --title "feat: ..." --body "..." | glab mr create --title "feat: ..." --description "..." |
| Create + request Copilot review | gh pr create --title "..." --body "..." --reviewer @copilot (gh >= 2.88) | n/a |
Stacked PR (GitHub): gh pr create --base {parent_branch} .... By default CodeRabbit skips auto-review on a non-default base (Review skipped: reviews are disabled for this base branch, green check) unless auto_review.base_branches matches it, so an explicit @coderabbitai review starts its round. Merging a stack is Critical Rule 11 (references/stacked-prs.md).
Keep bodies lean. The title follows Conventional Commits (git-commit skill); the body is a few sentences or tight bullets on what changes and why -- no restating the diff, no boilerplate sections beyond what the repo's PR template requires.
After creating a non-draft GitHub PR, check gh api repos/{owner}/{repo}/pulls/{n}/requested_reviewers before requesting any bot review -- repos with automatic Copilot review already have one in flight (and it will NOT show in gh pr view --json reviewRequests). On a repo you know has no auto-review, skip the create-then-edit round-trip and request Copilot at creation with --reviewer @copilot; when unsure, create normally and let the detection decide.
A round in flight after creation is the next step, not the end of the turn. CodeRabbit shows it as HEAD's CodeRabbit check still running (bot_requested checks both surfaces). Wait for it the way the host allows (Critical Rule 9) -- with a PR monitor and no self-polling, the message that reports the new PR is the one that asks the user to switch the monitor on.
Merge (Write -- Manual Approval)
Check for a stack first (GitHub). PRs stacked on this one target its head branch:
gh pr list --base "$(gh pr view {pr} --json headRefName --jq .headRefName)" --json number,title,headRefName,isDraft
gh pr view {pr} --json baseRefName --jq .baseRefName # compare with the default branch:
gh repo view --json defaultBranchRef --jq .defaultBranchRef.name # a different base means this PR is itself stackedAny PR in the first result, or a base that differs from the default branch, means stop and ask (Critical Rule 11).
Reference: See
references/stacked-prs.mdfor detecting a stack and what a push to the default branch starts, the top-down and bottom-up recipes, and recovering a closed child PR.
| Action | GitHub | GitLab |
| Squash merge | gh pr merge --squash --delete-branch | glab mr merge --squash --remove-source-branch |
| Rebase merge | gh pr merge --rebase --delete-branch | glab mr merge --rebase --remove-source-branch |
Review Comment Handling
Reference: See
references/pr-comment-workflow.mdfor the full opinionated workflow with all command patterns and examples.
The workflow has two distinct phases -- never mix them:
Phase 1: Analyze and Fix (local work, no GitHub API writes) -- the fetches are zero-approval; git commit/git push are writes and stay a human checkpoint
- Fetch all unresolved review threads in a single GraphQL query with inline
--jqfilter, then the bot's review bodies -- threads are not the whole review (see below) - For each thread: read the file at the referenced path+line, check if the comment is valid by researching the codebase (patterns, conventions, CLAUDE.md, git log)
- Be critical -- validate each comment against actual code before accepting. Reviewers can be wrong.
- Make all necessary code fixes -- without adding code comments that narrate the fix or restate what the code already reads
- Commit the fixes (as many commits as the change needs) and push once for the whole round -- the message describes the change itself, never the review process (no "address review feedback", bot names, or round numbers; see the
git-commitskill)
Not every finding is a thread (CodeRabbit). Nitpicks (under profile: chill), outside-diff-range findings, duplicates and failed-to-post comments exist only in the review body; reviewThreads never returns them, which is the usual reason a review looks handled but isn't. Fetch the bot's review bodies, triage those items too, and reconcile the top-level bot threads against the Actionable comments posted: N the reviews claim -- commands in references/bot-review-loop.md.
Phase 2: Reply and Resolve (one batched command, one approval)
6. Combine all replies and all resolves into a single &&-chained command
7. REST replies first, then a single GraphQL mutation with aliases to batch-resolve all handled threads
8. Leave "Needs discussion" threads unresolved -- and every CodeRabbit thread you replied to, rejected ones included: its answer re-checks a fix at HEAD or weighs your reason, then resolves the thread itself, the confirmation that stands in for a re-review (references/bot-review-loop.md, Fixes Confirmed in the Thread). Resolve one yourself only when no answer came within 10 minutes and no review on HEAD is running or just finished (its answers follow it), and don't count it as confirmed
This ordering matters: pushing fixes first ensures reviewers see the changes when they read replies. Never reply to a comment claiming "Fixed" before the fix is actually pushed.
Fetch Unresolved Threads (Zero Approvals)
GitHub -- one command with $(...) substitution. Generate as a single line and do NOT prepend variable assignments (OWNER=..., REPO=...) -- both break allowlist matching:
gh api graphql -f query="{ repository(owner: \"$(gh repo view --json owner --jq '.owner.login')\", name: \"$(gh repo view --json name --jq '.name')\") { pullRequest(number: $(gh pr view --json number --jq '.number')) { reviewThreads(first: 100) { totalCount pageInfo { hasNextPage endCursor } nodes { id isResolved isOutdated path line startLine comments(first: 20) { nodes { id fullDatabaseId body author { login } } } } } } } }" --jq '.data.repository.pullRequest.reviewThreads | {total: .totalCount, nextCursor: (if .pageInfo.hasNextPage then .pageInfo.endCursor else null end), unresolved: [.nodes[] | select(.isResolved==false)]}'Returns the unresolved threads plus the two numbers that prove the fetch was complete. reviewThreads does not paginate on its own -- a non-null nextCursor means threads 101+ exist and may hold unresolved comments; re-run with reviewThreads(first: 100, after: \"{nextCursor}\") and merge before deciding anything is handled.
Response field mapping (critical -- using wrong ID causes silent failures):
| Field | Format | Use for |
thread .id | PRRT_... (node ID) | resolveReviewThread mutation |
comment .fullDatabaseId | "2949637341" (string) | REST reply endpoint |
comment .id | PRRC_... (node ID) | Not typically needed |
GitLab (REST):
glab api projects/{project_id}/merge_requests/{iid}/discussions --paginate | jq '[.[] | select(.notes[0].resolvable==true and .notes[0].resolved==false) | {id:.id,path:.notes[0].position.new_path,line:.notes[0].position.new_line,body:.notes[0].body,author:.notes[0].author.username}]'Reply and Resolve (One Batched Command)
GitHub -- combine all REST replies and a batch GraphQL resolve mutation into one &&-chained command. Reply uses fullDatabaseId (a string; databaseId is deprecated), resolve uses thread id (PRRT_ node ID). The example is for human and Copilot threads: on CodeRabbit threads keep every reply but leave all of their threads out of the mutation, rejected ones included, since CodeRabbit answers each reply and resolves the thread itself (step 8):
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{fullDatabaseId_1}/replies -f body="Fixed in {sha} -- {explanation}" && \
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{fullDatabaseId_2}/replies -f body="Addressed in {sha}" && \
gh api graphql -f query="
mutation {
t1: resolveReviewThread(input: {threadId: \"PRRT_thread1\"}) { thread { isResolved } }
t2: resolveReviewThread(input: {threadId: \"PRRT_thread2\"}) { thread { isResolved } }
}"A round with only CodeRabbit threads is the replies alone -- no mutation.
GitLab:
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1}/notes --method POST --field "body=Fixed in {sha}" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_1} --method PUT --field "resolved=true" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2}/notes --method POST --field "body=Addressed" && \
glab api projects/{id}/merge_requests/{iid}/discussions/{disc_2} --method PUT --field "resolved=true"Code Review Policy (Convention)
Review preferences are declared in a Code Review Policy section of an agent instructions file -- check for one before requesting any review. Two scopes, most specific wins:
- Repo policy -- the project's AGENTS.md or CLAUDE.md. AGENTS.md is the preferred home: Copilot code review itself reads the root AGENTS.md, so one file steers both the agent and the reviewer.
- User-global policy -- the user's global agent instructions (Claude Code:
~/.claude/CLAUDE.md) as the default flow across repos.
Both reviewers are optional. Detect what is actually available (CodeRabbit app installed / CLI authenticated, Copilot ruleset or observed auto-review) and never assume a reviewer exists, is paid for, or should be added. Reviewer: none is a valid policy -- human review only. Example:
## Code Review Policy
- Reviewer: coderabbit # coderabbit | copilot | both | none
- CodeRabbit plan: team until 2026-10-20, then essentials # free | essentials | team | advanced | enterprise
- Copilot billing: legacy # legacy (premium requests) | credits
- Local review: coderabbit review --committed --base main # run before every push; --agent for JSON lines, no --plain
- PR review rounds: ask # ask | loop <= NDeclare the CodeRabbit plan -- no API reports it. coderabbit usage gives a repository's included allowance and the billing period, not the tier, and the PR API never mentions it, so an agent that isn't told will either over-schedule PRs into a bucket that cannot serve them or idle a bucket that could. The plan sets the CEILING on the hourly allowance (Free 1 / Essentials 5 / Team 8 / Advanced 10 PR reviews per developer; Essentials and Team were Pro and Pro+ until September 2026, and a grandfathered Pro+ keeps 10 -- table in the coderabbit skill), but fair-usage throttling sets the effective rate beneath it from the developer's review count over a rolling 24-hour or 7-day window -- a heavy review week lands an Essentials developer at 1--2/hour. Two surfaces do report the live figure: the run-configuration block inside each posted review (which also names the plan), and a @coderabbitai rate limit comment, which returns the remaining allowance and next availability without spending a review -- the cheap check before opening a loop. The allowance in turn sets how many PRs can be non-draft at once and how much iteration belongs in the local CLI lane. Note a trial's end date the same way: the queue that works on Advanced stalls on Essentials the morning the trial lapses. Undeclared, infer a floor instead of guessing -- bot_bucket (references/bot-review-loop.md) lists recent rounds across every open PR, and the completions in the trailing hour are a lower bound on the real allowance.
When no policy exists (either scope), default conservative: if an auto-review fired, process that round -- waiting for it the way the host allows (Critical Rule 9); then ask before any billable re-request -- and inform the recommendation with the quality of the round's findings (mostly valid substantive issues -> another round likely pays off; mostly noise -> stop). The exception is CodeRabbit after its first full review: the round closes in its threads, so there is no re-request to ask about (Critical Rule 10). Never initiate billable reviews unprompted on repos without auto-review; loop only when explicitly asked.
Bot Review Loop (GitHub)
Reference: See
references/bot-review-loop.mdfor the full loop: per-bot config blocks (Copilot, CodeRabbit), thebot_status/bot_tickdriver, polling and host-aware waiting, and termination logic. Reference: Seereferences/copilot-review-config.mdfor Copilot review configuration: billing models and quota checks, auto-review ruleset detection/management, custom instructions, and the Copilot CLI local review option.
GitHub review bots (Copilot, CodeRabbit) are GitHub-only, asynchronous (~minutes per review), and do not block by default: their review state is COMMENTED, unless CodeRabbit's Automatic Approvals is on -- then it requests changes and approves, and its approval counts toward required approvals (references/bot-review-loop.md, How Bot Reviews Appear). The loop is identical per bot; only the identity (which login to filter), the re-request trigger, and the detectable failure/rate-limit/clean-review notices differ -- a per-bot config block sets them. Enablement detection is partial (the Copilot auto-review ruleset is readable, but personal-setting auto-review and overall bot availability are not -- see Context Check above), so bot_tick exits 5 when the remote isn't GitHub or the re-request errors; an accepted-but-unanswered request exits 3 (slow or silently unavailable).
Iterate until no valid comments remain. Source a bot's config + the bot_status/bot_tick driver -- one round is:
- Re-request only when needed + wait --
bot_tick {N}first checks for unresolved bot threads (handle those, never re-request over them), then a review at HEAD (a clean CodeRabbit review posts no review object -- its "no actionable comments" walkthrough text or a "Review finished." ack is the clean signal, never a failure or rate limit), then HEAD'sCodeRabbitcheck (bot_check: the check run or the legacy commit status), which never fails even when the round was refused (Review rate limited= HEAD was never reviewed), then a pending request in RESTrequested_reviewers(auto-review on non-draft PR creation usually means round 1 needs no re-request at all). Only if none of those apply does it re-request (Copilot:gh pr edit {N} --add-reviewer "@copilot", gh >= 2.88, no auto re-review on push; CodeRabbit: a@coderabbitai reviewcomment), then polls for the async review -- where the host allows polling; otherwise the wait goes to its PR monitor or the user (Critical Rule 9). Returns0clean /2not clean /3retry /4failed (already cooled down ~5 min + re-requested -- re-run to poll) /5not applicable /6rate-limited /7fixes confirmed in the thread (CodeRabbit re-checked each fix at HEAD, or accepted each reason, in chat and resolved its threads; no re-request -- cover extra code the fixes added with the local CLI lane, and on a large PR offer the user one@coderabbitai full reviewrather than posting it). - Validate, don't blind-fix -- evaluate each unresolved comment and every body-only bucket of the review (nitpick, outside-diff-range, duplicate, failed-to-post; Research Checklist); bots can be out of context or outdated. Fix valid ones (commit each, then one push per round; the message names the change, never the bot or round), reply with a rationale + resolve invalid ones -- except CodeRabbit's: reply to every one of its threads and leave them open for it to resolve (Phase 2, step 8). To clear every reviewer, run the loop once per active bot and handle human threads via the comment workflow above.
- Terminate -- stop when the bot has no comments; on zero valid comments (re-requesting would only resurface them); after ~3 consecutive failed reviews (
exit 4is transient -- e.g. "Copilot encountered an error" -- andbot_tickretries it with a ~5-min cooldown + re-request; only repeated failure is structural: oversized PR, binary files, quota; escalate); on a rate limit (exit 6: CodeRabbit -- schedule from theBOT_WAIT_UNTILthe tick exported, since the notice it came from can be edited away; that is the printed window when one was readable, else ~10 min from the bounce, doubling only after a retry bounces again. Checkbot_bucketfirst -- a sibling PR reviewed after your bounce means the shared bucket is open now -- then post a fresh trigger, since nothing is queued, and make it@coderabbitai full review: the bounced round still marked the commits as reviewed, so a plainreviewno-ops. A bounce consumes no review and moves no deadline, but it is never queued either, so probe with@coderabbitai rate limit(consumes no review, reports next availability -- but it is a PR comment, so it needs write approval like any other) rather than with repeat triggers; or skip the bot when Copilot also covers the repo; Copilot -- a hard weekly limit diagnosed from the review run's CI log behind the generic "encountered an error" comment: never re-request before the logged reset date, report cause + date to the user); on unavailability (exit 5); after the round cap (default 5, or "loop 3"); or if HEAD is unchanged since the last round.
Rounds are billable, and on auto-review repos a push is a round -- each Copilot round bills a full review; each CodeRabbit round spends hourly quota that is per developer, not per PR: all your open PRs contend for the same review windows, so with several PRs in flight keep the waiting ones as drafts (excluded from auto-review; marking ready is the request) and promote one at a time -- see the reference's Scheduling Several PRs Through One Bucket and One Push Per Round. Without an explicit loop instruction or a permissive Code Review Policy: process the auto-review round if one fired, then ask before re-requesting (recommend based on finding quality). For CodeRabbit, that ask exists only when its threads did not close the round (Critical Rule 10). Autonomous looping is for when the user asked for it.
CodeRabbit: after the first full review, the threads are the loop. Push the round's fixes once, reply to every thread -- "Fixed in {sha}", partly taken, or not changed and why -- and let its answers close them: chats, not reviews, so they spend no PR review (references/bot-review-loop.md, Fixes Confirmed in the Thread). Request no further review by default: extra code the fixes added goes through the local CLI lane. Only on a large PR, offer the user one @coderabbitai full review -- a full pass over new commits sometimes finds what the threads cannot -- and post it only on a yes.
Identity gotcha: each bot has a [bot]-suffixed login on REST and an unsuffixed one on GraphQL threads (Copilot: copilot-pull-request-reviewer[bot] / copilot-pull-request-reviewer, plus Copilot on REST inline comments; CodeRabbit: coderabbitai[bot] / coderabbitai). Filter the right one per surface.
Line-Specific Comments (Write)
Reference: See
references/line-comments.mdfor full patterns: single-line, multi-line range, replies, edit/delete, batch reviews.
GitHub:
gh api repos/{owner}/{repo}/pulls/{pr}/comments \
-f body="{comment}" -f path="{file}" -F line={line} -f side=RIGHT \
-f commit_id="$(gh pr view {pr} --json headRefOid --jq .headRefOid)"GitLab:
glab api projects/{project_id}/merge_requests/{iid}/discussions --method POST \
--field "body={comment}" \
--field "position[base_sha]={base_sha}" \
--field "position[head_sha]={head_sha}" \
--field "position[start_sha]={base_sha}" \
--field "position[position_type]=text" \
--field "position[new_path]={file}" \
--field "position[new_line]={line}"Read-Only API Endpoints
Reference: See
references/api-readonly.mdfor the full list of read-only REST and GraphQL endpoints (PR data, issue timelines, review threads) for both providers.
Key glab vs gh Differences
| Aspect | gh | glab |
| MR description flag | --body | --description |
| Delete source branch | --delete-branch | --remove-source-branch |
| JSON output | --json field1,field2 (filtered) | -F json (full resource) |
| jq filtering | --jq '.expr' (native) | pipe to | jq '.expr' |
| Squash on create | --squash | --squash-before-merge |
| GraphQL | gh api graphql -f query='...' | Not supported (REST only) |
| Thread resolution | GraphQL mutation | PUT /discussions/:id with resolved=true |
| Approval model | Review states (APPROVED, CHANGES_REQUESTED) | Approval rules + approve/revoke |
| Pagination | --paginate (subcommands + api) | --paginate (api only), -P (subcommands) |
Allowlist
Reference: See
references/allowlist.mdfor tieredBash(command:*)patterns covering all read-only operations -- safe to auto-approve in Claude Codesettings.jsonor OpenCode config.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

