S11 (a1): live tracking — the read locked, the game watched
MLB statsapi + WNBA ESPN live boxscores -> per-player current values
(live:{sport}:{date} TTL 90s, /api/live/:sport + Next proxy). Pure
propState math (HIT / ON PACE / NEEDS N / HOLDS / LINE PASSED — never
red in-progress), attachLiveProgress strip join on nameKey+statType,
proximity-to-hit slate float, StatStrip LiveTracker in the ROW-GRAMMAR
outcome slot (spec amended + lock test updated). Grades never change
in-game — tracking, labeled as such. 2698 -> 2757 tests, web build 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -967,6 +967,40 @@ phased plan in the Session-57 conversation / BUILD-STATE Next section).
|
||||
weight files competed with Inter + CSS on slow 4G). Measure before/after
|
||||
via PageSpeed post-deploy — not runnable from the box.
|
||||
|
||||
## Live Tracking (Session S11, A1 board — non-obvious)
|
||||
- **GRADES NEVER CHANGE IN-GAME.** `liveTrackingService` + `/api/live/:sport`
|
||||
produce per-player CURRENT box values; `web/src/lib/liveProgress.js` turns
|
||||
them into PROTO-OUTCOMES rendered in the ROW-GRAMMAR outcome slot
|
||||
(`StatStrip.LiveTracker`). Spec = `specs/LIVE-TRACKING.md`; slot-6 + color
|
||||
amendments are locked in `rowGrammar.test.js` — an in-progress prop is
|
||||
NEVER red (green = hit/on-pace/holding, amber = needs/line-passed).
|
||||
- **THREE MLB stat maps now exist on purpose** — do NOT merge them:
|
||||
`featureCache.MLB_LOG_FIELD` (features), `outcomeService.MLB_LOG_FIELD`
|
||||
(settlement, game-log rows pick ONE group by position), and
|
||||
`liveTrackingService.LIVE_BOX_FIELD` (live boxscore carries BOTH
|
||||
stats.batting AND stats.pitching per player → each stat names its group,
|
||||
and innings_pitched parses in THIRDS: '5.2' = 5⅔ — parseFloat is wrong).
|
||||
Adding an MLB stat_type = wire all three.
|
||||
- **Absent beats zero, live edition:** a player not yet in the game has
|
||||
EMPTY `stats.batting`/`stats.pitching` objects (MLB) or `didNotPlay`/empty
|
||||
stats row (ESPN WNBA) → he is OMITTED from the live index. Never coerce to 0.
|
||||
- **Quota shape:** `live:{sport}:{date}` TTL 90s is the shared window — 1
|
||||
schedule (`hydrate=linescore`, so inning progress costs no extra call) + 1
|
||||
boxscore per live game per 90s TOTAL across all users; zero boxscore calls
|
||||
when nothing is live. The Slate polls `/api/live/{sport}` every 60s ONLY
|
||||
while live mlb/wnba games are on screen. The route never fetches for
|
||||
unwired sports (short-circuits before the service).
|
||||
- **The strip join needs `statType`** — `buildPlayerStripsFromProps` now puts
|
||||
the canonical lowercase stat key on every strip prop (`stat` is the short
|
||||
display label like 'TB' and can't be joined on). attachLiveProgress only
|
||||
touches graded, unsettled, non-dead props, and computes state vs the
|
||||
LOCKED line (`gradedAt.line`). Under semantics are HOLDS-IF: an under is
|
||||
never 'hit' until the settle pass; exceeded → amber LINE PASSED, not red.
|
||||
- **Actions are suppressed while live** (`!p.live` on ParlayBtn/BookIt —
|
||||
the pre-game market for a locked line closed at first pitch); the label
|
||||
"TRACKING — READ LOCKED PRE-GAME" renders once per live card (GameCard,
|
||||
dim — it's meta, not a caution signal).
|
||||
|
||||
## Active Skills
|
||||
- vyndr-voice (all user-facing output)
|
||||
- prop-analysis (grading methodology)
|
||||
|
||||
Reference in New Issue
Block a user