diff --git a/src/lib/analytics/score/__tests__/config-delta-guard.test.ts b/src/lib/analytics/score/__tests__/config-delta-guard.test.ts index 4eff8ddfc..c9609b154 100644 --- a/src/lib/analytics/score/__tests__/config-delta-guard.test.ts +++ b/src/lib/analytics/score/__tests__/config-delta-guard.test.ts @@ -403,11 +403,23 @@ describe("the seam", () => { }); it("treats a day that names no recipe as a break rather than a link", () => { - const points = scoreSeriesSeams([ - day("2026-08-19", null), - day("2026-08-20", 1), - ]); - expect(points[1].seamBreak).toBe(true); + // Both directions, including two unknowns in a row. Without the + // second case the arm would be doing nothing that plain inequality + // does not already do: `null !== 1` breaks on its own, while + // `null !== null` would quietly claim two rows share a basis that + // neither of them names. + expect( + scoreSeriesSeams([day("2026-08-19", null), day("2026-08-20", 1)])[1] + .seamBreak, + ).toBe(true); + expect( + scoreSeriesSeams([day("2026-08-19", 1), day("2026-08-20", null)])[1] + .seamBreak, + ).toBe(true); + expect( + scoreSeriesSeams([day("2026-08-19", null), day("2026-08-20", null)])[1] + .seamBreak, + ).toBe(true); }); it("breaks the composite line and never rejoins it", () => { diff --git a/src/lib/analytics/score/composite.ts b/src/lib/analytics/score/composite.ts index dd2b61cda..3522d8d47 100644 --- a/src/lib/analytics/score/composite.ts +++ b/src/lib/analytics/score/composite.ts @@ -235,17 +235,19 @@ function comparableDynamicPillars( * * No date means nothing to compare, and that does not suppress: * refusing every delta forever over an unreadable timestamp would trade - * one silent lie for a permanent silence. + * one silent lie for a permanent silence. Both cases — an account that + * never chose, and a stored date this build cannot read — parse to NaN, + * and every comparison against NaN is false, so the refusal falls out + * of the arithmetic. Two early returns stood here and neither could + * change an answer, which makes them a comment wearing an `if`. */ export function crossesConfigBoundary( boundary: ScoreConfigBoundary, previousAt: Date, asOf: Date, ): boolean { - if (boundary.changedAt === null) return false; - const changedAt = new Date(boundary.changedAt); - if (Number.isNaN(changedAt.getTime())) return false; - return asOf >= changedAt && previousAt < changedAt; + const changedAt = Date.parse(boundary.changedAt ?? ""); + return asOf.getTime() >= changedAt && previousAt.getTime() < changedAt; } /**