/** * FREE PROOF SURFACE — the honesty contract (specs/free-proof-surface-review-zero.md). * These tests exist to make fabrication fail loudly. */ const p = require('../../web/src/lib/proofRecord'); const fs = require('fs'); const path = require('path'); const page = fs.readFileSync(path.join(__dirname, '../../web/src/app/record/page.tsx'), 'utf8'); // the REAL canonical shape, live 2026-07-31 const BY_GRADE = { B: { hits: 309, misses: 203, total: 512, pct: 60 }, C: { hits: 235, misses: 178, total: 413, pct: 57 }, A: { hits: 1, misses: 1, total: 2, pct: null }, D: { hits: 1, misses: 4, total: 5, pct: null }, F: { hits: 1, misses: 4, total: 5, pct: null }, }; describe('hollow buckets stay hollow — never derived', () => { const rows = p.tierRows(BY_GRADE, 20); const by = (t) => rows.find((r) => r.tier === t); test('a null pct is preserved as hollow, NOT computed from hits/total', () => { for (const t of ['A', 'D', 'F']) { expect(by(t).pct).toBeNull(); expect(by(t).hollow).toBe(true); } // A is 1/2 = 50% — derivable, and deliberately NOT derived expect(by('A').hits).toBe(1); expect(by('A').total).toBe(2); expect(by('A').pct).not.toBe(50); }); test('real percentages pass through untouched — no rounding, no smoothing', () => { expect(by('B').pct).toBe(60); expect(by('C').pct).toBe(57); }); test('C ships BELOW B — the unflattering truth is not reordered or hidden', () => { expect(by('C').pct).toBeLessThan(by('B').pct); const order = rows.map((r) => r.tier); expect(order.indexOf('B')).toBeLessThan(order.indexOf('C')); // tier order, not rank order }); test('the sample is always shown, even when the rate is withheld', () => { for (const r of rows) expect(r.total).toBeGreaterThan(0); }); }); describe('CLV — the panel must never publish the untrustworthy number', () => { const live = { beat_close_pct: null, clv_sample: 937, clv_beat: 34 }; test('null beat_close_pct yields NO number and names the guard', () => { const c = p.clvPanel(live); expect(c.publishable).toBe(false); expect(c.beatClosePct).toBeNull(); expect(c.reason).toBe('capture_reliability'); }); test('it does NOT fall back to clv_beat/clv_sample (34/937 = 3.6%)', () => { const c = p.clvPanel(live); // the derived value would be ~3.63; assert we returned ABSENCE, not that number const derived = (34 / 937) * 100; expect(c.beatClosePct).toBeNull(); expect(c.beatClosePct).not.toBe(3.6); expect(c.beatClosePct).not.toBe(Math.round(derived * 10) / 10); expect(JSON.stringify(c)).not.toMatch(/3\.6/); }); test('the real sample IS surfaced (accrual is honest, the rate is not)', () => { expect(p.clvPanel(live).sample).toBe(937); }); test('when the guard passes, the real number is used as-is', () => { const c = p.clvPanel({ beat_close_pct: 61, clv_sample: 1200 }); expect(c.publishable).toBe(true); expect(c.beatClosePct).toBe(61); }); test('junk aggregate degrades to the honest not-published state', () => { for (const v of [null, undefined, {}, { beat_close_pct: 'x' }]) { expect(p.clvPanel(v).publishable).toBe(false); expect(p.clvPanel(v).beatClosePct).toBeNull(); } }); }); describe('client-side slicing (the endpoints ignore ?sport=)', () => { const acc = { overall: { sample: 937, overall: { pct: 58 }, byGrade: BY_GRADE, min_sample: 20 }, sports: { mlb: { sample: 526, overall: { pct: 62 }, byGrade: {}, min_sample: 20 }, wnba: { sample: 411, overall: { pct: 54 }, byGrade: {}, min_sample: 20 } } }; test('all / mlb / wnba each read their own canonical numbers', () => { expect(p.sliceFor(acc, 'all').sample).toBe(937); expect(p.sliceFor(acc, 'mlb').sample).toBe(526); expect(p.sliceFor(acc, 'mlb').pct).toBe(62); expect(p.sliceFor(acc, 'wnba').pct).toBe(54); }); test('an unknown sport is empty, never a silent fallback to overall', () => { expect(p.sliceFor(acc, 'nfl').sample).toBe(0); expect(p.sliceFor(acc, 'nfl').pct).toBeNull(); }); }); describe('the page itself', () => { test('renders no hard-coded percentage — every figure comes from the aggregate', () => { const hard = page.match(/\b\d{2}%/g) || []; expect(hard).toEqual([]); }); test('carries the honest CLV copy and the hollow explanation', () => { expect(page).toMatch(/NOT PUBLISHED YET/); expect(page).toMatch(/reliability check/); expect(page).toMatch(/too few settled reads to quote a rate/); }); test('names the held pieces honestly rather than faking them', () => { expect(page).toMatch(/Calibration and accuracy-over-time are not shown/); expect(page).toMatch(/not because they are unflattering/); }); test('reads the canonical endpoints, uncached', () => { expect(page).toMatch(/\/api\/accuracy/); expect(page).toMatch(/\/api\/ledger\/model/); expect(page).toMatch(/cache: 'no-store'/); }); test('exposes NO itemized grade rows — aggregate only (Build-1 gate holds)', () => { expect(page).not.toMatch(/\/api\/snapshot/); expect(page).not.toMatch(/player/i); }); });