Block merge until Copilot reviews HEAD + threads resolved#25
Merged
Conversation
Copilot reviews asynchronously, so a fast self-merge can land *before* Copilot posts its review threads — native required_review_thread_resolution has nothing to block on, the merge succeeds, and the comments arrive seconds later (observed on a real PR: threads created 2s after merge). Add a custom required check that closes the race: - copilot-review-gate.yml (reusable): GraphQL-evaluates the PR and fails unless Copilot has reviewed the current HEAD commit AND every review thread is resolved. Drafts and bot-authored PRs are exempt (avoid deadlocks). - required-copilot-review-gate.yml (wrapper): re-evaluates on pull_request_review and pull_request_review_thread events so resolving a thread flips the check green without a re-push. Skips on the meta-repo. - apply-org-policy.sh: two tier=production rulesets — production-copilot-review (Copilot auto-review with review_on_push:true, so HEAD is always re-reviewed after a fixup push and the gate can't deadlock) and production-review-gate (requires the wrapper). - self-ci: ignore actionlint's stale "unknown event" error for the real pull_request_review_thread trigger. Honest limit documented in ORG-POLICY.md: "resolved" is a manual ack, not proof a comment was fixed — this forces conscious per-thread resolution of the current code, making skip deliberate rather than accidental. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem (evidence-based)
Copilot reviews asynchronously. On pituitary #413 the review threads were created at
07:09:47Z/:48Z— the PR merged at07:09:45Z, ~2s earlier. Nativerequired_review_thread_resolutioncan't block on threads that don't exist yet at merge time. Two other gaps: ungated repos (cortex wastier=null) and summary-only Copilot reviews with no inline threads.Fix
A custom required status check that stays red until Copilot has reviewed the current HEAD commit AND every review thread is resolved.
copilot-review-gate.yml(reusable) — GraphQL evaluation; exempts drafts + bot PRs.required-copilot-review-gate.yml(wrapper) — re-evaluates onpull_request_review+pull_request_review_threadso resolving a thread flips it green without a re-push; skips on the meta-repo.apply-org-policy.sh— addsproduction-copilot-review(Copilotreview_on_push: true) andproduction-review-gate(requires the wrapper), bothtier=production.Why
review_on_push: trueis load-bearingWithout it, the strict "reviewed HEAD" gate deadlocks the instant you push a fixup past Copilot's first review. With it, Copilot re-reviews every push, so HEAD always gets a fresh review.
Honest limit
"Resolved" is a manual acknowledgment, not proof a comment was fixed — GitHub has no concept of "addressed". This forces conscious, per-thread resolution of the current code; for a solo self-merger it makes skipping deliberate and loud rather than accidental.
Apply order
Merge first (wrapper must be on
main), then./scripts/apply-org-policy.sh. Scope:tier=production+ cortex promoted to production.🤖 Generated with Claude Code