From 0ecca461deec5b7f9de8913990d3c37e28f9c0b1 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Mon, 6 Jul 2026 03:54:28 -0700 Subject: [PATCH] fix(review): skip open-PR refresh for registered-but-uninstalled repos in the regate sweep The scheduled regate sweep refreshed open-PR data (via the shared GITHUB_PUBLIC_TOKEN) for every repo in the subnet registry, including repos with no installed GitHub App -- even though the per-PR re-review fan-out already skips these repos entirely. This burned real, shared REST budget on data no part of the sweep could use, and starved that same shared budget for installed repos processed later in the staggered per-repo dispatch. --- src/queue/processors.ts | 9 +++++++- test/unit/queue.test.ts | 48 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/queue/processors.ts b/src/queue/processors.ts index c603cad9a6..e352a542e2 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -1332,7 +1332,14 @@ async function refreshOpenPullRequestsForScheduledSweep( requestedBy: "schedule" | "api" | "test", ): Promise { if (requestedBy !== "schedule") return; - if (!repo || !sweepOpenPullRequestSyncCredentialAvailable(env, repo)) return; + // No installation -> no per-PR regate fan-out will ever happen for this repo (the candidate-selection + // gate below only dispatches agent-regate-pr jobs for installed repos), so refreshing its open-PR list + // here only spends the shared GITHUB_PUBLIC_TOKEN budget on data nothing in THIS sweep will use. A + // registry-only repo (registry/sync.ts, isRegistered) still gets its own data kept fresh by the + // dedicated backfill-registered-repos/refresh-registry jobs, so skipping here is pure waste removal, + // not a functionality gap (#audit-rate-headroom, #sweep-uninstalled-budget-waste). + if (!repo?.installationId) return; + if (!sweepOpenPullRequestSyncCredentialAvailable(env, repo)) return; const segment = await getRepoSyncSegment( env, repo.fullName, diff --git a/test/unit/queue.test.ts b/test/unit/queue.test.ts index 798423a3cf..1dca51a38d 100644 --- a/test/unit/queue.test.ts +++ b/test/unit/queue.test.ts @@ -6737,6 +6737,54 @@ describe("queue processors", () => { warn.mockRestore(); }); + it("REGRESSION (#sweep-uninstalled-budget-waste): a scheduled sweep never refreshes open PRs (via the shared GITHUB_PUBLIC_TOKEN) for a registered-but-uninstalled repo, since no per-PR fan-out will ever follow", async () => { + const sent: import("../../src/types").JobMessage[] = []; + const env = createTestEnv({ + GITHUB_PUBLIC_TOKEN: "public-token", + JOBS: { + async send(m: import("../../src/types").JobMessage) { + sent.push(m); + }, + } as unknown as Queue, + }); + // Registered (e.g. via the subnet registry sync) but NOT installed — no installationId. + await upsertRepositoryFromGitHub(env, { name: "no-install", full_name: "owner/no-install", private: false, owner: { login: "owner" } }); + await upsertRepositorySettings(env, { repoFullName: "owner/no-install", autonomy: { merge: "auto" } }); + const segmentSpy = vi.spyOn(repositoriesModule, "getRepoSyncSegment"); + const backfillSpy = vi.spyOn(backfillModule, "backfillRepositorySegment"); + vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z")); + + await processJob(env, { type: "agent-regate-sweep", requestedBy: "schedule", repoFullName: "owner/no-install" }); + + expect(segmentSpy).not.toHaveBeenCalled(); + expect(backfillSpy).not.toHaveBeenCalled(); + expect(sent.filter((job) => job.type === "agent-regate-pr")).toEqual([]); + segmentSpy.mockRestore(); + backfillSpy.mockRestore(); + }); + + it("scheduled sweeps DO still refresh open PRs for an installed repo even when GITHUB_PUBLIC_TOKEN is also configured (installation presence gates the skip, not credential kind)", async () => { + const sent: import("../../src/types").JobMessage[] = []; + const env = createTestEnv({ + GITHUB_PUBLIC_TOKEN: "public-token", + JOBS: { + async send(m: import("../../src/types").JobMessage) { + sent.push(m); + }, + } as unknown as Queue, + }); + await upsertInstallation(env, { action: "created", installation: { id: 9405, account: { login: "owner", id: 1, type: "Organization" }, target_type: "Organization", repository_selection: "selected", permissions: {}, events: [] } }); + await upsertRepositoryFromGitHub(env, { name: "agent-repo", full_name: "owner/agent-repo", private: false, owner: { login: "owner" } }, 9405); + await upsertRepositorySettings(env, { repoFullName: "owner/agent-repo", autonomy: { merge: "auto" }, gateCheckMode: "off", checkRunMode: "off", commentMode: "off", publicSurface: "off" }); + const backfillSpy = vi.spyOn(backfillModule, "backfillRepositorySegment").mockResolvedValueOnce(undefined as never); + vi.setSystemTime(new Date("2026-05-28T02:00:00.000Z")); + + await processJob(env, { type: "agent-regate-sweep", requestedBy: "schedule", repoFullName: "owner/agent-repo" }); + + expect(backfillSpy).toHaveBeenCalledWith(env, expect.objectContaining({ segment: "open_pull_requests", mode: "light", force: true })); + backfillSpy.mockRestore(); + }); + it("scheduled sweeps refresh incomplete open-PR sync segments", async () => { const sent: import("../../src/types").JobMessage[] = []; const env = createTestEnv({