Repository navigation
Hold pr_review.py merge on a Running Hosted Review and Route Declined Qodo Findings to a Dismiss Request - #3809
Conversation
…smiss Request `wait` now holds an attested head while a CodeRabbit or Qodo check on it is still settling, whatever the merge state reads, and `merge` refuses it as CHECKS_PENDING. A reviewer whose newest output is its rate limit holds nothing. A gate refusal in `merge` prints `pending=` with each check still running, so a pull request handed to the maintainer names what is not done. Qodo's remedy text and the drive-pr and pr-review-conduct skills now say that only Qodo's badge closes its finding. A disproved one is answered with a comment mentioning Qodo that asks it to dismiss the finding by number, with the reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tie the rate-limit clear to a limit posted since the check began, so an older limit a reviewer has moved past no longer releases its running review. Print `pending=` on every in-scope refusal routed to redrive or the maintainer, read through `checks_settling` rather than a near copy. Derive the hosted reviewers from `OTHER_REVIEWERS`, name Qodo's login in the dismiss remedy, and stop calling a threaded Qodo finding unthreaded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CodeRabbit rewrites its one summary comment in place, so a limit edited into it after a push kept the comment's first creation time and held the new head's pending status as a running review. The held read now carries each comment's updatedAt, and the rate-limit clear compares that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
`limited_since` took the newest edit across every reviewer comment, so a summary comment CodeRabbit edits as a review starts could date an older rate-limit reply and clear the running review's hold. It now picks the newest output as `rate_limited_by` does and compares that node's own edit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
There was a problem hiding this comment.
🟡 Changes recommended
Two critical issues can allow merges to proceed while the selected rate-limit review or hosted checks are still incomplete, so the gating logic must be corrected.
2 open issues
What changed in this PR
This PR strengthens Merge Gate handling for active CodeRabbit and Qodo reviews, adds pending-check diagnostics, and documents the Qodo dismissal-request workflow across skill distributions.
Changes:
- Tracks check posters and holds merges while hosted reviews remain unfinished.
- Reports pending checks during merge refusals.
- Updates Qodo finding remedies and synchronized skill guidance.
- Adds regression coverage for hosted reviews, rate limits, pending checks, and merge routing.
This pull request requires changes.
Review findings:
scripts/pr_review_checks.py: [P1, critical, 4 votes] compare the selected rate-limit node’s timestamp; [P1, critical, 1 vote] hold every unfinished hosted check; [P2, moderate, 1 vote] evaluate hosted-review holds before theBLOCKEDshort circuit.scripts/pr_merge.py: [P1, moderate, 1 vote] handleGraphQLErrorduring the pending read; [P2, moderate, 1 vote] treat truncated check rollups as unread.
| File | Description |
|---|---|
tests/test_pr_review.py |
Tests hosted-review detection, rate-limit handling, pending checks, and Qodo remedies. |
tests/test_pr_merge.py |
Tests merge holds, pending diagnostics, and refusal routing. |
scripts/pr_review.py |
Integrates hosted-review data into queries, wait handling, and reporting. |
scripts/pr_review_checks.py |
Normalizes check posters and detects hosted reviews still settling. |
scripts/pr_review_answers.py |
Adds hosted-review gate findings and Qodo dismissal guidance. |
scripts/pr_merge.py |
Adds fresh pending-check reporting during merge refusal handling. |
.github/skills/pr-review-conduct/SKILL.md |
Documents hosted-review holds and Qodo dismissal requests. |
.github/skills/drive-pr/SKILL.md |
Routes hosted-review holds and Qodo findings through the driving workflow. |
.claude-plugin/fleet-skills/skills/pr-review-conduct/SKILL.md |
Generated Claude distribution of the review-conduct guidance. |
.claude-plugin/fleet-skills/skills/drive-pr/SKILL.md |
Generated Claude distribution of the drive guidance. |
.claude-plugin/fleet-skills/.source-digests/pr-review-conduct |
Updates the generated review-conduct source digest. |
.claude-plugin/fleet-skills/.source-digests/drive-pr |
Updates the generated drive source digest. |
.agents/skills/pr-review-conduct/SKILL.md |
Updates the canonical review-conduct skill. |
.agents/skills/drive-pr/SKILL.md |
Updates the canonical drive skill. |
Review effort: Lite
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #3809 +/- ##
===========================================
+ Coverage 82.72% 82.83% +0.10%
===========================================
Files 29 29
Lines 9629 9686 +57
===========================================
+ Hits 7966 8023 +57
Misses 1663 1663
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A CodeRabbit or Qodo check left queued past the pickup grace, waiting on its environment, or a stale record has still posted no review, yet the hold read only the settling shapes and released it. The hold now reads every shape short of a pass or a failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
…rge on a Running Hosted Review, and Gate Skill Description Length (#3843) Promotes the changes merged into `develop` since promotion #3797 to `main`, the end of an away-mode backlog burndown. - [#3803](#3803) exempts the Roslyn embedded-language marker (`// lang=json`, `language=`) from the prose gate's comment rules as a tool directive. - [#3807](#3807) has `local_review.py record` take `--report`, the file the reviewer wrote, bind the pass to its sha256, and derive the finding count from it. `status` gains `reportPath`. - [#3809](#3809) holds `pr_review.py merge` while a hosted review is still running on the head, and routes a declined Qodo finding to a dismiss request. - [#3811](#3811) dates an anchored `intentRef` by the section its anchor names, and lets a `driftNote` acknowledge a verified intent advisory. - [#3816](#3816) moves the null GraphQL node check into the shared `gh_graphql` transport as `NullNodeError`. - [#3818](#3818) explains the workspace-edit default in `GOVERNANCE.md` and names the aggregator's expression form. - [#3822](#3822) moves the abandon discard to the `backlog-burndown` orchestrator, aligns the abandoned-branch delete, and holds a grown agent-safety set. - [#3823](#3823) scopes the Husky prose gate to staged paths and adds `--skip-generated` so a named file inside a generated tree is skipped. - [#3828](#3828) reads Copilot's `Open findings:` label, drops the duplicate `null_node`, and matches `scripts/README.md` to the Merge Gate. - [#3829](#3829) bumps the two stale hub caller snippet pins and documents the fallback's mixed-pair refusal. - [#3831](#3831) keeps an inherited `GIT_DIR` from rerooting the prose gate's subdirectory git reads. - [#3832](#3832) gives `backlog-burndown` a disposition for a worker's standalone clone and keeps the agent-safety hold past a park. - [#3835](#3835) makes `carry.py check-sections` refuse what `apply-sections` would, and name an open fence. - [#3836](#3836) pins the reusable-workflow stubs by placeholder and ticks the PlexCleaner gates item. - [#3838](#3838) has the `runtime-secrets` audit dimension detect a bare `secrets/` directory from the tracked files that name it. - [#3839](#3839) gates skill descriptions at the 1024-character limit and trims every one over it. - [#3846](#3846) fixes an adjacent doc, an in-file pre-existing defect, and an edge case on new code in the open pull request instead of filing an issue for each, and keeps filing for code that runs elsewhere. - [#3847](#3847) refuses skill frontmatter that parses to a list or a scalar, so the description length gate cannot be bypassed. Fixes #3770 Fixes #3699 Fixes #3705 Fixes #3789 Fixes #1819 Fixes #727 Fixes #3710 Fixes #3706 Fixes #3623 Fixes #3687 Fixes #3617 Fixes #3757 Fixes #3790 Fixes #3786 Fixes #3785 Fixes #3772 Fixes #1657 Fixes #3443 Fixes #3824 Fixes #3817 Fixes #3805 Fixes #1666 Fixes #3700 Fixes #3821 Fixes #3771 Fixes #3794 Fixes #3825 Fixes #3690 Fixes #1472 Fixes #3813 Fixes #3719 Fixes #1592 Fixes #3845 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Summary
Two Merge Gate gaps
pr_review.py mergehit on PlexCleaner pull requests.A hosted review still running holds the merge (#3789).
mergesquash-merged a feature pull request while CodeRabbit was still reviewing its head. That happened because anUNSTABLEmerge state let an unrequired check stop holding the wait.check_nodesnow records who posted each check. That is a StatusContext'screatorlogin, newly read by the query, or a CheckRun's app slug.hosted_reviews_runningnames each CodeRabbit or Qodo check on the head still settling. It matches by the poster or by a context named for the reviewer. The reviewers come fromOTHER_REVIEWERS. It skips a reviewer whose newest output is a rate limit posted or edited since the check began, so that state still clears. An older limit the reviewer has moved past does not. The held read now carries each comment'supdatedAtfor that.waitholds an attested head on such a check whatever the merge state reads. ItsCHECKS_PENDINGline then adds(reviewing: <name>).merge's fresh read refuses it asCHECKS_PENDING, which routesredrive. That covers a headwaitdoes not poll and a review that starts after the gate read.mergerun inside the write scope that merged nothing and routes toredriveor the maintainer now printspending=beforenext=. It names each check on the head that has neither passed nor failed, from a fresh read. So a pull request handed to the maintainer names what still runs.Qodo findings are answered with a dismiss request (#2252). Per the maintainer's answer on #2252,
qodo_openkeeps reading Qodo's own badge.--ackcomment's body mentions@<Qodo's login>and asks it to dismiss that finding by its number, with the reason. The number comes from the findings comment.pr-review-conductMerge Gate item 3 anddrive-prstep 4 say the same thing.drive-prroutes anUNTHREADED_FINDINGSline namingqodo_opento that answer rather than to a blocked merge.pr-review-conductitem 2 states the hosted-review hold.The live check #2252 asks for is not part of this change. It confirms on a PlexCleaner pull request that a dismiss request adds the badge, which wording Qodo accepts, and which number it wants. So #2252 stays open.
scripts/README.mdis held by another group in this round, so itspr_merge.py,wait, and findings paragraphs are not updated here. #3805 tracks that.Line counts stay under every ceiling:
pr_review.py2171 of 2200,pr_review_answers.py402 of 450,pr_review_checks.py435 of 450,pr_merge.py246 of 250.Local-review finding outcomes
introduced, listed on the opening push:limited_sincedated a rate limit by the newest edit across every reviewer comment, so a summary comment edited as a review starts could clear the hold. Fixed in f38355e, which compares the edit time of the noderate_limited_byreads, with a test for that case.[P1] Hold every unfinished hosted check: fixed in 7eb8ee6 and 75b4dd1. The hold now reads every shape short of a pass or a failure, so a hosted check queued past the pickup grace, waiting, or a stale record still holds. Its thread was already resolved when the fix landed.Verification
tests/test_pr_review.py(550),tests/test_pr_merge.py(70),tests/test_pr_review_copilot.py,tests/test_pr_review_size.py,tests/test_pr_cleanup.py, andtests/test_build_dist.pypass.CLEAN,UNSTABLE, andHAS_HOOKS, andmerge'sCHECKS_PENDINGrefusal. Thepending=line, its unread form, and its absence on an out-of-scope refusal are covered, and so is the Qodo dismiss remedy.repo_gate.py --check eol, andbuild_dist.py --checkare clean.Closes on promotion: #3789
🤖 Generated with Claude Code