feat(review): add per-contributor gate-decision history table - #4152
Conversation
Adds contributor_gate_history (migration 0126), populated from the same call sites as recordNativeGateDecision, as the data substrate a future personalized gate-prediction confidence adjustment would read. Keyed by login rather than an HMAC hash (unlike review_audit's cross-instance export path, this table never leaves the instance and is never rendered publicly) and never wired into the fleet telemetry export. Write-only in this PR -- no confidence-adjustment logic reads it yet. That consumption, and the safety-critical invariant that a personalization adjustment must never bypass a hard blocker, are deliberate follow-up work.
|
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 #4152 +/- ##
=======================================
Coverage 93.72% 93.72%
=======================================
Files 385 386 +1
Lines 36243 36257 +14
Branches 13281 13285 +4
=======================================
+ Hits 33968 33982 +14
Misses 1618 1618
Partials 657 657
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-08 08:16:50 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
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
packages/gittensory-engine/src/predicted-gate.ts'sbuildPredictedGateVerdict, no.gittensory.ymlknob. The consumption logic is explicit follow-up work, deliberately deferred: the issue's own framing flags the confidence-adjustment function as safety/trust-weighting-sensitive (a personalization adjustment must never be able to flip a hard blocker off), which deserves its own focused review rather than being bundled with schema work.contributor_gate_history(migration0126), a new local-only table populated from the exact same two call sites asrecordNativeGateDecision(src/queue/processors.ts), structurally a sibling ofreview_audit(migration0049) but keyed by GitHub login.review_auditis deliberately actor-login-free — its own migration comment states this explicitly, because it feedsexportOrbBatch's anonymized cross-instance telemetry export (src/selfhost/orb-collector.ts).contributor_gate_historyis a separate, local-only table specifically soreview_audit's "no actor logins" guarantee for that export path doesn't have to change.review_audit's cross-instance concern, this table never leaves the instance and is never rendered on any public surface. This mirrors the existing precedentcontributor_evidence/contributor_scoring_profiles(migration0004) already establish for per-login local-only data; hashing would only add a lookup-key translation step with no privacy benefit for this access pattern.src/review/contributor-calibration.tscarries an explicit design-note comment: this table (and anything derived from it) must never be rendered on any public surface, and must never be wired intoexportOrbBatchor any other cross-instance export path.Scope
CONTRIBUTING.md.Validation
git diff --checknpm run typechecknpm run db:migrations:check(129 migrations, contiguous through 0126) /npm run db:schema-drift:check(addedcontributor_gate_historytoRAW_SQL_ONLY_TABLESinscripts/check-schema-drift.mjs, matchingreview_audit's own raw-SQL-only precedent — this table is written via directenv.DB.prepare(...)SQL mirroringrecordNativeGateDecision's exact pattern, not a Drizzle query builder).npx vitest run test/unit/contributor-calibration.test.ts— 9/9 new tests passing (self-hosted-always-records, same-commit upsert-replaces, new-commit-gets-own-row, per-login isolation, missing/null/blank-login no-op, null-head_sha still records, cloud-worker flag-off/flag-on gating mirroringrecordNativeGateDecision's own contract, and a fail-safe D1-write-error test). Scoped coverage onsrc/review/contributor-calibration.ts: 100% statements/branches/functions/lines.npx vitest run test/unit/queue.test.ts test/unit/parity-wire.test.ts— 746/746 passing (no regressions in the two call sites' surrounding logic).src/queue/processors.ts(fullqueue.test.tsrun) confirms every new/changed line hit. One branch —if (contributorDecision !== null)at the second call site — is marked/* v8 ignore else */with an inline comment explaining why:gateEvaluation.conclusioncan only be"skipped"(the one valuenativeGateActionFromConclusionmaps tonull) whengateEvaluationitself isundefined, which is already excluded by the enclosingif (gateEvaluation)— neitherevaluateGateCheck/evaluateGateCheckCorenorevaluateWithSurfaceLaneever construct a"skipped"conclusion object, confirmed by reading both. The null-check itself is kept (not asserted away) for robustness against a future caller that does produce one, mirroringrecordNativeGateDecision's own defensive null-check one line above it.npm run test:workers,build:mcp,test:mcp-pack,ui:openapi:check,ui:lint,ui:typecheck,ui:build,npm audit— not re-run locally (no worker/MCP/OpenAPI/UI-component code touched); CI runs them authoritatively.Safety
contributor-calibration.ts).contributor_gate_historyyet).Notes
.gittensory.ymlgate knob (e.g.gate.personalizedCalibration) gating whether the adjustment applies at all.src/queue/processors.ts(upstream added a newgetSubmitterReputationimport on the same line range) — resolved by keeping both additions, no logic conflict.