From 8cb3e4914a98f5f3750062e1f0fad65f87c097b1 Mon Sep 17 00:00:00 2001 From: JSONbored <49853598+JSONbored@users.noreply.github.com> Date: Tue, 7 Jul 2026 03:44:51 -0700 Subject: [PATCH] fix(queue): repair malformed regate-repair diff breaking main typecheck PR #3998 shipped a garbled hunk in sweepRepoRegate's job-dispatch block and regatePullRequest's signature/body -- an object literal spliced with a dangling recordAuditEvent's fields, no closing brace or JOBS.send call, and a required parameter (repoFullName) following an optional one (repairHeadSha). Reconstructed both regions from the parent commit plus the PR's stated intent: move the repair-attempt audit event from dispatch-time to execution-time (after rate-limit admission), so a deferred/dropped job no longer burns an attempt against REGATE_REPAIR_MAX_ATTEMPTS_PER_SHA. Also fixed a duplicate declaration of that same constant (value 5 shadowing the original 2, introduced by the same bad hunk) and an invalid "started" outcome literal that isn't part of the audit-event outcome enum. --- src/queue/processors.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/queue/processors.ts b/src/queue/processors.ts index df986f7359..8db1c30782 100644 --- a/src/queue/processors.ts +++ b/src/queue/processors.ts @@ -1462,7 +1462,7 @@ async function refreshOpenPullRequestsForScheduledSweep( // surfaceRepairPriorityPullNumbers has no memory of prior attempts -- if the repair keeps failing for the SAME // head SHA (e.g. every AI-provider attempt times out), it would otherwise re-select that PR forever, burning a // fresh review attempt every cycle for zero output. These two constants cap that: once a SHA has already had -const REGATE_REPAIR_MAX_ATTEMPTS_PER_SHA = 5; +// REGATE_REPAIR_MAX_ATTEMPTS_PER_SHA dispatches recorded, it drops back to ordinary staleness-gated candidacy // (still eventually re-checked, just not on every tick) and a single REGATE_REPAIR_EXHAUSTED_EVENT_TYPE audit // event is recorded so the stuck PR is visible instead of silently retried forever. A new commit changes the // head SHA, which resets the count naturally (the target key is scoped to repo+PR+SHA). @@ -1871,21 +1871,21 @@ async function sweepRepoRegate( const job: JobMessage = { type: "agent-regate-pr", deliveryId: isPriorityRepair - // #orb-retry-storm: pass the repair SHA so regatePullRequest can record the attempt at - // execution time (after rate-limit admission), not here at dispatch time. Jobs that are - // deferred or dropped before they run no longer count against the per-SHA cap. - ...(isPriorityRepair && pr.headSha ? { repairHeadSha: pr.headSha } : {}), ? `regate-repair:${repoFullName}#${pr.number}` : `regate-sweep:${repoFullName}#${pr.number}`, repoFullName, prNumber: pr.number, installationId: sweepInstallationId, - targetKey: regateRepairTargetKey(repoFullName, pr.number, pr.headSha), - outcome: "queued", - detail: `outage-repair re-review dispatched for ${repoFullName}#${pr.number}`, - metadata: { repoFullName, prNumber: pr.number, headSha: pr.headSha }, - }); - } + // #orb-retry-storm: pass the repair SHA so regatePullRequest can record the attempt at + // execution time (after rate-limit admission), not here at dispatch time. Jobs that are + // deferred or dropped before they run no longer count against the per-SHA cap. + ...(isPriorityRepair && pr.headSha ? { repairHeadSha: pr.headSha } : {}), + ...(pr.createdAt ? { prCreatedAt: pr.createdAt } : {}), + }; + const delaySeconds = Math.min(index * 10, 600); + await (delaySeconds > 0 + ? env.JOBS.send(job, { delaySeconds }) + : env.JOBS.send(job)); } } await recordAuditEvent(env, { @@ -2089,7 +2089,7 @@ async function sweepRepoBacklogConvergence( // per-PR job always re-evaluates the head. async function regatePullRequest( env: Env, - repairHeadSha?: string, + repairHeadSha: string | undefined, repoFullName: string, prNumber: number, installationId: number, @@ -2122,6 +2122,12 @@ async function regatePullRequest( repoFullName, prNumber, installationId, + ...(prCreatedAt ? { prCreatedAt } : {}), + ...(force ? { force: true } : {}), + }, + { delaySeconds: delayUntil(rateResetAt) }, + ); + return; } // #orb-retry-storm: record the repair attempt NOW — after rate-limit admission — so the cap in // surfaceRepairPriorityPullNumbers counts actual executions, not queued dispatches that may have @@ -2132,16 +2138,10 @@ async function regatePullRequest( eventType: REGATE_REPAIR_ATTEMPT_EVENT_TYPE, actor: "gittensory", targetKey: regateRepairTargetKey(repoFullName, prNumber, repairHeadSha), - outcome: "started", + outcome: "completed", detail: `outage-repair re-review executing for ${repoFullName}#${prNumber}`, metadata: { repoFullName, prNumber, headSha: repairHeadSha }, }); - ...(prCreatedAt ? { prCreatedAt } : {}), - ...(force ? { force: true } : {}), - }, - { delaySeconds: delayUntil(rateResetAt) }, - ); - return; } const settings = await resolveRepositorySettings(env, repoFullName); await reReviewStoredPullRequest(