You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix(settings): cap review nag cooldown
* fix(review): avoid a UI typecheck regression from a new agent-actions import
focus-manifest.ts is part of the UI package's typechecked closure (its
transitive deps get walked by apps/gittensory-ui's own tsc run). Importing
MAX_REVIEW_NAG_COOLDOWN_DAYS from settings/agent-actions.ts pulled that
module's own import of github/commands.ts -> utils/crypto.ts into the UI
build for the first time, exposing a pre-existing latent
Uint8Array<ArrayBufferLike>/BufferSource type mismatch in crypto.ts that
the UI's tsc had never previously reached.
Duplicates the small constant locally in focus-manifest.ts instead of
importing it, keeping db/repositories.ts's own import from agent-actions.ts
(never part of the UI closure) unaffected. Also rebases the branch's merge
commit into a linear rebase onto current main.
* fix(review): make the review-nag cooldown-cap regression test actually exercise the guard
Gate review: the original regression test seeded an oversized
reviewNagCooldownDays through upsertRepositorySettings, but both
upsertRepositorySettings and getRepositorySettings already clamp that field
on write AND read -- so the value read back inside resolveRepositorySettings
was never actually oversized by the time maybeThrottleReviewNagPing saw it.
The test could pass even with processors.ts's own
Math.min(reviewNagCooldownDays, MAX_REVIEW_NAG_COOLDOWN_DAYS) guard removed
entirely.
Mocks resolveRepositorySettings directly (bypassing the DB/yml clamp layers
entirely, not just the write-time one) to actually deliver an oversized
value to the function under test, then proves the guard's effect
behaviorally: three prior pings 400 days old fall outside the CORRECTLY
capped 365-day window (no cooldown applied), whereas an uncapped
"1-billion-day" window would count them and trip the threshold. Confirmed
by mutation-testing: removing the Math.min throws a real RangeError
(Invalid time value) building the Date.
Copy file name to clipboardExpand all lines: src/queue/processors.ts
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -237,6 +237,7 @@ import { aiReviewCacheInputFingerprint } from "../review/ai-review-cache-input";
237
237
import{
238
238
downgradeCloseToHold,
239
239
downgradeMergeToHold,
240
+
MAX_REVIEW_NAG_COOLDOWN_DAYS,
240
241
isProtectedAutomationAuthor,
241
242
planAgentMaintenanceActions,
242
243
typePlannedAgentAction,
@@ -8858,7 +8859,7 @@ async function maybeThrottleReviewNagPing(
8858
8859
/* v8 ignore next -- resolveRepositorySettings always resolves a concrete positive integer (NOT NULL DEFAULT 3); the undefined side is defensive against the field's optional TS type. */
8859
8860
constmaxPings=settings.reviewNagMaxPings??3;
8860
8861
/* v8 ignore next -- resolveRepositorySettings always resolves a concrete positive integer (NOT NULL DEFAULT 5); the undefined side is defensive against the field's optional TS type. */
awaitenv.DB.prepare("update repository_settings set review_nag_cooldown_days = ? where repo_full_name = ?").bind(1_000_000_000,"owner/bigwindowrepo").run();
it("REGRESSION (gate-flagged): caps an oversized review-nag cooldown at MAX_REVIEW_NAG_COOLDOWN_DAYS before Date arithmetic, even when the resolved settings object itself carries an oversized value", async () => {
12247
+
// upsertRepositorySettings/getRepositorySettings both clamp reviewNagCooldownDays on write AND read, so
12248
+
// seeding an oversized value through the normal repository layer (even via a raw DB update bypassing the
12249
+
// write-time clamp) can never actually reach maybeThrottleReviewNagPing uncapped -- the read-time clamp in
12250
+
// getRepositorySettings neutralizes it first. Mock resolveRepositorySettings directly so this test proves
12251
+
// processors.ts's OWN Math.min(reviewNagCooldownDays, MAX_REVIEW_NAG_COOLDOWN_DAYS) guard, not the DB layer.
// The 400-day-old pings fell outside the CAPPED 365-day window, so this is only the 1st ping this
12284
+
// window — under maxPings=3, never throttled. An uncapped window would have counted all 3 prior pings
12285
+
// (pingCount=4 > maxPings=3) and applied the cooldown instead.
12286
+
const applied = await env.DB.prepare("select count(*) as n from audit_events where event_type = 'github_app.review_nag_cooldown_applied'").first<{ n: number }>();
0 commit comments