STATE: Session 74 — public park base pluggable, game-context capture live

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCNgGSt5qvcLxaeQqa7Zpj
This commit is contained in:
Kev
2026-07-21 01:23:28 -04:00
parent f33091ddb8
commit 5b4af67d93
+72 -1
View File
@@ -1,5 +1,5 @@
# VYNDR — STATE OF THE WORLD
### As of `3ac91c3` (main, DEPLOYED), 2026-07-21. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
### As of `f33091d` (main, DEPLOYED + fingerprinted live), 2026-07-21. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
---
@@ -131,6 +131,77 @@ exist locally; harmless, the data restores completely.
`specs/snapshot-retention.md` (Phase 2 report + schema) ·
`specs/audit-data/grade-collapse.md` · `specs/audit-data/gate-simulation.md`.
---
# 🟢 SESSION 74 — PARK BASE (public, pluggable) + GAME-LEVEL CAPTURE (2026-07-21)
## Phase 0 — the grain is cheaper than expected
Settle sees a player's game-log line (date + teams), **never venue or totals**.
But **ONE statsapi schedule call per game DATE** returns every game that day with
venue + linescore + scoringPlays. **Not per game, not per prop.** Verified: 15
games, 1 call.
## Public base — the ingestion was ALREADY DONE
`src/data/parkFactors.js` (static FanGraphs, S15) **is** the public base.
`src/services/parkBase.js` converts its 100-index to the composable multiplier
(COL 128 → **1.28**) instead of ingesting a second copy.
**🔴 THE COMMODITY LINE IS IN CODE, not just a comment.** Every resolution
carries `provenance`:
- public → `proprietary: false`, *"Commodity: a public number. Not a VYNDR
derivation."*
- derived → `proprietary: true`**reserved**, and only earned once it beats
the public base on the instrument.
**Never market "proprietary park factors" about the public base.**
**Honest-absent where even PUBLIC is thin** (`UNSTABLE_PUBLIC`: ATH/OAK/SAC/LV —
relocated club, temporary venue). Extend that set whenever a park opens or a
club moves; a missing entry means a confident factor for a stadium with no data.
## SOURCE-PLUGGABLE — the architectural point
`resolveParkBase()` is the ONLY accessor; public and derived return **identical
shapes**, so callers never branch on source. Self-derived swaps into the same
slot with nothing downstream rewritten. **A derived source with no factor
returns `absent` — it does NOT silently fall back to public** (that would turn a
commodity number into a proprietary claim).
## Game-level capture — LIVE
`game_context` (migration 035), **game grain, deduped on `game_id`, never copied
onto prop rows**. Named-purpose fields ONLY: venue → park factors · runs → run
environment · HR totals → HR factors. Nothing else stored.
- **Finals only** (an in-progress total is not a result).
- **No scoring plays → HR is `null`, not 0.**
- HR from scoringPlays is COMPLETE — every HR scores ≥ the batter.
- Runs nightly beside the settle pass (yesterday's date).
**Live fingerprint:** `POST /api/internal/gamectx/2026-07-20` → **15 games, 15
venues, 15 with HR totals, 0 duplicates.**
## 📅 ACCRUAL TARGET — "later" is a number
**150 home games/venue** (≈81/season) → **~1.9 seasons** before a self-derived
factor can be NOMINATED against the public base.
Live now: **15 games · 15 venues · 0 ready.** Track:
`GET /api/internal/gamectx/accrual`.
## Induced (live)
COL HR **+0.061** hitter · **+0.061** pitcher HR-allowed (same park, sign lives
in the STAT) · mirrored on under · SF negative · **TB weather_na=true with its
factor STILL applying** · ATH **absent** · strikeouts untouched.
## ⚠️ STILL OPEN (unchanged from S73)
**Park does not yet reach live props** — `snapshotService` still doesn't attach a
venue per prop and pass `environment` into `attachChallenger`. `parkBase` +
`parkMultiplier` + the challenger's `environment` slot are all ready; the
prop→venue lookup is the missing link.
**And still blocking ALL measurement: no settled row carries `p_win`.**
## Next
1. Attach venue → prop → `environment` (closes the park loop).
2. **Weather** — multiplies `park_base`; domes already `weather_na`; add
weather-actuals to `game_context` for later self-derived modulation.
3. Self-derived park factors at ~1.9 seasons of accrual.
---
# 🟡 SESSION 73 — PARK FACTORS (derived, composable) (2026-07-21)