Severity: medium (wasted GitHub API calls, comment noise, and it's the direct cause of the ongoing review burst ops_anomaly false alarms across the fleet)
Failure scenario
A draft PR opened from a fork (e.g. JSONbored/loopover#6592, author claytonlin1110) republishes its review surface every 2-3 minutes for as long as its CI keeps running, even though nothing about the PR's content, review, or labels has changed since the first publish.
Confirmed live via the self-host Postgres audit_events table for #6592 between 16:20-16:52 UTC on 2026-07-16 — 12 github_app.pr_public_surface_published events in ~29 minutes, each with a different webhook deliveryId but identical reviewEffortMinutes: 290, interleaved with a github_app.ci_completion_fork_resume event every cycle:
16:20:52 github_app.review_deferred_ci_pending CI still running — review deferred until all checks finish
16:22:20 github_app.ci_completion_fork_resume resumed fork PR via head-SHA fallback (empty check pull_requests[])
16:22:25 github_app.type_label_decision applied labels: gittensor:feature
16:22:25 github_app.ai_slop_cache_miss running a fresh advisory (first pass)
16:23:01 github_app.linked_issue_satisfaction_cache_miss
16:23:14 github_app.ai_review_auto_review_skipped review skipped (draft)
16:23:49 github_app.pr_public_surface_published <- publish #1
16:25:20 github_app.ci_completion_fork_resume resumed fork PR via head-SHA fallback (empty check pull_requests[])
16:25:23 github_app.type_label_decision applied labels: gittensor:feature (same labels, reapplied)
16:25:23 github_app.ai_slop_one_shot_skip already had its slop advisory pass; not spending a fresh call
16:25:23 github_app.linked_issue_satisfaction_one_shot_skip
16:25:23 github_app.ai_review_auto_review_skipped review skipped (draft)
16:26:23 github_app.pr_public_surface_published <- publish #2 (nothing changed since #1)
... repeats every 2-5 minutes, 12 times total in this window ...
Root cause (two parts)
1. Re-trigger source: #6592 is a fork PR. Per a well-known GitHub API quirk, check_run/check_suite webhook payloads for fork-originated checks carry an empty pull_requests[] array, so the webhook handler falls back to ci_completion_fork_resume ("resumed fork PR via head-SHA fallback") on every individual check completion. A CI run with N jobs produces N separate completion webhooks, each independently re-running the full per-PR evaluation pipeline — there's no coalescing across these fork-resume events for the same head SHA within a short window.
2. Missing skip-guard: Each re-run correctly avoids wasting AI spend — ai_slop_one_shot_skip, linked_issue_satisfaction_one_shot_skip, and ai_review_auto_review_skipped ("review skipped (draft)", from src/signals/focus-manifest.ts:156) all fire as expected. But nothing stops the pipeline from proceeding to republish the surface anyway. The only existing "skip republish if nothing changed" guard is in src/queue/processors.ts around line 9679-9695, and it's explicitly scoped to settings.publicSurface === "off" (check-run-only repos) — by design, per that guard's own comment, because a lastPublishedSurfaceSha match is considered insufficient proof of a complete comment+label publish (unlike an atomic completed check-run). loopover, awesome-claude, and metagraphed all use publicSurface: comment_and_label, so none of them have any equivalent guard — every fork-resume cycle on a draft PR unconditionally republishes.
Suggested fix direction
Add a narrower, safer skip specifically for the case this issue documents — not a blanket extension of the existing publicSurface === "off" guard (that guard's narrow scope is intentional and documented). When ALL of the following hold for the current pass:
autoReviewSkipReason === "review skipped (draft)" (i.e., we know deterministically why no review ran, not just that one was reused)
- slop advisory and linked-issue satisfaction both hit their one-shot-skip path (not freshly computed)
- resolved labels are unchanged from the PR's current label set
advisory.headSha === pr.lastPublishedSurfaceSha
... skip the republish. This is a stronger proof-of-no-op than the existing check-run-only guard already accepts (it doesn't rely solely on the SHA marker — it also confirms every substantive dimension explicitly took the "nothing to do" path this pass), so it should be safe to apply to comment_and_label surfaces too, without the partial-publish risk the existing guard's scoping comment warns about.
Separately worth a look: whether fork-PR check-run completions for the same head SHA within a short window (e.g. a few seconds/minutes) can be coalesced into one ci_completion_fork_resume evaluation instead of one per completing check job — would reduce the trigger frequency at the source, independent of the publish-skip fix above.
Impact
This is the actual root cause of the review burst (stuck-CI finalize loop or retry storm) ops_anomaly that's been firing every ~1-2h across loopover, awesome-claude, and metagraphed continuously for at least 24h+ prior to this issue being filed — rotating across whichever draft fork PR happens to have CI running at the time, not a single stuck PR.
Severity: medium (wasted GitHub API calls, comment noise, and it's the direct cause of the ongoing
review burstops_anomaly false alarms across the fleet)Failure scenario
A draft PR opened from a fork (e.g.
JSONbored/loopover#6592, authorclaytonlin1110) republishes its review surface every 2-3 minutes for as long as its CI keeps running, even though nothing about the PR's content, review, or labels has changed since the first publish.Confirmed live via the self-host Postgres
audit_eventstable for#6592between 16:20-16:52 UTC on 2026-07-16 — 12github_app.pr_public_surface_publishedevents in ~29 minutes, each with a different webhookdeliveryIdbut identicalreviewEffortMinutes: 290, interleaved with agithub_app.ci_completion_fork_resumeevent every cycle:Root cause (two parts)
1. Re-trigger source:
#6592is a fork PR. Per a well-known GitHub API quirk,check_run/check_suitewebhook payloads for fork-originated checks carry an emptypull_requests[]array, so the webhook handler falls back toci_completion_fork_resume("resumed fork PR via head-SHA fallback") on every individual check completion. A CI run with N jobs produces N separate completion webhooks, each independently re-running the full per-PR evaluation pipeline — there's no coalescing across these fork-resume events for the same head SHA within a short window.2. Missing skip-guard: Each re-run correctly avoids wasting AI spend —
ai_slop_one_shot_skip,linked_issue_satisfaction_one_shot_skip, andai_review_auto_review_skipped("review skipped (draft)", fromsrc/signals/focus-manifest.ts:156) all fire as expected. But nothing stops the pipeline from proceeding to republish the surface anyway. The only existing "skip republish if nothing changed" guard is insrc/queue/processors.tsaround line 9679-9695, and it's explicitly scoped tosettings.publicSurface === "off"(check-run-only repos) — by design, per that guard's own comment, because alastPublishedSurfaceShamatch is considered insufficient proof of a complete comment+label publish (unlike an atomic completed check-run).loopover,awesome-claude, andmetagraphedall usepublicSurface: comment_and_label, so none of them have any equivalent guard — every fork-resume cycle on a draft PR unconditionally republishes.Suggested fix direction
Add a narrower, safer skip specifically for the case this issue documents — not a blanket extension of the existing
publicSurface === "off"guard (that guard's narrow scope is intentional and documented). When ALL of the following hold for the current pass:autoReviewSkipReason === "review skipped (draft)"(i.e., we know deterministically why no review ran, not just that one was reused)advisory.headSha === pr.lastPublishedSurfaceSha... skip the republish. This is a stronger proof-of-no-op than the existing check-run-only guard already accepts (it doesn't rely solely on the SHA marker — it also confirms every substantive dimension explicitly took the "nothing to do" path this pass), so it should be safe to apply to
comment_and_labelsurfaces too, without the partial-publish risk the existing guard's scoping comment warns about.Separately worth a look: whether fork-PR check-run completions for the same head SHA within a short window (e.g. a few seconds/minutes) can be coalesced into one
ci_completion_fork_resumeevaluation instead of one per completing check job — would reduce the trigger frequency at the source, independent of the publish-skip fix above.Impact
This is the actual root cause of the
review burst(stuck-CI finalize loop or retry storm) ops_anomaly that's been firing every ~1-2h acrossloopover,awesome-claude, andmetagraphedcontinuously for at least 24h+ prior to this issue being filed — rotating across whichever draft fork PR happens to have CI running at the time, not a single stuck PR.