Fix /gauntlet freezing: shadow-backfill now reads from Supabase
Root cause: scripts/backfill-shadow-signals.ts read data/paper-trade/ledger.json directly from the filesystem. In the container this file is frozen at whatever shipped in the Docker image, while production writes go to Supabase. Result:
Root cause: scripts/backfill-shadow-signals.ts read data/paper-trade/ledger.json directly from the filesystem. In the container this file is frozen at whatever shipped in the Docker image, while production writes go to Supabase. Result: the script kept running cleanly but only saw 72 settled bets capped at Mar 21, and /gauntlet has been stuck on Portsmouth v Derby (Apr 7) for almost a week.
Changes:
- backfill-shadow-signals.ts now calls loadLedger() (Supabase via DATABASE_URL),
throws if it loads 0 settled bets so we fail loud instead of writing garbage.
- shadow-backfill.ts (the runner) surfaces script failures instead of swallowing
them, bumps the timeout from 60s to 5min (the real runtime is ~90s and was getting SIGKILLed), and verifies the output file was actually refreshed.
- /api/gauntlet attaches _meta.ageHours + stale flag so the next regression
can't silently serve week-old data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>