'use strict'; /** * A VALIDATOR IS NOT A REPAIR. `servable:false` must mean something mechanically. * * The previous release detected the violation correctly and then served the * certified state anyway. These tests exist so that cannot recur. */ const pc = require('../../src/services/model/probabilityContract'); const svc = require('../../src/services/model/probabilityContractService'); const registry = require('../../src/services/model/artifactRegistry'); const fp = require('../../src/services/model/fitPolicy'); const ERA = 'engine1@2026-08-07-fullwindow'; const good = registry.load('mlb', 'hits'); const read = (p) => ({ sport: 'mlb', stat: 'hits', model_version: ERA, p_win: p }); const est = () => 0.6; describe('an unservable artifact can never emit a certified state', () => { // Era and estimator mismatch resolve to VERSION_MISMATCH rather than the new // state — that is DELIBERATE. "This artifact belongs to a different // forecaster" is a more precise thing to say than "policy blocked", and the // existing state already says it exactly. The invariant asserted for all six // is the one that matters: never certified, never a number. const violations = { ERA_NOT_RESTRICTED: [{ era_audit: { era_counts: { [ERA]: 10, 'engine1@2026-07-20': 5 }, wrong_era_rows: 5 } }, 'ARTIFACT_POLICY_BLOCKED'], MODEL_VERSION_MISMATCH: [{ model_version: 'engine1@2026-07-20' }, 'VERSION_MISMATCH'], ESTIMATOR_MISMATCH: [{ estimator_type: 'low_param' }, 'VERSION_MISMATCH'], MISSING_IDENTITY: [{ knot_digest: null }, 'ARTIFACT_POLICY_BLOCKED'], THIN_FIT: [{ fit_n: 3 }, 'ARTIFACT_POLICY_BLOCKED'], SUPPORT_WIDENING: [{ certified_bands: [[0.50, 0.99]] }, 'ARTIFACT_POLICY_BLOCKED'], }; for (const [name, [over, expected]] of Object.entries(violations)) { it(`${name} -> ${expected}, never CERTIFIED_CALIBRATED`, () => { const base = { ...good, ...over }; const check = fp.validate(base, { era_counts: base.era_audit ? base.era_audit.era_counts : null }); expect(check.servable).toBe(false); const artifact = { ...base, servable: check.servable, fit_policy_violations: check.violations }; const r = pc.resolve(read(0.65), { estimate: est, artifact }); expect(r.probability_state).toBe(pc.STATE[expected]); expect(r.probability_state).not.toBe(pc.STATE.CERTIFIED_CALIBRATED); expect(r.served_probability).toBeNull(); expect(r.raw_model_probability).toBe(0.65); // raw is still evidence expect(pc.derivedClaims(r, -115).available).toBe(false); }); } it('and every probability-derived claim is withheld with it', () => { const artifact = { ...good, servable: false, fit_policy_violations: ['ERA_NOT_RESTRICTED'] }; const d = pc.derivedClaims(pc.resolve(read(0.65), { estimate: est, artifact }), -115); expect(d.available).toBe(false); expect(d.ev_pct).toBeNull(); expect(d.kelly).toBeNull(); expect(d.value).toBeNull(); }); it('the blocked state names the violation rather than shrugging', () => { const artifact = { ...good, servable: false, fit_policy_violations: ['ERA_NOT_RESTRICTED'] }; expect(pc.resolve(read(0.65), { estimate: est, artifact }).reason).toContain('ERA_NOT_RESTRICTED'); }); }); describe('no environment variable can override the gate', () => { const artifact = { ...good, servable: false, fit_policy_violations: ['ERA_NOT_RESTRICTED'] }; it('shadow ON does not make an unservable artifact certify', () => { expect(pc.shadowState({ PROBABILITY_CONTRACT_SHADOW: '1' }).shadow).toBe('ON'); // the gate lives in the resolution, not beside the flag const r = pc.resolve(read(0.65), { estimate: est, artifact }); expect(r.probability_state).toBe(pc.STATE.ARTIFACT_POLICY_BLOCKED); }); it('resolve takes no flag, so there is nothing for a flag to reach', () => { const src = require('fs').readFileSync( require('path').join(__dirname, '../../src/services/model/probabilityContract.js'), 'utf8'); const body = src.slice(src.indexOf('function resolve'), src.indexOf('const isCertified')); expect(body).not.toContain('process.env'); expect(body).not.toContain('PROBABILITY_CONTRACT_SHADOW'); }); }); describe('one validity decision for shadow AND live', () => { it('a shadow-approved artifact is refused for live use', () => { expect(good.approved_for_shadow).toBe(true); expect(good.approved_for_live).toBe(false); const live = pc.resolve(read(0.65), { estimate: est, artifact: good, usage: 'live' }); expect(live.probability_state).toBe(pc.STATE.ARTIFACT_POLICY_BLOCKED); expect(live.reason).toContain('not promoted for live'); const shadow = pc.resolve(read(0.65), { estimate: est, artifact: good, usage: 'shadow' }); expect(shadow.probability_state).toBe(pc.STATE.CERTIFIED_CALIBRATED); }); it('live consumes the SAME servable decision, not a parallel one', () => { const bad = { ...good, servable: false, approved_for_live: true, fit_policy_violations: ['X'] }; expect(pc.resolve(read(0.65), { estimate: est, artifact: bad, usage: 'live' }).probability_state) .toBe(pc.STATE.ARTIFACT_POLICY_BLOCKED); }); }); describe('the active curve does not move', () => { it('the runtime holds no fitter — nothing to refit on a snapshot', () => { const src = require('fs').readFileSync( require('path').join(__dirname, '../../src/services/model/probabilityContractService.js'), 'utf8'); const code = src.replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); expect(code).not.toContain('fitIsotonic'); expect(code).not.toContain('fromLedger'); expect(code).not.toContain('loadRows'); }); it('repeated builds return the same artifact object and the same numbers', async () => { const a = await svc.build(null, { sport: 'mlb', stat: 'hits' }); const b = await svc.build(null, { sport: 'mlb', stat: 'hits' }); expect(a.artifact).toBe(b.artifact); // cached, identical identity expect(a.artifact.source_digest).toBe(b.artifact.source_digest); expect(a.resolve(read(0.72)).served_probability).toBe(b.resolve(read(0.72)).served_probability); }); it('a new settled outcome cannot alter the curve — it is a committed file', () => { const before = registry.applyCurve(good, 0.65); registry.__resetCache(); const after = registry.applyCurve(registry.load('mlb', 'hits'), 0.65); expect(after).toBe(before); }); }); describe('promotion is a deliberate act', () => { it('the promotion table is a frozen source constant, not runtime state', () => { expect(Object.isFrozen(registry.PROMOTED)).toBe(true); expect(Object.isFrozen(registry.PROMOTED['mlb:hits'])).toBe(true); // strict mode makes the write throw rather than fail silently — either way // the table is unchanged, which is the property under test expect(() => { registry.PROMOTED['mlb:rbi'] = { artifact_id: 'x', stage: 'APPROVED_FOR_LIVE' }; }).toThrow(); expect(registry.PROMOTED['mlb:rbi']).toBeUndefined(); }); it('an artifact file that exists but is not named is NOT loaded', () => { // load() resolves the file FROM the promotion table, so an unnamed artifact // sitting in the directory is inert. expect(registry.load('mlb', 'rbi')).toBeNull(); }); it('the loaded artifact id must equal the promoted id', () => { expect(registry.load('mlb', 'hits').artifact_id).toBe(registry.PROMOTED['mlb:hits'].artifact_id); }); it('a file declaring a DIFFERENT id is refused — dropping one in promotes nothing', () => { const promoted = registry.PROMOTED['mlb:hits']; expect(registry.acceptFile({ artifact_id: promoted.artifact_id }, promoted)).toBe(true); // the case load() can never reach on the happy path, and the reason the // guard existed unprotected until a teeth injection came back green expect(registry.acceptFile({ artifact_id: 'mlb-hits-isotonic@2099-01-01' }, promoted)).toBe(false); expect(registry.acceptFile({ artifact_id: null }, promoted)).toBe(false); expect(registry.acceptFile({}, promoted)).toBe(false); expect(registry.acceptFile(null, promoted)).toBe(false); expect(registry.acceptFile({ artifact_id: 'x' }, null)).toBe(false); }); }); describe('model-era transition law', () => { it('a NEW model era does not inherit this artifact', () => { const r = pc.resolve({ sport: 'mlb', stat: 'hits', model_version: 'engine1@2027-01-01', p_win: 0.65 }, { estimate: est, artifact: good }); expect(r.probability_state).toBe(pc.STATE.VERSION_MISMATCH); expect(r.served_probability).toBeNull(); }); it('and an artifact relabelled to a new era fails its own policy', () => { const relabelled = { ...good, model_version: 'engine1@2027-01-01' }; const check = fp.validate(relabelled, { era_counts: good.era_audit.era_counts }); expect(check.valid).toBe(false); expect(check.servable).toBe(false); }); }); describe('the runtime can name its artifact with the shadow OFF', () => { it('reports the full identity without enabling anything', () => { const st = pc.shadowState({}); expect(st.shadow).toBe('OFF'); expect(st.live_serving).toBe('OFF'); const a = st.artifact; for (const k of ['artifact_id', 'procedure_version', 'model_version', 'fit_as_of', 'training_cutoff', 'fit_n', 'source_digest', 'knot_digest', 'served_curve_digest', 'certified_bands', 'stage']) expect(a[k]).toBeTruthy(); expect(a.servable).toBe(true); expect(a.approved_for_shadow).toBe(true); expect(a.approved_for_live).toBe(false); expect(a.wrong_era_rows).toBe(0); expect(a.withheld_from_fit).toBe(0); }); it('does not put a second copy of the curve on a status surface', () => { expect(pc.shadowState({}).artifact.served_curve).toBeUndefined(); }); it('two resolutions return the same artifact — no refit between calls', () => { expect(JSON.stringify(pc.shadowState({}).artifact)) .toBe(JSON.stringify(pc.shadowState({}).artifact)); }); }); describe('ONE ARTIFACT, ONE STAT — the cross-stat leak found by cohort 0353c551', () => { const retention = require('../../src/services/retentionService'); /** The real collector, with a MIXED-STAT batch — the shape production sends. */ function mixedBatch() { const c = retention.createCollector({ snapshotId: 's1', sport: 'mlb', modelVersion: ERA, codeSha: 't', gameDate: '2026-09-03', gameIdFor: () => 'mlb:2026-09-03:AAA@BBB', }); for (const stat of ['hits', 'total_bases', 'rbi', 'runs', 'walks', 'strikeouts', 'home_runs']) { c.onGraded( { player: `P ${stat}`, stat_type: stat, line: 0.5, sport: 'mlb', over_odds: -110, under_odds: -110 }, [{ direction: 'over', grade: 'C+', p_win: 0.65, confidence: 65 }], ); } return c.rows; } it('calibrates hits and NOTHING else, even in one mixed batch', async () => { const contract = await svc.build(null, { sport: 'mlb', stat: 'hits' }); const merged = retention.mergeProbabilityContract(mixedBatch(), contract); const byStat = {}; for (const r of merged) { byStat[r.stat] = byStat[r.stat] || { certified: 0, served: 0, other: 0 }; const st = r.probability_contract.probability_state; if (st === pc.STATE.CERTIFIED_CALIBRATED) byStat[r.stat].certified++; else byStat[r.stat].other++; if (r.probability_contract.served_probability != null) byStat[r.stat].served++; } // hits: calibrated. p_win 0.65 sits inside certified support. expect(byStat.hits.certified).toBeGreaterThan(0); expect(byStat.hits.served).toBeGreaterThan(0); // EVERY other stat: no certified state and no number, at the SAME p_win. for (const stat of ['total_bases', 'rbi', 'runs', 'walks', 'strikeouts', 'home_runs']) { expect(byStat[stat].certified).toBe(0); expect(byStat[stat].served).toBe(0); } }); it('a non-hits row resolves UNSUPPORTED — the contract does not exist for it', async () => { const contract = await svc.build(null, { sport: 'mlb', stat: 'hits' }); const [tb] = retention.mergeProbabilityContract( mixedBatch().filter((r) => r.stat === 'total_bases'), contract); expect(tb.probability_contract.probability_state).toBe(pc.STATE.UNSUPPORTED); expect(tb.probability_contract.served_probability).toBeNull(); expect(tb.probability_contract.derived.available).toBe(false); }); it('the resolver does not substitute its own identity for the row\'s', async () => { const contract = await svc.build(null, { sport: 'mlb', stat: 'hits' }); // a read naming another stat must NOT be resolved as hits expect(contract.resolve({ sport: 'mlb', stat: 'rbi', model_version: ERA, p_win: 0.65 }) .probability_state).toBe(pc.STATE.UNSUPPORTED); // and a read naming NO stat resolves to no contract, never a fallback expect(contract.resolve({ model_version: ERA, p_win: 0.65 }) .probability_state).toBe(pc.STATE.UNSUPPORTED); }); it('an artifact for another stat is refused even with correct plumbing', () => { const wrong = { ...good, stat: 'total_bases' }; const r = pc.resolve(read(0.65), { estimate: est, artifact: wrong }); expect(r.probability_state).toBe(pc.STATE.VERSION_MISMATCH); expect(r.served_probability).toBeNull(); expect(r.reason).toContain('total_bases'); }); it('and an artifact for another sport is refused', () => { const r = pc.resolve(read(0.65), { estimate: est, artifact: { ...good, sport: 'wnba' } }); expect(r.probability_state).toBe(pc.STATE.VERSION_MISMATCH); expect(r.served_probability).toBeNull(); }); });