Process and resolve GitHub Copilot automated PR review comments...
โ Load fx-dev:review first (Skill tool: skill="fx-dev:review"). It is the
canonical review procedure. This skill is the Copilot thread adapter: the
GraphQL calls that fetch, reply to and resolve Copilot's review threads, and the
category table that maps a Copilot comment onto a disposition. Where the two
appear to disagree, fx-dev:review wins.
From fx-dev:review, and not restated here:
REVIEW.md entry for an incorrect finding, and the rule
against writing .github/copilot-instructions.md or running fx-dev:setup
from here.NEVER leave new comments directly on GitHub PRs. Forbidden: gh pr review --comment, gh pr comment, any GraphQL mutation creating a new review or
PR-level comment, and any response to a human reviewer's thread.
This skill ONLY processes GitHub Copilot threads. Permitted operations are
exactly two: reply to an existing Copilot thread with
addPullRequestReviewThreadReply, and resolve it with resolveReviewThread.
Addressing feedback without resolving the thread is INCOMPLETE WORK. After handling any Copilot feedback you MUST push the code changes (where the disposition called for a change), resolve each thread via the mutation below, and verify by re-querying the PR. Code changes alone are insufficient.
Copilot reads REVIEW.md from the head branch, so a rule you add there takes
effect on this same PR's next review.
CRITICAL: Load the fx-dev:github skill FIRST before running any GitHub API operations. This skill provides essential patterns and error handling for gh CLI commands.
Use this resolver only when the user explicitly names or invokes it, or when an active explicitly invoked workflow calls fx-dev:copilot-feedback-resolver by name. A standalone mention of Copilot, a PR, comments, review state, or failing checks does not auto-load it.
Invocation: always with the brief and your dispositions, never bare โ
Skill tool: skill="fx-dev:copilot-feedback-resolver",
args="<Scope Brief verbatim> โ dispositions: <thread id> blocking, <thread id> immaterial, <thread id> deferred (<exclusion>) โ false premise (this skill's own handler): <thread id> (<what does not hold>)"
ONLY process UNRESOLVED comments. NEVER touch, modify, or re-process already resolved comments. Skip them entirely.
Query review threads using GraphQL.
IMPORTANT: Use inline values, NOT $variable syntax. The $ character causes shell escaping issues.
# Replace OWNER, REPO, PR_NUMBER with actual values
gh api graphql -f query='
query {
repository(owner: "OWNER", name: "REPO") {
pullRequest(number: PR_NUMBER) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 10) {
nodes {
author { login }
body
}
}
}
}
}
}
}'
Filter for: isResolved: false AND author is Copilot (github-actions bot or copilot signature)
Triage per fx-dev:review Steps 2โ3. This table is the Copilot-specific mapping
from what a comment looks like onto the disposition that triage produces โ it is
not a shortcut around the filters.
A coordinator's disposition wins over this table, which classifies from
comment text alone (fx-dev:review Step 5). Use the table only for threads it did
not cover, and for a standalone run.
| Category | Indicator | Action |
|---|---|---|
| Nitpick | Contains [nitpick] prefix and reaches filter 3 and fails it โ in scope, violating no rule, and immaterial. An out-of-scope one exits at filter 1 and is Deferred, not this row |
Reply with the materiality reasoning and resolve, without editing |
| Outdated | Refers to code that no longer exists | Reply with the explanation, resolve |
| Incorrect | Misreads a deliberate project convention | Reply with the explanation, resolve, record it in REVIEW.md |
| Valid โ blocking | Is blocking per fx-dev/skills/dev/references/scope-contract.md ยง Blocking โ which includes a contract blocker, and those never pass through the bar at all. Do not narrow it here |
Delegate to coder sub-agent to fix |
| Valid โ immaterial | Correct, but would change nothing if it shipped uncorrected | Reply with that reasoning, resolve. Do not edit |
| Deferred | Valid but out of scope for this PR | Reply citing the exclusion, resolve. No edit and no commit โ return the follow-up to the coordinator |
The [nitpick] prefix is Copilot's own label, never a verdict: a project-rule,
security, privacy or correctness defect carrying it is still blocking. Never
auto-resolve on the prefix alone.
Use GraphQL mutation to resolve.
IMPORTANT: Use inline values, NOT $variable syntax.
# Replace THREAD_ID with actual thread ID (e.g., PRRT_kwDONZ...)
gh api graphql -f query='
mutation {
resolveReviewThread(input: {threadId: "THREAD_ID"}) {
thread { isResolved }
}
}'
CRITICAL: reply to the Copilot review thread, NOT to the PR. Use inline
values, NOT $variable syntax.
# Replace THREAD_ID and message with actual values
gh api graphql -f query='
mutation {
addPullRequestReviewThreadReply(input: {
pullRequestReviewThreadId: "PRRT_xxx",
body: "Your explanation here"
}) {
comment { id }
}
}'
โ FORBIDDEN โ never use: gh pr review <PR_NUMBER> --comment,
gh pr comment, or any interaction with a human reviewer's thread.
Every disposition ends with a reply and a resolve; what differs is only the reply
and whether anything was changed (fx-dev:review Step 5). Phrasing that works:
REVIEW.md entry is required work (fx-dev:review Step 6), and Copilot reads
that file from the head branch, so it takes effect on this PR's next review.Never defer without recording it somewhere durable โ and that record must not be
a commit on this PR. Return it to the coordinator for the finding ledger or the
PR description; running standalone in a repo that tracks follow-ups in
PROJECT.md, propose the entry to the user instead of committing it. A bare
"acknowledged for follow-up" recorded nowhere is INCOMPLETE WORK; a PROJECT.md
commit here is a widened change.
git pushTask is INCOMPLETE until ALL of these are done:
REVIEW.md updated to prevent recurrencePROJECT.md commit on this branchisResolved: true for all processed threadsYou MUST output this table after processing all threads:
| Thread ID | File:Line | Category | Action Taken | Status |
|-----------|-----------|----------|--------------|--------|
| PRRT_xxx | src/foo.ts:42 | Nitpick | Replied with reasoning, no edit | โ
Resolved |
| PRRT_yyy | src/bar.ts:15 | Valid | Fixed null check | โ
Resolved |
| PRRT_zzz | lib/util.js:8 | Outdated | Code refactored | โ
Resolved |
| PRRT_aaa | src/ui.tsx:20 | Deferred | Returned to coordinator, no edit | โ
Resolved |
Column definitions:
Common failure mode: Fixing code but forgetting to resolve the threads. This leaves the PR with unresolved conversations even though the issues are fixed. ALWAYS run the resolution mutation after pushing code.