Skip to content

fix(review): make submitter-reputation burst/AI-spend defense install-wide for confirmed miners#4546

Merged
JSONbored merged 9 commits into
mainfrom
feat/reputation-install-wide-miner
Jul 10, 2026
Merged

fix(review): make submitter-reputation burst/AI-spend defense install-wide for confirmed miners#4546
JSONbored merged 9 commits into
mainfrom
feat/reputation-install-wide-miner

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • getSubmitterReputation's burst/low-sample thresholds are scoped WHERE project = ? AND submitter = ? — a single repo. A fleet identity spreading a handful of gate-passing-but-low-value PRs across dozens of repos in one self-hosted install never accumulates enough same-repo sample density to read as "burst" or "low" anywhere, so the reputation defense never fires for it and every submission burns full paid AI-review spend indefinitely.
  • New getSubmitterReputationAcrossInstall (submitter-reputation.ts): identical quality-weighted signal derivation, scoped by review_targets.installation_id (already existed, migrations/0050) instead of project. New migration adds the supporting index.
  • New getEffectiveSubmitterReputation (reputation-wire.ts): the per-repo signal, additionally widened to the install-wide view for a CONFIRMED official Gittensor miner — only when the per-repo signal alone doesn't already justify caution, so an ordinary contributor or an already-flagged submitter pays no extra lookup.
  • Extracted the miner-identity check (shared with fix(review): velocity-aware exception in the unlinked-issue-match escalation for machine-cadence (miner) authors #4512's velocity exception) into src/gittensor/miner-detection-cache.ts so both this module and unlinked-issue-guardrail.ts can use it without a circular import through processors.ts.
  • Wired into both real call sites: shouldSkipAiForReputation (the main AI-spend gate) and the vision-review reputation check.
  • The all-time submitter_stats display aggregate (the /stats view) is deliberately NOT widened — only the SIGNAL (which actually gates AI spend) is; that table has no installation_id column and isn't security-relevant.

Test plan

  • test/unit/miner-detection-cache.test.ts (new) — confirmed/not-found/unavailable, cache-hit, cache-read/write-failure paths
  • test/unit/submitter-reputation.test.ts — 6 new tests for getSubmitterReputationAcrossInstall
  • test/unit/reputation-wiring.test.ts — 7 new tests for getEffectiveSubmitterReputation: widens for a confirmed miner with a real cross-repo pattern, does NOT widen for an unconfirmed submitter with the identical pattern, skips the identity lookup entirely when the per-repo signal already justifies downgrading, and fails safe on no-submitter / no-installationId / repository-lookup-throws / cross-repo-signal-also-neutral
  • 99%+ statement/branch, 100% line coverage across all 3 touched/new source files
  • npx tsc --noEmit clean

Fixes #4513

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.09%. Comparing base (6646b87) to head (7a749dd).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4546   +/-   ##
=======================================
  Coverage   94.09%   94.09%           
=======================================
  Files         430      431    +1     
  Lines       38215    38242   +27     
  Branches    13931    13940    +9     
=======================================
+ Hits        35958    35985   +27     
  Misses       1600     1600           
  Partials      657      657           
Files with missing lines Coverage Δ
src/gittensor/miner-detection-cache.ts 100.00% <100.00%> (ø)
src/queue/processors.ts 95.31% <100.00%> (ø)
src/review/reputation-wire.ts 100.00% <100.00%> (ø)
src/review/submitter-reputation.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@gittensory-orb gittensory-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier. label Jul 10, 2026
@gittensory-orb

gittensory-orb Bot commented Jul 10, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-10 07:44:45 UTC

10 files · 1 AI reviewer · no blockers · readiness 100/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review: This PR changes guardrail-protected path(s): src/queue/processors.ts (matched src/queue/**).

Review summary
This PR extends the per-repo submitter-reputation burst/low-sample signal to an install-wide view for submitters confirmed as official Gittensor miners, closing a real gap where a fleet identity spread across many repos in one install never accumulates same-repo sample density. The core logic in getEffectiveSubmitterReputation correctly short-circuits (no extra DB/API call) when the per-repo signal already justifies downgrading, and falls back safely to the per-repo result on any miner-lookup, repo-lookup, or install-wide-query failure — all paths are exercised by the new tests, including the neutral-vs-neutral fallback case. The new migration is a pure `CREATE INDEX IF NOT EXISTS` (D1-safe, no temp/pragma/transaction issues) supporting the new installation_id-scoped query, and both real call sites (shouldSkipAiForReputation, runVisualVisionForAdvisory) are correctly rewired.

Nits — 7 non-blocking
  • src/queue/processors.ts's import line changes from `import { getSubmitterReputation, type SubmissionOutcome } from "../review/submitter-reputation"` to a type-only import — worth double-checking no other call site in that ~8360-line file still references `getSubmitterReputation` directly, since the diff doesn't show the rest of the file and an unresolved reference there wouldn't show up in this diff.
  • migrations/0131_review_targets_installation_submitter_idx.sql — confirm 0131 is actually the next contiguous migration number in the repo (not verifiable from the diff alone).
  • reputation-wire.ts:61 getEffectiveSubmitterReputation does `args.submitter?.trim()` but getSubmitterReputation itself is called with `args.submitter ?? undefined` (no trim) — a submitter value with only whitespace difference could theoretically diverge between the per-repo and install-wide lookups, though this is a corner case with low real-world impact.
  • The verbose multi-paragraph JSDoc comments on the new exports are longer than typical for this change size; consider trimming to the essential fail-safe/scoping facts once the PR is reviewed and the rationale is captured in the linked issue instead.
  • Consider extracting a small constant/comment block explaining why `getSubmitterReputationAcrossInstall` deliberately zeroes out submissions/merged/closed/manual (signal-only) so future readers don't try to 'fix' it into a full aggregate.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ✅ Linked #4513
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 48 registered-repo PR(s), 40 merged, 334 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 48 PR(s), 334 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Linked issue satisfaction

Addressed
The PR adds an install-wide, installation_id-scoped reputation aggregate (getSubmitterReputationAcrossInstall) gated on a confirmed-miner check via a new shared miner-detection-cache module, wires it into both real call sites (shouldSkipAiForReputation and vision review), adds a supporting index/migration, and includes fleet-spread-across-repos tests alongside unchanged-behavior tests for non-mine

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 48 PR(s), 334 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 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.

  • Re-run Gittensory review

@JSONbored JSONbored force-pushed the feat/reputation-install-wide-miner branch from 9f9172f to b014d39 Compare July 10, 2026 00:52
@JSONbored

Copy link
Copy Markdown
Owner Author

Renumbered the migration 0130 → 0131 and rebased onto main — #4538 merged migrations/0130_grounding_file_content_cache.sql in the meantime, which collided with this PR's original 0130 filename.

@gittensory-orb gittensory-orb Bot added the manual-review Gittensor contributor context label Jul 10, 2026
@JSONbored JSONbored force-pushed the feat/reputation-install-wide-miner branch 4 times, most recently from 662bf6d to d597b22 Compare July 10, 2026 05:08
JSONbored added 7 commits July 9, 2026 22:42
…-wide for confirmed miners

getSubmitterReputation's burst/low-sample thresholds are scoped
WHERE project = ? AND submitter = ? -- a single repo. A fleet
identity spreading a handful of gate-passing-but-low-value PRs
across dozens of repos in one self-hosted install never accumulates
enough same-repo sample density to read as "burst" or "low"
anywhere, so the reputation defense never fires for it and every one
of its submissions burns full paid AI-review spend indefinitely.

- New getSubmitterReputationAcrossInstall in submitter-reputation.ts:
  the identical quality-weighted signal derivation, scoped by
  review_targets.installation_id instead of project (that column
  already existed, migrations/0050; this adds the supporting index).
- New getEffectiveSubmitterReputation in reputation-wire.ts: the
  per-repo signal, additionally widened to the install-wide view for
  a CONFIRMED official Gittensor miner -- but only when the per-repo
  signal alone doesn't already justify caution, so an ordinary
  contributor or an already-flagged submitter pays no extra lookup.
- Extracted the miner-identity check (shared with #4512) into
  src/gittensor/miner-detection-cache.ts so both this module and
  unlinked-issue-guardrail.ts can use it without a circular import
  through processors.ts.
- Wired into both call sites: shouldSkipAiForReputation (the main
  AI-spend gate) and the vision-review reputation check.

Fixes #4513
…ty check in visual-vision tests

runVisualVisionForAdvisory now resolves reputation via getEffectiveSubmitterReputation
(#4513), which checks confirmed-official-miner identity (a fetch to
api.gittensor.io/miners) whenever the submitter's per-repo signal is
neutral -- a real, intentional behavior change this test file's existing
"no network calls at all" assertions didn't account for. Stub that one
identity check to resolve cleanly and assert precisely that no OTHER
(BYOK/vision-spend) network call happens, rather than asserting zero fetch
calls outright.
… PRs)

origin/main has since merged #4545 (0131_screenshot_table_gate_matrix.sql)
and #4554 (0132_impact_map_query_cache.sql, itself a collision fix); rebase
onto current main and take the next free number.
…4556)

Rebase onto current main and take the next free number now that
migrations/0133_screenshot_table_gate_skill_link.sql (from #4556) occupies
the number this branch previously took.
…ay collision on main)

main currently has three DIFFERENT already-merged files at 0134
(#4549/#4558/#4563) -- tracked separately as its own fix (PR #4577, not yet
merged). Since that fix already claims through 0138, take 0139 here to
avoid colliding with it once it lands; this branch's own
db:migrations:check will stay red until #4577 merges (unrelated to this
branch's own changes), and will need one more rebase afterward.
getEffectiveSubmitterReputation's getRepository().catch() needed a real
read-failure test (added); its isConfirmedOfficialMiner().catch() is
unreachable (that function already catches every internal failure point
itself) and getSubmitterReputationAcrossInstall's results ?? [] fallback is
the same "D1 always populates results" case already v8-ignored elsewhere in
this codebase -- both marked accordingly.
# Conflicts:
#	src/queue/processors.ts
…oss-test miner-cache pollution

Several earlier tests in this file cache "contributor" as a confirmed official
Gittensor miner (5-min TTL) in the shared per-file D1 instance. That collided
with #4513's new install-wide reputation widening, which correctly detects the
stale cache and adds a 4th reputation-scan D1 read for a submitter this test
never intended to be a miner. Use a submitter login unique to this test instead.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 10, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui 7a749dd Commit Preview URL

Branch Preview URL
Jul 10 2026, 07:37 AM

@JSONbored JSONbored merged commit 53bd82b into main Jul 10, 2026
13 checks passed
@JSONbored JSONbored deleted the feat/reputation-install-wide-miner branch July 10, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.5x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

fix(review): make submitter-reputation burst/AI-spend defense install-wide (or confirmed-miner-aware) using the existing official_miner_detections cache

1 participant