Skip to content

feat: implement issue #1408 — [Phase 4] Narrow pr-review-sweep's cron scope to genuinely un-eventable cases and surface a sweep-hit-rate metric in daily health - #1504

Merged
don-petry merged 4 commits into
mainfrom
dev-lead/issue-1408-20260812-1807
Aug 12, 2026
Merged

feat: implement issue #1408 — [Phase 4] Narrow pr-review-sweep's cron scope to genuinely un-eventable cases and surface a sweep-hit-rate metric in daily health#1504
don-petry merged 4 commits into
mainfrom
dev-lead/issue-1408-20260812-1807

Conversation

@don-petry

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

Copy link
Copy Markdown
Collaborator

User description

Closes #1408

Implemented by dev-lead agent. Please review.


CodeAnt-AI Description

Limit scheduled PR review sweeps to checks without an event trigger and track sweep activity

What Changed

  • Scheduled sweeps now re-review only green PRs with un-eventable checks, such as SonarCloud or other checks without a workflow event; eventable-only PRs are left to the fast path
  • Daily health reports now show scheduled sweep ticks, reviews dispatched, and the resulting hit rate, with guidance for detecting eventable cases reaching the timer
  • Added coverage for eventability classification, scheduled-sweep selection, unchanged fast-path behavior, and hit-rate reporting

Impact

✅ Fewer redundant PR reviews
✅ Faster event-driven reviews
✅ Clearer sweep exception monitoring

💡 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.

Summary by CodeRabbit

  • New Features

    • Added sweep health metrics, including hit rates, dispatched-review counts, coverage details, and partial-measurement warnings.
    • Scheduled sweeps now focus retries on checks that cannot be handled through completion events.
  • Bug Fixes

    • Improved classification of eventable and non-eventable checks while preserving existing CI status handling.
  • Documentation

    • Clarified when scheduled sweeps apply versus event-driven processing.
  • Tests

    • Added coverage for sweep metrics, eventability classification, scheduled filtering, and regression scenarios.

… scope to genuinely un-eventable cases and surface a sweep-hit-rate metric in daily health
@don-petry
don-petry requested a review from a team as a code owner August 12, 2026 18:27
@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 12, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR b0c8736 Aug 12, 2026 · 18:27 18:30

@codeant-ai

codeant-ai Bot commented Aug 12, 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 12, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 48 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: 000943d9-11ac-4ea1-9ddd-11326b75a05d

📥 Commits

Reviewing files that changed from the base of the PR and between ede64ff and 3ce1579.

📒 Files selected for processing (3)
  • interaction-contracts/pr-review.yml
  • scripts/lib/ci-status.sh
  • tests/test_ci_status.bats
📝 Walkthrough

Walkthrough

The PR classifies CI checks by workflow eventability, limits scheduled sweeps to uneventable or mixed checks, and adds scheduled sweep hit-rate telemetry to daily health reporting. It also updates the interaction contract and extends Bats coverage.

Changes

Sweep eventability and telemetry

Layer / File(s) Summary
Eventability classification
scripts/lib/ci-status.sh, tests/test_ci_status.bats
Shared jq logic filters own checks. classify_rollup_eventability returns none, eventable-only, or has-uneventable.
Scheduled sweep selection
scripts/sweep-stuck-reviews.sh, interaction-contracts/pr-review.yml, tests/test_sweep_stuck_reviews.bats
Scheduled sweeps skip eventable-only checks and dispatch uneventable or mixed candidates. Other invocation paths retain their existing behavior.
Sweep health telemetry
scripts/lib/pr-review-sweep-metrics.sh, scripts/pr_review_health.sh, tests/pr_review_sweep_metrics.bats, .github/workflows/lint.yml
The health script collects capped scheduled-run logs, calculates hit rates, renders coverage warnings, and runs the new metrics tests in lint.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler
  participant sweep_stuck_reviews.sh
  participant classify_rollup_eventability
  participant ReviewDispatch
  Scheduler->>sweep_stuck_reviews.sh: Start scheduled sweep
  sweep_stuck_reviews.sh->>classify_rollup_eventability: Classify pull request checks
  classify_rollup_eventability-->>sweep_stuck_reviews.sh: Return eventability result
  sweep_stuck_reviews.sh->>ReviewDispatch: Dispatch uneventable or mixed candidate
Loading
sequenceDiagram
  participant pr_review_health.sh
  participant GitHubAPI
  participant pr_review_sweep_metrics.sh
  participant DailyHealthReport
  pr_review_health.sh->>GitHubAPI: Fetch scheduled runs and logs
  GitHubAPI-->>pr_review_health.sh: Return run data and log text
  pr_review_health.sh->>pr_review_sweep_metrics.sh: Calculate hit rate
  pr_review_sweep_metrics.sh-->>pr_review_health.sh: Return metrics and coverage
  pr_review_health.sh->>DailyHealthReport: Write sweep metrics
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the issue, narrowed cron scope, un-eventable cases, and sweep-hit-rate metric.
Description check ✅ Passed The description provides a clear summary, implementation details, impact, and test coverage, but omits the template checklist confirmations.
Linked Issues check ✅ Passed The changes implement the linked issue objectives for eventability filtering, fast-path preservation, sweep metrics, contract updates, and test coverage.
Out of Scope Changes check ✅ Passed The changed workflows, scripts, contract, and tests directly support the linked issue objectives without unrelated code changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-lead/issue-1408-20260812-1807

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 12, 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 12, 2026 18:28
@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-12T19:29:43Z.

Comment thread scripts/pr_review_health.sh
Comment thread scripts/pr_review_health.sh Outdated
Comment thread scripts/sweep-stuck-reviews.sh Outdated
Comment thread scripts/lib/ci-status.sh Outdated
@don-petry
don-petry disabled auto-merge August 12, 2026 18:30

@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 narrows the scheduled pr-review-sweep cron path to target only un-eventable checks (such as SonarCloud) that do not emit workflow_run events, leaving eventable GitHub Actions checks to the fast path. It also introduces a deterministic sweep-hit-rate metric to the daily health report and adds corresponding unit tests. The review feedback focuses on improving shell script robustness and performance, suggesting guards for grep pipelines under set -e, optimizing loop-based jq invocations using positional arguments, defensively handling missing JSON properties with optional chaining, and refining test assertions to check for specific exit codes.

Comment thread scripts/lib/pr-review-sweep-metrics.sh Outdated
Comment thread scripts/pr_review_health.sh Outdated
Comment thread scripts/pr_review_health.sh Outdated
Comment thread scripts/sweep-stuck-reviews.sh Outdated
Comment thread tests/test_sweep_stuck_reviews.bats Outdated
@donpetry-bot

donpetry-bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at b0c8736edfdbe0b93257e0ff979568f11924f0e3 — click to expand prior review.

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: b0c8736edfdbe0b93257e0ff979568f11924f0e3
Review mode: triage-approved (single reviewer)

Summary

Narrows the pr-review-sweep cron to un-eventable checks and adds a sweep-hit-rate metric (#1408). Implementation is well-tested and CI is fully green, but one unresolved reviewer finding is validated as a real coverage gap: the eventability classifier treats ANY check with a workflowName as fast-path-covered, while the workflow_run fast path only listens to 5 named workflows — so a PR whose last-completing check comes from an unlisted Actions workflow (e.g. CodeQL) would be skipped by the narrowed cron and stranded, breaking the guaranteed ≤15-min backstop.

Linked issue analysis

Closes #1408. ACs 2–5 are substantively met: sweep-hit-rate computed in pr_review_health.sh via pure, unit-tested helpers (tests/pr_review_sweep_metrics.bats), interpretation note rendered deterministically before model content, no new cron, contract timers[] updated (validate-interaction-contracts green). AC #1 is where the gap lies: 'genuinely un-eventable' is implemented as 'no workflowName', which is BROADER fast-path coverage than reality — pr-review-sweep.yml's workflow_run trigger is scoped to [CI, Tests, Holdout Guard, SonarCloud Analysis, Lint], and check_suite:completed does not fire for Actions-created suites. Checks from unlisted Actions workflows (CodeQL et al. are present on this repo's PRs) are therefore just as un-eventable as SonarCloud, but the cron now skips them.

Findings

Blocking (validated from CodeAnt thread on scripts/lib/ci-status.sh:122):

  1. classify_rollup_eventability marks every check with a non-empty workflowName as eventable, but the fast path only fires for the 5 workflows listed in pr-review-sweep.yml. A stuck-green PR whose last-completing blocking check belongs to an unlisted Actions workflow (e.g. CodeQL 'Analyze (…)', Agent Security Scan) emits no workflow_run the sweep listens to and no check_suite event (Actions suites are excluded) — the narrowed cron classifies it eventable-only and never re-dispatches. This silently makes the fast-path workflow list load-bearing, contradicting pr-review-sweep.yml's own header ('this list is best-effort, not load-bearing') and the updated contract claim that the fast path 'fully covers every eventable GitHub Actions check'. Fix: restrict eventability to workflowNames actually in the fast-path trigger list (kept in one place), or classify unlisted workflow names as un-eventable residue.

Non-blocking notes (remaining unresolved CodeAnt threads assessed):
2. pr_review_health.sh SWEEP_MAX_LOG_FETCH truncation only warns in the job log, not the report; with ~96 ticks/day vs a 200 cap it will not trigger at LOOKBACK_DAYS=1 — acceptable, but consider surfacing truncation in the report for larger windows.
3. Failed 'gh run view --log' counts a tick as a measured 0-hit, biasing the hit-rate LOW — the direction that could mask a leak signal. Documented as best-effort and consistent with existing patterns; acceptable, worth a follow-up.
4. The rate-limited-retry path dispatches before the narrowing on cron ticks — this is correct behavior (quota reset is time-based, no event fires), not a bug; at most it slightly inflates the hit-rate metric semantics.

Process: dev-lead replied 'no-changes' to the review comments without rationale addressing them; all 4 threads remain unresolved.

Secret scan: run_secret_scanning MCP tool unavailable in this environment; gitleaks CI check is SUCCESS, diff adds no credential-like content.

CI status

All checks green at b0c8736: shellcheck, bats, unit-tests, actionlint, CodeQL, SonarCloud quality gate, gitleaks, validate-interaction-contracts, template-drift, caller-stub-freeze all SUCCESS. CANCELLED entries are superseded dev-lead orchestration runs (non-blocking per #608).


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

donpetry-bot
donpetry-bot previously approved these changes Aug 12, 2026

@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: b0c8736edfdbe0b93257e0ff979568f11924f0e3
Cascade: triage → deep (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5)

Summary

Feature PR (#1408) narrows the pr-review-sweep cron to genuinely un-eventable checks (SonarCloud-style, no workflowName) and adds a deterministic sweep-hit-rate metric to the daily health report, with new pure helpers and thorough bats coverage. The triage's central HIGH signal — an unguarded grep pipeline in pr-review-sweep-metrics.sh crashing pr_review_health.sh under set -euo pipefail — is a verified FALSE POSITIVE: the function's last command is always a successful printf, and set -e is ignored inside a function invoked via command-substitution assignment (the exact production call pattern), so it returns 0 and cannot abort the caller (reproduced on bash 5.2). No auth/secrets/crypto/migrations/CI-scanner/Actions-security surface is touched; CodeQL, SonarCloud, gitleaks, shellcheck, bats and unit-tests are all green. Downstream: 5 consumers pin pr-review.yml (informational; this PR does not alter that workflow's interface).

Downstream impact

This change is consumed by 5 downstream repo(s) that pin the affected reusable workflow / lib / prompt. Impacted consumers:

Impacted shared surfaces:
  - .github/workflows/pr-review.yml

Impacted consumers (5, fetching up to 10):
  - petry-projects/.github-private (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review-canary.yml
      .github/workflows/pr-review-trigger.yml
      .github/workflows/test-dev-lead.yml
  - petry-projects/ContentTwin (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/bmad-bgreat-suite (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/google-app-scripts (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/markets (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml

Findings

  • INFO [correctness] (scripts/lib/pr-review-sweep-metrics.sh:63): Triage HIGH signal disproven. pr_review_sweep_dispatched_from_log ends in a successful printf, so its return status is always 0; and set -e is ignored for the function body when it is called as dispatched=$(...) (command-substitution assignment) at pr_review_health.sh:317. Empirically reproduced under set -euo pipefail on bash 5.2: no-match input yields '0' and the script reaches its end (exit 0). The bats test 'no summary line yields 0' also exercises this and passes in CI.
  • MINOR [maintainability] (scripts/lib/pr-review-sweep-metrics.sh:63): Non-blocking robustness nit (Gemini flagged 'high', but impact is low given the above): the grep pipeline is only crash-safe because it runs in a set-e-ignored command-substitution context and ends in printf. If the function were ever called as a bare statement or as the last element of a pipeline, a no-match grep (exit 1) could abort under pipefail. Appending '|| true' (or ': ${count:=0}') would make the safety explicit and future-proof. Optional.
  • INFO [correctness] (scripts/lib/ci-status.sh:73): ci-status.sh refactor extracts the shared is_own_check jq into _CI_STATUS_JQ_IS_OWN_CHECK and switches compute_ci_status to a double-quoted jq program with escaped $ jq-vars and " literals; new classify_rollup_eventability reuses the same def. No untrusted data is interpolated into the jq program (data is passed via <<< heredoc), so no jq/shell injection. Behavior preservation is corroborated by the existing test_ci_status.bats suite plus new eventability tests, all green in CI.
  • INFO [correctness] (scripts/pr_review_health.sh:300): pr_review_health.sh sweep telemetry loop uses only internal constants in the gh api URL (WORKFLOW_REPO, SWEEP_WORKFLOW_FILE) and numeric sweep_id from the runs API; --argjson d "${dispatched:-0}" is fed a digits-only value from the ^[0-9]+ grep, so argjson cannot receive malformed JSON. SWEEP_MAX_LOG_FETCH bounds per-run log I/O. No injection or unbounded-cost concern.
  • INFO [downstream-impact]: Downstream-impact block lists 5 consumers pinning .github/workflows/pr-review.yml (petry-projects/.github-private, ContentTwin, bmad-bgreat-suite, google-app-scripts, markets). This PR does NOT modify pr-review.yml or any consumed interface — it changes internal sweep/health scripts and the interaction-contract doc. Informational only; no interface break, so not an escalation trigger.
  • MINOR [maintainability] (scripts/sweep-stuck-reviews.sh:258): Remaining advisory nits are non-blocking and optional: defensive jq optional-chaining (.statusCheckRollup?, .workflow_runs[]?) at sweep-stuck-reviews.sh:258 / pr_review_health.sh:100, jq -n '$ARGS.positional' to avoid per-iteration jq spawns at pr_review_health.sh:116, and asserting exit status == 1 (not just non-zero) in the negative grep bats assertions. None affect correctness or security. Codex posted a usage-limit notice (not a finding); SonarCloud quality gate passed.
  • INFO [process]: MCP run_secret_scanning tool was not available in this environment (GitHub Secret Protection MCP not exposed); the gitleaks CI check passed and the diff introduces no secret-like material (pure shell logic, tests, docs).

Reviewed by the PR-review cascade (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5). Reply if you need a human review.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 12, 2026
@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 12, 2026 18:44
@don-petry
don-petry disabled auto-merge August 12, 2026 18:45
@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 12, 2026 18:50
@don-petry
don-petry disabled auto-merge August 12, 2026 18:51
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: review-changes)

PR: #1504
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-08-12T19:21:36Z

@don-petry

Copy link
Copy Markdown
Collaborator Author

Note

@don-petry I reviewed this PR and no code changes were needed, but it still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews), so I cannot mark it done yet. I'll re-check automatically.
Next attempt after: 2026-08-12T19:21:36Z

@don-petry
don-petry enabled auto-merge (squash) August 12, 2026 18:51
coderabbitai[bot]
coderabbitai Bot previously requested changes Aug 12, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@interaction-contracts/pr-review.yml`:
- Around line 17-24: Update the documentation comment describing uneventable
checks to define eventability by membership in pr-review-sweep.yml’s
workflow_run.workflows list. Document checks with unsupported workflowName
values as uneventable alongside checks with no workflowName, and align the
scheduled-sweep description with this classifier behavior.

In `@scripts/lib/ci-status.sh`:
- Around line 124-129: Update the CI status validation around is_uneventable and
the workflow configuration to add an automated allowlist drift check that
compares the classifier’s workflow-name list against the names configured for
workflow_run. Fail validation when either list differs, using the actual
configuration as the source rather than duplicating the same hardcoded names in
the test.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f51c591c-50b7-4374-9ae0-ac305c7f7247

📥 Commits

Reviewing files that changed from the base of the PR and between c4a597c and ede64ff.

📒 Files selected for processing (9)
  • .github/workflows/lint.yml
  • interaction-contracts/pr-review.yml
  • scripts/lib/ci-status.sh
  • scripts/lib/pr-review-sweep-metrics.sh
  • scripts/pr_review_health.sh
  • scripts/sweep-stuck-reviews.sh
  • tests/pr_review_sweep_metrics.bats
  • tests/test_ci_status.bats
  • tests/test_sweep_stuck_reviews.bats

Comment thread interaction-contracts/pr-review.yml Outdated
Comment thread scripts/lib/ci-status.sh Outdated
@don-petry
don-petry disabled auto-merge August 12, 2026 18:54
@donpetry-bot

donpetry-bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor
Superseded by automated re-review at 3ce15799fa94799e01108d88a9e35977824c0599 — click to expand prior review.

Review — fix requested (cycle 3/3)

The automated review identified the following issues. Please address each one:

Findings to fix

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: ede64ffe6a7d53f0a891e5b445e52a763998fdb7
Cascade: triage → deep (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5)

Summary

Shell refactor narrows the scheduled pr-review-sweep to skip 'eventable-only' green PRs on the premise that a workflow_run fast path already re-reviews them, plus a new deterministic sweep-hit-rate metric with good test coverage. CI is fully green (SonarCloud/CodeQL/gitleaks/ShellCheck/bats all pass) and the compute_ci_status refactor is behavior-preserving, but coderabbitai's CHANGES_REQUESTED is unresolved (merge BLOCKED) and — more importantly — the narrowing's stated 'workflow_run:[completed]' fast path does not exist in the cascade (the real re-trigger is check_suite:completed), so skipping eventable-only PRs risks reintroducing the exact stuck-green gap (#573) the sweep was built to close. This touches scripts consumed transitively by pr-review.yml, pinned by 5 downstream consumers (.github-private, ContentTwin, bmad-bgreat-suite, google-app-scripts, markets). Escalating for the author to resolve; own findings are sufficient (no security-audit tier needed).

Downstream impact

This change is consumed by 5 downstream repo(s) that pin the affected reusable workflow / lib / prompt. Impacted consumers:

Impacted shared surfaces:
  - .github/workflows/pr-review.yml

Impacted consumers (5, fetching up to 10):
  - petry-projects/.github-private (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review-canary.yml
      .github/workflows/pr-review-trigger.yml
      .github/workflows/test-dev-lead.yml
  - petry-projects/ContentTwin (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/bmad-bgreat-suite (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/google-app-scripts (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml
  - petry-projects/markets (pins .github/workflows/pr-review.yml)
      .github/workflows/pr-review.yml

Findings

  • MAJOR [correctness] (interaction-contracts/pr-review.yml:45): The narrowing rests on a fast path that does not exist. interaction-contracts/pr-review.yml and the code comments assert 'workflow_run:[completed]' fully covers every eventable GitHub Actions check, so the cron can safely skip eventable-only PRs. But there is NO workflow_run trigger anywhere in the pr-review cascade: pr-review-sweep.yml has only schedule + workflow_dispatch, and pr-review-trigger.yml re-triggers on check_suite:[completed] / pull_request / pull_request_review. The only workflow_run triggers in the repo are ci-failure-analyst.md ([CI,Lint,Tests]) and auto-rebase-retry.yml — neither dispatches a review. Because pr-review: PRs skipped as ci-pending are never re-reviewed after CI goes green #573 (the sweep's founding bug) documents that the event path is unreliable for the stuck-green case, unconditionally skipping eventable-only PRs on the scheduled sweep risks stranding them at REVIEW_REQUIRED — the very gap the sweep exists to close.
  • MINOR [maintainability] (scripts/lib/ci-status.sh:124): classify_rollup_eventability hardcodes the eventable workflow list ["CI","Tests","Holdout Guard","SonarCloud Analysis","Lint"] and the comment says it 'mirrors pr-review-sweep.yml's workflow_run.workflows:'. That referenced list does not exist (pr-review-sweep.yml has no workflow_run trigger), so the list mirrors nothing verifiable and cannot be kept in sync — silent misclassification risk if trigger topology changes. This matches coderabbitai's second actionable comment requesting an allowlist drift check driven by the real config rather than duplicated hardcoded names.
  • MINOR [process]: coderabbitai submitted CHANGES_REQUESTED at head ede64ff with 2 unresolved actionable comments (doc-comment eventability definition in interaction-contracts/pr-review.yml lines 17-24; allowlist drift check in ci-status.sh lines 124-129). reviewDecision=CHANGES_REQUESTED, mergeStateStatus=BLOCKED. Gate not satisfied.
  • INFO [downstream-impact] (scripts/lib/ci-status.sh:50): Changed shared surface (ci-status.sh / sweep-stuck-reviews.sh sourced by the pr-review reusable) is pinned by 5 consumers: petry-projects/.github-private, ContentTwin, bmad-bgreat-suite, google-app-scripts, markets. compute_ci_status was refactored (extracted shared is_own_check jq def, single→double-quote with correct $ escaping) but is behavior-preserving — identical defs/branches and 'passing' error default; existing bats + ShellCheck pass. Informational only.
  • INFO [secret]: run_secret_scanning MCP tool is not exposed in this environment; skipped per instructions (never block on MCP unavailability). Manual review of the diff found no secrets/credentials/tokens; gitleaks CI check passed.

Reviewed by the PR-review cascade (triage: haiku 4.5 → deep: opus 4.8 + duck: o4-mini → audit: fable 5). Reply if you need a human review.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 12, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@donpetry-bot
donpetry-bot dismissed coderabbitai[bot]’s stale review August 12, 2026 19:02

Auto-dismissed (#617): coderabbitai[bot] CHANGES_REQUESTED on a superseded commit. The bot re-reviews the new head automatically — a valid concern will return as a fresh review.

@don-petry
don-petry disabled auto-merge August 12, 2026 19:03
@sonarqubecloud

Copy link
Copy Markdown

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: fix-reviews)

PR: #1504
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-08-12T19:33:41Z

@don-petry
don-petry enabled auto-merge (squash) August 12, 2026 19:03
@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-12T20:05:26Z.

@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: 3ce15799fa94799e01108d88a9e35977824c0599
Review mode: triage-approved (single reviewer)

Summary

Re-review at 3ce1579 confirms all prior findings are resolved. The prior MAJOR finding (claiming pr-review-sweep.yml has no workflow_run trigger) was factually incorrect: the file at head defines workflow_run with workflows [CI, Tests, Holdout Guard, SonarCloud Analysis, Lint], matching issue #1408's Dev Notes. The fix commit extracted the eventable allowlist into _CI_STATUS_EVENTABLE_WORKFLOWS, added a bats drift-guard test that parses the real trigger list from pr-review-sweep.yml, and tightened the interaction-contract docs to define eventability by allowlist membership. coderabbitai has APPROVED at head and all review threads are resolved. CI is fully green.

Linked issue analysis

Closes #1408. All five acceptance criteria are substantively addressed: (1) scheduled sweep narrowed to un-eventable residue in sweep-stuck-reviews.sh with the workflow_run fast path explicitly unchanged (tested); (2) sweep-hit-rate computed in pr_review_health.sh via pure helpers in pr-review-sweep-metrics.sh; (3) interpretation note (low = exception-only, rising = eventable leak) rendered with the metric; (4) no new cron, idempotent, cron minutes untouched; (5) interaction contract timers[] updated and validate-interaction-contracts is green. The residual risk of a dropped workflow_run event stranding an eventable-only PR is the design tradeoff the issue explicitly requests, and the new hit-rate metric exists to detect exactly that leakage.

Findings

  • RESOLVED (prior MAJOR, correctness): the workflow_run fast path exists at head (pr-review-sweep.yml triggers on workflows [CI, Tests, Holdout Guard, SonarCloud Analysis, Lint]); docs now describe eventability as allowlist membership rather than mere presence of a workflowName.
  • RESOLVED (prior MINOR, maintainability): hardcoded list replaced with _CI_STATUS_EVENTABLE_WORKFLOWS plus a drift-guard bats test comparing it against the actual workflow_run.workflows line in pr-review-sweep.yml.
  • RESOLVED (prior MINOR, process): coderabbitai APPROVED at head 3ce1579; all 11 review threads resolved; no CHANGES_REQUESTED remains.
  • INFO (downstream): ci-status.sh / sweep-stuck-reviews.sh are shared surfaces pinned by 5 consumers; compute_ci_status refactor is behavior-preserving (identical defs, single-to-double-quote conversion with correct escaping) and existing bats + ShellCheck pass.
  • INFO (secret scan): run_secret_scanning MCP tool not exposed in this environment; gitleaks CI check passed and manual diff review found no secrets.

CI status

All checks green at head: shellcheck, bats (including the new drift-guard and narrowing tests), unit-tests, actionlint, CodeQL (actions+python), SonarCloud quality gate, gitleaks, agent-shield, validate-interaction-contracts, and all governance checks SUCCESS. Remaining CANCELLED entries are superseded dev-lead orchestration/review runs (non-blocking per issue #608); their latest runs are SUCCESS.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

@don-petry
don-petry merged commit 8c032d1 into main Aug 12, 2026
59 of 64 checks passed
@don-petry
don-petry deleted the dev-lead/issue-1408-20260812-1807 branch August 12, 2026 19:08
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] Narrow pr-review-sweep's cron scope to genuinely un-eventable cases and surface a sweep-hit-rate metric in daily health

2 participants