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
6 changes: 3 additions & 3 deletions src/scoring/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,13 +732,13 @@
if (blockedBy.length === 0) return `Currently scoreable at ${core.scoreEstimate.estimatedMergedScore}; underlying potential ${core.scoreEstimate.pendingSaturationScore}.`;
return `Effective score ${core.scoreEstimate.estimatedMergedScore}; underlying potential ${core.scoreEstimate.pendingSaturationScore}; blocked or reduced by ${blockedBy.map((blocker) => blocker.code).join(", ")}.`;
}

Check notice on line 735 in src/scoring/preview.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.
function selectLabelMultiplier(labels: string[], multipliers: Record<string, number>, fallback: number): number {
const normalized = new Set(labels.map((label) => label.toLowerCase()));
return Math.max(
fallback || 1,
...Object.entries(multipliers).flatMap(([label, multiplier]) => (normalized.has(label.toLowerCase()) ? [multiplier] : [])),
const matched = Object.entries(multipliers).flatMap(([label, multiplier]) =>
normalized.has(label.toLowerCase()) ? [multiplier] : [],
);
return matched.length > 0 ? Math.max(...matched) : fallback || 1;
}

function decideLinkedIssueMultiplier(
Expand Down
12 changes: 8 additions & 4 deletions src/services/score-breakdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,22 +135,26 @@
leverageScore: reviewPenaltyMultiplier >= 0.99 ? 8 : 60,
};
}

Check notice on line 138 in src/services/score-breakdown.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.
function labelMultiplierBreakdown(preview: ScorePreviewResult): ScoreMultiplierBreakdown {
const { labelMultiplier } = preview.scoreEstimate;
const band = labelMultiplier > 1 ? "full" : "neutral";
const band: ScoreMultiplierBand = labelMultiplier > 1 ? "full" : labelMultiplier < 1 ? "reduced" : "neutral";
return {
component: "labelMultiplier",
band,
summary:
labelMultiplier > 1
? "A configured trusted label multiplier is applied."
: "No trusted label multiplier is applied beyond the default.",
: labelMultiplier < 1
? "A configured penalty label multiplier is reducing the preview."
: "No trusted label multiplier is applied beyond the default.",
lever:
labelMultiplier > 1
? "Ensure the label match is legitimate and documented for maintainers."
: "Check whether the change legitimately matches a configured trusted label before submission.",
leverageScore: labelMultiplier > 1 ? 12 : 25,
: labelMultiplier < 1
? "Confirm the penalty label is accurate; substantive changes may warrant a different label."
: "Check whether the change legitimately matches a configured trusted label before submission.",
leverageScore: labelMultiplier > 1 ? 12 : labelMultiplier < 1 ? 40 : 25,
};
}

Expand Down
27 changes: 27 additions & 0 deletions test/unit/score-breakdown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,36 @@
expect(breakdown.components.find((entry) => entry.component === "issueMultiplier")).toMatchObject({ band: "neutral" });
expect(breakdown.components.find((entry) => entry.component === "openPrMultiplier")).toMatchObject({ band: "full" });
expect(breakdown.components.find((entry) => entry.component === "credibilityMultiplier")).toMatchObject({ band: "full" });
expect(breakdown.components.find((entry) => entry.component === "reviewPenaltyMultiplier")).toMatchObject({ band: "full" });

Check notice on line 165 in test/unit/score-breakdown.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.
});

it("marks penalty label multipliers as reduced strength (#994)", () => {
const penaltyRepo: RepositoryRecord = {
...repo,
registryConfig: { ...repo.registryConfig!, labelMultipliers: { refactor: 0.5, bug: 1.2 } },
};
const preview = buildScorePreview({
repo: penaltyRepo,
snapshot,
input: {
repoFullName: penaltyRepo.fullName,
sourceTokenScore: 80,
totalTokenScore: 120,
sourceLines: 60,
openPrCount: 0,
credibility: 1,
labels: ["refactor"],
linkedIssueMode: "none",
},
});

const breakdown = explainScoreBreakdown(preview);
expect(breakdown.components.find((entry) => entry.component === "labelMultiplier")).toMatchObject({
band: "reduced",
summary: expect.stringMatching(/penalty label multiplier/i),
});
});

it("explains failed base-token and invalid linked-issue branches", () => {
const preview = buildScorePreview({
repo,
Expand Down
32 changes: 32 additions & 0 deletions test/unit/scoring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,41 @@
},
});

expect(preview.scoreEstimate.labelMultiplier).toBe(1);

Check notice on line 371 in test/unit/scoring.test.ts

View check run for this annotation

Deleted GitHub App / Gittensory Context

Issue discovery is disabled for this repo

This repo is configured for direct contribution review rather than issue-discovery flow.
});

it("applies penalty label multipliers instead of flooring them to 1 (#994)", () => {
const baseInput: ScorePreviewInput = {
repoFullName: repo.fullName,
sourceTokenScore: 60,
totalTokenScore: 90,
sourceLines: 50,
openPrCount: 0,
credibility: 1,
linkedIssueMode: "none",
};
const penaltyOnly = buildScorePreview({ repo, snapshot, input: { ...baseInput, labels: ["refactor"] } });
const unmatched = buildScorePreview({ repo, snapshot, input: { ...baseInput, labels: ["unmatched"] } });
const bonusAndPenalty = buildScorePreview({ repo, snapshot, input: { ...baseInput, labels: ["bug", "refactor"] } });
const bonusOnly = buildScorePreview({ repo, snapshot, input: { ...baseInput, labels: ["bug"] } });
const customFallback = buildScorePreview({
repo: { ...repo, registryConfig: { ...repo.registryConfig!, defaultLabelMultiplier: 1.05, labelMultipliers: { bug: 1.2 } } },
snapshot,
input: { ...baseInput, labels: ["unmatched"] },
});

expect(penaltyOnly.scoreEstimate.labelMultiplier).toBe(0.5);
expect(unmatched.scoreEstimate.labelMultiplier).toBe(1);
expect(bonusAndPenalty.scoreEstimate.labelMultiplier).toBe(1.2);
expect(bonusOnly.scoreEstimate.labelMultiplier).toBe(1.2);
expect(customFallback.scoreEstimate.labelMultiplier).toBe(1.05);
expect(penaltyOnly.scoreEstimate.estimatedMergedScore).toBeLessThan(bonusOnly.scoreEstimate.estimatedMergedScore);
expect(penaltyOnly.scoreEstimate.estimatedMergedScore).toBeCloseTo(
bonusOnly.scoreEstimate.estimatedMergedScore * (0.5 / 1.2),
5,
);
});

it("gates linked-issue assumptions with branch eligibility evidence", () => {
const baseInput = {
repoFullName: repo.fullName,
Expand Down
Loading