Skip to content

feat(review): add per-contributor gate-decision history table - #4152

Merged
JSONbored merged 1 commit into
mainfrom
feat/personalized-calibration-ledger-2349
Jul 8, 2026
Merged

feat(review): add per-contributor gate-decision history table#4152
JSONbored merged 1 commit into
mainfrom
feat/personalized-calibration-ledger-2349

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • PR 1 of a multi-PR epic for maintainer: personalized gate-prediction tuning per contributor/miner history #2349 (personalized gate-prediction tuning per contributor/miner history). This PR is scoped strictly to the data-collection substrate — no confidence-adjustment logic, no wiring into packages/gittensory-engine/src/predicted-gate.ts's buildPredictedGateVerdict, no .gittensory.yml knob. 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.
  • Adds contributor_gate_history (migration 0126), a new local-only table populated from the exact same two call sites as recordNativeGateDecision (src/queue/processors.ts), structurally a sibling of review_audit (migration 0049) but keyed by GitHub login.
  • review_audit is deliberately actor-login-free — its own migration comment states this explicitly, because it feeds exportOrbBatch's anonymized cross-instance telemetry export (src/selfhost/orb-collector.ts). contributor_gate_history is a separate, local-only table specifically so review_audit's "no actor logins" guarantee for that export path doesn't have to change.
  • Login (not an HMAC hash) is the key — deliberately. Unlike review_audit's cross-instance concern, this table never leaves the instance and is never rendered on any public surface. This mirrors the existing precedent contributor_evidence/contributor_scoring_profiles (migration 0004) 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.ts carries 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 into exportOrbBatch or any other cross-instance export path.

Scope

Validation

  • git diff --check
  • npm run typecheck
  • npm run db:migrations:check (129 migrations, contiguous through 0126) / npm run db:schema-drift:check (added contributor_gate_history to RAW_SQL_ONLY_TABLES in scripts/check-schema-drift.mjs, matching review_audit's own raw-SQL-only precedent — this table is written via direct env.DB.prepare(...) SQL mirroring recordNativeGateDecision'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 mirroring recordNativeGateDecision's own contract, and a fail-safe D1-write-error test). Scoped coverage on src/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).
  • Scoped coverage on src/queue/processors.ts (full queue.test.ts run) 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.conclusion can only be "skipped" (the one value nativeGateActionFromConclusion maps to null) when gateEvaluation itself is undefined, which is already excluded by the enclosing if (gateEvaluation) — neither evaluateGateCheck/evaluateGateCheckCore nor evaluateWithSurfaceLane ever 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, mirroring recordNativeGateDecision'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

  • No secrets, wallet/hotkey/trust-score/reward data anywhere. GitHub logins are public information tied to public PRs — the privacy concern this design addresses is never rendering an aggregate per-actor accuracy figure publicly, not the raw login itself (see the design-note comment in contributor-calibration.ts).
  • No auth/cookie/CORS/session changes.
  • No new decision-making logic — this PR cannot change any gate outcome (write-only; nothing reads contributor_gate_history yet).
  • No UI changes — no UI Evidence section needed.
  • No docs/changelog changes needed.

Notes

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-security

Copy link
Copy Markdown
Contributor

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

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 8, 2026
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.72%. Comparing base (97f087b) to head (28f7eec).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

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           
Files with missing lines Coverage Δ
src/queue/processors.ts 95.22% <100.00%> (+<0.01%) ⬆️
src/review/contributor-calibration.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.

@loopover-orb

loopover-orb Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Warning

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

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-08 08:16:50 UTC

5 files · 1 AI reviewer · 2 blockers · readiness 93/100 · CI green · clean

⏸️ Suggested Action - Manual Review

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.

Review summary
This adds a write-only `contributor_gate_history` table (migration 0126) and a `recordContributorGateDecision` helper wired into the same two `processors.ts` call sites that already feed `recordNativeGateDecision`, gated identically (self-hosted-always / cloud-flag-gated) so there's no new on/off knob to keep in sync. The design deliberately keeps this separate from `review_audit` to preserve that table's actor-login-free export guarantee, and correctly registers the new table in `RAW_SQL_ONLY_TABLES` so `check-schema-drift` doesn't flag it as an undeclared drizzle table. Migration is D1-remote-safe (no CREATE TEMP/ATTACH/PRAGMA/transaction control), the dedup id scheme (`login:source:project:pr@​sha`) matches the described per-commit-replace semantics, and tests exercise the write, replace-on-same-commit, per-login/per-commit separation, missing-login no-op, null head_sha, both gating states, and the swallowed-write-failure path.

Nits — 5 non-blocking
  • src/queue/processors.ts's second call site marks the `contributorDecision !== null` branch with `/* v8 ignore else */` and a comment asserting it's currently unreachable — that's an honest disclosure rather than a hidden dead branch, but worth double-checking `nativeGateActionFromConclusion`'s actual conclusion set at merge time so this doesn't silently rot into a real gap if a new conclusion is added later.
  • Migration 0126 isn't shown alongside the rest of migrations/ in this diff — worth confirming 0126 is in fact the next contiguous number (no gap/duplicate) against the current HEAD of migrations/.
  • contributor-calibration.ts:52/66 repeats the `200`-char project-name truncation without a named constant; a shared constant (or reuse of whatever `review_audit`'s writer uses, if any) would keep the two tables' truncation behavior visibly in sync.
  • Since this table is explicitly described as the future input to a safety-sensitive confidence adjustment, consider adding a short comment at the call sites in processors.ts (not just in contributor-calibration.ts) pointing back to the design-note, so a future editor touching the gate-finalization block sees the constraint before adding a reader.
  • The PR description's 'never rendered on any public surface' guarantee currently rests entirely on convention/comments — consider whether a lightweight assertion or lint rule (mirroring how src/signals/redaction.ts is enforced elsewhere) is worth a follow-up issue so this isn't purely honor-system.

Concerns raised — review before merging

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.
Signal Result Evidence
Code review ❌ 2 blockers 1 reviewer
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
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 (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 52 registered-repo PR(s), 43 merged, 496 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 52 PR(s), 496 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
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: Python, TypeScript, JavaScript, Ruby, Go, Kotlin, MDX, Shell
  • Official Gittensor activity: 52 PR(s), 496 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
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

@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 8, 2026
@JSONbored
JSONbored merged commit 3a3f67c into main Jul 8, 2026
11 checks passed
@JSONbored
JSONbored deleted the feat/personalized-calibration-ledger-2349 branch July 8, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

1 participant