fix(stats): drop counterfactual-replay rows from the public per-rule precision - #9720
Conversation
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-29 06:39:50 UTC
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
📋 Copy for AI agents — paste into your coding agentDecision drivers
Context & advisory signals — never blocks the verdict
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://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Decision record
🟩 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.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
loopover-ui | 1a79901 | Jul 29 2026, 04:55 AM |
Bundle ReportBundle size has no change ✅ |
09576f2 to
a86c91e
Compare
a86c91e to
1a79901
Compare
|
Merge-order note: this PR and #9675 both edit Verified: all four open branches (#9675, #9718, #9720, #9721) merge cleanly into |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9720 +/- ##
==========================================
- Coverage 90.27% 89.45% -0.82%
==========================================
Files 904 904
Lines 113177 113179 +2
Branches 26840 26840
==========================================
- Hits 102171 101249 -922
- Misses 9676 10842 +1166
+ Partials 1330 1088 -242
Flags with carried forward coverage won't be shown. Click here to find out more.
|
…precision The public "Measured accuracy per rule" table published `ai_consensus_defect` and `slop_gate_score` with byte-identical decided=460 / confirmed=287 / precision=62.4%. That is not a coincidence: `slop_gate_score`'s override rows are the same label set, copied. #8277's slop backfill re-scores the deterministic slop signals over archived diffs but takes each label verbatim from the `ai_consensus_defect` corpus's human verdict on the same target (`manifestToSourceCases` in backfill-slop-corpus.ts passes `backtestCase.label` straight through). That is exactly what it was built to be — internal evidence for a flip-to-live decision, and by its own module header a LOWER BOUND on live scoring — but the public table describes itself as "precision of each automated rule over its human-decided cases", and those were another rule's human-decided cases. Corroborating that the rows cannot be live: `slop_gate_score` is in GATE_SCORE_SIGNAL_CODES, which `recordImplicitTerminalConfirmations` excludes, and `recordConfiguredGateBlockerOverrides` only ever writes `reversed` — so on the live path the rule has no route to a `confirmed` verdict at all. A 62.4% could only ever have come from replayed rows. Excluded by provenance rather than by rule id, so the next cross-rule replay inherits the same protection. `review_targets_decision_level` (#8083's own backfill) is deliberately NOT excluded: its labels come from what happened to the PRs that rule actually fired on, so they do support a precision claim for it. Refs #9676
1a79901 to
bb5835b
Compare
Summary
The public "Measured accuracy per rule" table published
ai_consensus_defectandslop_gate_scorewith byte-identicaldecided: 460, confirmed: 287, precision: 62.4%. Not a coincidence —slop_gate_score's override rows are the same label set, copied.#8277's slop backfill re-scores the deterministic slop signals over archived diffs, but takes each label verbatim from the
ai_consensus_defectcorpus's human verdict on the same target:manifestToSourceCases(scripts/backfill-slop-corpus.ts:51-58) passesbacktestCase.labelstraight through, andreplaySlopCorpuswrites it unchanged into the new rule'sverdict(scripts/backfill-slop-corpus-core.ts:133-134,165). Only the score side is recomputed.That is exactly what it was built to be — internal evidence for a flip-to-live decision, and by its own module header "a LOWER BOUND on what live scoring would have produced". But the public table describes itself as "Precision of each automated rule over its human-decided cases in the last 90 days", and those were another rule's human-decided cases. It also made the table print one number twice, since both rules then shared a label set and a target set.
Corroborating that the published rows cannot be live measurements:
slop_gate_scoreis inGATE_SCORE_SIGNAL_CODES(src/rules/advisory.ts:207), whichrecordImplicitTerminalConfirmationsexplicitly excludes (src/review/outcomes-wire.ts:654), andrecordConfiguredGateBlockerOverridesonly ever writesreversed. On the live path that rule has no route to aconfirmedverdict at all, so a 62.4% could only ever have come from replayed rows.Excluded by provenance, not by rule id, so the next cross-rule replay inherits the same protection.
review_targets_decision_level(#8083's own backfill) is deliberately not excluded — its labels come from what actually happened to the PRs that rule fired on, so they do support a precision claim for it, and there is a test pinning that distinction.Refs #9676
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=moderateIf any required check was skipped, explain why:
vitest run --coverageoverpublic-rule-precision.test.tsrestricted to the changed module reports 100% statements / branches / functions / lines (19/19, 10/10, 6/6, 17/17). Both sides of the new exclusion are pinned — a cross-rule replay row is dropped, a same-rule synthesized row is kept.public-stats,public-stats-route,public-eval-scores-route): 59 tests green.ui:lint/ui:typecheck/ui:buildwere not run.ui:openapi:checkpasses — response shape is unchanged, only which rows qualify.test:workers,build:mcp,test:mcp-packuntouched by this diff; left to CI.Safety
UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.No auth/CORS/session change. No UI file is touched — the fairness page already renders whatever rows the block returns, so this removes a row rather than changing a component; that is why there is no UI Evidence table here. The existing
INVARIANT: the public payload never carries target keys, repos, confidences, or private termstest still passes.Notes
On the current production data every
slop_gate_scorerow carries this provenance, so that rule drops out of the public table entirely andai_consensus_defectremains at 460 / 287 / 62.4%. That is the honest outcome: one rule with a real (if synthesized-from-its-own-history) measurement, instead of two rules appearing to independently corroborate each other while sharing one label set.