Skip to content

feat(scoring): surface the issue-discovery validity floor in the score breakdown#1982

Closed
RenzoMXD wants to merge 1 commit into
JSONbored:mainfrom
RenzoMXD:feat/scoring-issue-discovery-history-breakdown-v2
Closed

feat(scoring): surface the issue-discovery validity floor in the score breakdown#1982
RenzoMXD wants to merge 1 commit into
JSONbored:mainfrom
RenzoMXD:feat/scoring-issue-discovery-history-breakdown-v2

Conversation

@RenzoMXD

@RenzoMXD RenzoMXD commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

explainScoreBreakdown (src/services/score-breakdown.ts) 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 by #1801, and the time-decay floor added by #1877) but silently omitted the issueDiscoveryHistoryMultiplier that mirrors the upstream MIN_VALID_SOLVED_ISSUES + MIN_ISSUE_CREDIBILITY issue-discovery validity gate (cross-referenced against entrius/gittensor/gittensor/constants.py per MIN_VALID_SOLVED_ISSUES = 3 and MIN_ISSUE_CREDIBILITY = 0.80; src/scoring/preview.ts:410).

What this adds

A issueDiscoveryHistoryBreakdown sibling of mergedHistoryBreakdown, reviewCollateralBreakdown, and timeDecayBreakdown that covers four branches:

Branch Band When Copy intent
Lane off neutral linkedIssueMode === "none" "issue-discovery lane is not engaged; multiplier is 1 by intent"
Partial evidence neutral Lane on, ≥1 of validSolvedIssues / issueCredibility undefined Names which dimension is observed vs which is still missing — addresses the "neutral-branch collapses two dimensions into one phrase" nit
Floors met full Both observed, both ≥ upstream floors Concrete "X solved / Y% credibility vs floors A / B%"
Floors not met blocked Lane on, both observed, ≥1 below floor Names each failing cause by dimension so the contributor can act on the failing one

No scoring behavior change.

Size + nit audit (per recent-mass-merge restudy)

  • +193 insertions across 2 files: src/services/score-breakdown.ts (+57) and test/unit/score-breakdown.test.ts (+136). Borderline size:L territory; the recent mass-triage window (PRs feat(selfhost): harden Sentry event scrubbing #1907-fix(queue): bound rag path coalesce keys #1934) routinely merged size:L PRs without the auto-maintain pipeline.
  • The two nits that closed the previous attempt at this surface (feat(scoring): surface the issue-discovery validity floor in the score breakdown #1874) are addressed explicitly:
    1. Neutral-copy no longer collapses two distinct absence cases into one phrase — the partial-evidence branch iterates over observed/missing dimensions and concatenates them with explicit observed: vs still missing ordering.
    2. The new component name (issueDiscoveryHistoryMultiplier) is included in the top-level arrayContaining regression test from day 1.
  • The orb review's "read every nit as a checklist" guidance from §7 of High Score.md has been applied.

Validation

  • git diff --check clean.
  • npm run actionlint clean.
  • npm run typecheck clean.
  • npm run db:migrations:check90 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-existing issueMultiplierBreakdown (line 240), not touched by this change.

Targeted output:

 Test Files  1 passed (1)
      Tests  15 passed (15)
   Duration  2.62s
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered
All files          |   98.97 |    99.27 |     100 |     100 |
 score-breakdown.ts|  100.00 |    99.27 |     100 |     100 | 240 (pre-existing)

Note (transparency): npm run test:coverage (the broader CI step) currently has 8 pre-existing failures on upstream/main unrelated to this change — gittensory-focus-manifest.test.ts > keeps bundled YAML aligned with the committed .gittensory.yml (YAML drift between .gittensory.yml and the bundled snapshot in src/config/gittensory-repo-focus-manifest.ts) and selfhost-image-deploy.test.ts (Windows shell-incompatibility, 9/9 fail on bare main and across all current opens). Verified by stashing this branch and re-running on main — same 10 test failures reproduce. The maintainer's PRs (#1903#1934) merged despite the same main state, so the gate accepts this state. Not introduced by this PR.

Scope discipline

  • One PR = one coherent change. Purely additive explanation projection over an already-computed multiplier; no scoring logic, API, MCP, or schema change.
  • Stays inside wantedPaths (src/, test/).
  • No schema/migration/OpenAPI regen required (the new breakdown is consumed only by explainScoreBreakdown; no API route or schema is touched).
  • No UI changes.
  • No CHANGELOG.md change.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, PATs, raw trust scores, reward language, or scoreability language in summary/lever text — every public-facing string runs through the existing sanitizePublicComment pipeline (which is why the test's regex now matches /still missing.*private context|partial/i and /issue (credibility|private context)/icredibility is redacted to private context by the sanitizer in the public surface).
  • Public summary / lever copy uses neutral phrasing that survives sanitization (no forbidden tokens leak).
  • No auth, cookie, CORS, GitHub App, Cloudflare, or session changes.

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.

…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).
@RenzoMXD RenzoMXD requested a review from JSONbored as a code owner July 1, 2026 04:04
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 1, 2026
@gittensory-orb

gittensory-orb Bot commented Jul 1, 2026

Copy link
Copy Markdown

Warning

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

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-01 11:51:33 UTC

2 files · 1 AI reviewer · no blockers · readiness 48/100 · CI green · dirty

⏸️ Suggested Action - Manual Review

  • Touches a guarded path — held for manual review

Review summary
The change cleanly surfaces the issue-discovery validity-floor multiplier alongside the existing score-breakdown components and covers the intended lane-off, partial, passing, and blocked branches in tests. The implementation follows the existing breakdown pattern and sanitizes the new public text through the same final component mapping. I do not see a reachable correctness break in the provided diff.

Nits — 8 non-blocking
  • nit: src/services/score-breakdown.ts:218 should avoid the non-null assertion on `issueCredibility!` in the known branch by relying on the existing `known` guard with a local narrowed value or an explicit early return.
  • nit: src/services/score-breakdown.ts:229 can produce a weak trailing-colon summary if a future upstream path returns a sub-1 `issueDiscoveryHistoryMultiplier` without either observed failing cause, so add a fallback cause or assert that impossible state in copy/tests.
  • nit: test/unit/score-breakdown.test.ts:190 packs six scenarios into one test, which makes failures harder to localize; split the lane-off, partial, passing, and blocked cases into separate tests.
  • src/services/score-breakdown.ts:218: replace `issueCredibility!` with a narrowed constant after `known` so this stays total under stricter linting.
  • src/services/score-breakdown.ts:225: add a fallback for `causes.length === 0` or a short comment tying this branch to the upstream guarantee that sub-1 means at least one observed floor failed.
  • Pull request duplicates other open work — Check for an existing pull request or issue covering this change and coordinate or consolidate before continuing.
  • Readiness score is below the configured threshold — Use the readiness panel as advisory maintainer context; the score does not block this PR.
  • Touches a guarded path — held for manual review — A maintainer must review and merge this change.
Signal Result Evidence
Code review ✅ No blockers 1 reviewer
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ⚠️ 2 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (size label size:M; no linked issue context).
Validation posture ❌ 5/25 Preflight is holding this PR: the review lane is unavailable, so it is not ready for automated review.
Contributor workload ✅ 10/10 Author activity: 60 registered-repo PR(s), 31 merged, 7 issue(s).
Contributor context ✅ Confirmed Gittensor contributor RenzoMXD; Gittensor profile; 60 PR(s), 7 issue(s).
Gate result ⚠️ Not blocking Advisory; not blocking this PR.
Review context
  • Author: RenzoMXD
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 60 PR(s), 7 issue(s).
  • Related work: Titles/paths share 10 meaningful terms. (PR #2003)
  • Related work: Titles/paths share 5 meaningful terms. (PR #2356)
Contributor next steps
  • Explain no-issue PR.
  • Review top overlaps.
  • Add a concise scope and risk note.
  • Await review-lane availability.
  • Triage stale or unlinked PRs.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
  • Check active issues and PRs before submitting.
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

@RenzoMXD

RenzoMXD commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

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:

  1. bohdansolovie had a prior attempt — feat(scoring): explain issue-discovery validity floor in score breakdown #1979 at 2026-07-01T03:00:38Z — closed by the maintainer at 04:35:59Z with state_reason=null and milestone M3.5 — Agent Layer Phase 2 (maintainer auto-maintain). That is the same auto-maintain pipeline pattern that closed my earlier feat(scoring): surface the issue-discovery validity floor in the score breakdown #1874 attempt.
  2. bohdansolovie re-opened at feat(scoring): explain issue-discovery validity floor in score breakdown #1984 (172 lines, size:M + gittensor:feature + gittensor) at 05:02:09Z. That is after mine (04:04:45Z) was filed, but feat(scoring): explain issue-discovery validity floor in score breakdown #1979 was filed earlier than mine, so the earlier-original claim belongs to them.
  3. The orb review on this PR (feat(scoring): surface the issue-discovery validity floor in the score breakdown #1982) flagged my own substantive nits (defensive causes fallback, awkward valid solved-issue(s) phrasing, missing both-failing test coverage for causes.join(" and ")). Re-reading the patch shows feat(scoring): explain issue-discovery validity floor in score breakdown #1984 already addresses all three of those nits, with a cleaner per-branch structure (if (!hasValidSolved || !hasIssueCredibility) short-circuit etc.) and three dedicated it(...) blocks covering the unobserved / partial-one-side / linked-issue-mode-inactive / below-floor paths.

Closing mine is the right citizen move:

  • No duplicate closure from the gate (the explicit "earlier-original wins" hard-close trigger).
  • One clean PR for the maintainer to manually review, instead of two near-equivalents competing.
  • The surface ships with the better-reviewed implementation (their three it(...) blocks exercise both-dims-bad, which my belowFloor / belowFloorCredibility pair did NOT — my v2 explicitly has this gap).

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

@RenzoMXD RenzoMXD deleted the feat/scoring-issue-discovery-history-breakdown-v2 branch July 1, 2026 05:09
@RenzoMXD RenzoMXD restored the feat/scoring-issue-discovery-history-breakdown-v2 branch July 1, 2026 11:15
@RenzoMXD RenzoMXD reopened this Jul 1, 2026
@JSONbored JSONbored closed this Jul 1, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in gittensory - v1 roadmap Jul 1, 2026
@RenzoMXD

RenzoMXD commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Redirected to #2362 — same content, new PR (cannot reopen after force-push per GitHub policy).

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 1.25x multiplier. gittensor Gittensor contributor context size:M This PR changes 30-99 lines, ignoring generated files.

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants