From bdc3644e9fe4a0cfba83a587a460b6149220e5a0 Mon Sep 17 00:00:00 2001 From: ghost <49853598+JSONbored@users.noreply.github.com> Date: Wed, 8 Jul 2026 00:23:20 -0700 Subject: [PATCH] fix(review): avoid review effort boundary undercounts --- src/review/review-effort.ts | 5 +++-- test/unit/review-effort.test.ts | 7 +++++++ test/unit/stats.test.ts | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/review/review-effort.ts b/src/review/review-effort.ts index 8c2a1b3a94..64ab8b2dbd 100644 --- a/src/review/review-effort.ts +++ b/src/review/review-effort.ts @@ -46,9 +46,10 @@ function bandForEffort(effort: number): 1 | 2 | 3 | 4 | 5 { return 5; } -/** Map a persisted minutes estimate back to its complexity band (inverse of `estimateReviewEffort`'s minutes step). */ +/** Map a persisted rounded minutes estimate to the highest complexity band it could represent. */ export function bandFromMinutes(minutes: number): 1 | 2 | 3 | 4 | 5 { - return bandForEffort(Math.max(0, minutes) / MINUTES_PER_EFFORT); + const maxRepresentedEffort = (Math.max(0, minutes) + 0.5) / MINUTES_PER_EFFORT; + return bandForEffort(maxRepresentedEffort); } /** Estimate the review effort of a change set. Pure and deterministic. */ diff --git a/test/unit/review-effort.test.ts b/test/unit/review-effort.test.ts index 8f336435e9..cc686cb530 100644 --- a/test/unit/review-effort.test.ts +++ b/test/unit/review-effort.test.ts @@ -69,4 +69,11 @@ describe("bandFromMinutes (#2155)", () => { expect(bandFromMinutes(sample.minutes)).toBe(sample.band); } }); + + it("keeps rounded boundary minutes in the higher possible band (regression for #2155)", () => { + expect(bandFromMinutes(5)).toBe(2); + expect(bandFromMinutes(20)).toBe(3); + expect(bandFromMinutes(60)).toBe(4); + expect(bandFromMinutes(150)).toBe(5); + }); }); diff --git a/test/unit/stats.test.ts b/test/unit/stats.test.ts index 30b1a70f7a..20460576ee 100644 --- a/test/unit/stats.test.ts +++ b/test/unit/stats.test.ts @@ -152,6 +152,10 @@ describe("aggregateReviewEffort — maintainer complexity fold (#2155)", () => { // minutes 4 -> band 1; minutes 96 -> band 4 -> rounded avg 3; total 100. expect(aggregateReviewEffort([4, 96])).toEqual({ avgBand: 3, totalEstimatedMinutes: 100 }); }); + + it("keeps boundary-rounded minutes in the higher possible avgBand (regression for #2155)", () => { + expect(aggregateReviewEffort([5, 20, 60, 150])).toEqual({ avgBand: 4, totalEstimatedMinutes: 235 }); + }); }); describe("computeStats — review-effort read is fail-safe", () => {