Reality assessment: the forward model exists, wired to the wrong side of the pipe

READ-ONLY. src/ and web/ untouched.

Inventoried every forward-model component against the real objective -- a
forward matchup projection, not an edge number. The finding is that all of it
already exists and is already loaded in production, and 100% of it sits
DOWNSTREAM of the grade in challenger columns nothing serves. The served p_win
reads three features and a game log; it has never seen a pitcher.

Inputs are HAVE, not missing: statcast_aggregates carries 1,354 rows (750
pitchers, 604 batters) with exit velo, launch angle, barrel, hard-hit, whiff,
chase, pitch mix, GB/FB, arm angle, and handedness complete on every row. Real
gaps are team defense and catcher/umpire. So Stage A is a plumbing-and-
modelling job, not a data-acquisition job.

Found along the way: the Statcast nightly refresh is unreachable code. tick()
returns for any hour not in HOURS_UTC (14,19,22,1,3) and the refresh block
then tests h === 11, which that guard can never admit. The mechanism data has
been frozen at its 2026-07-21 backfill for 13 days, and the block's own
failure alert sits in the same dead branch -- the identical silently-guarded-
out shape as the settlement outage.

Design shows the counter: every factor label the SIGNAL BREAKDOWN renders is a
restatement of recent frequency (l5_hot_vs_line, l20_over_line, back_to_back,
home_game) plus several structurally-NBA labels (referees, coach pace,
starters out) inside a baseball product. Not one names a pitcher, pitch type,
handedness or park. The card's forward-read slots already exist and go
unfilled -- the surface needs feeding, not redesigning.

On what changes: the prior measurements were outcome-accuracy, not edge, so
the metric was right and the question was narrow. proj-v1.1 and hits-v1 stay
correctly refuted as DISTRIBUTION swaps on thin inputs -- neither tested a
matchup-fed projection. arch-v1 is a market-relative nudge by construction and
is the one component genuinely measured on the wrong axis. AT CEILING is
provisional: measured only against features the champion already reads.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
This commit is contained in:
Kev
2026-08-03 00:53:56 -04:00
parent d8bf7765db
commit c551bf0340
3 changed files with 299 additions and 0 deletions
+29
View File
@@ -3,6 +3,35 @@
## Last Updated
2026-08-03
## Session 79 (2026-08-03) — Reality assessment vs the FORWARD-PROJECTION objective ✅
Spec: `specs/forward-model-reality-assessment.md`. READ-ONLY (src/web untouched).
- **Finding: the forward model's parts all EXIST and are all wired downstream of
the grade.** `probabilityEstimator` (the served p_win) reads 3 features + the
game log. Statcast/arsenal/park/weather/platoon/archetype load in
`snapshotService` AFTER grading, into challenger columns nothing serves.
`mlbContext` has zero consumers.
- **Statcast nightly refresh is DEAD CODE by guard** — tick() returns for hours
not in HOURS_UTC (14,19,22,1,3); the block tests h===11. Data frozen at
2026-07-21 (13 days stale); its own failure alert is in the same dead branch.
- **Inputs are HAVE** — 1,354 statcast rows, handedness complete both sides,
pitch mix/velo/break, GB/FB, barrel, exit velo, launch. MISSING: team defense
(OAA/DRS), catcher framing/umpire. PARTIAL: batter GB/FB (in `metrics` JSONB),
lineup slot (role tables 0 rows).
- **Design shows the COUNTER.** Factor labels are all `l5_hot_vs_line`-family
plus NBA leftovers (refs, coach pace). The card's forward-read slots
(archetypeBlend "Why this grade", vyndrIntel.matchup, propDNA) exist and go
unfilled. Needs feeding, not redesign.
- **STAGED DISTANCE:** Stage A (forward baseball model) = ONE real build, ZERO
data acquisitions — assemble hitter profile × pitcher stuff × conditions as the
SPINE with frequency demoted to a prior; risk is sample, not feasibility.
Stage B (calibrated + scouting surface) = short once A exists (clamp/calibration
already diagnosed + swap the factor vocabulary). Stage C (per sport) = blocked
on mechanism data we do not have for NBA/WNBA (ESPN is box scores, Python
service offline) and soccer is odds-api quota-blocked.
- **Verdict re-checks:** proj-v1.1 + hits-v1 stay refuted AS DISTRIBUTION SWAPS
(neither tested a matchup-fed projection); arch-v1 is market-relative by
construction = the one measured on the wrong axis; "AT CEILING" is provisional.
## Session 78 (2026-08-03) — Champion decomposed: the edge is a hit-rate counter ✅
Spec: `specs/champion-input-diagnosis.md`. READ-ONLY (src/web untouched);
4,159 tests green.