You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The quota-safety half of #2261, per the maintainer's answers recorded on that issue: a generic error round is a possible quota hit after one occurrence, and the tooling never requests into it.
Error rounds. "Copilot encountered an error and was unable to review this pull request" is what the weekly rate limit posts. The maintainer pointed out that the real cause shows in the round's details. pr_review.py now finds the reviewer's own failed Actions run on that commit (dynamic/agents/copilot-pull-request-reviewer) and reads its job log. A logged errorType: 'rate_limit' reports as refusal=QUOTA with the reset time the log states. Anything else, an unreadable log included, reports as refusal=ERROR, a possible quota hit.
wait stops requesting. No request goes out while the pull request's newest Copilot review is a quota or error refusal, on this head or an earlier one, and wait exits 46. A request already pending is still polled for. Where nothing covers the head, the digest's refusal= field reads that refusal from the earlier head.
Defect fixed.wait used to send its auto-request before it consulted the repository-wide quota signal, so an exhausted account still spent a request. It now holds the request back under that signal too.
--ignore-quota-signal overrides both stops.
The defined-moments half of #2261 (the ruleset triggers, the local-pass attestation, and the Merge Gate change) follows in a separate pull request, since it rewrites this same wait region.
Verification
python3 -m unittest tests.test_pr_review: 507 tests pass. The liveness payload in the stop tests is body-less, as the real Q_LIVE is. Each new behavior was shown to fail with the change reverted or mutated.
Two local strict-review passes. Round 1 found 12 findings, including a critical one: the stop was read from the body-less liveness payload, so it never fired. Round 2 found 6. All are fixed except two deliberate declines, the time bound from the parsed reset date and the unchanged # comment at the request site.
A Copilot round reading only "encountered an error" is what the weekly rate limit posts,
its cause written to the reviewer's own Actions run. pr_review.py now reads that run's job
log: a logged rate limit reports as refusal=QUOTA with the reset time, and anything else as
refusal=ERROR, a possible quota hit.
wait sends no request while the pull request's newest Copilot review is a quota or error
refusal, on this head or an earlier one, and exits 46. It also no longer requests while the
repository-wide quota signal is set, where it used to request first and stop after.
--ignore-quota-signal overrides both.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The liveness query carries no review bodies, so the stop never fired there. wait now reads
it from a full read, still polls a request already pending, and the digest reports a quota
or error refusal on an earlier head. Any rate_limit errorType in the log counts, a log that
is not UTF-8 no longer crashes the read, and the 46 lines name the override.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The signal branch skipped the poll even with a request already pending, which also cut the
46 path short. Both quota branches now hold back only the request. The stale-refusal test
reads its own pull request's reviews and expects 46, and the docs are reflowed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
❌ Patch coverage is 94.44444% with 4 lines in your changes missing coverage. Please review. ⚠️ Please upload report for BASE (develop@d2529f1). Learn more about missing BASE report.
The escape-sequence flag arrived in gh 2.97 and the supported floor is 2.47, so a raw read
refused on an unknown flag is retried without it. The pending-poll claim is narrowed to the
earlier-head case the stop covers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Do not resurrect spent refusals after newer answers
scripts/pr_review.py:3084
[P1] Do not resurrect a spent refusal after a newer answer. When a newer Copilot comment follows an earlier-head refusal, answered_outside_review(pr) treats that refusal as spent, but this new stopping_refusal(pr) ignores the comment and makes the digest print the old refusal=ERROR/QUOTA block anyway. That misreports an already-answered pull request and conflicts with the existing quota_signal and answered_outside_review semantics. Exclude the stopping refusal when answer is present.
Answering the previously missed finding "Do not resurrect spent refusals after newer answers" (scripts/pr_review.py:3084): fixed in 7edefc1. stopping_refusal now returns nothing where answered_outside_review finds a newer Copilot comment, so neither the digest nor wait revives a refusal that comment spent. A test covers it and fails with the check removed.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
Address pending-request detection, override handling, repository-wide error signals, and the documented pending-request exception.
Review effort: Lite Findings: None
Previously missed (1)
In code that hasn't changed since last review
Allow override to reevaluate current-head refusals
scripts/pr_review.py:4105
[P1] Let the override re-evaluate a current-head refusal
Q_LIVE intentionally omits review bodies, so a current-head quota/error refusal makes head_review_done return True. Because this branch skips stopping_refusal when done is true, and the request condition also requires not done, --ignore-quota-signal can neither request nor poll past that refusal, despite the CLI help and docs promising it overrides both stops. Re-read the full review state when the override is set, while preserving the bodyless fast path, so a genuine review remains done but a refusal can be re-requested.
The body-less liveness read counts a head refusal as done, so with --ignore-quota-signal the
full read is consulted and the round baseline moves past that refusal, the same way
--min-rounds holds out for a new round.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Answering the previously missed finding "Allow override to reevaluate current-head refusals" (scripts/pr_review.py:4105): fixed in 3bc4a84. With --ignore-quota-signal, a head the body-less liveness read reports as done gets a full read, and where its only round is a refusal, the round baseline moves past that refusal the way --min-rounds does. A request then goes out, and the wait holds for a genuinely new round. A test covers it and fails with the re-read removed.
…ted Local Pass (#2278)
## Summary
This is the defined-moments half of #2261, per the maintainer's answers
recorded on that issue. A Copilot round is requested when a pull request
opens and on the head of a pull request into the default branch, a
promotion among them, rather than on every push. On a pull request into
any other branch, a fix push after the first round is covered by the
recorded local strict-review pass the push already owes. The PR
publishes that pass so the review gate can read it.
- **Ruleset.** `repo-config/develop.json` and `main.json` set
`review_on_push` and `review_draft_pull_requests` to false and keep
review on open. Applying the change to live repositories is a separate
config run, which needs its own go-ahead. Narrowing the account-level
setting is a UI step for the maintainer.
- **`pr_review.py attest`.** It publishes the local pass as a comment
carrying `<!-- fleet-local-review: head=<sha> findings=<n> -->`, after
confirming four things:
- the checkout is at the pushed head
- the checkout holds no other change
- its merge base is the pull request's own
- `local_review.py check` passes against the base
The comment carries the findings count the pass recorded. Per the
maintainer's answer, the count is shown and not gated, since local
findings are advisory. `local_review.py status` now reports the
per-reviewer `findings` map that this reads.
- **`status`.** An attested head on a pull request into a non-default
branch, after Copilot's first round, reads as `review_on_head=local` and
`coverage=local`. That holds only for an owner, member, or collaborator
comment whose marker stands as a line of its own outside a fence, and
only where the whole review history is in view and no round on record
states or appears to state partial coverage.
- **`wait`.** On such a head `wait` requests nothing. An attested head
ends as covered, and one with no attestation exits `49`
(`AWAITING_LOCAL_PASS`). `--request` asks for a round anyway. A
promotion, a first round, a partial on record, and a history past the
window are all requested as before.
- **A post-merge finding on #2277, fixed here.** A newer quota or error
refusal now outranks older genuine coverage of the same head, in the
digest's `refusal=` field and in `wait`'s verdict, since it is the
newest word on the pull request.
- **CodeRabbit.** A drive prompts it at most once per pull request, on
the head it judges final, and never after a rate-limit notice.
- **Docs.** The rule is stated in `GOVERNANCE.md` "PR Review Etiquette",
`pr-review-conduct` (loop step 3, step 8, Merge Gate item 2, and the
reviewer bullets), the Copilot runbook, `scripts/README.md`,
`repo-config/README.md`, `docs/pr-reviewer-reference.md`, and the
one-liners in `README.md`, `RESYNC.md`, and `AUDIT.md`.
## Verification
- `tests.test_pr_review` and `tests.test_local_review` pass (658 tests).
Each new behavior was shown to fail with it reverted or mutated,
including the stale-refusal, partial, old-answer, and marker-shape
cases.
- A live GraphQL read confirmed that `baseRepository.defaultBranchRef`
and `IssueComment.authorAssociation` exist.
- Two local strict-review passes ran. Round 1 raised 16 findings: 15 are
fixed, and #5 went to the maintainer, who chose to show the count
without gating on it. Round 2 raised 3 low findings, all fixed.
Closes#2261
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…eview (#2284)
## Summary
Promotes develop to main with the pull requests below. Each was already
reviewed and merged into develop.
- [#2271](#2271): Correct
the false no-vocabulary claims about environment secrets.
- [#2276](#2276): A full
Copilot file table on an earlier round carries forward to a later head
when the pull request changes the same set of files at both commits, the
same bound a coverage statement uses.
- [#2275](#2275):
`install-tools.sh` no longer exits 1 silently when the tools named leave
out the last managed tool, and its report notes show a home path as `~`.
- [#2277](#2277): A
Copilot round that says only "encountered an error" is read as a
possible quota hit. `pr_review.py` reads the reviewer's own Actions run
log, which states the rate limit and the time it resets, and `wait` no
longer requests a review into either case.
- [#2278](#2278): A
Copilot round is requested when a pull request opens and on the head of
a pull request into the default branch, rather than on every push.
Covering a fix push into develop:
- A recorded local strict-review pass covers the push, published with
`pr_review.py attest` and read by `status` as `review_on_head=local`.
- The Copilot rule in `repo-config/develop.json` and `main.json` now
reviews on open only, not on push or for drafts.
Applying that ruleset change to the live fleet repositories is a
separate config run after this merges, and it needs the maintainer's
go-ahead. Until it runs, GitHub still reviews every push, including
pushes to this pull request.
Closes#2256Closes#2260Closes#2261Closes#2268Closes#2272
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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
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.
Summary
The quota-safety half of #2261, per the maintainer's answers recorded on that issue: a generic error round is a possible quota hit after one occurrence, and the tooling never requests into it.
pr_review.pynow finds the reviewer's own failed Actions run on that commit (dynamic/agents/copilot-pull-request-reviewer) and reads its job log. A loggederrorType: 'rate_limit'reports asrefusal=QUOTAwith the reset time the log states. Anything else, an unreadable log included, reports asrefusal=ERROR, a possible quota hit.waitstops requesting. No request goes out while the pull request's newest Copilot review is a quota or error refusal, on this head or an earlier one, andwaitexits46. A request already pending is still polled for. Where nothing covers the head, the digest'srefusal=field reads that refusal from the earlier head.waitused to send its auto-request before it consulted the repository-wide quota signal, so an exhausted account still spent a request. It now holds the request back under that signal too.--ignore-quota-signaloverrides both stops.The defined-moments half of #2261 (the ruleset triggers, the local-pass attestation, and the Merge Gate change) follows in a separate pull request, since it rewrites this same
waitregion.Verification
python3 -m unittest tests.test_pr_review: 507 tests pass. The liveness payload in the stop tests is body-less, as the realQ_LIVEis. Each new behavior was shown to fail with the change reverted or mutated.run_causeagainst the real error round on Promote develop to main: Fork Handoff Chains, Qodo Login, JSON Report #2254 returnsrate_limitwith "reset on October 5, 2026 at 12:00 AM".#comment at the request site.Refs #2261
🤖 Generated with Claude Code