copilot-pr-review-loop
GitHub自动化GitHub PR的Copilot代码审查循环,通过多轮迭代处理评论直至收敛。涵盖请求审查、修复或驳回反馈、线程清理及人工交接,适用于PR功能完成后的最终正确性检查。
Trigger Scenarios
Install
npx skills add microsoft/intelligent-terminal --skill copilot-pr-review-loop -g -y
SKILL.md
Frontmatter
{
"name": "copilot-pr-review-loop",
"description": "Drive a GitHub pull request through repeated rounds of Copilot code review until convergence. Use when the user asks to \"request Copilot review\", \"run a Copilot review loop\", iterate on Copilot feedback, or wants automated triage-and-respond on Copilot PR comments. Covers re-request mechanics, open-thread filtering, fix-vs-decline triage, reply-and-resolve, and end-of-loop cleanup."
}
Copilot PR Review Loop
Drive any GitHub pull request through repeated rounds of Copilot code
review until the agent has done its job — every Copilot finding has
a reply from the agent (fix-acknowledgement, decline-with-rationale,
or explicit escalate-to-user hand-off). Remaining open threads, if
any, are deliberate hand-offs to the human merge owner — they're
not loop failures. Repository-agnostic — works on any repo that has
Copilot Code Review enabled, run from a machine with gh CLI
installed and authenticated (see Prerequisites).
When to Use This Skill
- The user asks to "request Copilot review" or "run a Copilot review loop" on a PR.
- A PR is functionally complete and the user wants a final correctness pass via repeated automated review rounds.
- A previous Copilot review on the PR has left open threads that need triage, fixing, replying, and resolving.
When NOT to Use This Skill
- The PR is still under active design — wait until the structure is stable; otherwise findings churn round-over-round.
- The user wants human reviewer feedback, not Copilot's.
Prerequisites
ghCLI installed and authenticated against the target repository.- PowerShell on PATH — Windows PowerShell 5.1+ (
powershell.exe) or PowerShell 7+ (pwsh). Both are tested. - Copilot Code Review is the primary use case (
01-request-review.ps1uses GraphQLrequestReviewsByLoginto trigger Copilot). It is NOT a hard requirement — if01-request-review.ps1fails because Copilot isn't enabled on the repo / account, the agent can still drive existing review threads (human, advanced-security, etc.) to completion by running steps 3–8 once as a single iteration; just skip the trigger + wait. There is no auto-detect for "Copilot unavailable" — the agent makes that decision after the trigger fails (the script can't reliably tell "Copilot disabled" from "Copilot enabled but not yet triggered" from API state alone).
Every script dot-sources scripts/_lib.ps1 which
runs Assert-GhReady on load: if gh is missing OR gh auth status
fails, the script halts before any work with a single actionable
error message naming the install command and gh auth login. The
agent should surface that message to the user verbatim and stop the
loop — do not retry or work around it.
Step-by-Step Workflow
Each round runs steps 1–9; step 10 is a one-time cleanup after
convergence. The parent agent coordinates; every substantive step is
delegated to a fresh sub-agent with a bounded budget (default ≤5 min;
per-step exceptions in the delegation table in
references/workflow.md), so the parent
never blocks on long-running work and each step gets a clean context.
Sub-agents must summarize and return before their budget expires; the
parent extends via write_agent when needed. Full procedure,
per-step budgets, return contracts, and the extension protocol live
in references/workflow.md.
Single-iteration fallback (Copilot unavailable): when
01-request-review.ps1 throws because Copilot Code Review isn't
enabled on the repo / account (the GraphQL mutation reports the bot
isn't a valid reviewer), the agent skips step 2 and runs steps 3–8
once, then calls 02-check-review-status.ps1 -SingleIteration for
the convergence check (which then ignores the stale-review checks
that can't advance without a new Copilot review). Converged: true
when OpenThreadsAwaitingReply == 0. Re-iteration happens only when
a human posts new comments later — re-run the skill at that point.
Request review → Wait for review (sub-agent) → List + categorize open
threads → Triage (sub-agent) → Fix (sub-agents, parallel) → Build/test
per the repo's own conventions → Commit + push → Reply + resolve
(citing pushed SHA) → Convergence check → Cleanup outdated (final, once)
Build, test, and lint commands are NOT prescribed here. Each
step that runs them defers to the target repo's own conventions —
CONTRIBUTING.md, AGENTS.md, README, package.json/Makefile/
language-specific tooling, or whatever the repo uses. The skill's job
is the review loop; the repo's job is to tell us how it's built.
Convergence is computed by scripts/02-check-review-status.ps1
as a single Converged: true boolean. Do not call task_complete
until it returns true; print the proof (HeadOid,
LatestCopilotReview.commitOid, submittedAt) in the completion
message.
Gotchas
- NEVER post
@copilot please review(or any@copilotmention) as a PR comment to trigger a code review. That summons the Copilot Coding Agent (which makes commits), not the reviewer bot, and will not produce a review. Use scripts/01-request-review.ps1 (GraphQLrequestReviewsByLogin); if it can't land the trigger, push a substantive commit (auto-assign onsynchronizeis the most reliable fallback) — never fall back to@-mentions. - HTTP 200 / exit 0 from the trigger call is NOT proof Copilot
accepted it. The server can silently drop a request (quiet-period
after dismissal, trivial-diff suppression, repo without Copilot
enabled). The authoritative signal is a
copilot_work_startedevent on the issue (viaGET /repos/{o}/{r}/issues/{n}/events) newer than your request.01-request-review.ps1enforces this via event-idcomparison — don't weaken it. - A "no new comments" review is necessary but not sufficient for
convergence. It must ALSO be at the current
HEADSHA AND every open thread must have a reply from the agent (OpenThreadsAwaitingReply == 0). A stale review on an earlier commit lets a regression slip through unreviewed; an open Copilot thread the agent hasn't replied to means the loop hasn't done its job yet.02-check-review-status.ps1'sConvergedflag enforces all three. Open threads with our reply (escalate-to-user hand-offs, contested declines) are by design — they're awaiting the human merge owner, not the loop. - Reply to every open thread; resolve only when the loop owns the
disposition (
fixordecline). For threads classifiedescalate-to-user, reply with the analysis but leave the thread OPEN (use08-reply-and-resolve.ps1 -NoResolve) so the human merge owner can act on it. Resolving without a reply leaves no record of why the issue was considered addressed; resolving an escalated thread hides the hand-off from the human. - Copilot threads are loop-owned; human / advanced-security / other-bot threads default to escalate-to-user. Auto-replying or auto- resolving a human review thread can hide unaddressed concerns and is socially wrong. The triage rubric explicitly distinguishes reviewer types.
- One focused commit per round, not one per PR. Bundling rounds
destroys the audit trail of which finding drove which change and
breaks
git bisect. - Build/test/lint with the repo's own commands (per its
CONTRIBUTING/AGENTS/README) before pushing a fix. A broken build wastes the next full review cycle (3–10 minutes). - Research the repo's own docs before generating any fix, build,
or test command. Read
.github/instructions/*.md(often withapplyToglobs pinning them to specific files),.github/skills/,AGENTS.md,CONTRIBUTING.md, and recent commits to similar files. Fan out multiple sub-agents in parallel when several axes need checking. Never invent generic answers that contradict repo practice — that's the "elephant in school" anti-pattern. - Don't poll the review state faster than ~3 minutes. There is no progress signal; faster polling only wastes API budget.
- Respect repo-specific spell-check / lint / format policies. Some repos prefer rewording over allowlist entries; some have a patterns/regex file; some accept inline-ignore directives. Inspect the repo's existing config and recent commits before applying a generic Copilot suggestion.
- Push back with written rationale when a Copilot finding would over-engineer the design for a hypothetical edge case. Auto-accepting every suggestion erodes the design.
- Scripting traps (
gh api graphql -Ftype-coercion,git stash push -mpositional parsing, the three GraphQL traps for the reviewer mutation) are documented in references/api-quirks.md. Read before modifying any script.
Troubleshooting
| Issue | Solution |
|---|---|
Script throws prerequisite missing — gh CLI is not on PATH |
Install gh (winget install GitHub.cli on Windows; brew install gh on macOS; package manager on Linux; or download from https://cli.github.com). Then gh auth login. Surface the message to the user and STOP the loop — do not retry. |
Script throws prerequisite missing — gh CLI is not authenticated |
Run gh auth login. STOP the loop until the user completes auth. |
Trigger fails or no copilot_work_started event lands |
Push a substantive (non-whitespace) commit — auto-assign on synchronize is the most reliable trigger. Persistent failure indicates Copilot Code Review may not be enabled on the repo / account (check repo Settings → Code & automation → Copilot, or account-level Copilot Pro/Pro+). |
| No new review after waiting ~10 min | Quiet-period after recent dismissal or trivial-diff suppression. Push a substantive commit and retry. Do not blindly re-run 01-request-review.ps1 — it reports InFlight while Copilot is still a requested reviewer. |
| Outdated-but-unresolved threads in the open list | Expected: unresolved state is the source of truth. Reply + resolve them like any other open thread. 10-cleanup-outdated.ps1 is only a final safety net. |
| Unsure whether to fix or decline a finding | See references/03-triage-criteria.md. |
| Need a reply phrasing for "fixed", "declined", or "drift" | See references/06-reply-templates.md. |
References
- references/workflow.md — ten-step procedure with per-step sub-agent budgets, return contracts, and the extension protocol.
- references/03-triage-criteria.md — fix-vs-decline decision rubric.
- references/api-quirks.md — verified GitHub API behavior, dead-ends, and the GraphQL traps for the reviewer mutation.
- references/06-reply-templates.md — reply patterns for accepted fixes, declined-with-rationale findings, and description-update acknowledgements.
- scripts/_lib.ps1 — shared helpers (
Invoke-Gh,Invoke-GhGraphQL,Resolve-RepoCoords); dot-sourced by every script. - scripts/01-request-review.ps1 —
trigger Copilot review and verify pickup via the
copilot_work_startedevent. - scripts/02-check-review-status.ps1 —
single-shot snapshot of the PR's Copilot review state; emits
Converged: trueonly when all three conditions hold. - scripts/03-list-open-threads.ps1 — every unresolved PR review thread from all reviewers (Copilot, humans, github-advanced-security, etc.).
- scripts/08-reply-and-resolve.ps1 — post a reply and resolve in one call.
- scripts/10-cleanup-outdated.ps1 — safety net for outdated Copilot threads.
Version History
- 36e5cf0 Current 2026-07-05 18:26


