STATE: Session 77 — dormant adjusters wired; env non-null proven, ledger row pending

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 21:41:21 -04:00
parent 7b25d97891
commit 535a7b70ea
+67 -1
View File
@@ -1,5 +1,5 @@
# VYNDR — STATE OF THE WORLD
### As of `6dd6f59` (main, DEPLOYED), 2026-07-21. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
### As of `7b25d97` (main, DEPLOYED), 2026-07-21. This file opens every future session. **Start with the CURRENT STATUS + OPEN ITEMS block below.**
---
@@ -131,6 +131,72 @@ 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 77 — DORMANT ADJUSTERS WIRED LIVE (2026-07-21)
The four-order plumbing gap is CLOSED. park + weather + platoon now reach live
grades. Pure input-wiring — **the 5 adjuster files are byte-identical** (verified
`git diff --quiet`).
## Phase 0 gate — all three inputs AVAILABLE at build
| Input | Availability | Source |
|---|---|---|
| Venue | **ALWAYS** 15/15 | schedule game object |
| First-pitch | **ALWAYS** | schedule `gameTime` |
| Opposing-SP hand | **declared 30/30 this afternoon** (morning locks precede it → platoon absent, correct) | probable `pitcherId` → statsapi hand |
Batter hand (`statcast.bats`) + MLBAM id were already on each grade.
## What was built
**`src/services/environmentContext.js`** (the wiring; adjusters untouched).
Fetches ONCE per snapshot: schedule, probable pitchers, ONE batched handedness
call, ONE Open-Meteo forecast per home park, batter splits per hitter.
`PARK_COORDS` (30 parks) lives here as public geometry (like the dome list), NOT
in an adjuster. Best-effort throughout — any failure → that prop archetype-only,
never a pipeline break.
**`attachChallenger` is now async** + takes `contextFor(grade)``{environment,
matchup}``adjust()` (which already accepted both).
## Independent attribution (each of 4 measurable separately)
Ledger columns `env_multiplier / env_park_base / env_weather_mod /
env_weather_state` + `challenger_adjustments` jsonb keeping archetype /
environment / matchup as SEPARATE entries. Not one blended delta.
## Combined bound (tested)
Coors slugger + wind-out + favourable platoon, all at once → **δ < 0.12**. Every
layer capped, total nudge clamped. Stacks lean, never re-forecast.
## ✅ PASS CONDITION MET — env_multiplier non-null (was 0 for 4 orders)
Proven END-TO-END on the live slate (buildContext + adjust against real feeds):
`venues_with_weather 15 · opp_declared 30 · pitchers_with_hand 30`.
| Park | env | compose |
|---|---|---|
| PHI | **1.179** | park 1.09 × wx 1.082 → **δ +0.041** |
| COL/ATL | >1 | hitter parks |
| CLE 0.929 · KC 0.937 | <1 | pitcher parks |
| **TOR/MIL** | park only | `wx 1 [dome_na]` — weather stands down, **park still applies** |
## 🔴 THE ONE HONEST GAP — not yet on a LEDGER ROW
Immutability refused to rewrite today's already-locked props (`ignoreDuplicates`),
so re-inducing wrote 0 new rows and **`env_multiplier` is still 0 on ledger rows**.
The wiring is PROVEN to produce the value (above); it lands on a row at the **next
NEW MLB lock**. Verify then:
```sql
select count(*) filter (where env_multiplier is not null) with_env,
count(*) filter (where challenger_adjustments::text like '%matchup%') with_platoon
from ledger_entries where user_id is null;
```
## Point-in-time / no lookahead
Weather = FORECAST for first pitch fetched at projection time. Platoon = split
entering the game. Neither reads settle-time.
## Still open (unchanged, NOT this order)
- **No settled row carries `p_win`** — all adjusters still unmeasurable until
tonight's locks settle.
- Read-card triplet gap · mappingHarness nomination flow · A/D emission ·
EV overconfidence · zero-push bug · edge_pct surfaces · 3 key rotations.
---
# 🟡 SESSION 76 — PLATOON SPLITS (regressed) (2026-07-21)