Skip to content

feat: implement issue #1469 — [Phase 4] Detect merge-ready PRs stranded with no agent acting and no signal - #1516

Open
don-petry wants to merge 3 commits into
mainfrom
dev-lead/issue-1469-20260814-2300
Open

feat: implement issue #1469 — [Phase 4] Detect merge-ready PRs stranded with no agent acting and no signal#1516
don-petry wants to merge 3 commits into
mainfrom
dev-lead/issue-1469-20260814-2300

Conversation

@don-petry

@don-petry don-petry commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

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

  • Daily health checks scan open PRs for approved, mergeable, green PRs that have been idle for over 12 hours.
  • Reports identify each stranded PR with its link, title, idle duration, and reason, and create a dated health-check issue when candidates are found.
  • Human-gated PRs and PRs blocked by untrusted-bot review threads or pending checks are excluded and classified separately.
  • Detection is read-only: it does not comment on, label, merge, or otherwise modify PRs.
  • Added coverage for thresholds, exclusions, classification, malformed data, reports, and empty results.

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:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

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:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

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.

@don-petry
don-petry requested a review from a team as a code owner August 14, 2026 23:18
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@codeant-ai

codeant-ai Bot commented Aug 14, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 7452a3a Aug 14, 2026 · 23:18 23:21

@codeant-ai

codeant-ai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@don-petry, you've reached your PR review limit, so we couldn't start this review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4076d302-1f08-4bf7-bef6-5141902c5763

📥 Commits

Reviewing files that changed from the base of the PR and between f0764b0 and 08ab953.

📒 Files selected for processing (5)
  • .github/workflows/daily-pr-review-health.yml
  • .github/workflows/lint.yml
  • scripts/lib/pr-mergeready-detect.sh
  • scripts/pr_mergeready_scan.sh
  • tests/test_pr_mergeready_detect.bats

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Aug 14, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry
don-petry enabled auto-merge (squash) August 14, 2026 23:19

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread scripts/lib/pr-mergeready-detect.sh Outdated
Comment thread scripts/pr_mergeready_scan.sh Outdated
@don-petry
don-petry disabled auto-merge August 14, 2026 23:20
Comment thread scripts/pr_mergeready_scan.sh Outdated
Comment thread scripts/pr_mergeready_scan.sh Outdated
Comment thread scripts/pr_mergeready_scan.sh Outdated
Comment on lines +267 to +269
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Suggested change
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

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) August 14, 2026 23:22
@don-petry
don-petry disabled auto-merge August 14, 2026 23:23
@donpetry-bot

Copy link
Copy Markdown
Contributor

CI checks on this PR are still running. Once they complete, re-mention @donpetry-bot to trigger a fresh review.

Posted by the donpetry-bot PR-review cascade.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) August 14, 2026 23:27
@don-petry
don-petry disabled auto-merge August 14, 2026 23:28
@sonarqubecloud

Copy link
Copy Markdown

@donpetry-bot

Copy link
Copy Markdown
Contributor

CI checks on this PR are still running. Once they complete, re-mention @donpetry-bot to trigger a fresh review.

Posted by the donpetry-bot PR-review cascade.

@don-petry
don-petry enabled auto-merge (squash) August 14, 2026 23:30
@donpetry-bot

Copy link
Copy Markdown
Contributor

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 donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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's DON_PETRY_BOT_GH_PAT usage 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 4] Detect merge-ready PRs stranded with no agent acting and no signal

2 participants