Measure the batter cluster: the proven set is empty, and hits is closed
PREMISE CORRECTION FIRST, because it defines the bar. total_bases has not
passed BAR 1. Its head-to-head is inconclusive at parity -- delta +0.004 to
+0.007 with a CI spanning zero -- and it is contaminated, and no feature of
its passed the gate. It was described last session as the first challenger
that did not LOSE, which is not the same as proven. If it is installed as the
frozen proven reference and every other stat is held to "the identical bar
total_bases cleared", the bar becomes "be inconclusive at parity" and the
whole cluster passes on a null result. The proven set is EMPTY.
HITS IS NOW A FINAL ANSWER. At n=803 it clears the gate's sample requirement,
so its features were properly TESTED rather than refused: every one fails on
effect size (max marginal |r| 0.053 against a 0.15 bar), every interaction's
incremental contribution collapses to about zero, and the model loses
head-to-head by 0.096 with a CI excluding zero. That is a well-powered
negative and hits should be closed rather than retried.
The rest are n-blocked: total_bases 383, rbi 391, home_runs 228, runs 188,
against a bar of 500. Two leads are worth carrying. home_runs barrel rate has
a marginal r of -0.135, and the sign matters -- higher barrel rate goes with
the counter OVER-predicting, which would be a correction rather than a new
predictor. And runs batterK x pitcherK has the largest incremental in the
cluster at +0.132, with a clean mechanism: strikeouts destroy plate
appearances, and a PA that never happens cannot score.
RBI deserves a caveat rather than a verdict. It is power times OPPORTUNITY,
and we ingest no baserunner state at all, so half its mechanism is missing. A
weak RBI result is evidence that we are modelling half the stat.
total_bases was held frozen: git diff on skillProjection against the prior
commit is empty. The counter is untouched.
Also fixed and verified in production: the point-in-time retention shipped
after yesterday's refresh had already run, so statcast_history was empty, and
its first run then failed on a hand-enumerated schema that had already drifted
from its source ("could not find the 'swing_pct' column"). The refresh itself
still succeeded and wrote all 1,387 aggregate rows, which confirmed the
best-effort guard in prod. The table now mirrors the source via LIKE and the
writer passes rows through whole. Verified live: 1,387 rows retained at as_of
2026-08-03. A usable point-in-time window starts 2026-08-04.
Stage B has nothing to calibrate. Everything now waits on a point-in-time
window and on sample -- both waiting problems, not building problems.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
This commit is contained in:
@@ -1375,6 +1375,36 @@ phased plan in the Session-57 conversation / BUILD-STATE Next section).
|
||||
deterministic bases-per-hit made P(TB>=2) EXACTLY P(hits>=1); non-degeneracy is
|
||||
locked by test.
|
||||
|
||||
## Batter cluster + the bar (Session 83 — non-obvious)
|
||||
- **total_bases has NOT passed BAR 1.** Its head-to-head is INCONCLUSIVE at
|
||||
parity (delta +0.004..+0.007, CI includes zero) and CONTAMINATED. It is
|
||||
frozen, but frozen as an *inconclusive* model — do NOT install it as "the
|
||||
proven reference standard", because then the bar other stats must clear
|
||||
becomes "be inconclusive at parity", which admits everything on a null result.
|
||||
**The proven set is EMPTY.**
|
||||
- **HITS IS CLOSED — a well-powered negative.** At n=803 it CLEARS the gate's
|
||||
sample bar, so its features were properly TESTED, not refused: max marginal
|
||||
|r| = 0.053 vs the 0.15 bar, every interaction's incremental ≈ 0, and the
|
||||
model loses head-to-head −0.096 with CI [−0.165,−0.029]. Don't re-run hits.
|
||||
- **Everything else is n-blocked:** TB 383, rbi 391, HR 228, runs 188 (gate needs
|
||||
500). Two leads worth carrying: `home_runs · barrel_pct` marginal r = **−0.135**
|
||||
(NEGATIVE — higher barrel goes with the counter OVER-predicting, i.e. a
|
||||
correction not a predictor), and `runs · batterK×pitcherK` incremental **+0.132**
|
||||
(largest in the cluster; mechanism = strikeouts destroy PA, and a PA that never
|
||||
happens cannot score).
|
||||
- **RBI is half-unmodellable today:** it is power × OPPORTUNITY and we ingest NO
|
||||
baserunner state. A weak RBI result is evidence we model half the stat, not
|
||||
that skill inputs fail for RBI.
|
||||
- **`statcast_history` retention is LIVE and verified in prod** (1,387 rows,
|
||||
as_of 2026-08-03). Two gotchas: the first run failed on a drifted hand-written
|
||||
schema (`swing_pct` missing) — the table is now `create ... (like
|
||||
statcast_aggregates)` and the writer passes rows through whole; and the
|
||||
refresh still succeeded during that failure, confirming the best-effort guard.
|
||||
A usable point-in-time WINDOW starts 2026-08-04 (as_of < game_date).
|
||||
- **`scripts/cluster-prove.js`** runs the whole both-ways program for any stat via
|
||||
`CLUSTER_STAT=`. Per-stat interaction sets are the TB map RE-WEIGHTED, never
|
||||
copied — reuse speeds the search and grants no pass.
|
||||
|
||||
## Active Skills
|
||||
- vyndr-voice (all user-facing output)
|
||||
- prop-analysis (grading methodology)
|
||||
|
||||
Reference in New Issue
Block a user