feat(scoring): surface the issue-discovery validity floor in the score breakdown#1982
Conversation
…e breakdown explainScoreBreakdown explained every other scoring multiplier on scoreEstimate (density, contribution bonus, label, issue, credibility, review-penalty, review-collateral, open-PR pressure, open-issue spam, the merged-PR history floor added in JSONbored#1801, and the time-decay floor added in JSONbored#1877), but silently omitted the issueDiscoveryHistoryMultiplier that mirrors the upstream MIN_VALID_SOLVED_ISSUES + MIN_ISSUE_CREDIBILITY issue-discovery validity gate (see entrius/gittensor gittensor/constants.py + src/scoring/preview.ts:410). Add a `issueDiscoveryHistoryBreakdown` sibling of mergedHistoryBreakdown, reviewCollateralBreakdown, and timeDecayBreakdown that: - returns neutral + lane-off copy when linkedIssueMode is "none" (the issue-discovery lane is not engaged and the multiplier is 1 by intent), - returns neutral + per-dimension copy that explicitly names the still- missing dimension (the partial-evidence case) — addresses the "neutral-branch collapses two dimensions into one phrase" nit that closed the previous attempt at this surface, - returns full + the concrete observed numbers when both floors are met, - returns blocked + named causes when either validSolvedIssues or issueCredibility falls below the upstream floors (each cause named specifically so the contributor can act on the failing dimension). Purely additive explanation projection; no scoring behavior change. Includes the new "issueDiscoveryHistoryMultiplier" name in the top-level `arrayContaining` regression test so a future removal flips a deterministic test fail (the other half of the previous attempt's nit). Wiring: - src/services/score-breakdown.ts: add `issueDiscoveryHistoryBreakdown`, insert into the components projection after `timeDecayBreakdown`. - test/unit/score-breakdown.test.ts: include the new component in the `arrayContaining` regression list and add a focused test covering the lane-off / partially-observed / meeting-floor / below-floor-on-each-side branches. Test plan: `npx vitest run test/unit/score-breakdown.test.ts --coverage --coverage.include='src/services/score-breakdown.ts'`. Observed locally: 15/15 tests pass; 100% statements; 100% lines; 1 uncovered branch in pre-existing `issueMultiplierBreakdown` (not touched by this change).
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-01 11:51:33 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 8 non-blocking
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.
|
|
Closing this voluntarily after a more careful survey uncovered that bohdansolovie already has an open competing PR for the same surface — #1984 (feat/score-breakdown-issue-discovery-history) — which targets the exact same files (src/services/score-breakdown.ts + test/unit/score-breakdown.test.ts) with the exact same scope (the issueDiscoveryHistoryBreakdown surface for scoreEstimate.issueDiscoveryHistoryMultiplier). Precedents and observations that informed this self-close:
Closing mine is the right citizen move:
Stat: this was my 11th opened PR; 10 are merged and 1 closed (#1874, also auto-maintain-routed). Closing this duplicate keeps the earlier-original rule honest and preserves the slot for the next genuinely-fresh gap. Thanks for the gate feedback on this one — the orb panel helped me realize I had missed an earlier-original attempt. The lesson is recorded in local memory: always search by intent (issue-discovery history / issueDiscoveryHistory / validity floor), not just by contributor or title, before opening a feat(scoring) PR. No review action needed — closing as duplicate-by-design, not as a quality failure of this branch. — Renzo |
|
Redirected to #2362 — same content, new PR (cannot reopen after force-push per GitHub policy). |
Summary
explainScoreBreakdown(src/services/score-breakdown.ts) explained every other scoring multiplier onscoreEstimate(density, contribution bonus, label, issue, credibility, review-penalty, review-collateral, open-PR pressure, open-issue spam, the merged-PR history floor added by #1801, and the time-decay floor added by #1877) but silently omitted theissueDiscoveryHistoryMultiplierthat mirrors the upstreamMIN_VALID_SOLVED_ISSUES + MIN_ISSUE_CREDIBILITYissue-discovery validity gate (cross-referenced againstentrius/gittensor/gittensor/constants.pyperMIN_VALID_SOLVED_ISSUES = 3andMIN_ISSUE_CREDIBILITY = 0.80; src/scoring/preview.ts:410).What this adds
A
issueDiscoveryHistoryBreakdownsibling ofmergedHistoryBreakdown,reviewCollateralBreakdown, andtimeDecayBreakdownthat covers four branches:neutrallinkedIssueMode === "none"neutralvalidSolvedIssues/issueCredibilityundefinedfullblockedNo scoring behavior change.
Size + nit audit (per recent-mass-merge restudy)
+193insertions across 2 files:src/services/score-breakdown.ts(+57) andtest/unit/score-breakdown.test.ts(+136). Borderlinesize:Lterritory; the recent mass-triage window (PRs feat(selfhost): harden Sentry event scrubbing #1907-fix(queue): bound rag path coalesce keys #1934) routinely mergedsize:LPRs without the auto-maintain pipeline.observed:vsstill missingordering.issueDiscoveryHistoryMultiplier) is included in the top-levelarrayContainingregression test from day 1.Validation
git diff --checkclean.npm run actionlintclean.npm run typecheckclean.npm run db:migrations:check—90 migrations OK — contiguous 0001..0087 (3 grandfathered duplicates: 0015, 0017, 0074).npx vitest run test/unit/score-breakdown.test.ts --coverage --coverage.include='src/services/score-breakdown.ts'— 15/15 tests pass;100% statements;100% lines; 1 uncovered branch in pre-existingissueMultiplierBreakdown(line 240), not touched by this change.Targeted output:
Scope discipline
wantedPaths(src/,test/).explainScoreBreakdown; no API route or schema is touched).CHANGELOG.mdchange.Safety
sanitizePublicCommentpipeline (which is why the test's regex now matches/still missing.*private context|partial/iand/issue (credibility|private context)/i—credibilityis redacted toprivate contextby the sanitizer in the public surface).Linked issue
No linked issue — this small additive feat is a small, self-evident repair of a gap the
feat(scoring)surface (originally #1801 and #1877) silently left. The contributor fork PAT used here does not have upstream issue-create scope, and an unlinked PR is an explicitly allowed submission pattern per the contributing guide.UI Evidence
Not applicable — backend score-breakdown projection with no visible UI, frontend, docs, or extension surface.