Skip to content

fix(review): stop redundant republishing for a draft fork PR's repeat CI-completion triggers#6710

Merged
JSONbored merged 1 commit into
mainfrom
claude/fix-draft-fork-pr-republish-6685
Jul 17, 2026
Merged

fix(review): stop redundant republishing for a draft fork PR's repeat CI-completion triggers#6710
JSONbored merged 1 commit into
mainfrom
claude/fix-draft-fork-pr-republish-6685

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • A draft fork PR's own CI produces one check_run.completed webhook per job (each arriving with an empty pull_requests[] payload, forcing the fork-resume fallback in webhook-coalesce.ts to re-run the whole evaluation pass), so a multi-job CI run republished the SAME comment/label surface once per completing job even though nothing about the PR changed between them. Confirmed live: 12 identical republishes of feat(ui): maintainer dashboard panel for the existing @loopover chat Q&A surface #6592 in 29 minutes — the actual root cause of the ops_anomaly "review burst" false alarms that have been firing across the fleet for at least a day.
  • The one-shot cadence guard already avoids wasting AI spend on these repeat passes (ai_slop_one_shot_skip, linked_issue_satisfaction_one_shot_skip, ai_review_auto_review_skipped all correctly fire), but nothing stopped the pipeline from proceeding to republish anyway. The only existing "skip republish if nothing changed" guard (canSkipCurrentSurface) is deliberately scoped to publicSurface: "off" repos, and requires gateEnabled — which is false fleet-wide here since reviewCheckMode is disabled, so that guard never even engages for loopover/awesome-claude/metagraphed regardless of surface type.
  • Added a narrower, independent skip specifically for the draft case: when autoReviewSkipReason is deterministically "review skipped (draft)" (not just reused from cache) and the head SHA matches what was last fully published, republishing is a provable no-op. Hoisted the reason into a try-block-independent variable (autoReviewSkipReasonForPublish) since the original is scoped inside the try block that ends before the publish site, mirroring the existing aiReviewExpected/aiReviewWasReused hoisting pattern.

Closes #6685

Validation

  • npm run typecheck
  • npm run test:coverage (full unsharded run — new lines fully covered, verified line-by-line against coverage/lcov.info)
  • npm run test:ci (full gate; one unrelated, pre-existing miner-attempt-worktree.test.ts timeout reproduced under heavy concurrent-session load, confirmed to pass cleanly in isolation twice and unrelated to this diff — every other step in the chain verified individually green)
  • npm audit --audit-level=moderate — 0 vulnerabilities
  • git diff --check — clean

… CI-completion triggers (#6685)

A draft fork PR's own CI produces one check_run.completed webhook per job (each
arriving with an empty pull_requests[] payload, forcing the fork-resume
fallback in webhook-coalesce.ts to re-run the whole evaluation pass), so a
multi-job CI run republished the SAME comment/label surface once per completing
job even though nothing about the PR changed between them. Confirmed live: 12
identical republishes of #6592 in 29 minutes -- the actual
root cause of the ops_anomaly "review burst" false alarms that have been firing
across the fleet for at least a day.

The one-shot cadence guard already avoids wasting AI spend on these repeat
passes (ai_slop_one_shot_skip, linked_issue_satisfaction_one_shot_skip,
ai_review_auto_review_skipped all correctly fire), but nothing stopped the
pipeline from proceeding to republish anyway. The only existing "skip
republish if nothing changed" guard (canSkipCurrentSurface) is deliberately
scoped to publicSurface: "off" repos, and requires gateEnabled -- which is
false fleet-wide here since reviewCheckMode is disabled, so that guard never
even engages for loopover/awesome-claude/metagraphed regardless of surface
type.

Add a narrower, independent skip specifically for the draft case: when
autoReviewSkipReason is deterministically "review skipped (draft)" (not just
reused from cache) and the head SHA matches what was last fully published,
republishing is a provable no-op. Hoisted the reason into a
try-block-independent variable (autoReviewSkipReasonForPublish) since the
original is scoped inside the try block that ends before the publish site,
mirroring the existing aiReviewExpected/aiReviewWasReused hoisting pattern.

Closes #6685
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.65%. Comparing base (3acc512) to head (0d9c29f).
⚠️ Report is 23 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6710   +/-   ##
=======================================
  Coverage   93.65%   93.65%           
=======================================
  Files         681      682    +1     
  Lines       68098    68126   +28     
  Branches    18695    18704    +9     
=======================================
+ Hits        63775    63802   +27     
  Misses       3347     3347           
- Partials      976      977    +1     
Flag Coverage Δ
shard-1 43.85% <100.00%> (-0.05%) ⬇️
shard-2 36.95% <25.00%> (+0.10%) ⬆️
shard-3 32.44% <25.00%> (+0.05%) ⬆️
shard-4 34.21% <25.00%> (-0.44%) ⬇️
shard-5 31.39% <0.00%> (+0.45%) ⬆️
shard-6 45.76% <37.50%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/queue/processors.ts 95.52% <100.00%> (+0.01%) ⬆️

... and 1 file with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-16 20:36:04 UTC

2 files · 1 AI reviewer · no blockers · readiness 88/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
This adds a narrow, independent skip in maybePublishPrPublicSurface: when a draft PR's deterministic skip reason is "review skipped (draft)" and the head SHA matches the last fully published SHA (and no explicit force override), the pipeline now short-circuits before republishing, closing the loop that caused 12 identical republishes of #6592 from repeat fork-CI check_run.completed events. The hoisting pattern (autoReviewSkipReasonForPublish) mirrors the existing aiReviewExpected/aiReviewWasReused hoisting, and the fix is correctly scoped independent of the existing canSkipCurrentSurface guard which requires gateEnabled (false fleet-wide here). Test coverage is thorough: repeat-same-head skip, new-head/force-override non-skip, and a failing-audit-write resilience case, all exercising the real processJob path rather than a fabricated unit slice.

Nits — 6 non-blocking
  • src/queue/processors.ts: the magic string "review skipped (draft)" is compared by literal value at the new skip site — if the producer of autoReviewSkipReason ever changes that string, this guard silently stops firing with no compile-time signal; consider extracting a shared constant.
  • src/queue/processors.ts: the new inline comment block is ~12 lines of prose duplicating most of the PR description — consider trimming to the load-bearing invariant (deterministic reason + matching headSha ⇒ no-op) and pointing to the issue for the rest.
  • The audit-write failure is silently swallowed via `.catch(() => undefined)` with no logging — consistent with the pattern this PR mirrors, but worth confirming there's an observability path elsewhere for repeated skip-audit failures.
  • Consider adding an explicit assertion (or a comment pointing at the code) confirming `pr.lastPublishedSurfaceSha` is updated on every real publish pass, since the whole skip's correctness hinges on that invariant and it isn't visible in this diff.
  • Extracting `"review skipped (draft)"` into a shared constant used both at the point autoReviewSkipReason is set and at this new comparison site would remove the string-drift risk noted above.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6685
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 33 registered-repo PR(s), 26 merged, 273 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 33 PR(s), 273 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 33 PR(s), 273 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 16, 2026
@JSONbored
JSONbored merged commit e592d90 into main Jul 17, 2026
17 checks passed
@JSONbored
JSONbored deleted the claude/fix-draft-fork-pr-republish-6685 branch July 17, 2026 02:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(review): draft fork PRs republish the same review comment every few minutes (missing skip-guard)

1 participant