feat(ui): add confidence-calibration card to the analytics dashboard - #4720
feat(ui): add confidence-calibration card to the analytics dashboard#4720claytonlin1110 wants to merge 1 commit into
Conversation
Closes JSONbored#2192 Adds CalibrationCard: predicted slop-severity band vs. realized merge rate per bucket, plus the recommendation-outcome split, wired into app.analytics.tsx via a new fleet-wide calibration field on the operator-dashboard payload (buildFleetOutcomeCalibration). JSONbored#2192 cites src/review/ops.ts's Calibration/computeCalibration as the data source, but that module is ported-but-unwired "reviewbot" code: nothing in this repo constructs its OpsAgentConfig, its handlers are registered on no route, and its own review_targets/review_audit tables are never populated here (see ops-wire.ts's header comment). This mirrors the live native equivalent instead — buildSlopOutcomeCalibration / buildRecommendationOutcomeCalibration in src/services/outcome- calibration.ts, already used by the per-repo outcome-calibration route and the ops-observability cron — via a new thin fleet-wide loader that reuses those same pure, already-tested builders (no new SQL).
|
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 #4720 +/- ##
=======================================
Coverage 94.14% 94.15%
=======================================
Files 437 437
Lines 38561 38565 +4
Branches 14058 14058
=======================================
+ Hits 36304 36309 +5
Misses 1599 1599
+ Partials 658 657 -1
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-10 20:29:42 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy. 🟩 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.
|
|
Gittensory detected this pull request has been converted to draft 2 times — repeatedly cycling between ready and draft to solicit review feedback without a real one-shot attempt is not allowed. Please open a new pull request with the issues addressed. |
Summary
CalibrationCardto the analytics dashboard (/app/analytics): predicted slop-severity band vs. realized merge rate per bucket (a genuine confidence-calibration curve), plus the recommendation-outcome split and a headline "is this actually predictive?" verdict.src/review/ops.ts'sCalibration/computeCalibration(lines 61/250) as "the existing computed payload." I traced that all the way through before implementing and found it's ported-but-unwired "reviewbot" code from a prior convergence (3c4a30b0 Convergence: reviewbot → gittensory): nothing anywhere in this repo constructs itsOpsAgentConfig, itshandleInternalCalibration/handleInternalDecisionhandlers are registered on no route, and its ownreview_targets/review_audittables are never populated in gittensory —src/review/ops-wire.ts's own header comment says so explicitly ("ADAPTED TO GITTENSORY'S OWN OUTCOME DATA — NOT reviewbot'sreview_targets/review_audit(those tables are not populated here)"). Building a card against it would mean either fabricating a fakeslug/config or shipping a card that can never show real data.src/services/outcome-calibration.ts'sbuildSlopOutcomeCalibration/buildRecommendationOutcomeCalibration— already used by the real, maintainer-authenticatedGET /v1/repos/:owner/:repo/outcome-calibrationroute and theops-wire.tsobservability cron. This PR mirrors that instead: same "bins" concept (per-slop-band merge rate, the deterministic predicted-risk signal gittensory actually computes), same "is it predictive" verdict (discriminates), just fleet-wide instead of per-repo.buildFleetOutcomeCalibrationinsrc/services/outcome-calibration.ts— a thin new async loader that feedslistAllPullRequests/listAgentRecommendationOutcomes(both pre-existing bulk-read helpers) into the same purebuildSlopOutcomeCalibration/buildRecommendationOutcomeCalibration/buildOutcomeCalibrationSignalsfunctions the per-repo route already uses and already tests. Wired intooperator-dashboard.ts'sOperatorDashboardPayloadexactly like PR feat(ui): add gate-precision analytics card (#2191) #4314 wiredgateEvalfor the sibling gate-precision card (feat(ui): gate-precision analytics card (precision + confusion matrix) #2191).Stat("Calibration signal": Predictive / Not discriminating / Insufficient data) +BoundaryBadge boundary="private-api", since a literal numeric floor doesn't exist in the real signal — the verdict + boundary marker is the equivalent "is this trustworthy, and is it private-scoped" signal the issue asks for.GatePrecisionCard's established convention on this same page.gateEvalandcycleTimecards (not aftercycleTime) deliberately: PR feat(ui): reversal-rate + auto-action health card #4702 (still open, sibling issue feat(ui): reversal-rate + auto-action health card #2193) is sitting on the "after cycleTime" insertion point in this same file, so this avoids a guaranteed line-level collision with it.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 (full unsharded run; new backend code —src/services/outcome-calibration.ts'sbuildFleetOutcomeCalibrationand itsoperator-dashboard.tswiring — issrc/**, so it IS Codecov-patch-gated, unlike my prior UI-only PRs this session. Added 2 newbuildFleetOutcomeCalibrationtests (populated fleet data across multiple repos, and a fully-empty fail-safe case) plus anoperator-dashboard.test.tsassertion for the newcalibrationfield's fail-safe empty shape. Scoped--coveragerun on just these two files showed 100%/100% lines onoutcome-calibration.tsand confirmed zero of my added lines were uncovered on either file — the only flagged gaps were pre-existing lines I never touched.)npm run test:workersnpm run build:mcpnpm run db:migrations:checknpm run db:schema-drift:checknpm run ui:openapi:checknpm run ui:openapi:settings-paritynpm run ui:version-auditnpm run docs:drift-checknpm run manifest:drift-checknpm run command-reference:checknpm run ui:lintnpm run ui:typechecknpm run ui:test(149/149 passed across both UI workspaces)npm run ui:buildnpm audit --audit-level=moderate(0 vulnerabilities)If any required check was skipped, explain why:
npm run test:mcp-packandnpm run cf-typegen:checkfail locally only due to a pre-existing Windows dev-machinespawnSyncbare-command resolution gap (ENOENTfornpm/wranglerwithoutshell: true) — unrelated to this diff.npm run engine-parity:drift-checkfails locally only because it falls back to my local (stale) forkorigin/mainref absentGITHUB_BASE_SHA, which real CI sets. Nosrc/signals/**/packages/gittensory-engine/**files are touched by this PR.Safety
gateEval/cycleTimesiblings — no schema regen needed.)calibrationfield; the "no signal yet" state is a genuinetotalResolved === 0early return, not a demo placeholder.UI Evidencesection below with JPG/JPEG or PNG screenshots.UI Evidence
predictive verdict, merge rate descending clean→high
insufficient-data verdict, 3 bands shown as "no data"
Notes
GatePrecisionCard's identical convention on this same page.src/services/operator-dashboard.ts, a file PR feat(ui): reversal-rate + auto-action health card #4702 (open, sibling issue feat(ui): reversal-rate + auto-action health card #2193) is also mid-flight on modifying, though at a different insertion point chosen specifically to avoid overlap. If feat(ui): reversal-rate + auto-action health card #4702 merges first, this branch may still need a follow-up rebase.