The receipts · published verbatim from the working file
The pitcher luck gap — arm-call validation, pre-registration
Frozen 2026-07-15 and pushed before the run. A ship/kill gate: does FIP predict next-year ERA beyond ERA? A pass authorizes forward-graded arm calls; a miss kills them. The final pitcher test on the reserved seasons.
Last changed
Pre-registration — the pitcher luck gap, the arm-call engine (H-ARMGAP)
Frozen 2026-07-15, before any 2022–2025 pitch was examined for the FIP→ERA relationship. The git timestamp of this file is the freeze receipt. One confirmatory run; results published regardless. This is the definitive pitcher study, and it carries a ship/kill gate: a pass ships the pitcher call engine, a miss kills it.
Motivation
Two prior studies established that CSW% is a real but modest pitcher process signal — it adds to next-year run prevention but does not beat the box score (H-ARM on ERA, H-ARM2 on FIP). The founder reframed the goal: stop hunting a predictive silver bullet, and instead do for arms what the engine already does for bats — strip the noise the pitcher does not control (the fielders → FIP) and CALL the gap between his results (ERA) and his noise-stripped quality (FIP). A pitcher whose ERA sits well below his FIP is running lucky and his ERA should rise; well above, unlucky, and it should fall. This is the hitter luck-gap engine, pointed at arms — and it is the canonical DIPS result (McCracken 2001), here tested on our own data before we ship a call on it.
Exploratory findings (TRAIN pairs 2015→16 … 2020→21, n=1,551)
catalyst/analysis/armgap_exploratory.py, guarded against the reserved
seasons. FIP is put on the ERA scale (the per-season constant aligning
IP-weighted FIP to IP-weighted RA9) so the gap is an honest expected-ERA
gap — without it, the raw FIP core sits ~3 runs low and every pitcher
reads "unlucky," a scale error the call simulation caught.
The foundation — predicting next-year ERA:
z(era_next) ~ z(era) + z(fip) (n=1,551)
ra9 beta +0.060 p = 0.071 (not significant)
fip beta +0.158 p < 0.0001
Once you know a pitcher's FIP, his current ERA adds nothing significant to predicting next year's ERA. FIP is the forward-looking signal; ERA is noise around it. Head-to-head, |r(fip, era_next)| = 0.198 beats |r(era, era_next)| = 0.164. Holds within role (SP fip beta +0.324, RP +0.145, both p<0.01, both dominating ERA).
The call, simulated (gap = ERA − FIP; buy = gap>0 unlucky, predict ERA falls; fade = gap<0 lucky, predict ERA rises):
|gap|>0.50: 867 calls 73.0% moved as called
|gap|>1.00: 378 calls 80.4%
|gap|>1.50: 162 calls 85.8%
The larger the mispricing, the more reliably it resolves. Honest caveat, declared here: this hit-rate is partly mechanical — an ERA far above its FIP is a high ERA, and high ERAs regress regardless. That is why the hit-rate is NOT the gate. The gate is the PRIMARY below, which is non-mechanical: it asks whether FIP knows where the ERA regresses to, beyond the mere fact that it regresses.
PRIMARY hypothesis (H-ARMGAP-1, the ship/kill gate)
On the reserved seasons:
z(era_next) ~ z(era) + z(fip)
Sample: pairs with predictor seasons 2022, 2023, 2024 (outcomes 2023, 2024, 2025), pooled. Pitchers with ≥500 pitches in the predictor season and ≥100 batters faced in the outcome season. FIP = (13·HR + 3·(BB+HBP) − 2·K)/IP + the season constant that puts it on the RA9 scale. ERA and RA9 are 9·runs_allowed/IP.
SUCCESS = the fip coefficient is POSITIVE and two-tailed p < 0.05. That is the non-mechanical claim the call rests on: the noise-stripped expectation carries real forward information about ERA that current ERA does not. Anything else is a MISS, published as a hit would be.
SECONDARY (reported, with criterion — expected fragile)
|corr(fip, era_next)| > |corr(era, era_next)|, pooled.
SUCCESS = the inequality holds. Pre-declared risk: the train margin is 0.034, and in H-ARM a larger CSW-over-ERA margin (0.107) flipped out of sample. The head-to-head may miss even if the primary passes; the call does not depend on it (the call uses the gap, i.e. both terms), so a secondary miss does not kill the engine.
TERTIARY (reported, no criterion)
- The call simulation on the reserved seasons (hit-rate by gap threshold), with the mechanical caveat above.
- The foundation within role (SP / RP).
- Does CSW% add to FIP for predicting next-year ERA (the leading-indicator angle — CSW stabilises faster than FIP within a season). Reported, not a criterion, and read with the H-ARM caveat that CSW's out-of-sample edge over ERA did not survive.
Pre-committed readings
- The ship/kill gate. If the PRIMARY passes, this authorizes building the pitcher arm-call engine: fade/buy calls on the ERA-FIP gap (the noise-stripped expected ERA vs the actual), filed with metric/threshold/window/timestamp like every other call, and graded forward in public — the moat. The engine is designed, built, and ratified separately (this does not authorize a live surface tonight); but a pass is the green light. If the PRIMARY misses, the arm-call engine is dead — CSW% stays a declared context number and nothing files a pitcher call.
- This is the LAST pitcher hypothesis tested on the 2022–2025 reserved seasons. Three pitcher studies have now spent them (H-ARM csw→era, H-ARM2 csw→fip, this fip→era). Whatever this returns, no further pitcher relationship is tested on this holdout — the next pitcher question waits for fresh reserved seasons (2026+ completing). Writing this down caps the multiple-comparisons erosion honestly.
- The dominance of FIP over ERA (fip beta > era beta) is REPORTED, not gated, because with ERA and FIP collinear (~0.7) the individual betas can be close; the gate is FIP's own significance, which is robust.
The way it can fail
- FIP is a small-margin winner over ERA on train (0.198 vs 0.164). A thin edge can vanish on ~1,000 out-of-sample pairs.
- The 2023 rule package (pitch clock, shift ban) sits inside the holdout and shifted the run environment mid-window; the FIP→ERA link is tested through it.
- If the primary comes back significant-but-tiny, the engine ships on a weak foundation — which is why the gate is significance, and the strength (dominance, head-to-head, hit-rate) is reported alongside so the founder ratifies the BUILD with the full picture, not just a P/F.
Caveats declared in advance
- Third pitcher test on these reserved seasons (see pre-commitment 2). The specific FIP→next-ERA relationship has not been computed on any reserved season before this freeze; H-ARM/H-ARM2 tested csw→era and csw→fip. What I have already seen on the reserved seasons: the year-over-year stability of ra9 (0.225) and fip (0.354), printed by H-ARM2. Neither is the quantity under test here.
- Season isolation is imperfect, as in every study. 2022–2023 were H2's holdout; 2024–2025 were H-BT's train years. Neither involved FIP→ERA.
- 2026 excluded (in progress, no
components_pit_2026). - One evaluation.
catalyst/analysis/armgap_confirmatory.py, committed in the same commit as this file, before it is run.
Integration gate
PRIMARY pass → the arm-call engine is authorized to be designed, built, validated on its own terms, ratified by the founder, and its first calls published and forward-graded. It does NOT authorize a ranked prospect board or ranking pitchers by the gap without its own design review. Its honest boundary: the call is a regression-to-quality claim on established pitchers, graded in public — not a prospect ranking.
PRIMARY miss → no arm calls, no engine. CSW% remains a declared context number on the pitcher pages, and the pitcher pages otherwise stand.