Files
vyndr/tests/unit/intradayRefresh.test.js
T
builtbykev 889a96584a Intraday is a market overlay: it may not restate belief
`grade` is a band label over `p_win` and nothing else. `servedGrade.gradeFor`
reads exactly { p_win, refused, refusal_reason, insufficient_data,
factor_adjustment } -- no line, no odds, no edge, no side -- and
`gradeFreeze.TOLERANCES.MAX_LETTER_MISMATCH` is 0, so the served letter MUST
equal the band of the served probability.

The intraday refresh re-graded an adversely-moved prop AT THE CURRENT LINE and
then copied only `res.grade` onto the row for the LOCKED line, discarding the
p_win that produced it. Two defects in one write: the letter stopped matching
the probability beside it, and the letter answered a different proposition than
the claim it was stamped on.

MEASURED on ledger_entries in the current model era
(engine1@2026-08-07-fullwindow): 30,047 unrevised rows carry ZERO letter/p_win
mismatches; all 9 intraday-revised rows are mismatched. The revision was the
sole producer of incoherent authoritative rows. The pre-cutover era is
uninterpretable here (its `grade` was the engine index, not a p_win band, and
mismatches 49.4% of the time WITHOUT any revision) -- which is exactly why the
control was run before quoting a rate.

Simulated over the 57 historical revisions: in the current era, keeping the
published grade restores coherence on 9 of 9.

So the adverse branch now records the move and stops there. No grader is
invoked, no ledger revision is applied, and the grade-rank comparator is
deleted rather than parked -- a dead comparator beside the code is how the
mutation gets re-wired. A production coherence gate compares every output row
to its input on every BELIEF field and, on any divergence, publishes the
untouched slate instead.

History is untouched: the 57 existing `revised_from_grade` rows keep their
values, and the UI that renders them is unchanged. Forward-only.

Lineage is not touched and stays OFF.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQJeAG8vcDoL5zkiaJyVb8
2026-08-28 18:48:07 -04:00

189 lines
9.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Session 60 (night2/D) — Phase 2.5 intraday refresh, as amended by the
// INTRADAY BELIEF INTEGRITY repair. Direction is still the signal: WITH the
// grade = STEAM, AGAINST = recorded with its signed delta. The re-grade branch
// is GONE — `grade` is a band label over p_win, so a market move may not
// restate it. All lines are real feed values; the refresh recaptures the close.
const { runIntradayRefresh, inSlateHours, __internals } = require('../../src/services/intradayRefreshService');
const { signedDelta, trackHistory, HISTORY_CAP } = __internals;
const NOW = '2026-07-11T20:00:00.000Z';
function harness({ grades, oddsProps, analyzeResult }) {
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 }),
analyze: async (prop) => { calls.analyze.push(prop); return analyzeResult; },
ledger: {
applyRevision: async (sport, rev) => { calls.revisions.push(rev); return { revised: true }; },
captureClosing: async () => { calls.closing += 1; return { updated: 0 }; },
},
pushTickerItems: async (events) => { calls.ticker.push(...events); },
now: () => NOW,
};
return { deps, store, calls };
}
const GRADE = {
player: 'Aaron Judge', stat_type: 'home_runs', line: 0.5, direction: 'over',
grade: 'A', confidence: 78, gradedAt: { line: 0.5, odds: -115, timestamp: NOW },
};
const prop = (line) => ({ player: 'Aaron Judge', stat_type: 'home_runs', line, book: 'draftkings' });
describe('signedDelta — relative to the graded side', () => {
test('over: rising line = positive (market chasing the over)', () => {
expect(signedDelta('over', 1.5, 2.5)).toBe(1);
expect(signedDelta('over', 1.5, 1.0)).toBe(-0.5);
});
test('under: falling line = positive', () => {
expect(signedDelta('under', 1.5, 1.0)).toBe(0.5);
expect(signedDelta('under', 1.5, 2.5)).toBe(-1);
});
test('missing values → null, never a fabricated zero', () => {
expect(signedDelta('over', null, 2)).toBeNull();
});
});
describe('runIntradayRefresh — directional handling', () => {
test('moved WITH the grade → STEAM, NO re-grade', async () => {
const { deps, store, calls } = harness({ grades: [GRADE], oddsProps: [prop(1.5)], analyzeResult: null });
const res = await runIntradayRefresh('mlb', deps);
expect(res).toMatchObject({ status: 'ok', steam: 1, against: 0, belief_mutations: 0 });
expect(calls.analyze).toHaveLength(0); // steam never re-grades
const snap = store.get('snapshot:mlb:latest');
expect(snap.grades[0].movement).toMatchObject({ kind: 'steam', delta: 1, currentLine: 1.5 });
expect(calls.ticker.length).toBeGreaterThan(0); // ≥1.0 move → ticker MOVE
expect(calls.ticker[0].text).toContain('o0.5 → o1.5');
});
test('moved AGAINST >= 1.0 records the move and NEVER re-grades', async () => {
const { deps, store, calls } = harness({
grades: [{ ...GRADE, gradedAt: { line: 2.5, odds: -110, timestamp: NOW }, line: 2.5 }],
oddsProps: [prop(1.5)],
analyzeResult: { grade: 'C', confidence: 40, p_win: 0.31 },
});
const res = await runIntradayRefresh('mlb', deps);
expect(res).toMatchObject({ against: 1, belief_mutations: 0 });
// The grader is never consulted. Injecting one and finding it untouched is
// the point: the torn state is unreachable, not merely unwritten.
expect(calls.analyze).toHaveLength(0);
expect(calls.revisions).toHaveLength(0);
const g = store.get('snapshot:mlb:latest').grades[0];
expect(g.movement).toMatchObject({ kind: 'against', delta: -1, currentLine: 1.5 });
expect(g.grade).toBe('A');
expect(g.revised_from_grade).toBeUndefined();
});
test('a favourable grade the old branch would have adopted is still refused', async () => {
const { deps, store, calls } = harness({
grades: [{ ...GRADE, grade: 'C', gradedAt: { line: 2.5, odds: -110, timestamp: NOW }, line: 2.5 }],
oddsProps: [prop(1.5)],
analyzeResult: { grade: 'B+', confidence: 82, p_win: 0.81 },
});
await runIntradayRefresh('mlb', deps);
expect(calls.analyze).toHaveLength(0);
expect(store.get('snapshot:mlb:latest').grades[0].grade).toBe('C');
});
test('a row already carrying a historical revised_from_grade is left alone', async () => {
const already = { ...GRADE, grade: 'B', revised_from_grade: 'A', gradedAt: { line: 2.5, odds: null, timestamp: NOW }, line: 2.5 };
const { deps, store } = harness({ grades: [already], oddsProps: [prop(1.5)], analyzeResult: { grade: 'C' } });
await runIntradayRefresh('mlb', deps);
const g = store.get('snapshot:mlb:latest').grades[0];
// History is preserved verbatim — the repair is forward-only.
expect(g.revised_from_grade).toBe('A');
expect(g.grade).toBe('B');
});
test('prop gone from the feed → frozen untouched; close recaptured every run', async () => {
const { deps, store, calls } = harness({ grades: [GRADE], oddsProps: [prop(0.5)], analyzeResult: null });
const res = await runIntradayRefresh('mlb', deps);
expect(res.checked).toBe(1);
expect(store.get('snapshot:mlb:latest').grades[0].movement).toBeNull(); // <0.5 noise
expect(calls.closing).toBe(1); // refresh-fidelity closing capture
});
test('no snapshot → honest skip, zero quota spent', async () => {
const calls = { odds: 0 };
const res = await runIntradayRefresh('mlb', {
cacheGet: async () => null,
cacheSet: async () => {},
getOdds: async () => { calls.odds += 1; return { props: [] }; },
ledger: {}, pushTickerItems: async () => {}, now: () => NOW,
});
expect(res.status).toBe('skipped');
expect(calls.odds).toBe(0);
});
});
// S6 (A1 board) — sparkline fuel: {t, line} history capture on each grade's
// movement tracking, persisted inside the snapshot write-back (no new keys).
describe('trackHistory — real {t, line} points, seeded, deduped, capped', () => {
const LOCK_TS = '2026-07-11T14:00:00.000Z';
const g = (extra = {}) => ({ ...GRADE, gradedAt: { line: 0.5, odds: -115, timestamp: LOCK_TS }, ...extra });
test('first capture seeds the LOCKED line at its own timestamp, then the move', () => {
const h = trackHistory(g(), 1.5, NOW);
expect(h).toEqual([{ t: LOCK_TS, line: 0.5 }, { t: NOW, line: 1.5 }]);
});
test('a flat line never appends a duplicate point (a point means it MOVED)', () => {
const h = trackHistory(g(), 0.5, NOW); // current == locked
expect(h).toEqual([{ t: LOCK_TS, line: 0.5 }]);
const again = trackHistory(g({ history: h }), 0.5, '2026-07-11T21:00:00.000Z');
expect(again).toHaveLength(1);
});
test('an unparseable current line appends nothing (real points only)', () => {
expect(trackHistory(g(), null, NOW)).toBeUndefined();
const prior = [{ t: LOCK_TS, line: 0.5 }];
expect(trackHistory(g({ history: prior }), 'n/a', NOW)).toBe(prior);
});
test('capped at 24 points, newest kept', () => {
const prior = Array.from({ length: HISTORY_CAP }, (_, i) => ({ t: `t${i}`, line: i }));
const h = trackHistory(g({ history: prior }), 99, NOW);
expect(h).toHaveLength(HISTORY_CAP);
expect(h[HISTORY_CAP - 1]).toEqual({ t: NOW, line: 99 });
expect(h[0]).toEqual({ t: 't1', line: 1 }); // oldest point aged out
});
});
describe('runIntradayRefresh — history rides the snapshot write-back', () => {
test('a steam move persists history on the grade (locked point + current)', async () => {
const { deps, store } = harness({ grades: [GRADE], oddsProps: [prop(1.5)], analyzeResult: null });
await runIntradayRefresh('mlb', deps);
const snap = store.get('snapshot:mlb:latest');
expect(snap.grades[0].history).toEqual([
{ t: NOW, line: 0.5 }, // seeded from the lock (gradedAt.timestamp === NOW here)
{ t: NOW, line: 1.5 },
]);
// grades:{sport} carries the same enriched grades.
expect(store.get('grades:mlb').grades[0].history).toHaveLength(2);
});
test('a flat run keeps a single seeded point — the sparkline stays hidden (<3)', async () => {
const { deps, store } = harness({ grades: [GRADE], oddsProps: [prop(0.5)], analyzeResult: null });
await runIntradayRefresh('mlb', deps);
expect(store.get('snapshot:mlb:latest').grades[0].history).toEqual([{ t: NOW, line: 0.5 }]);
});
test('a prop gone from the feed leaves prior history untouched', async () => {
const withHist = { ...GRADE, stat_type: 'hits', history: [{ t: 'x', line: 1 }] };
const { deps, store } = harness({ grades: [withHist], oddsProps: [prop(1.5)], analyzeResult: null });
await runIntradayRefresh('mlb', deps);
const frozen = store.get('snapshot:mlb:latest').grades.find((g) => g.stat_type === 'hits');
expect(frozen.history).toEqual([{ t: 'x', line: 1 }]);
});
});
describe('inSlateHours — noon–midnight ET', () => {
test('3 PM ET yes, 4 AM ET no', () => {
expect(inSlateHours(new Date('2026-07-11T19:00:00Z'))).toBe(true); // 3 PM EDT
expect(inSlateHours(new Date('2026-07-11T08:00:00Z'))).toBe(false); // 4 AM EDT
});
});