diff --git a/packages/gittensory-engine/src/phase7-calibration-loop.ts b/packages/gittensory-engine/src/phase7-calibration-loop.ts index 35969f5ac6..bbd1eb2215 100644 --- a/packages/gittensory-engine/src/phase7-calibration-loop.ts +++ b/packages/gittensory-engine/src/phase7-calibration-loop.ts @@ -331,9 +331,11 @@ export function shouldScheduleHistoricalReplayRun(input: { function extractHistoricalReplayScore( compositeScore: number | GateVerdictCompositeCalibrationScore, -): number { - if (typeof compositeScore === "number") return roundScore(compositeScore); - return roundScore(compositeScore.compositeScore); +): number | null { + const rawScore = + typeof compositeScore === "number" ? compositeScore : compositeScore.compositeScore; + if (!Number.isFinite(rawScore)) return null; + return roundScore(rawScore); } /** @@ -423,6 +425,10 @@ export function computePhase7CalibrationLoop(input: { replayHarnessHold = true; holdReasons.push("replay_run_stale"); rejectedSources.push({ source: "historical_replay", reason: "replay_run_stale" }); + } else if (accuracy === null) { + replayHarnessHold = true; + holdReasons.push("invalid_replay_score"); + rejectedSources.push({ source: "historical_replay", reason: "invalid_replay_score" }); } else { contributingSources.push("historical_replay"); } diff --git a/packages/gittensory-engine/test/phase7-calibration-loop.test.ts b/packages/gittensory-engine/test/phase7-calibration-loop.test.ts index ad286f7779..1751e8a90d 100644 --- a/packages/gittensory-engine/test/phase7-calibration-loop.test.ts +++ b/packages/gittensory-engine/test/phase7-calibration-loop.test.ts @@ -345,6 +345,28 @@ test("computePhase7CalibrationLoop fails closed when the replay harness is degra } }); +test("REGRESSION: malformed historical replay scores fail closed instead of permitting autonomy increases", () => { + for (const compositeScore of [{} as never, Number.NaN, Number.POSITIVE_INFINITY] as const) { + const result = computePhase7CalibrationLoop({ + config: enabledConfig({ autonomyIncreaseMinAccuracy: 0.99 }), + prOutcome: sufficientPrOutcome(1), + historicalReplay: { + ...healthyReplay(0.82), + compositeScore, + }, + now: NOW, + }); + + assert.equal(result.bySource.historical_replay.accuracy, null); + assert.equal(result.combinedAccuracy, 1); + assert.equal(result.replayHarnessHold, true); + assert.equal(result.autonomyIncreasePermitted, false); + assert.ok(result.holdReasons.includes("invalid_replay_score")); + assert.ok(!result.audit.contributingSources.includes("historical_replay")); + assert.ok(result.audit.rejectedSources.some((row) => row.reason === "invalid_replay_score")); + } +}); + test("computePhase7CalibrationLoop fails closed on stale replay rather than silently using pr_outcome only", () => { const result = computePhase7CalibrationLoop({ config: enabledConfig(),