STATE: game_date root fixed, 64 voids reverted, grading blast radius flagged
This commit is contained in:
@@ -133,6 +133,51 @@ exist locally; harmless, the data restores completely.
|
||||
|
||||
---
|
||||
|
||||
## 🟢 game_date ROOT FIXED + 64 WRONG VOIDS REVERTED (2026-07-20 07:30 UTC)
|
||||
- **ROOT (not DNP, as first diagnosed):** PropLine emits **no `commence_time`**
|
||||
(grep-verified), so `ledgerService`'s `dateET(prop.game_time) ||
|
||||
dateET(gradedTs)` always fell through to the **GRADE clock**. A 01:00/03:00
|
||||
UTC snapshot is 21:00/23:00 ET the PREVIOUS day → tonight's props filed under
|
||||
yesterday → settlement correctly found no game → Order 1's void logic
|
||||
destroyed 64 real results.
|
||||
- **FIX — `src/services/gameBinder.js`:** binds each prop to a scheduled game by
|
||||
TEAMS across the ET window (grade date, +1, −1) and attaches the GAME'S own
|
||||
time/date/id, in `snapshotService` **before** grading and the ledger write, so
|
||||
ledger + retention + settlement all inherit one correct date.
|
||||
**PROVEN against the live schedule at the failing hour:** a `2026-07-20T03:00Z`
|
||||
grade (ET date 07-19, what the old code used) bound Steven Kwan to
|
||||
**game_date 2026-07-20**, `mlb:2026-07-20:401816188`.
|
||||
- **HARD CONTRACT:** unbindable → **nothing**. The grade-clock fallback is gone;
|
||||
ledgerService SKIPS and counts such rows. Verified live: a prop with an
|
||||
invented matchup returned `unresolved`, never a guessed date.
|
||||
- **Doubleheaders** are flagged `ambiguous`, never attributed. Real case already
|
||||
in data: `mlb:2026-07-11:MilwaukeeBrewers@PittsburghPirates(Game1)`.
|
||||
- **Retention had the same bug** (rows dated by the snapshot clock) — fixed to
|
||||
the bound game's ET date.
|
||||
- **64 wrong voids REVERTED** (60 mlb + 4 wnba), scoped exactly to
|
||||
`settlement_version=2 AND outcome='void' AND settlement_source='player_dnp'`.
|
||||
- **LIVE PROOF of the safety fix:** the next induced settle pass returned
|
||||
**`voided: 0, pending: 64`**. The old code voided all 64; the deployed code
|
||||
refuses to claim DNP on an unconfirmed absence.
|
||||
|
||||
### 🔴 STOP-AND-REPORT — the date bug also reaches GRADING (not just settlement)
|
||||
`computeFeatures.lookupTodayGame` calls the ESPN scoreboard with **no date
|
||||
param** — it takes whatever ESPN calls "today". A prop graded at 23:00 ET can
|
||||
therefore bind its `home_away` / `opponentAbbr` features to the WRONG game
|
||||
(yesterday's finished one), which feeds `opp_rank_stat` and the home/away factor.
|
||||
**Not fixed — flagged per the order's stop rule.** Blast radius:
|
||||
- **Grading: AFFECTED** (feature correctness at late-ET slots — 01:00/03:00 UTC).
|
||||
- **Settlement: FIXED** (this order).
|
||||
- **Retention: FIXED** (this order).
|
||||
- **Display/slate: NOT affected** — the board renders from the date-pinned
|
||||
schedule and joins grades by player+stat, never by ledger `game_date`.
|
||||
|
||||
### 🔶 STILL OPEN — the reverted 64 cannot settle yet
|
||||
Their `game_date` is still the OLD wrong value (Jul 17/18); the binder only
|
||||
corrects rows written from now on. They will retry and age to `unrecoverable`
|
||||
until their dates are corrected. **Correcting them is the first act of the heal
|
||||
order** — healing against wrong dates would simply re-fail.
|
||||
|
||||
## 🟢 RETENTION CLOCK TICKS ON ITS OWN (2026-07-20 06:05 UTC)
|
||||
Induced the REAL cron entrypoint rather than waiting for 14:00 UTC.
|
||||
- **Cron capture needed NO wiring — verified in code.** `snapshotScheduler`'s
|
||||
|
||||
Reference in New Issue
Block a user