Problem
The scheduled re-gate sweep re-reviews + re-publishes EVERY open registered PR every ~2-min cycle, regardless of whether anything changed. Audit shows ~4292 github_app.pr_public_surface_published events in 2h for ~64 PRs (~67 re-publishes per PR). createOrUpdateIssueCommentWithMarker PATCHes the sticky comment unconditionally (no body compare), and there is no per-PR marker recording the head the surface was last published at — so the sweep can't tell a current PR from a changed one.
The AI review itself is already deduped (ai_review_cache is head_sha-keyed), so this is GitHub-write/processing churn, not AI spend.
Fix
- Add
pull_requests.last_published_surface_sha (migration 0080), stamped (head_sha-keyed) after a successful publish — omitted from the GitHub-sync SET clause like the sibling approved_head_sha marker so it survives sync.
- In
reReviewStoredPullRequest, AFTER the live-head resync, skip the re-review + re-publish when last_published_surface_sha === head_sha. A never-published PR (NULL marker) or a changed head (push/rebase/force-push → marker != live head) falls through and re-reviews at the new head; the head_sha-keyed AI cache also misses on a rebase. The webhook synchronize/opened paths review directly and always re-stamp, so this guard only gates the sweep.
- Defense-in-depth: skip the comment PATCH when the rendered body is byte-identical.
Rebase re-review (explicitly preserved)
A rebase/force-push changes head_sha → marker no longer matches → the PR is re-reviewed at the new head (resync refreshes head+files; AI cache misses). Pinned by a regression test. Expected effect: pr_public_surface_published drops from ~1/PR/sweep to ~1/PR/head_sha (only on real change).
Problem
The scheduled re-gate sweep re-reviews + re-publishes EVERY open registered PR every ~2-min cycle, regardless of whether anything changed. Audit shows ~4292
github_app.pr_public_surface_publishedevents in 2h for ~64 PRs (~67 re-publishes per PR).createOrUpdateIssueCommentWithMarkerPATCHes the sticky comment unconditionally (no body compare), and there is no per-PR marker recording the head the surface was last published at — so the sweep can't tell a current PR from a changed one.The AI review itself is already deduped (
ai_review_cacheis head_sha-keyed), so this is GitHub-write/processing churn, not AI spend.Fix
pull_requests.last_published_surface_sha(migration 0080), stamped (head_sha-keyed) after a successful publish — omitted from the GitHub-sync SET clause like the siblingapproved_head_shamarker so it survives sync.reReviewStoredPullRequest, AFTER the live-head resync, skip the re-review + re-publish whenlast_published_surface_sha === head_sha. A never-published PR (NULL marker) or a changed head (push/rebase/force-push → marker != live head) falls through and re-reviews at the new head; the head_sha-keyed AI cache also misses on a rebase. The webhook synchronize/opened paths review directly and always re-stamp, so this guard only gates the sweep.Rebase re-review (explicitly preserved)
A rebase/force-push changes head_sha → marker no longer matches → the PR is re-reviewed at the new head (resync refreshes head+files; AI cache misses). Pinned by a regression test. Expected effect:
pr_public_surface_publisheddrops from ~1/PR/sweep to ~1/PR/head_sha (only on real change).