'use strict'; /** The withdrawal record โ€” spec: specs/read-integrity-harness.md ยง6. */ const wv = require('../../src/services/model/withdrawnVerdicts'); describe('withdrawnVerdicts', () => { it('records BOTH hits PROVES as withdrawn', () => { expect(wv.isWithdrawn('mlb', 'hits', 'defense_by_direction')).toBe(true); expect(wv.isWithdrawn('mlb', 'hits', 'pitcher_contact_profile')).toBe(true); }); it('does not withdraw a factor that was never proven', () => { // platoon_severity never returned PROVES (n=452 < 500). Withdrawing it would // imply it once stood, which is its own falsehood. expect(wv.isWithdrawn('mlb', 'hits', 'platoon_severity')).toBe(false); expect(wv.isWithdrawn('mlb', 'hits', 'park_hits')).toBe(false); }); it('is scoped per stat โ€” a hits withdrawal says nothing about total_bases', () => { expect(wv.isWithdrawn('mlb', 'total_bases', 'defense_by_direction')).toBe(false); }); it('APPENDS rather than replaces: the original verdict and evidence survive', () => { for (const w of wv.WITHDRAWALS) { expect(w.original_verdict).toBe('PROVES'); expect(w.original_evidence.n).toBeGreaterThan(0); expect(Array.isArray(w.original_evidence.ci)).toBe(true); } }); it('every withdrawal carries a measured cause and implicated readers', () => { for (const w of wv.WITHDRAWALS) { expect(w.cause).toMatch(/unordered-pagination/); expect(w.cause).toMatch(/2026-08-09/); expect(w.readers_implicated.length).toBeGreaterThan(0); expect(w.status).toBe(wv.STATUS.WITHDRAWN_PENDING_REAUDIT); } }); it('names the eligibility arithmetic for defense_by_direction AS arithmetic', () => { const d = wv.WITHDRAWALS.find((w) => w.factor === 'defense_by_direction'); expect(d.eligibility_note).toMatch(/422/); expect(d.eligibility_note).toMatch(/not a re-measurement/); }); it('records the honesty gap: both are STILL SERVED despite withdrawal', () => { const served = wv.servedButWithdrawn(); expect(served).toHaveLength(2); for (const w of served) expect(w.still_served_note).toMatch(/hitsFactors/); }); it('states a reinstatement path that requires a measured clean read', () => { for (const w of wv.WITHDRAWALS) expect(w.reinstatement).toMatch(/readIntegrity/); }); it('is frozen โ€” a withdrawal must not be mutated in place', () => { expect(Object.isFrozen(wv.WITHDRAWALS)).toBe(true); for (const w of wv.WITHDRAWALS) expect(Object.isFrozen(w)).toBe(true); }); it('withdrawalsFor filters by sport and stat', () => { expect(wv.withdrawalsFor('mlb', 'hits')).toHaveLength(2); expect(wv.withdrawalsFor('mlb', 'runs')).toHaveLength(0); expect(wv.withdrawalsFor('mlb')).toHaveLength(2); }); });