// INTRADAY BELIEF INTEGRITY — the coherence contract. // // `grade` is a BAND LABEL OVER p_win: `servedGrade.gradeFor` reads only // { p_win, refused, refusal_reason, insufficient_data, factor_adjustment }. // `gradeFreeze.TOLERANCES.MAX_LETTER_MISMATCH` is 0, so a served letter that // disagrees with the served probability is already a frozen violation. // // The intraday refresh is therefore a MARKET OVERLAY: it may record what the // market did and may not restate what the model believes. These tests assert // that no authoritative Read can leave a refresh with a new letter beside an // old probability. const intraday = require('../../src/services/intradayRefreshService'); const { runIntradayRefresh, BELIEF_FIELDS, beliefMutations } = intraday; const servedGrade = require('../../src/services/model/servedGrade'); const gradeFreeze = require('../../src/services/evaluator/gradeFreeze'); const readLineage = require('../../src/services/read/readLineage'); const fs = require('fs'); const path = require('path'); const NOW = '2026-08-28T21:00:00.000Z'; const SRC = path.join(__dirname, '../../src/services/intradayRefreshService.js'); function harness({ grades, oddsProps, analyzeResult, ledgerThrows }) { const store = new Map([['snapshot:mlb:latest', { sport: 'mlb', updated_at: NOW, grades, deltas: [] }]]); const calls = { analyze: [], revisions: [], closing: 0, ticker: [] }; const deps = { cacheGet: async (k) => store.get(k) ?? null, cacheSet: async (k, v) => { store.set(k, v); }, getOdds: async () => ({ props: oddsProps }), // Injected and expected to stay untouched. A dep that is present and never // called is stronger evidence than a dep that was deleted. analyze: async (p) => { calls.analyze.push(p); return analyzeResult; }, ledger: { applyRevision: async (sport, rev) => { calls.revisions.push(rev); if (ledgerThrows) throw new Error('ledger down'); return { revised: true }; }, captureClosing: async () => { calls.closing += 1; return { updated: 0 }; }, }, pushTickerItems: async (ev) => { calls.ticker.push(...ev); }, now: () => NOW, }; return { deps, store, calls }; } // A real published claim: p_win 0.900 -> the band table says B+. const CLAIM = { player: 'Aaron Judge', stat_type: 'home_runs', line: 1.5, direction: 'over', p_win: 0.9, grade: 'B+', confidence: 90, confidence_basis: 'p_win', projection: 1.9, fair_prob: 0.55, fair_odds: -122, gradedAt: { line: 1.5, odds: -115, timestamp: NOW }, }; const prop = (line) => ({ player: 'Aaron Judge', stat_type: 'home_runs', line, book: 'draftkings' }); describe('the grade contract: a letter is a band over p_win', () => { test('gradeFor reads no market input — only belief', () => { const base = { p_win: 0.9 }; const letter = servedGrade.gradeFor(base).letter; // Every market term the refresh could move, added and varied. None may // change the letter, because none is an input. for (const extra of [{ line: 0.5 }, { line: 99 }, { odds: -500 }, { book: 'fanduel' }, { edge_pct: 40 }, { side: 'under' }, { currentLine: 12 }]) { expect(servedGrade.gradeFor({ ...base, ...extra }).letter).toBe(letter); } }); test('the served letter is exactly the frozen band of the served p_win', () => { for (let p = 0; p <= 1000; p += 1) { const pw = p / 1000; expect(servedGrade.gradeFor({ p_win: pw }).letter).toBe(gradeFreeze.expectedLetter(pw)); } expect(gradeFreeze.TOLERANCES.MAX_LETTER_MISMATCH).toBe(0); }); test('BELIEF_FIELDS does not drift from the repository claim taxonomy', () => { const lineageBelief = Object.entries(readLineage.CLAIM_FIELD_CLASSES) .filter(([, c]) => c === readLineage.FIELD_CLASS.BELIEF) .map(([f]) => f); // Every field lineage calls BELIEF must be protected here. This module may // protect MORE (line/direction identify which proposition the belief is // about), but it may never protect fewer. for (const f of lineageBelief) expect(BELIEF_FIELDS).toContain(f); }); }); describe('intraday is a market overlay and may not mutate belief', () => { test('sub-threshold move: no movement chip, belief untouched', async () => { const { deps, store, calls } = harness({ grades: [CLAIM], oddsProps: [prop(1.8)], analyzeResult: { grade: 'F' } }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ status: 'ok', steam: 0, against: 0, belief_mutations: 0 }); expect(store.get('snapshot:mlb:latest').grades[0].movement).toBeNull(); expect(calls.analyze).toHaveLength(0); }); test('large ADVERSE move: recorded, belief frozen, grader never called', async () => { // OVER 1.5 -> the book drops the line to 0.5: the market is moving AGAINST // the graded side (our locked number is now the worse one). const { deps, store, calls } = harness({ grades: [CLAIM], oddsProps: [prop(0.5)], analyzeResult: { grade: 'F', p_win: 0.1 } }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ against: 1, belief_mutations: 0 }); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.movement).toMatchObject({ kind: 'against', currentLine: 0.5 }); expect(beliefMutations(CLAIM, g)).toEqual([]); expect(calls.analyze).toHaveLength(0); expect(calls.revisions).toHaveLength(0); expect(calls.ticker.length).toBeGreaterThan(0); }); test('large FAVOURABLE move: STEAM, belief frozen', async () => { const { deps, store } = harness({ grades: [CLAIM], oddsProps: [prop(3.5)], analyzeResult: { grade: 'A' } }); const res = await runIntradayRefresh('mlb', deps); expect(res).toMatchObject({ steam: 1, belief_mutations: 0 }); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.movement.kind).toBe('steam'); expect(beliefMutations(CLAIM, g)).toEqual([]); }); test('a grader that would IMPROVE the grade changes nothing', async () => { const { deps, store } = harness({ grades: [{ ...CLAIM, p_win: 0.5, grade: 'C', confidence: 50 }], oddsProps: [prop(0.5)], analyzeResult: { grade: 'B+', p_win: 0.82 }, }); await runIntradayRefresh('mlb', deps); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.grade).toBe('C'); expect(g.p_win).toBe(0.5); }); test('a grader that returns grade AND p_win together still changes nothing', async () => { const { deps, store } = harness({ grades: [CLAIM], oddsProps: [prop(0.5)], analyzeResult: { grade: 'D', p_win: 0.36, projection: 0.4, confidence: 36 }, }); await runIntradayRefresh('mlb', deps); expect(beliefMutations(CLAIM, store.get('snapshot:mlb:latest').grades[0])).toEqual([]); }); test('a refusing grader changes nothing and never blanks the letter', async () => { const { deps, store } = harness({ grades: [CLAIM], oddsProps: [prop(0.5)], analyzeResult: { grade: null, insufficient_data: true }, }); await runIntradayRefresh('mlb', deps); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.grade).toBe('B+'); expect(g.refused).toBeUndefined(); }); test('missing market data: prop frozen exactly as published', async () => { const { deps, store } = harness({ grades: [CLAIM], oddsProps: [], analyzeResult: null }); const res = await runIntradayRefresh('mlb', deps); expect(res.status).toBe('skipped'); expect(store.get('snapshot:mlb:latest').grades[0]).toEqual(CLAIM); }); test('an already-revised historical row keeps its history and gains no new one', async () => { const hist = { ...CLAIM, grade: 'C', revised_from_grade: 'B+' }; const { deps, store } = harness({ grades: [hist], oddsProps: [prop(0.5)], analyzeResult: { grade: 'F' } }); await runIntradayRefresh('mlb', deps); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.revised_from_grade).toBe('B+'); expect(g.grade).toBe('C'); }); test('repeated refreshes never accumulate belief drift', async () => { let grades = [CLAIM]; for (const line of [3.5, 4.5, 0.5, 2.5]) { const { deps, store } = harness({ grades, oddsProps: [prop(line)], analyzeResult: { grade: 'F', p_win: 0.05 } }); await runIntradayRefresh('mlb', deps); grades = store.get('snapshot:mlb:latest').grades; expect(beliefMutations(CLAIM, grades[0])).toEqual([]); } }); test('publication then refresh: the published claim survives the overlay', async () => { const published = { ...CLAIM }; const { deps, store } = harness({ grades: [published], oddsProps: [prop(0.5)], analyzeResult: { grade: 'F' } }); await runIntradayRefresh('mlb', deps); const g = store.get('snapshot:mlb:latest').grades[0]; for (const f of BELIEF_FIELDS) expect(g[f]).toEqual(published[f]); expect(g.movement).toBeTruthy(); // market state DID advance }); test('the letter and the probability stay mutually derivable after a refresh', async () => { const { deps, store } = harness({ grades: [CLAIM], oddsProps: [prop(0.5)], analyzeResult: { grade: 'F' } }); await runIntradayRefresh('mlb', deps); const g = store.get('snapshot:mlb:latest').grades[0]; expect(g.grade).toBe(gradeFreeze.expectedLetter(g.p_win)); expect(g.confidence).toBe(Math.round(g.p_win * 100)); }); }); describe('ranking is unaffected because belief is unaffected', () => { // `rankByForecast` sorts on p_win FIRST and uses the grade rank only as a // TIEBREAK. Because the letter is a function of p_win, that tiebreak is // normally redundant with the primary key -- an intraday grade mutation was // the ONLY thing that could make the two disagree. const { rankByForecast } = require('../../src/utils/gradeRanking'); const mk = (name, pWin) => ({ player: name, stat_type: 'home_runs', line: 1.5, direction: 'over', p_win: pWin, grade: gradeFreeze.expectedLetter(pWin), confidence: Math.round(pWin * 100), gradedAt: { line: 1.5, odds: -110, timestamp: NOW }, }); test('slate order is byte-identical before and after a refresh', async () => { const slate = [mk('A Hitter', 0.82), mk('B Hitter', 0.71), mk('C Hitter', 0.55), mk('D Hitter', 0.33)]; const before = rankByForecast(slate).map((g) => g.player); const oddsProps = slate.map((g) => ({ player: g.player, stat_type: 'home_runs', line: 0.5, book: 'draftkings' })); const { deps, store } = harness({ grades: slate, oddsProps, analyzeResult: { grade: 'F', p_win: 0.02 } }); const res = await runIntradayRefresh('mlb', deps); expect(res.against).toBe(4); const after = rankByForecast(store.get('snapshot:mlb:latest').grades).map((g) => g.player); expect(after).toEqual(before); }); test('every ranked row still has a letter derivable from its own p_win', async () => { const slate = [mk('A Hitter', 0.82), mk('B Hitter', 0.71)]; const oddsProps = slate.map((g) => ({ player: g.player, stat_type: 'home_runs', line: 0.5, book: 'draftkings' })); const { deps, store } = harness({ grades: slate, oddsProps, analyzeResult: { grade: 'F', p_win: 0.02 } }); await runIntradayRefresh('mlb', deps); for (const g of rankByForecast(store.get('snapshot:mlb:latest').grades)) { expect(g.grade).toBe(gradeFreeze.expectedLetter(g.p_win)); } }); }); describe('structural guarantees', () => { test('the module invokes no grading logic and writes no ledger revision', () => { const src = fs.readFileSync(SRC, 'utf8') .replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); expect(src).not.toMatch(/deps\.analyze/); expect(src).not.toMatch(/applyRevision/); expect(src).not.toMatch(/analyzeViaEngine1/); // No letter comparison may exist here at all. expect(src).not.toMatch(/GRADE_RANK/); }); test('the coherence gate fails CLOSED and reports the offending field', () => { const before = { grade: 'B+', p_win: 0.9, line: 1.5, direction: 'over' }; const after = { ...before, grade: 'C' }; const v = beliefMutations(before, after); expect(v).toHaveLength(1); expect(v[0]).toMatchObject({ field: 'grade', before: 'B+', after: 'C' }); // A market-only change is not a violation. expect(beliefMutations(before, { ...before, movement: { kind: 'against' } })).toEqual([]); }); test('the gate ACTIVELY BLOCKS and does not merely sit there', async () => { // A gate that never fires is indistinguishable from a gate that is gone: // deleting it changed nothing, which is a coverage hole rather than a safe // defect. This drives a REACHABLE divergence — a slate carrying two rows // for one (player, stat, line, side) whose belief disagrees — so the gate // has something to catch and its fail-closed behaviour is observable. // // It proves the MECHANISM blocks and refuses to publish. It does not, by // itself, prove an intraday mutation would be caught; that is covered by // the overlay tests above, which assert no mutation is produced at all. const a = { ...CLAIM }; const b = { ...CLAIM, grade: 'F', p_win: 0.1 }; const { deps, store } = harness({ grades: [a, b], oddsProps: [prop(0.5)], analyzeResult: null }); const before = JSON.stringify(store.get('snapshot:mlb:latest')); const res = await runIntradayRefresh('mlb', deps); expect(res.status).toBe('blocked'); expect(res.reason).toBe('belief_mutation'); expect(res.belief_mutations).toBeGreaterThan(0); // FAIL CLOSED: the previous slate is left standing, untouched. expect(JSON.stringify(store.get('snapshot:mlb:latest'))).toBe(before); }); test('this tranche touches no lineage code or configuration', () => { const lineage = fs.readFileSync(path.join(__dirname, '../../src/services/read/readLineage.js'), 'utf8'); expect(lineage).toContain("const LINEAGE_VERSION = 'lin@1'"); expect(lineage).toContain("const CLAIM_SCHEMA_VERSION = 'claim@1'"); const cfg = fs.readFileSync(path.join(__dirname, '../../src/services/lineageCanaryConfig.js'), 'utf8'); expect(cfg).toContain('process.env.LINEAGE_CANARY_SPORTS'); // The refresh must never reach the lineage layer. Comments are STRIPPED // first: this module's own docstring names `readLineage` when explaining // why BELIEF_FIELDS is a local constant, and a scanner that trips on prose // about a rule instead of a violation of it is the scar this repo keeps // re-learning. const src = fs.readFileSync(SRC, 'utf8') .replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, ''); expect(src).not.toMatch(/readLineage|commitPublication|attachLineage/); }); test('the frozen game-date and canonical-participant repairs are intact', () => { const binder = fs.readFileSync(path.join(__dirname, '../../src/services/gameBinder.js'), 'utf8'); expect(binder).toContain('if (!p.game_date) p.game_date = etFast;'); const evid = fs.readFileSync(path.join(__dirname, '../../src/services/event/eventIdentity.js'), 'utf8'); expect(evid).toContain('function resolveParticipant'); expect(evid).toMatch(/ids\.size !== 1/); }); });