Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions src/services/score-breakdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export type ScoreBreakdownExplanation = {
highestLeverageLever: {
component: string;
lever: string;
/** Other components that tie with the selected top component at the same leverageScore
* (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;
};
};
Expand Down Expand Up @@ -361,15 +366,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),
};
}
Expand Down
51 changes: 51 additions & 0 deletions test/unit/score-breakdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,4 +677,55 @@ 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", () => {
// 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: 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).toEqual([]);
expect(top.reason).not.toMatch(/ties with/);
});
});
Loading