feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) - #1197
Conversation
…d / skip absent advisory bots (durable hardening)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 18 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. 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 Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe advisory review gate now uses configurable head-age and quiescence timeouts when advisory bots produce no output. It parses GraphQL committer timestamps, proceeds after the head-age timeout, and waits conservatively when head time is unavailable. Bats tests cover these outcomes. ChangesAdvisory gate timeout handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant check_advisory_reviews
participant get_advisory_bot_states
participant GitHubGraphQL
check_advisory_reviews->>get_advisory_bot_states: request advisory bot states
get_advisory_bot_states-->>check_advisory_reviews: no bot output
check_advisory_reviews->>GitHubGraphQL: read committer.date
GitHubGraphQL-->>check_advisory_reviews: head timestamp
check_advisory_reviews-->>check_advisory_reviews: wait or proceed based on head age
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 timeout-proceed windows to prevent pull requests from being permanently blocked when advisory bots are absent or fail to produce output. It defines timeout constants, implements a helper function _head_age_seconds to determine the age of the head commit, and integrates this check into the advisory review gate. Unit tests are also added to verify these timeout behaviors. Feedback on the changes suggests improving the portability of the date parsing in _head_age_seconds by adding a fallback for macOS/BSD systems.
Dev-Lead — fix-reviews (applied)Changes committed and pushed. |
Dev-Lead — waiting on PR blockers (intent: review-changes)PR: #1197 |
|
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. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/lib/advisory-review-gate.sh (1)
368-380: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winMissing BSD date fallback for
latest_sub_at.While the BSD
date -u -jffallback was successfully added for parsinghead_time(line 368), the same fallback was omitted forlatest_sub_at(line 379).On macOS environments (which use BSD
date),date -u -dwill fail to parse the timestamp, leavinglatest_sub_rawempty. This silently bypasses the conditional block at line 380, leavingtime_since_last_subas0and effectively disabling the quiescence timeout feature for local testing.Apply the same cross-platform date parsing to
latest_sub_rawto maintain consistency and ensure the quiescence timeout operates correctly across environments.🛠️ Proposed fix
- latest_sub_raw=$(date -u -d "$latest_sub_at" +%s 2>/dev/null) || latest_sub_raw="" + latest_sub_raw=$(date -u -d "$latest_sub_at" +%s 2>/dev/null) || latest_sub_raw=$(date -u -jf "%Y-%m-%dT%H:%M:%SZ" "$latest_sub_at" +%s 2>/dev/null) || latest_sub_raw=""🤖 Prompt for 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. In `@scripts/lib/advisory-review-gate.sh` around lines 368 - 380, Apply the same GNU-then-BSD date parsing fallback used for head_time to latest_sub_raw when parsing latest_sub_at, falling back to an empty value only if both date commands fail. Preserve the existing latest_sub_at conditional and quiescence timeout flow.
🤖 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.
Outside diff comments:
In `@scripts/lib/advisory-review-gate.sh`:
- Around line 368-380: Apply the same GNU-then-BSD date parsing fallback used
for head_time to latest_sub_raw when parsing latest_sub_at, falling back to an
empty value only if both date commands fail. Preserve the existing latest_sub_at
conditional and quiescence timeout flow.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 95cf89cb-6100-4eb5-9255-5f0e2c31b3e4
📒 Files selected for processing (2)
scripts/lib/advisory-review-gate.shtests/dev-lead/unit/test_advisory_review_gate.bats
Dev-Lead — fix-reviews (no-changes)Agent reasoning |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
|
Dev-Lead — fix-bot-comment (no-changes)Agent reasoning |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: a722f05660220d75e8279bb4026ed5a961d78fee
Review mode: triage-approved (single reviewer)
Summary
Adds a head-age timeout (1200s) to the zero-output branch of the advisory review gate so PRs on repos where advisory bots are not enabled/installed (or during a bot outage) no longer block forever. Magic numbers are extracted into named constants (ADVISORY_HEAD_AGE_TIMEOUT_SEC / ADVISORY_QUIESCENCE_TIMEOUT_SEC), a BSD date parsing fallback is added, and 5 new bats tests cover the recent / timed-out / head-time-unavailable scenarios. Confirms the triage assessment: well-scoped, correct, and fully tested.
Linked issue analysis
Closes #1193 (durable hardening split from #1181). The issue asks the gate to timeout-proceed / skip absent advisory bots instead of re-driving indefinitely. The PR implements exactly this: the previously unconditional wait in the zero-bot-output branch now applies the same head-age timeout the partial-submission path uses, treating absent bots as missing reviews past the window. Graceful degradation when head age is undeterminable (GraphQL unreachable) is handled conservatively — the gate waits and the scheduled sweep retries. Substantively addressed.
Findings
No blocking findings.
- Correctness verified: _head_age_seconds returns empty output on any failure (missing committer date, unparseable timestamp) and the caller guards with [[ -n ... ]] before comparing, so the conservative-wait path is sound. Negative ages from clock skew fall through to waiting.
- Test helpers _make_mock_gh_dir_recent and _make_mock_gh_dir_no_head_time exist in the test file; bats passed at this head SHA.
- Constants replace the previous magic numbers (1200/600) consistently in both the new and pre-existing timeout paths.
- Nit (non-blocking): the shellcheck disable=SC2034 annotations on the two new constants are unnecessary since both are referenced later in the same file — harmless.
- Secret scan: run_secret_scanning MCP tool not available in this environment; the gitleaks CI check passed and no credential-like content appears in the diff.
CI status
All quality checks green: shellcheck, ShellCheck, bats, unit, unit-tests, Lint, CodeQL, Analyze (actions/python), SonarCloud (quality gate passed), Secret scan (gitleaks), AgentShield, Agent Security Scan, validate-* and stub/permission guards. CodeRabbit approved. The two CANCELLED dev-lead jobs (dispatch, ci-relay) are the dev-lead orchestration workflow's own superseded runs — not code-quality checks. The in-progress review/review check is this review. Zero unresolved review threads.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: a722f05660220d75e8279bb4026ed5a961d78fee
Review mode: triage-approved (single reviewer)
Summary
Hardens the advisory review gate so PRs no longer block forever when NO advisory bot ever produces output (bot not vendor-enabled, uninstalled, or during an outage). The zero-output branch now applies the same 1200s head-age timeout as the partial-submission path, treating absent bots as missing reviews rather than a permanent block. The previously hardcoded 1200s/600s windows are extracted into named constants (ADVISORY_HEAD_AGE_TIMEOUT_SEC / ADVISORY_QUIESCENCE_TIMEOUT_SEC), head-age computation is factored into a _head_age_seconds helper with a BSD date fallback, and the gate stays conservative (keeps waiting) when the head commit time cannot be determined. 5 bats tests cover the recent-head wait, timeout-proceed, unavailable-head-time conservative wait, constant naming, and the empty-state branch consulting head age.
Linked issue analysis
Closes #1193 (split from #1181), which asks to make the advisory gate timeout-proceed / skip absent bots so a per-repo enablement gap or bot outage becomes a missing review, not a permanent block, including graceful degradation when a bot is uninstalled entirely. The PR implements exactly this in the shared gate library (scripts/lib/advisory-review-gate.sh) used by the review engine, aligned with the existing timeout windows from #457/#458, with the requested graceful-degradation coverage (zero-output timeout-proceed test) plus a conservative-wait path when timing data is unavailable. Substantively addressed.
Findings
This is a re-review after a prior single-reviewer approval at dedf87c was dismissed by new commits. Delta since then: merges of main plus one review-changes commit that addressed the two Copilot inline comments (corrected the _head_age_seconds doc comment to say it is used only by the zero-output branch; tightened the bats grep to a fixed-string match on the call site) — both threads resolved. Gemini's BSD date portability suggestion is incorporated (date -u -jf fallback in both parse sites). All 3 inline review threads are resolved; CodeRabbit APPROVED the current head. No security concerns: no secrets, no injection vectors (committer dates from the GitHub API are passed as arguments, and an unparseable date degrades to the conservative wait path). Secret-scanning MCP tool unavailable in this environment; the gitleaks CI check passed. No blocking findings.
CI status
All validation checks green: shellcheck, ShellCheck, bats, unit, unit-tests, Lint, CodeQL (actions + python), Agent Security Scan, agent-shield, Secret scan (gitleaks), SonarCloud, holdout-guard, template-drift, prompt-coverage, and all structural guards SUCCESS. Dependency-audit ecosystem jobs SKIPPED (no matching ecosystems). The two CANCELLED dev-lead checks (dispatch, ci-relay) are agent-orchestration runs superseded by newer activity, not code validation. review/review IN_PROGRESS is this review run itself.
Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
…d / skip absent advisory bots (durable hardening) (#1197) * feat: implement issue #1193 — pr-review advisory gate: timeout-proceed / skip absent advisory bots (durable hardening) * fix(reviews): address review comments [skip ci-relay] * chore: dev-lead update (review-changes) [skip ci-relay] --------- Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>



Closes #1193
Implemented by dev-lead agent. Please review.
Summary by CodeRabbit
Bug Fixes
Tests