Repository navigation
PR Review Agent — failures detected 2026-09-17 #1829
Description
Convergence latency (deterministic)
Workflow duration across 275 completed run(s) in the window — computed by pr_review_health.sh, not the model.
| Workflow | Runs | min | p50 | p95 | max |
|---|---|---|---|---|---|
pr-review-trigger.yml |
275 | 1s | 38s | 13m43s | 18m18s |
Run-outcome mix by triggering event
pr-review run conclusions over the window, split by the event that triggered each run — computed deterministically by pr-review-outcomes.sh, not the model. A high cancelled share means runs were evicted while PENDING (concurrency admits one running + one pending per group); a cancelled run is non-blocking but historically rendered as a failing check (#1421).
| Event | success | cancelled | skipped | failure | total | cancel % |
|---|---|---|---|---|---|---|
check_suite |
33 | 21 | 5 | 0 | 59 | 35% |
pull_request |
20 | 0 | 0 | 0 | 20 | 0% |
pull_request_review |
2 | 4 | 16 | 0 | 22 | 18% |
repository_dispatch |
59 | 41 | 0 | 1 | 101 | 40% |
workflow_dispatch |
73 | 0 | 0 | 0 | 73 | 0% |
| TOTAL | 187 | 66 | 21 | 1 | 275 | 24% |
Sweep hit-rate (deterministic)
How often the pr-review-sweep scheduled backstop actually had to re-review a PR — computed deterministically by pr-review-sweep-metrics.sh, not the model. The scheduled (cron) path re-dispatches only for genuinely un-eventable cases (GitHub-App / cross-repo checks like SonarCloud that emit no workflow_run); the workflow_run fast path handles every eventable case, so a scheduled re-dispatch is always a case the fast path did not cover.
| Metric | Value |
|---|---|
| Scheduled sweep ticks | 6 |
| Ticks that re-dispatched a review (hits) | 6 |
| Sweep hit-rate | 100% |
Interpretation: a low rate confirms the timer stays exception-only (the event fast path is carrying the load); a rising rate is a signal that an eventable case is leaking onto the timer — a hole in the narrowing worth investigating.
PR Review Agent — Health Report
Workflow: pr-review-trigger.yml | Repo: petry-projects/.github-private
Generated: 2026-09-17
1. Executive Summary
Status: HEALTHY
Period: 2026-09-16T12:07Z – 2026-09-17T10:23Z
Result: 1 of 275 runs failed (0.36%) — 187 succeeded, 66 cancelled, ~21 skipped
Key findings:
- Single failure (#77485) occurred inside a 32-minute high-volume burst (12:24–12:56 UTC on 2026-09-16); no log content was surfaced for that run, so root cause is unconfirmed
- 66 cancellations (24% of all runs) are entirely concentrated in the same 12:24–12:56 UTC burst window, consistent with rapid-fire event fan-out without a workflow-level
concurrency:guard - ~21 skipped runs (8%) distributed throughout the period represent expected no-op exits in the reusable (draft PRs, already-reviewed SHAs, bot authors, etc.)
Action required: Add a concurrency: group to the trigger stub to prevent cancellation storms during high-volume push/rebase events.
2. Failure Breakdown
| Failure Category | Affected Runs | Example Error Message |
|---|---|---|
| Unknown — logs unavailable | 1 (#77485) | (no log content returned for this run) |
| Concurrency cancellation (not a failure) | 66 | (cancelled by GitHub or a newer run superseding) |
| Expected no-op skip | ~21 | (reusable condition gate — not an error) |
No permission errors, rate-limit signals, auth failures, or engine quota exhaustion were present in the surfaced data.
3. Error Patterns
Cancellation Storm (runs ~#77343–#77503, 12:24–12:56 UTC)
(no explicit error — status: cancelled)
Source: GitHub Actions run lifecycle, not a script error.
Observed pattern: Within the 32-minute window, 66 runs were spawned in rapid succession — several pairs share identical timestamps (e.g., #77357/#77358 both at 12:25:20Z, #77464/#77465 both at 12:44:34Z). The trigger fires on pull_request (synchronize, ready_for_review, reopened) and check_suite completed — a single force-push or rebase-onto-main touching multiple PRs simultaneously fans out one run per event. Without a concurrency: group in pr-review-trigger.yml, all instances queue independently; newer ones supersede older queued ones.
Root cause: No concurrency: block in the calling stub. The reusable (pr-review.yml) may define its own group, but the stub is the entry point and controls queuing before the reusable is invoked.
Single Failure #77485 (12:48:30 UTC)
(log content not returned — failed run logs section was empty)
Source: Unknown — the run failed at the center of the cancellation burst. Possible causes in priority order: (1) a transient GitHub API 5xx during the congested window, (2) a race condition in engine.sh or review-one-pr.sh when multiple runs target the same PR simultaneously, (3) a secrets-resolution failure under load. Because this is a 1-in-275 event in the middle of an anomalous load spike, infrastructure transience is the most probable explanation.
4. Token Scope Analysis
Scopes granted in trigger stub:
| Permission | Level | Purpose |
|---|---|---|
contents |
read |
Checkout workflow source; passed to reusable |
pull-requests |
write |
Post review comments and approvals |
checks |
read |
Read check_suite payloads; filter by suite conclusion |
Assessment: The declared permissions match the documented needs of pr-review.yml. No missing-scope signals appear in the surfaced data (no 403/401 patterns, no insufficient scope log lines).
No changes recommended to permissions based on available evidence. If the single failure was a permission issue, its logs would need to be retrieved directly via gh run view 77485 --log-failed to confirm.
5. Recommendations
1. Add a concurrency: group to the trigger stub
- File:
.github/workflows/pr-review-trigger.yml - Change: Insert at the workflow level (or job level):
This deduplifies per-PR: a new
concurrency: group: pr-review-${{ github.event.pull_request.number || github.event.check_suite.id || github.run_id }} cancel-in-progress: true
synchronizepush cancels the still-running review for the same PR number rather than stacking a second run. Usegithub.run_idas the fallback sorepository_dispatchandworkflow_dispatchare never grouped together unintentionally. - Why: 66 cancellations in 32 minutes is wasteful and masks signal in dashboards. The current pattern makes it impossible to distinguish intentional cancels from infrastructure kills at a glance.
- Expected impact: Cancellation rate drops from ~24% to near-zero for push bursts; the run list becomes easier to reason about.
- Urgency: MEDIUM (operational noise; not causing failures today)
2. Retrieve and triage logs for failed run #77485
- Command:
gh run view 77485 --repo petry-projects/.github-private --log-failed - Why: The single failure has no associated log content in this report. Until logs are examined, the root cause is unconfirmed. If it was a transient API error it can be closed; if it reveals a script bug it may recur.
- Expected impact: Either closes the issue (transient) or surfaces a deterministic bug fix.
- Urgency: LOW (0.36% rate, likely transient given the burst context — but verify)
3. Add failure alerting for pr-review-trigger.yml
- File:
.github/workflows/pr-review-trigger.ymlor a separate notification workflow - Change: Add a
on: workflow_runwatcher that fires a Slack/issue notification when this workflow concludes withfailureconclusion, so the single failure would not require a periodic health report to surface. - Why: A 0.36% rate is healthy today, but without alerting, a regression to 5–10% could go unnoticed for days.
- Urgency: LOW
6. Health Score
Health: 9/10 — One undiagnosed transient failure in a 32-minute congestion burst; otherwise clean, with the only structural concern being an avoidable cancellation storm from missing concurrency guards.
Activity