fix(review): cache the review-memory suppression list read, invalidate on write (#4508) - #4599
Conversation
…e on write (#4508) listReviewSuppressions was re-read from D1 on every unified-comment render whenever a repo had review-memory enabled, even though the 3 independent maybePublishPrPublicSurface call sites (auto re-review, webhook-triggered review, manual panel retrigger) can each fire for the same repo within a short window. Adds a short in-isolate TTL cache mirroring rag.ts's chunkCountCache, explicitly invalidated the moment a maintainer records a fresh suppression via `@gittensory resolve` so the very next render sees it, not just after the TTL.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4599 +/- ##
=======================================
Coverage 94.12% 94.12%
=======================================
Files 430 430
Lines 38181 38190 +9
Branches 13922 13923 +1
=======================================
+ Hits 35939 35948 +9
Misses 1585 1585
Partials 657 657
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-10 07:18:34 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 7 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
listReviewSuppressionswas re-read from D1 on every unified-comment render whenevercommentGate.warnings.length > 0for a review-memory-enabled repo — not gated by any cache marker. The 3 independentmaybePublishPrPublicSurfacecall sites (auto re-review, webhook-triggered review, manual panel retrigger) can each fire this independently for the same repo/PR within a short window, with no shared cache between them.getCachedReviewSuppressions/invalidateReviewSuppressionCachetoreview-memory-wire.ts: a short (60s) in-isolate TTL cache keyed byrepoFullName, mirroringrag.ts'schunkCountCachepattern exactly (including threadingnowMsin from the caller rather than readingDate.now()internally, for deterministic behavior under fake timers).chunkCountCache's "only cache the positive" (a repo's index state is one-way, cold→hot), a suppression set can grow at any time via@gittensory resolve— so the cache is explicitly invalidated at the one write site (maybeProcessResolveCommand) immediately afterrecordReviewSuppressionsucceeds, rather than relying on TTL expiry alone. A maintainer's fresh suppression takes effect on the very next render.clearReviewSuppressionCacheForTest()(mirroring the existingclearInstallationTokenCacheForTest/clearGitHubResponseCacheForTestpattern) and wires it intoqueue.test.ts's globalbeforeEach— discovered during implementation that this file's fake-timer setup resetsDate.now()to the same fixed instant for every test, so without an explicit reset a module-level cache would leak one test's suppression read into the next test using the same repo name.Closes #4508.
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #4508).Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally — every changed line and branch insrc/queue/processors.tsandsrc/review/review-memory-wire.tsis covered (confirmed via preciselcov.infocross-referencing against the exact diff hunks: zero uncovered lines, zero zero-hit branch sides).npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderatelistReviewSuppressionscalls), a regression test (a fresh write between two renders is reflected immediately, not masked by a stale cache), plus TTL-expiry and per-repo-isolation tests — all empirically verified to fail against a deliberately-broken implementation (never-caches; invalidation no-op) and pass against the real one.Safety
UI Evidencesection below. (N/A — backend-only change, no visible UI.)