feat: implement issue #1469 — [Phase 4] Detect merge-ready PRs stranded with no agent acting and no signal - #1516
feat: implement issue #1469 — [Phase 4] Detect merge-ready PRs stranded with no agent acting and no signal#1516don-petry wants to merge 3 commits into
Conversation
…ed with no agent acting and no signal
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
Warning Review limit reached
Next review available in: 18 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
There was a problem hiding this comment.
Code Review
This pull request introduces a daily scan and detection system for merge-ready but idle pull requests, implementing detection logic in scripts/lib/pr-mergeready-detect.sh, a scanning script in scripts/pr_mergeready_scan.sh, and comprehensive unit tests in tests/test_pr_mergeready_detect.bats. The feedback recommends utilizing jq optional chaining to safely query nested JSON properties and prevent potential script crashes under set -e. Additionally, it suggests optimizing the timestamp comparison inside the scanning loop by using pure Bash string comparisons instead of spawning external jq processes.
| last_line=$(awk '{s+=length($0)+1; if(s>60000){print NR-1; exit}} END{if(s<=60000) print NR}' pr_mergeready_report.md) | ||
| head -n "${last_line:-0}" pr_mergeready_report.md > pr_mergeready_report.md.tmp | ||
| mv pr_mergeready_report.md.tmp pr_mergeready_report.md |
There was a problem hiding this comment.
Critical truncation bug: If the first line of the report exceeds 60,000 bytes, awk will print 0 (NR-1 where NR=1). Then head -n 0 produces an empty file, completely losing the report content before appending the truncation message.
Fix: Add a minimum line count guard:
last_line=$(awk '{s+=length($0)+1; if(s>60000){print NR-1; exit}} END{if(s<=60000) print NR}' pr_mergeready_report.md)
last_line=$((last_line > 0 ? last_line : 1))
head -n "${last_line}" pr_mergeready_report.md > pr_mergeready_report.md.tmp| last_line=$(awk '{s+=length($0)+1; if(s>60000){print NR-1; exit}} END{if(s<=60000) print NR}' pr_mergeready_report.md) | |
| head -n "${last_line:-0}" pr_mergeready_report.md > pr_mergeready_report.md.tmp | |
| mv pr_mergeready_report.md.tmp pr_mergeready_report.md | |
| last_line=$(awk '{s+=length($0)+1; if(s>60000){print NR-1; exit}} END{if(s<=60000) print NR}' pr_mergeready_report.md) | |
| last_line=$((last_line > 0 ? last_line : 1)) | |
| head -n "${last_line}" pr_mergeready_report.md > pr_mergeready_report.md.tmp | |
| mv pr_mergeready_report.md.tmp pr_mergeready_report.md | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
There was a problem hiding this comment.
Fixed in .github/workflows/daily-pr-review-health.yml — both the merge-ready report block (line ~269) and the stall report block (line ~201) which had the same pattern. Added last_line=$((last_line > 0 ? last_line : 1)) after the awk call so that when the first line alone exceeds 60 000 bytes (awk prints NR-1 = 0), we fall back to keeping at least 1 line rather than running head -n 0 and losing the entire report.
Dev-Lead — fix-reviews (applied)Changes committed and pushed. |
|
CI checks on this PR are still running. Once they complete, re-mention Posted by the donpetry-bot PR-review cascade. |
Dev-Lead — review-changes (applied)Changes committed and pushed. |
|
|
CI checks on this PR are still running. Once they complete, re-mention Posted by the donpetry-bot PR-review cascade. |
|
Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-08-15T00:31:01Z. |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: 08ab953c230b8edf30b6d28ed5625e60f59fc54d
Review mode: triage-approved (single reviewer)
Summary
Confirmation review of the triage-approved verdict for PR #1516, which adds the merge-ready-and-idle PR detection net (issue #1469, epic #1402): a new pure-function library (scripts/lib/pr-mergeready-detect.sh), a read-only daily scan (scripts/pr_mergeready_scan.sh), two new steps in the daily health-check workflow, and 30 bats tests. The triage assessment holds: the change is detection-only (no PR mutation), follows the established runaway/stall-net patterns in this repo, pins its new action by SHA, and reuses the existing DON_PETRY_BOT_GH_PAT pattern already present in the same workflow. Risk is MEDIUM (new workflow steps + non-trivial shell logic), which permits auto-approval with all gates green.
Linked issue analysis
Closes #1469. All four acceptance criteria are substantively addressed:
- AC#1 — flags open PRs with reviewDecision APPROVED + mergeable MERGEABLE + required checks green, idle past a configurable threshold (MERGEREADY_MIN_AGE_HOURS, default 12h, env-overridable; non-numeric overrides fall back to the default rather than 0).
- AC#2 — three-way classification distinguishes merge-ready-idle from #1425 (agent-blocked, via the untrusted-bot thread discriminator using the shared reviewer-sources trust registry) and #1427 (reviewer-defer, via ci_status pending). Human gates (needs-human-review via the canonical pr_has_escalation_label, plus dev-lead:hands-off / initiative:hold) are excluded.
- AC#3 — detection only: the scan never comments, labels, merges, or triggers anything on a PR; surfacing is via the existing health-check/automated-report issue channel, no new cron.
- AC#4 — bats tests cover the flagged case, the recently-active case, both adjacent-shape exclusions (no double-counting), threshold boundary (strict >), env overrides, gating, and malformed-input degradation.
Findings
No blocking findings.
- Prior advisory-bot thread (graphite-app, truncation bug) — verified fixed at this SHA. The unresolved thread flagged that a first line >60,000 bytes would make awk print 0 and head -n 0 would empty the report. The fix (
last_line=$((last_line > 0 ? last_line : 1))) is present in both the new merge-ready block and the pre-existing stall block in daily-pr-review-health.yml, with an author reply on the thread. The thread is not mechanically marked resolved, but the finding is substantively addressed in the reviewed commit. - Workflow security: new github-script step is SHA-pinned (v9.0.0); issue creation uses
github.token, not the PAT; report content is passed as an API body parameter (no template/code injection path); PR titles are sanitized (newlines/tabs/pipes stripped) before entering the report table. The scan step'sDON_PETRY_BOT_GH_PATusage mirrors the existing 'Run health check' step in the same workflow — no new secret exposure pattern. - Robustness: fail-quiet/fail-loud choices are deliberate and tested — API failures skip the PR and mark the scan incomplete (suppressing a false HAS_MERGEREADY=false all-clear), malformed labels degrade to not-gated so a real stranded PR still reports, and required-check filtering via compute_ci_status addresses the earlier CodeAnt suggestions (all marked resolved/outdated).
- MCP secret scan: the run_secret_scanning MCP tool is not available in this environment; relying on the passing gitleaks CI check. No secrets present in the diff.
- Minor (non-blocking): the prior donpetry-bot rate-limit withhold (reset 2026-08-15T00:31Z) has expired as of this review (01:45Z).
CI status
All checks green at 08ab953: shellcheck/ShellCheck, bats, unit-tests, actionlint, CodeQL (actions + python), SonarCloud quality gate, gitleaks secret scan, agent-shield, gh-aw-compile, pin-compliance, and all workflow-governance checks SUCCESS. Language-specific dependency audits SKIPPED (not applicable). The only non-success entry is 'review / review' = CANCELLED, which is this review cascade's own superseded run and not a code check.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.



User description
Closes #1469
Implemented by dev-lead agent. Please review.
CodeAnt-AI Description
Detect and report open PRs that are ready to merge but have gone unattended
What Changed
Impact
✅ Fewer merge-ready PRs left unnoticed✅ Clearer distinction between stranded, blocked, and deferred PRs✅ No automated changes to pull requests💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.