feat(review): add suppression-signal data model + memory matcher - #3841
Conversation
#2181) Adds the review-memory feature: a deterministic finding-fingerprint + suppression matcher that lets a maintainer-dismissed false positive stay suppressed on later re-reviews of the same repo, gated behind review.memory (default off, advisory only).
… gaps pruneReviewSuppressionsOverCap's OFFSET-only query is a syntax error on this driver (a bare OFFSET with no preceding LIMIT), so eviction silently failed on every insert -- the per-repo cap only appeared to hold because listReviewSuppressions clamps its own read-side limit to the same constant. Switches to an in-JS slice over the bounded row set instead of relying on SQL-level OFFSET, and strengthens the existing cap test to assert the underlying row count directly rather than through the limit-clamped read path.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | 9df0b54 | Commit Preview URL Branch Preview URL |
Jul 06 2026, 02:31 PM |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3841 +/- ##
==========================================
+ Coverage 93.41% 93.42% +0.01%
==========================================
Files 326 328 +2
Lines 32855 32934 +79
Branches 12035 12053 +18
==========================================
+ Hits 30691 30770 +79
Misses 1530 1530
Partials 634 634
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-06 14:50:31 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
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
review.memory(operator env kill-switch AND per-repo manifest opt-in, both default off, advisory-only by construction -- only ever applied tocommentGate.warnings, neverblockers).migrations/0114_review_suppression_memory.sql+src/db/schema.ts: newreview_suppressiontable (repo, category, path glob, pattern hash, created-by, timestamps) with a per-repo row cap.src/review/review-memory-match.ts: deterministic fingerprint (reviewMemoryFingerprint) + the suppress/demote/none matcher (matchSuppressions) -- exact hash match suppresses, same-category-different-hash demotes (kept but moved to the end so an existingmax_findingscap truncates it first), no match passes through untouched.src/review/review-memory-wire.ts: activation wiring (isReviewMemoryEnabled,shouldApplyReviewMemory) mirroring the existingimpact-map-wire.tspattern, plus the pureapplyReviewMemorySuppressionapply-to-findings function.src/queue/processors.ts: wires the suppression read + apply into the unified-comment render path, fail-safe (a store-read error leaves the original gate untouched rather than throwing) and zero-cost when the flag is off (no extra D1 read).src/signals/focus-manifest.ts+.gittensory.yml.example/config/examples/gittensory.full.yml: newreview.memoryconfig-as-code knob, documented in both required locations.pruneReviewSuppressionsOverCap's per-repo cap-eviction query used a bare SQLOFFSETwith no precedingLIMIT, which is a syntax error on this driver -- eviction silently failed on every single insert (swallowed by its own best-effort.catch). The cap only appeared to hold in the original test becauselistReviewSuppressionsindependently clamps its own read-sidelimitparameter to the same constant, masking the fact that the underlying table was never actually trimmed. Fixed by fetching the bounded row set and slicing the overflow off in JS instead of relying on SQL-levelOFFSET(Drizzle's D1 dialect silently drops a.limit(-1)"unbounded" hint from the emitted SQL, so that workaround doesn't work either). Strengthened the existing cap-enforcement test to assert the raw table row count directly, so this can't regress silently again.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally -- 100% branch coverage on every changed line in this diff (verified via targeted lcov branch inspection against the exact diff ranges).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=moderateSafety
UI Evidencesection. (N/A -- backend-only change, no UI.)Notes