feat(review): wire the copycat containment engine into the gate - #5999
Conversation
Implements the deterministic containment/similarity engine gate.copycat.mode was parsed for since JSONbored#4140 but never acted on. Scores a PR's added lines against a bounded, precision-first candidate set of earlier open siblings and recently-merged PRs on the same repo, resolving copy direction by submission timestamp so the original author is never flagged. warn surfaces an advisory finding; label also applies a label without blocking review; block also closes the PR and feeds the existing moderation-rules strikes ledger. Closes JSONbored#1969
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-15 06:34:11 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 5 non-blocking
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 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 LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Summary
gate.copycat.mode(off/warn/label/block, already parsed end-to-end since feat(review): add gate.copycat.mode config scaffold for copycat detection #4140 but previously inert with zero call sites) now actually drives behavior —warnsurfaces an advisory finding,labelalso applies a label without blocking review,blockalso closes the PR and counts toward astrikesescalation that reuses the existing generic moderation-rules violation ledger (auto-bans/blacklists a repeat offender at the configured threshold, same machinery as blacklist/contributor_cap/review_nag).Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #123) — a linked open issue is required for every contributor PR.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally;codecov/patchrequires ≥99% coverage of the lines AND branches you changed (aim for 100% on your diff so CI variance does not fail near the threshold). Global coverage is a non-blocking trend with a loose 90% backstop, not the gate.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=moderateRan the full local gate via
npm run test:ci(all of the above in one command) — green — plusnpm audit --audit-level=moderate(0 vulnerabilities). ~90 new tests across 13 test files (engine primitive: 100% branch coverage; candidate-set builder: 100% branch coverage incl. fail-safe paths; gate/actuation wiring: 16 dedicated tests; a full webhook-simulation integration test proving the score persists end-to-end against a real earlier sibling PR).Safety
copycatGateMode/copycatGateMinScorealready existed from feat(review): add gate.copycat.mode config scaffold for copycat detection #4140.UI Evidencesection below with JPG/JPEG or PNG screenshots. N/A — docs-page prose only, no visual/layout change..loopover.yml.example,config/examples/loopover.full.yml, and the twodocs.*.tsxpages to remove the now-stale "currently inert" language; did not touchCHANGELOG.md.If any required check was skipped, explain why:
Notes
review-diff.ts's existingdiffFilePriorityclassification), and the containment math itself uses the correct multiset denominator (the exact bug flagged — and since fixed in this PR's own reference implementation — on the prior closed attempt at this issue, feat(signals): add deterministic copycat containment engine for gate.copycat (#1969) #5129).gate.copycat.mode/gate.copycat.minScoreremain config-as-code only (no new DB column), consistent with the existing feat(review): add gate.copycat.mode config scaffold for copycat detection #4140 scaffold's design — this PR adds two NEWpull_requestscolumns (copycat_score,copycat_matched_pull_number) purely to persist the computed assessment for the later actuation pass to read back, mirroringslop_risk/slop_band's exact precedent.Closes #1969