/** * Session 64 — BACKTEST HARNESS. * * The harness is the validator every future metric family is gated on. Its * FIRST proven property is not the math — it is the REFUSAL. A harness that * emits a confident number on 4 rows is worse than no harness, because it * launders noise into a claim. These tests are written first, deliberately. */ const h = require('../../src/services/backtestHarness'); const row = (o = {}) => ({ sport: 'mlb', model_version: 'engine1@2026-07-20', grade: 'B', grade_11: 'B-', p_win: 0.6, outcome: 'hit', quarantine_reason: null, snap_quarantine: null, features: { l5_avg: 1.2 }, ...o, }); describe('THE REFUSAL — sample-size honesty is the first property', () => { test('a tiny sample reports INSUFFICIENT, never a point estimate', () => { const rows = [row(), row({ outcome: 'miss' }), row()]; const out = h.runBacktest(rows, { minSample: 20 }); const b = out.grade_buckets.find((x) => x.bucket === 'B'); expect(b.status).toBe('INSUFFICIENT'); expect(b.n).toBe(3); expect(b.need).toBe(20); expect(b.hit_rate).toBeNull(); // no number, at all }); test('the top-line verdict itself refuses on thin data', () => { const out = h.runBacktest([row(), row()], { minSample: 20 }); expect(out.verdict).toBe('INSUFFICIENT_HISTORY'); expect(out.can_validate).toBe(false); }); test('an INSUFFICIENT bucket carries no rate anywhere in its payload', () => { const out = h.runBacktest([row()], { minSample: 20 }); const json = JSON.stringify(out.grade_buckets); expect(json).not.toMatch(/"hit_rate":\s*[0-9]/); }); test('at/above threshold it DOES report a rate with an interval', () => { const rows = Array.from({ length: 25 }, (_, i) => row({ outcome: i < 15 ? 'hit' : 'miss' })); const out = h.runBacktest(rows, { minSample: 20 }); const b = out.grade_buckets.find((x) => x.bucket === 'B'); expect(b.status).toBe('OK'); expect(b.hit_rate).toBeCloseTo(0.6, 2); expect(b.ci_low).toBeLessThan(0.6); expect(b.ci_high).toBeGreaterThan(0.6); }); }); describe('DENOMINATOR — the excluded states', () => { test('quarantined, void, unrecoverable, pending and push never count', () => { const rows = [ row({ outcome: 'hit' }), row({ outcome: 'miss' }), row({ outcome: 'void' }), row({ outcome: 'unrecoverable' }), row({ outcome: null }), row({ outcome: 'push' }), row({ outcome: 'hit', quarantine_reason: 'wrong_opponent_grade' }), row({ outcome: 'hit', snap_quarantine: 'wrong_opponent_grade' }), ]; const out = h.runBacktest(rows, { minSample: 1 }); expect(out.counts.scored).toBe(2); // only the real hit + miss expect(out.counts.excluded_quarantine).toBe(2); expect(out.counts.excluded_terminal).toBe(2); expect(out.counts.excluded_pending).toBe(1); expect(out.counts.excluded_push).toBe(1); }); }); describe('NEVER MIX sports or model versions', () => { test('buckets are split per sport and per version', () => { const rows = [ ...Array.from({ length: 21 }, () => row({ sport: 'mlb' })), ...Array.from({ length: 21 }, () => row({ sport: 'wnba' })), ...Array.from({ length: 21 }, () => row({ model_version: 'engine2@x' })), ]; const out = h.runBacktest(rows, { minSample: 20 }); const keys = out.strata.map((s) => `${s.sport}|${s.model_version}`); expect(new Set(keys).size).toBe(3); }); }); describe('MONOTONICITY — and refusing to rank overlapping buckets', () => { test('reports overlapping intervals as not distinguishable, not as a ranking', () => { const mk = (grade, hits, n) => Array.from({ length: n }, (_, i) => row({ grade, outcome: i < hits ? 'hit' : 'miss' })); // A: 13/25 (52%), B: 14/25 (56%) — intervals overlap heavily. const out = h.runBacktest([...mk('A', 13, 25), ...mk('B', 14, 25)], { minSample: 20 }); const cmp = out.monotonicity.comparisons.find((c) => c.pair === 'A>B' || c.pair === 'B>A'); expect(cmp.distinguishable).toBe(false); expect(out.monotonicity.verdict).toMatch(/NOT_DISTINGUISHABLE|INSUFFICIENT/); }); }); describe('PROBABILITY calibration', () => { test('a thin sample reports INSUFFICIENT and NO Brier score', () => { const rows = [row({ p_win: 0.8 }), row({ p_win: 0.2, outcome: 'miss' })]; const out = h.runBacktest(rows, { minSample: 20 }); expect(out.probability.status).toBe('INSUFFICIENT'); expect(out.probability.brier).toBeNull(); }); test('Brier score is computed from p_win vs realized outcome', () => { const rows = [row({ p_win: 1, outcome: 'hit' }), row({ p_win: 0, outcome: 'miss' })]; const out = h.runBacktest(rows, { minSample: 1 }); expect(out.probability.status).toBe('OK'); expect(out.probability.brier).toBeCloseTo(0, 6); // perfect prediction }); test('rows without p_win are excluded from Brier, not defaulted to 0.5', () => { const rows = [row({ p_win: null, outcome: 'hit' }), row({ p_win: 1, outcome: 'hit' })]; const out = h.runBacktest(rows, { minSample: 1 }); expect(out.probability.n).toBe(1); }); }); describe('ALTERNATIVE-MODEL REPLAY SEAM', () => { test('identity replay reproduces the live prediction exactly', () => { const rows = [row({ p_win: 0.7 }), row({ p_win: 0.3, outcome: 'miss' })]; const res = h.replayAlternative(rows, (r) => ({ p_win: r.p_win }), { minSample: 1 }); expect(res.identical).toBe(true); expect(res.candidate.brier).toBeCloseTo(res.live.brier, 9); }); test('a row whose needed input was never retained is UN-BACKTESTABLE, not guessed', () => { const rows = [row({ features: {} })]; const res = h.replayAlternative(rows, (r) => ( r.features && r.features.opp_rank_stat != null ? { p_win: 0.9 } : { unavailable: 'opp_rank_stat_not_retained' } ), { minSample: 1 }); expect(res.un_backtestable).toBe(1); expect(res.candidate.n).toBe(0); }); test('the seam never refetches — it only sees the stored feature vector', () => { let sawOnlyStored = true; h.replayAlternative([row()], (r) => { if (Object.keys(r).some((k) => /fetch|client|http/i.test(k))) sawOnlyStored = false; return { p_win: 0.5 }; }, { minSample: 1 }); expect(sawOnlyStored).toBe(true); }); });