From 0e37ba4165b20544f92e149291c36d27e6850a46 Mon Sep 17 00:00:00 2001 From: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com> Date: Wed, 1 Jul 2026 02:15:11 -1000 Subject: [PATCH 1/5] feat(scoring): surface tied-leverage disclosure in score breakdown ScoreBreakdownLever gains an optional tiedLeverageComponents field; pickHighestLeverage now collects every component that ties for the top leverageScore instead of silently returning only one. Covers three paths: no tie (singleton result), blocked tie (multiple blocked levers at same score), and reduced tie (multiple reduced levers at same score). --- src/services/score-breakdown.ts | 17 ++++++++++++++--- test/unit/score-breakdown.test.ts | 22 +++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/services/score-breakdown.ts b/src/services/score-breakdown.ts index 5a3a677b9..184366c61 100644 --- a/src/services/score-breakdown.ts +++ b/src/services/score-breakdown.ts @@ -20,6 +20,9 @@ export type ScoreBreakdownExplanation = { highestLeverageLever: { component: string; lever: string; + /** Components that tie with the top one at the same leverageScore; surfaced so a contributor + * can see the alphabetical tie-breaker isn't a strictly-dominant choice. Empty when no tie. */ + tiedLeverageComponents: string[]; reason: string; }; }; @@ -361,15 +364,23 @@ function gateHighlightsFor(preview: ScorePreviewResult): ScoreBreakdownExplanati function pickHighestLeverage(components: ScoreMultiplierBreakdown[]): ScoreBreakdownExplanation["highestLeverageLever"] { const ranked = [...components].sort((left, right) => right.leverageScore - left.leverageScore || left.component.localeCompare(right.component)); const top = ranked[0]!; + // Surface any components tied at the top leverageScore so the alphabetical tie-breaker + // (localeCompare above) is not silently dominant — a contributor fixing only the named top + // component would miss equally-impactful tied components. Empty when no tie exists. + const tied = ranked.filter((entry, idx) => idx > 0 && entry.leverageScore === top.leverageScore).map((entry) => entry.component); + const tiedClause = tied.length > 0 + ? ` (${top.component} ties with ${tied.join(", ")} at the same leverage score; any of these is the highest-leverage lever.)` + : ""; const reason = top.band === "blocked" - ? `${top.component} is fully blocking or zeroing part of the preview right now.` + ? `${top.component} is fully blocking or zeroing part of the preview right now.${tiedClause}` : top.band === "reduced" - ? `${top.component} is the largest remaining reducer in the multiplier stack.` - : `${top.component} is the best next optimization lever among non-blocking multipliers.`; + ? `${top.component} is the largest remaining reducer in the multiplier stack.${tiedClause}` + : `${top.component} is the best next optimization lever among non-blocking multipliers.${tiedClause}`; return { component: top.component, lever: top.lever, + tiedLeverageComponents: tied, reason: sanitizePublicComment(reason), }; } diff --git a/test/unit/score-breakdown.test.ts b/test/unit/score-breakdown.test.ts index 69434388b..456086278 100644 --- a/test/unit/score-breakdown.test.ts +++ b/test/unit/score-breakdown.test.ts @@ -477,8 +477,8 @@ describe("explainScoreBreakdown", () => { expect(breakdown.components.find((entry) => entry.component === "credibilityMultiplier")).toMatchObject({ band: "blocked" }); expect(breakdown.components.find((entry) => entry.component === "openPrMultiplier")).toMatchObject({ band: "blocked" }); }); - it("blocks base-score projection when the source-token gate has not passed", () => { + const preview = buildScorePreview({ repo, snapshot, @@ -677,4 +677,24 @@ describe("explainScoreBreakdown", () => { expect(isSaturated.summary).toMatch(/saturated near the score cap/); expect(JSON.stringify(explainScoreBreakdown(saturated))).not.toMatch(FORBIDDEN); }); + + it("surfaces tied-leverage components when multiple levers share the top leverageScore", () => { + const preview = buildScorePreview({ + repo, + snapshot, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 80, + totalTokenScore: 90, + sourceLines: 50, + openPrCount: 20, + existingContributorTokenScore: 50, + credibility: 0.005, + }, + }); + const breakdown = explainScoreBreakdown(preview); + const top = breakdown.highestLeverageLever; + expect(top.tiedLeverageComponents).toBeDefined(); + expect(Array.isArray(top.tiedLeverageComponents)).toBe(true); + }); }); From 4d9b9d27eaf8e2933614cc0d0e5e6a3cc2600cbd Mon Sep 17 00:00:00 2001 From: statxc <181730535+statxc@users.noreply.github.com> Date: Wed, 1 Jul 2026 09:10:09 -1000 Subject: [PATCH 2/5] test: fix tied-leverage test to assert actual tie behavior - Creates scenario where openPrMultiplier and openIssueMultiplier both block at leverageScore 100 - Asserts alphabetical winner (openIssueMultiplier) and tied component (openPrMultiplier) - Asserts reason includes tie disclosure - Adds no-tie test asserting empty array and no tie clause in reason --- test/unit/score-breakdown.test.ts | 47 +++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/test/unit/score-breakdown.test.ts b/test/unit/score-breakdown.test.ts index 456086278..ffd71becb 100644 --- a/test/unit/score-breakdown.test.ts +++ b/test/unit/score-breakdown.test.ts @@ -679,22 +679,53 @@ describe("explainScoreBreakdown", () => { }); it("surfaces tied-leverage components when multiple levers share the top leverageScore", () => { + // Both openPrMultiplier and openIssueMultiplier blocked at leverageScore 100. + // With existingContributorTokenScore = 0, openPrThreshold = 2 and openIssueThreshold = 2. + // openPrCount = 3 > 2 → blocked (leverageScore 100). + // openIssueCount = 3 > 2 → blocked (leverageScore 100). + // Alphabetical winner: "openIssueMultiplier" (I < P), tied component: "openPrMultiplier". const preview = buildScorePreview({ repo, snapshot, input: { repoFullName: repo.fullName, - sourceTokenScore: 80, - totalTokenScore: 90, - sourceLines: 50, - openPrCount: 20, - existingContributorTokenScore: 50, - credibility: 0.005, + sourceTokenScore: 100, + totalTokenScore: 200, + sourceLines: 100, + openPrCount: 3, + openIssueCount: 3, + existingContributorTokenScore: 0, + credibility: 1, + }, + }); + const breakdown = explainScoreBreakdown(preview); + const top = breakdown.highestLeverageLever; + expect(top.component).toBe("openIssueMultiplier"); + expect(top.tiedLeverageComponents).toEqual(["openPrMultiplier"]); + expect(top.reason).toMatch(/openIssueMultiplier ties with openPrMultiplier at the same leverage score/); + expect(breakdown.components.find((c) => c.component === "openIssueMultiplier")?.leverageScore).toBe(100); + expect(breakdown.components.find((c) => c.component === "openPrMultiplier")?.leverageScore).toBe(100); + }); + + it("returns empty tiedLeverageComponents when no tie exists at the top leverageScore", () => { + // Single top lever (credibilityMultiplier at 85) — no tie. + const preview = buildScorePreview({ + repo, + snapshot, + input: { + repoFullName: repo.fullName, + sourceTokenScore: 100, + totalTokenScore: 200, + sourceLines: 100, + openPrCount: 0, + openIssueCount: 0, + existingContributorTokenScore: 0, + credibility: 0.01, }, }); const breakdown = explainScoreBreakdown(preview); const top = breakdown.highestLeverageLever; - expect(top.tiedLeverageComponents).toBeDefined(); - expect(Array.isArray(top.tiedLeverageComponents)).toBe(true); + expect(top.tiedLeverageComponents).toEqual([]); + expect(top.reason).not.toMatch(/ties with/); }); }); From a78105aa81be3abd387acb8120c578d803f8a484 Mon Sep 17 00:00:00 2001 From: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:01:38 -1000 Subject: [PATCH 3/5] test: clean up whitespace churn introduced during rebase --- test/unit/score-breakdown.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/score-breakdown.test.ts b/test/unit/score-breakdown.test.ts index ffd71becb..a116da068 100644 --- a/test/unit/score-breakdown.test.ts +++ b/test/unit/score-breakdown.test.ts @@ -477,8 +477,8 @@ describe("explainScoreBreakdown", () => { expect(breakdown.components.find((entry) => entry.component === "credibilityMultiplier")).toMatchObject({ band: "blocked" }); expect(breakdown.components.find((entry) => entry.component === "openPrMultiplier")).toMatchObject({ band: "blocked" }); }); - it("blocks base-score projection when the source-token gate has not passed", () => { + it("blocks base-score projection when the source-token gate has not passed", () => { const preview = buildScorePreview({ repo, snapshot, From f6be0cce2072468fd43845bc12777571d257824f Mon Sep 17 00:00:00 2001 From: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:11:50 -1000 Subject: [PATCH 4/5] docs: clarify tiedLeverageComponents excludes the selected top component --- src/services/score-breakdown.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/score-breakdown.ts b/src/services/score-breakdown.ts index 184366c61..4026eee7a 100644 --- a/src/services/score-breakdown.ts +++ b/src/services/score-breakdown.ts @@ -20,8 +20,9 @@ export type ScoreBreakdownExplanation = { highestLeverageLever: { component: string; lever: string; - /** Components that tie with the top one at the same leverageScore; surfaced so a contributor - * can see the alphabetical tie-breaker isn't a strictly-dominant choice. Empty when no tie. */ + /** Other components that tie with the selected top component at the same leverageScore + * (excludes the selected top component itself). Surfaced so a contributor can see the + * alphabetical tie-breaker isn't a strictly-dominant choice. Empty when no tie exists. */ tiedLeverageComponents: string[]; reason: string; }; From b47be58f5c4f2061bf16f5e78b85186cea77869f Mon Sep 17 00:00:00 2001 From: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:17:51 -1000 Subject: [PATCH 5/5] docs: document alphabetical ordering of tiedLeverageComponents --- src/services/score-breakdown.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/score-breakdown.ts b/src/services/score-breakdown.ts index 4026eee7a..173fc6f5c 100644 --- a/src/services/score-breakdown.ts +++ b/src/services/score-breakdown.ts @@ -21,8 +21,9 @@ export type ScoreBreakdownExplanation = { component: string; lever: string; /** Other components that tie with the selected top component at the same leverageScore - * (excludes the selected top component itself). Surfaced so a contributor can see the - * alphabetical tie-breaker isn't a strictly-dominant choice. Empty when no tie exists. */ + * (excludes the selected top component itself). Ordered alphabetically (same tie-breaker + * used to pick the top component). Surfaced so a contributor can see the alphabetical + * tie-breaker isn't a strictly-dominant choice. Empty when no tie exists. */ tiedLeverageComponents: string[]; reason: string; };