Fixes the "slot is already filled" simulation error when First Four games
have already been played and their winners advanced to the Round of 64.
Changes:
- Fix FF→R64 validation to allow a filled R64 slot when the corresponding
First Four match is already complete (the original bug)
- Fix isComplete guard for E8/FF/Championship: derive loser from stored
participant IDs when loserId is null rather than re-simulating a real game
- Add round count validation for all rounds (R32 16, S16 8, E8 4, FF 2, Champ 1)
to catch malformed brackets before the hot sim loop instead of producing
silent garbage output
- Add participant1Id null check in the First Four path (mirrors the no-FF path)
- Add console.warn when participant IDs are missing from DB (fall-back to
average strength instead of crashing)
- Import NCAA_68.regions from bracket-templates.ts instead of duplicating the
hardcoded fallback in each simulator
- Fix duplicate step-9 comment number in ncaam-simulator.ts
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- NCAAM: KenPom AEM logistic formula (1/(1+exp(-diff/7.5))), data through 2025-26 March 15
- NCAAW: Barttorvik Barthag Log5 formula (A*(1-B)/(A*(1-B)+B*(1-A))), same bracket structure
- Both simulators: 50,000-iteration Monte Carlo, First Four simulation, honors completed matches
- Track E8+ placements only: champion, finalist, FF losers (3rd/4th), E8 losers (5th–8th)
- Add bracket configuration validation: null R64 slots must exactly match First Four mapping
- Fix DEFAULT_SCORING_RULES to 100/70/45/45/20/20/20/20 (3rd/4th=45, 5th–8th=20)
- Align scoring constants across simulate route, expected-values display, and server action
- Zero out EVs for non-bracket participants on every simulation run (prevents EV inflation)
- Add EV total invariant warning (expected ~340) on expected-values admin page
- 98 unit tests across NCAAM, NCAAW, and UCL simulators — all passing
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>