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
9 changes: 8 additions & 1 deletion packages/loopover-engine/src/phase7-calibration-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,14 @@ function normalizeCompositeWeights(config: Phase7CalibrationConfig): { historica
};
const total = raw.historicalReplay + raw.prOutcome;
if (total <= 0) {
return { historicalReplay: DEFAULT_CONFIG.historicalReplayWeight, prOutcome: DEFAULT_CONFIG.prOutcomeWeight };
// #8644: PRESERVE an explicit all-zero weighting instead of silently substituting the defaults. This
// branch is reachable ONLY when both weights were explicitly 0 -- `finiteNonNegative` floors any invalid
// input to a positive default, which cannot sum to 0 -- so a 0 total is a deliberate "disable composite
// weighting" signal from the operator, not a degraded input. Returning {0,0} leaves weightTotal 0
// downstream, which the combinedAccuracy guard already renders as a null composite (the same state reached
// when no source contributes), matching the "preserve explicit zero" principle the sibling calibration
// composers follow -- rather than overriding the operator's intent back to a 50/50 default.
return { historicalReplay: 0, prOutcome: 0 };
}
return {
historicalReplay: raw.historicalReplay / total,
Expand Down
18 changes: 18 additions & 0 deletions packages/loopover-engine/test/phase7-calibration-loop.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,21 @@ test("REGRESSION (#3014): combined metric stays anchored to the documented 62% b
assert.equal(result.combinedAccuracy, 0.62);
assert.equal(result.deltaFromBaseline, 0);
});

test("normalizeCompositeWeights preserves an explicit all-zero weighting rather than silently defaulting (#8644)", () => {
const config = enabledConfig({ historicalReplayWeight: 0, prOutcomeWeight: 0 });
assert.equal(config.historicalReplayWeight, 0);
assert.equal(config.prOutcomeWeight, 0);

const result = computePhase7CalibrationLoop({
config,
prOutcome: sufficientPrOutcome(0.75),
historicalReplay: healthyReplay(0.82),
now: NOW,
});

// Preserved, not reverted to the 50/50 default; {0,0} yields no composite (null), matching the
// "preserve explicit zero" principle rather than overriding the operator's intent.
assert.deepEqual(result.weights, { historicalReplay: 0, prOutcome: 0 });
assert.equal(result.combinedAccuracy, null);
});
33 changes: 33 additions & 0 deletions test/unit/phase7-calibration-loop-weights.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, expect, it } from "vitest";

import { computePhase7CalibrationLoop, resolvePhase7CalibrationConfig } from "../../packages/loopover-engine/src/index";

// #8644: root-vitest mirror so `normalizeCompositeWeights`'s explicit-all-zero branch in
// phase7-calibration-loop.ts is Codecov-measured. The package-native node:test suite
// (packages/loopover-engine/test/) runs under the engine workspace, not this root run that Codecov grades --
// same reasoning as #8438's signal-tracking root mirror. Imports the engine SOURCE (src/index) so coverage
// attributes to the .ts rather than the built dist.
describe("phase7 composite weights — explicit all-zero is preserved (#8644)", () => {
it("preserves both weights as 0 instead of silently reverting to the 50/50 default", () => {
const config = resolvePhase7CalibrationConfig({
miner: { calibration: { phase7LoopEnabled: true, historicalReplayWeight: 0, prOutcomeWeight: 0 } },
});
// Precondition: an explicit 0 is stored as 0, not defaulted — otherwise the branch under test is unreachable.
expect(config.historicalReplayWeight).toBe(0);
expect(config.prOutcomeWeight).toBe(0);

const result = computePhase7CalibrationLoop({ config });
expect(result.weights).toEqual({ historicalReplay: 0, prOutcome: 0 });
// {0,0} leaves no composite weighting, so combinedAccuracy is null — the same state reached when no
// source contributes, not a silently-defaulted weighted average.
expect(result.combinedAccuracy).toBeNull();
});

it("still normalizes a normal positive config to sum 1 (the unchanged happy path, both branches covered)", () => {
const config = resolvePhase7CalibrationConfig({
miner: { calibration: { phase7LoopEnabled: true, historicalReplayWeight: 3, prOutcomeWeight: 1 } },
});
const result = computePhase7CalibrationLoop({ config });
expect(result.weights).toEqual({ historicalReplay: 0.75, prOutcome: 0.25 });
});
});