Product / Track Record
What did we claim, how did we test it, and how did it do?
A decision tool is only as good as its record. Every model and recommendation here was tested where the data allowed it, and each claim says how: 32 were forward-tested (built on earlier seasons, scored on a later one), 10 cross-validated,
6 compared with a public measure, 18 in-sample (year-to-year repeat rates included: they describe the data, they don’t forecast it) and 1 a build check. Each verdict comes from one of a few written rules, applied to the claim’s own numbers and their noise. Here’s every claim, including the ones that
failed. Open recommendations are listed with the prediction each makes now and the metric and date they’ll be graded on.
Claims that held 23 of 67 tested · 13 of 32 forward-tested
Partly held 29 inside the noise, in-sample with no interval, or true for part
Failed 13 no better than the baseline, or no effect
Open recommendations 9 graded between Nov 2026 and the end of 2027
How a verdict is decided
- Beats a baseline
- Pass: better than every baseline shown, and better than the strongest one by more than the noise (a 95% interval that clears zero, or a significant majority of test seasons); with no noise estimate, by at least 5% less error or 10% more r. Partial: better than the strongest baseline but inside the noise, better than a weaker baseline only, or better for some groups only. Fail: no better than any baseline (under 1% less error or 2% more r counts as no better unless it clears the noise).
- An effect exists
- Pass: its 95% interval clears zero in the claimed direction (2+ standard errors). Partial: the claimed direction, but inside the noise or with no interval (most in-sample checks have none). Fail: the wrong direction, or a correlation under .10. Open: nothing to test yet (a rule that has flagged no one).
- A warning sign
- Pass: the relative risk's 95% interval sits above 1. Partial: above 1 but the interval reaches 1, or one sign passes and another doesn't. Fail: at or below 1. Open: under 10 injuries among the flagged, too few to tell.
- Luck that doesn’t repeat
- Pass: every 95% interval includes zero. Partial: an interval clears zero but r stays under .20. Fail: r of .20 or more with an interval above zero.
- Agreement
- Pass: r of .70 or more in every season or group shown; for dollar figures, a mean gap inside our own model's held-out error and no lean to one side (sign test p ≥ .05). Partial: some of it. Fail: no season or group reaches .40, or the gap is bigger than our own error.
- Enough history
- Pass: fewer seasons do worse and more seasons change the error by under 0.005 WAR. Partial: otherwise.
- Calibration
- Pass: within 3% of the target. Partial: within 15%. Fail: further off.
- Build check
- Pass: no violations at the last build.
Design Verdict
Pitching
- Partial Keystone Stuff predicts next season’s results better than this season’s results do Forward-testedTest: model trained on 2024 pitches only, graded 2025, scored on 2026 results; 324 pitchers; baseline: 2025 results r = .49 vs. .45; difference +0.03 (95% interval −0.07 to +0.13) An edge inside the noise. The cross-fit grades used elsewhere showed .60, but that season’s model had seen 2026 pitches, so those numbers measure stability, not prediction. Rule: An effect exists
- Pass Keystone Stuff agrees with the public standard (FanGraphs Stuff+) Agreement with a public measureTest: 469 pitchers, 2026 r = .85 Only the correlation is published; FanGraphs’ own values are never shown. Rule: Agreement
- Partial Keystone Location measures command Agreement with a public measureTest: vs. same-season walk rate, 469 pitchers r = −.69 (better Location, fewer walks) Rule: Agreement
- Fail Location adds to Stuff for predicting next season’s runs Forward-testedTest: model trained on 2024 pitches only, graded 2025, scored on 2026 results; 324 pitchers; baseline: Stuff alone combined Pitching grade r = .48 vs. Stuff .49; Location alone −.03 Command doesn’t carry forward as runs; Stuff does the forecasting. We use Location to diagnose walks, not to project runs. Rule: Beats a baseline
- Fail Location predicts next season’s walks better than last season’s walk rate Forward-testedTest: same time-ordered design, 324 pitchers, 2025 grade → 2026 walk rate r = .46 vs. .53 for 2025’s walk rate A real signal, but last season’s walk rate forecasts walks better. Location explains why a pitcher walks people; it doesn’t replace his walk rate. Rule: Beats a baseline
- Fail Stuff forecasts pitchers the model has never seen Forward-testedTest: the same time-ordered design, 4 random halves of the pitchers: the model trains on one half’s 2024 pitches and grades the other half in 2025; scored on 2026 run value; baselines: those pitchers’ own 2025 results, and Stuff for pitchers the model has seen (same training size); range across the halves unseen r = .39 (.29–.51) vs. .46 (.42–.49) for their 2025 results and .47 (.38–.54) for seen pitchers For a pitcher it has never seen, Stuff forecasts worse than his own results and worse than for a pitcher it has seen: on a new arm with a thin record it is an early read, not a better one. Half the pitchers each time, so each model trains on about half as many pitches as the main test; compare unseen with seen (same size), not with the main test's r. Rule: Beats a baseline
- Pass Cutting a flagged dead-weight pitch helps Forward-testedTest: 11 pitchers flagged on 2025 data, graded on 2026; baseline: flagged pitchers who kept the pitch Cut it: +0.59 runs/100 (5) vs. kept it: −0.13 (6); gap +0.73 (95% interval +0.08 to +1.38; Welch t 2.8, 6 df, p = .034) Observational and small (5 pitchers cut it): pitchers who change may differ in other ways. With groups this small the interval uses Welch’s t, not two standard errors. The 2025 flags were picked with Stuff from a model trained on 2024 only. Rule: An effect exists
- Fail Tighter pitch-to-pitch tunnels produce more whiffs In-sampleTest: 561,742 swings on the second pitch of a pair, 2025–26, controlling for pitch types, count, velocity gap, second pitch's velocity, second pitch's movement, second pitch's location, platoon matchup, season; placebo test: the same model with the pitcher’s arsenal-level tunnel added pair-specific (placebo-adjusted), 3 in tighter: −0.07 pts whiff (95% interval −0.21 to +0.06); before the placebo control: +0.4 pts (95% interval ±0.13); 2025: +0.4, 2026: +0.3; arsenal-level tunnel +1.8 pts The pair effect was the arsenal’s: once how closely a pitch tracks the pitcher’s other pitches is in the model, the pair’s own tunnel adds nothing that clears the noise. Going forward (fit on 2025, scored on 2026) the pair terms add about 11% of what the arsenal term adds. On a 23% base whiff rate. The Sequencing page no longer makes pair calls; the arsenal-level tunnel is a pitch-design input. Rule: An effect exists
- Fail Predictable pitchers get hit harder In-sampleTest: 541 pitcher-seasons (375 pitchers), 2025–26 stacked: predictability vs. results beyond Stuff in the same season r = −.01 (95% interval −.09 to .06, bootstrap over pitchers); by season 2025: −.06 (275), 2026: .05 (266) No detectable cost; we don’t coach unpredictability for its own sake. Rule: An effect exists
- Partial Pitch order adds to results beyond the pitch itself In-sampleTest: placebo test, 2025–26: the real previous pitch vs. a random pitch of the same type by the same pitcher, with the pitcher’s arsenal-level tunnel in the model; in-sample on every outcome (2 standard errors to count), and forward (fit on 2025, scored on 2026) In-sample, pair terms that clear: whiffs (pair separation −0.12 pts), whiffs on different pitch types (pair separation −0.13 pts), chases (pair tunnel +0.45 pts), chases (pair separation +0.19 pts), run value (pair tunnel +0.10 runs/100). Forward: whiffs +11% of the arsenal term’s gain (clears the noise); chases 0% of the arsenal term’s gain (inside the noise) The site’s word for it: barely. Some pair terms clear in-sample, but they mix signs across outcomes and the forward gain is a fraction of the arsenal term’s, so pitch order isn’t coached. Graded from that word: none is a fail, a sliver (barely) partial, some a pass. Rule: An effect exists
Projections
- Pass Keystone projections beat “same as last year” Forward-testedTest: 13 seasons forecast blind (2012–19, 2022–26); 8,767 hitter- and 7,276 pitcher-seasons RMSE hitters 1.21 vs. 1.39; pitchers 0.96 vs. 1.09 WAR; better in 26 of 26 role-seasons “Same as last year” is the weakest baseline. Keystone is Marcel with a measured hitter aging curve; its gain against Marcel with the textbook table is the claim “Measured aging beats the textbook aging table”. Rule: Beats a baseline
- Pass Three seasons of history is enough Forward-testedTest: same 13-season test with 1–5 seasons of history 1 yr: 1.259/.969 · 2 yr: 1.221/.959 · 3 yr: 1.209/.955 · 4 yr: 1.206/.956 · 5 yr: 1.206/.955 Hitter/pitcher RMSE. Seasons four and five change accuracy by at most 0.003 WAR, so we stop at three. Rule: Enough history
- Partial Measured aging beats the textbook aging table Forward-testedTest: curve fit only on seasons before each target, 13 seasons; baseline: Marcel with the textbook table Hitters 1.220 → 1.209 (13/13 seasons); pitchers 0.955 → 0.957 (4/13) Adopted for hitters only; pitchers keep the table. Rule: Beats a baseline
- Fail Statcast skills make projections more accurate Forward-testedTest: fit on earlier seasons, scored on 2024, 2025, 2026 Hitters 1.342 → 1.343 (2/3); pitchers 0.922 → 0.924 (1/3) Not adopted: tracking data didn’t add accuracy beyond three years of WAR. Rule: Beats a baseline
Defense
- Pass Expected outs separate easy plays from hard ones Held-out (cross-validated)Test: every ball in play 2021–26 (697,602), one model per season, scored out of fold (5 folds by game: no ball is predicted by a model that saw its game); baseline: every ball at the league out rate Brier 0.105 · 0.106 · 0.100 · 0.099 · 0.099 · 0.097 vs. 0.209 with no model Rule: Beats a baseline
- Partial Team expected-outs defense agrees with Savant OAA Agreement with a public measureTest: 30 teams a season, 2023–26: the zone model’s team outs above expected vs. Savant OAA summed over each club’s fielders all balls: r .64/.72/.71/.64; balls Savant grades: r .60/.68/.71/.67; infield liners and pop-ups: r .24/.40/.11/.04 Graded on all balls and on the balls Savant grades. Infield liners and pop-ups, which OAA doesn’t grade, agree weakly: that part of the team number is the zone model’s alone. Rule: Agreement
- Partial Zone ratings agree with Savant OAA Agreement with a public measureTest: fielders with 150+ balls in their zone, 2023–26 CF: r .47/.74/.71/.68; RF: r .72/.76/.82/.59; SS: r .36/.23/.34/.08 CF mixed, RF mixed, SS weak. Individual grades use Savant OAA; the zone model maps where a team leaks. Rule: Agreement
- Pass Team defense repeats year to year In-sampleTest: team outs above expected, consecutive seasons (30 teams; 95% intervals); a repeat rate, not a forecast 2021→2022: r .36 (.003 to .64) · 2022→2023: r .36 (.005 to .64) · 2023→2024: r .59 (.29 to .78) · 2024→2025: r .37 (.01 to .64) · 2025→2026: r .54 (.23 to .75) With 30 teams each interval is wide. Rosters and positioning change, so last year’s team number is a starting point, not a forecast. Rule: An effect exists
- Partial Three seasons of fielding runs beat one Forward-testedTest: built on 2023–25 (weights 5/4/3, regressed), scored on 2026, every arm on the same players (1,500+ outs in 2026 and a 2025 season); baselines: 2025 alone, raw and regressed the same way Fielders (n 239) RMSE 8.2 vs. 8.4 regressed and 12.4 raw (r .48 vs. .44 and .34); Catchers (n 43) RMSE 10.9 vs. 10.5 regressed and 18.5 raw (r .60 vs. .65 and .37) Against one raw season the gain is large. Against one season regressed the same way, three seasons’ error is 0.2 runs lower for fielders and 0.4 runs higher for catchers: most of the old gain was regression, not the extra seasons. Rule: Beats a baseline
- Pass Position fielding ratings predict next season’s fielding runs Forward-testedTest: the depth chart’s rating for 2025 and 2026, each built only on the three seasons before, vs. what the player did at that position (runs per full season); 421 player-position-seasons with 2,000+ batters defended, catchers excluded; baseline: every player at the average RMSE 8.19 runs vs. 9.35 for the average; r = .46 (95% interval .39 to .54); slope 0.99 A slope of 0.99 means the ratings are about the right size. Error by the evidence behind the rating (weighted batters defended at the position before): 0–10,000, 9.05 runs; 10,000–25,000, 8.39 runs; 25,000+, 7.67 runs. Every player at the average is the weakest baseline; a regressed prior season isn’t scored on this test. On the multi-season test (“Three seasons of fielding runs beat one”, other players and filters), one season regressed came within 0.2 runs of three seasons for fielders, so one regressed season might match much of this gain. Scored against one actual season, so the error includes that season’s own noise. The interval treats player-seasons as independent; a player can appear in both target seasons. Rule: Beats a baseline
Catching
- Pass Keystone framing matches the public measures Agreement with a public measureTest: 2024–26 vs. Savant (57 catchers a season); 2021–26 vs. FanGraphs r = .97 · .97 · .98 · .92 (Savant); .85 · .94 · .95 · .94 · .93 · .92 (FanGraphs) Rule: Agreement
- Partial Framing is worth less under the ABS challenge system In-sampleTest: spread of framing among regular catchers; repeatability 2025 → 2026 vs. before Spread 8.2 → 4.7 runs (57%); carry-over slope 0.64 → 0.34; 83% of the drop (measured on variances) is umpires’ own calls, the rest overturned challenges One season of the challenge era and no interval; re-measured every year. Rule: An effect exists
- Partial Re-valuing old framing improves catcher projections In-sampleTest: 2026 forecast for 98 catchers, framing before 2026 at 57%; baselines: framing as published, and no framing at all RMSE 1.139 as published → 1.096 re-valued; 1.082 with framing dropped (WAR) Dropping pre-2026 framing scored best on this in-sample test, by 0.014 WAR. We keep 57% because 2026 itself measured framing at 57% of its old spread, not at zero; 2027 is the first blind test. Rule: Beats a baseline
Roster
- Pass Depth-chart playing time beats Marcel’s formula Held-out (cross-validated)Test: every club’s opening-day 40-man, 2022–26 (2,753 hitter- and 3,465 pitcher-seasons), each season forecast blind PA error 176 → 162; IP 46.6 → 41.7; with opening-day status 155 / 36.4 Rule: Beats a baseline
- Fail Depth charts project team wins better than simpler playing time Held-out (cross-validated)Test: 150 team-seasons, 2022–26, centred within season; baselines: Marcel playing time, the best 13 + 13 RMSE 9.47 wins vs. 9.41 (Marcel playing time) and 9.53 (best 13 + 13); r 0.652 vs. 0.655 and 0.644 At the team level it is no better than the simpler methods; its value is in who plays where, which the PA and IP test above measures. Rule: Beats a baseline
- Pass Every brief fits one roster Build checkTest: automated check at every build: 9 briefs vs. the Winter Plan (8 scenarios) 0 conflicts; one starter per position, 40-man ≤ 40 in every scenario Added after two briefs both claimed second base. It checks names, positions and the 40-man. Tender values are measured in each player’s role on the plan’s roster, and a separate guardrail fails the build if a tender call would differ between today’s roster and the plan’s. Rule: Build check
Outlook
- Partial Run-based records predict next season better than the real record Held-out (cross-validated)Test: 150 team-seasons, 2021–2026, each season held out; 95% intervals resample whole clubs; baseline: the actual record error 10.3 wins (actual) → 9.9 (Pythagorean; gain −0.003 to +0.69), 9.9 (BaseRuns; gain −0.09 to +0.76); every club at .500: 12.5 Forward in time (fit only on earlier seasons, 120 team-seasons): actual 9.8, Pythagorean 9.3, BaseRuns 9.4. Neither gain clears zero. Pythagorean and BaseRuns predict about equally well. Rule: Beats a baseline
- Fail Adjusting for contact quality sharpens the record further Held-out (cross-validated)Test: same design; baseline: plain BaseRuns 10.1 wins vs. 9.9 for plain BaseRuns The contact step repeats a little (r .30, 95% interval .14 to .44): park, speed and defense live in it. Rule: Beats a baseline
- Partial Run-timing and sequencing luck don’t repeat In-sampleTest: the same team in consecutive seasons; 95% intervals; a repeat rate, not a forecast run timing r = .04 (−.12 to .20); sequencing r = .16 (.001 to .31); one-run record r = −.10 (−.26 to .06) Run timing: can’t be told from zero. Sequencing: its interval clears zero, so a sliver repeats. One-run record: can’t be told from zero. Rule: Luck that doesn’t repeat
- Partial Team projections track real wins Held-out (cross-validated)Test: 150 team-seasons, 2022–26, each forecast from opening-day rosters by a model that never saw that season; baselines: Marcel playing time, last season’s BaseRuns record r = .65, RMSE 9.47 wins vs. 9.41 (Marcel playing time) and 9.92 (last season’s BaseRuns) Better than last season’s record. Marcel playing time does slightly better at the team level. The miss is built into every playoff-odds simulation. Rule: Beats a baseline
- Pass Playoff odds beat a flat guess Held-out (cross-validated)Test: 150 team-seasons, 2022–26, each simulated from its blind forecast; baseline: every club at 40% Brier 0.198 vs. 0.240; difference −0.042 (approximate 95% interval −0.072 to −0.013) The talent spread used in the simulation was measured on the same seasons, so this is mildly in-sample. The interval’s width treats each club-season as its calibration bin’s average forecast. Rule: Beats a baseline
- Partial The lineup run model reproduces league scoring In-sampleTest: nine league-average hitters vs. 2026 MLB runs per game needs a 1.09× scale (4.12 vs. 4.48) No steals or wild pitches in the model; used for comparing lineups, not totals. Rule: Calibration
Development
- Fail A call-up rating beats an average call-up Held-out (cross-validated)Test: 218 hitters: 2025 AAA (150+ PA) → 2026 MLB (any PA, weighted by PA), WAR per 600 PA, held-out; baseline: an average call-up (the prospect-grade rule shown for context) error 2.494 for the blend with its weight chosen without each player (2.484 for the fixed 60/40 blend the depth chart runs) vs. 2.462 for an average call-up; grade rule 2.588, AAA contact quality alone 2.534; r .14 (AAA) vs. .11 (grade) AAA contact quality gives a weak ranking of call-ups (r .14); prospect grades give a weak one (r .11). The blend weight was chosen without each player (0.55, 0.60, 0.65 across the folds). It loses to an average call-up by 1.3% of the error; a bootstrap puts the 60/40 blend’s error between 0.07 lower and 0.16 higher than an average call-up’s (90% range; the verdict widens it to an approximate 95%), so the test can’t tell them apart. Rule: Beats a baseline
- Fail A translated AAA line predicts a hitter's MLB results Forward-testedTest: 218 hitters, factors from 2025 only, scored on 2026 MLB wOBA; baseline: league average miss 0.050 wOBA vs. 0.045 for league average; AAA contact quality 0.042 One AAA season says little; translated lines are shown for context, and readiness uses contact quality. Rule: Beats a baseline
- Partial AAA results or AAA Stuff predict a pitcher's MLB K−BB% Forward-testedTest: 94 pitchers, 2025 AAA → 2026 MLB; 95% intervals r .17 (−.04 to .36) for AAA K−BB%, .06 (−.14 to .26) for AAA Stuff Too weak to grade pitcher readiness; the page ranks, it doesn’t promise. Rule: An effect exists
- Pass A “Ready to push” minor leaguer keeps performing the next season Forward-testedTest: 2025 readiness labels (Perf+ 110+ and not old for the level), scored on 2026 at any level; every club’s minor leaguers with a full sample both seasons; baseline: everyone else with the same samples; 95% intervals on the difference hitters: 72% of 151 held Perf+ 100+ vs. 44% of 1,228 (difference +28 pts, +21 to +36); pitchers: 67% of 169 held Perf+ 100+ vs. 47% of 1,425 (difference +21 pts, +13 to +28) Pushed players averaged about 105 (hitters) and 104 (pitchers) the next season: they keep performing, at a level closer to average than the label season. The rule’s thresholds are fixed, not fit; one season pair. Rule: An effect exists
- Partial Minor-league park estimates are partly real In-sampleTest: 1,379 hitters with 150+ PA in 2025 and 2026 (353 changed park environment): 2026 raw Perf+ on 2025 raw Perf+ and the change in his park index, each club’s index without his own line; 1 = the index is all park coefficient 0.33 ± 0.18 (95% interval −0.02 to 0.68) Perf+ takes out 33% of the park index, the share this test supports (90% range 0.04 to 0.62). The index and the test use the same two seasons, so it is in-sample. Rule: An effect exists
- Partial A clear late-season change holds into the next season In-sampleTest: every MLB pitcher, 2024 and 2025: the feed’s in-season rule (last 40 days vs. the rest, a practical size, t at the clear level, 8+ games each), then the share of the change still there the next season (median); a repeat rate, not a forecast fastball velocity 2024: 52% kept (12 flags); fastball velocity 2025: 48% kept (12 flags); Stuff 2024: 34% kept (14 flags); Stuff 2025: 6% kept (8 flags) About half of a velocity change and a third of a Stuff change carry over; the feed reads a flag as about that much, not all of it. Medians on 10–15 flags a season, no interval. Rule: An effect exists
- Partial Plan targets ask for more than regression gives (about a quarter reach them with no plan) Forward-testedTest: rule fit on 2024 → 2025, scored on 2025 → 2026: targeted MLB players’ next season vs. their target, with no plan; 323 targeted players; target rate 26% (in-sample) 25% reached it with no plan (walks 21% of 70, chase 35% of 84, zone contact 13% of 68, mlb_take 28% of 72, platoon gap 28% of 29) Pooled, the targets sit where they were meant to. By target, zone contact misses the rate beyond binomial noise, so the stretch differs by skill. Prospect targets need two seasons at a tracked level, so only MLB targets are tested. Rule: Calibration
Contracts
- Pass Extension prices follow projection and free-agent years bought Held-out (cross-validated)Test: leave-one-out on 84 extensions signed 2021–26, blind projections; baseline: $9M per WAR AAV error $8.8M → $3.7M; r .78 A 2-WAR hitter’s control years price near $6.7M, his free-agent years near $14.8M. Comparable deals, not a player’s willingness: stars can hold out for more. Rule: Beats a baseline
- Partial Our free-agent price model beats a dollars-per-WAR rule Held-out (cross-validated)Test: leave-one-out on last winter’s 143 major-league free-agent deals, each player described by a blind projection; baselines: $9M per WAR with years by age, and “always one year” AAV error $3.33M → $2.89M; years exactly right 43% (by age) → 72% vs. 76% for “always one year” (average miss 0.37 vs. 0.48 years) Prices beat the rule. Length is mixed: most deals are one year, so “always one year” is exact more often; the model misses by less and gets 31% of 35 multi-year deals exactly right. One winter of deals; above last winter’s range (starters past 3.3 WAR) the curve extrapolates. Rule: Beats a baseline
- Pass Arbitration estimates match the published projections Agreement with a public measureTest: 10 Pittsburgh players, 2027; projections as reported by Pittsburgh Baseball Now (Oct 2026) mean absolute gap $0.64M (our own held-out error on real 2026 awards: $0.99M); average signed gap +$0.46M (ours higher); ours higher for 8 of 10 (sign test p = 0.11) Biggest gaps (ours minus published): Carmen Mlodzinski +$1.47M, Oneil Cruz +$1.43M, Jared Jones +$1.05M. By role, ours minus published on average: relievers +$1.16M (2 of 2 higher); starters +$0.41M (1 of 2 higher); hitters +$0.25M (5 of 6 higher). Payroll and walk-aways use Keystone’s figures. We haven’t confirmed which model the published figures relay. Rule: Agreement
Market
- Partial Opportunity flags find pitchers who rebound Forward-testedTest: flagged on 2025 data with Stuff from a model trained on 2024 only (n = 36) vs. peers with poor 2025 results and Stuff under 100 (n = 111) +0.37 vs. +0.26 runs/100; the gap is 0.8 standard errors (95% interval −0.17 to +0.39, Welch t) Both groups regress upward. Graded instead on the site’s published 2025 scale constants, the gap is 1.1 standard errors. The old cross-fit grades, whose 2025 model had seen 2026, made it look larger. Rule: An effect exists
- Pass Opportunity flags find hitters who rebound Forward-testedTest: 2025 xwOBA beat wOBA by .025+ (n = 15) vs. within ±.010 (n = 85) +0.024 vs. −0.002 wOBA; the gap is 2.3 standard errors (95% interval +0.002 to +0.049, Welch t) Clears the noise on a small flagged sample (15 hitters). Rule: An effect exists
Hitting
- Pass Regressed swing-decision and contact estimates beat last season’s raw numbers Forward-testedTest: 2024–25 estimates scored on 2026: 247 hitters with 300+ PA; baseline: last season’s raw value decisions RMSE 0.54 vs. 0.63 raw (r .77 vs. .73); contact RMSE 1.02 vs. 1.30 (r .63 vs. .57) 14% and 21% less error, no interval. Slopes 0.91 and 0.81: the estimates are close to the right size. Rule: Beats a baseline
- Partial Decision value predicts next season’s decisions better than chase rate Forward-testedTest: same 247 hitters; baseline: last season’s chase rate |r| = .77 vs. .73 for chase rate Chase rate carries most of the signal; decision value adds the rest of the zone and the count. No interval. Rule: Beats a baseline
- Partial A hitter’s split against left-handers adds to his overall estimate Forward-testedTest: 2024–25 estimates scored on 2026 against left-handed pitching: 231 hitters with 100+ PA vs. lefties; baseline: his overall estimate alone decisions RMSE 0.791 vs. 0.816; contact 1.396 vs. 1.411 3% and 1% less error: a diagnosis against lefties is mostly his overall diagnosis, so the lab shrinks the split hard. Rule: Beats a baseline
- Pass Park factors predict how a hitter’s home-road gap changes when he changes parks In-sampleTest: 38 hitters who changed home parks (2024→25, 2025→26; 150+ PA at home and on the road both seasons); baselines: no park adjustment, and side-level factors for the spray-aware fit RMSE .0743 with no park, .0701 side-level, .0699 spray-aware; r .41 (side-level), .42 (spray-aware) Park factors cut the error 6% against no adjustment; the spray-aware fit and the side-level factors are 0.2 points of wOBA apart, far inside what 38 hitters can detect, so the test can’t judge the spray model. The factors cover the same seasons, so this is not fully out of sample. Rule: Beats a baseline
Scouting
- Pass A rival staff’s clear weakness against the league holds the next season Forward-testedTest: club × pitch-type cells flagged clear (1.5+ standard errors from the league) on one season, scored the next; baseline: a coin flip on the sign; one-sided sign test 13 of 15 held (2024→2025: 7 of 8; 2025→2026: 6 of 7); p = .004 Staff quality carries over (year-ahead r .71 and .59), so bad staffs mostly stay bad: a flag that holds mostly reflects the staff’s level. Few flags each season: counts, not rates. Rule: An effect exists
- Partial A rival’s own pitch-type pattern (beyond its overall level) repeats the next season In-sampleTest: club × pitch-type cells, each club’s level taken out; consecutive seasons; 95% intervals; a repeat rate, not a forecast staffs 2024→2025 r = .17 (.04 to .30); staffs 2025→2026 r = .08 (−.05 to .21); lineups 2024→2025 r = .20 (.08 to .32); lineups 2025→2026 r = .01 (−.12 to .13); overall level, for comparison: staffs 2024→2025 .71, staffs 2025→2026 .59, lineups 2024→2025 .68, lineups 2025→2026 .46 The level repeats; the pattern within a club barely does, so Rival Intel shows the pattern regressed and leads with the level. Within-club flags held 6 of 7 the next season, too few to grade. Rule: An effect exists
Game strategy
- Partial The ABS challenge card holds up in games it wasn’t fit on Forward-testedTest: rules fit on the 5,330 challenges before Jul 1, 2026, scored on the 5,227 after it, per club over a season (80% ranges, resampled club-games); baselines: challenging as clubs already did (0 runs), and the first count grid this card: +0.01 runs a club-season (80% range −0.04 to +0.05), holding 20 of 5,227 challenges; the first grid: −9.4 runs (80% range −9.9 to −8.9), holding 2,777; both at Savant’s state cost (at a flat 0.21 runs a failed challenge: +0.04 and +3.9) At Savant’s state cost the card is better than the first grid by 9.4 runs a club-season; at a flat 0.21 runs a failed challenge the card scores +0.04 and the first grid +3.9, so the first grid would come out ahead. The state cost is the basis because it tracks the costs measured after real failed challenges (r = .95 across innings and challenges left). Against how clubs already challenged the difference is inside the noise. The card holds so few challenges that its value is the first grid’s loss it avoids. The verdict widens the 80% range to an approximate 95% interval. In-sample, on Pittsburgh’s 2026 challenges (355), the card holds 0; the first grid held 194, worth −6.9 runs at the state cost and +9.3 at a flat 0.21 runs a failed challenge: the verdict flips on the cost. Rule: Beats a baseline
- Partial The times-through-the-order penalty is a stable step In-sampleTest: 2024, 2025, 2026 estimated separately (replicated by season) 2024: .012/.008 · 2025: .008/.005 · 2026: .015/.005 Second- and third-pass steps in xwOBA. The same sign every season, but no interval is published, so it can’t pass. Rule: An effect exists
- Fail A starter’s own third-time penalty is a skill In-sampleTest: 2024 → 2025 (r .16, n 91) and 2025 → 2026 (r −.01, n 89), pooled; 180 starter-pairs; a repeat rate, not a forecast pooled r = .07 (95% interval −.08 to .21) The two season pairs disagree in sign; so the hook model shrinks a starter’s own penalty to almost nothing and leans on the league step. Rule: An effect exists
- Pass Our leverage index holds out of sample Forward-testedTest: 2024–25 table vs. 2026, 1163 states r = 0.984 Rule: Agreement
- Partial Blending Stuff with results ranks relievers better than either alone Forward-testedTest: Stuff share set on 2024 → 2025 (171 relievers) at 75%, scored on 2025 → 2026 (188 relievers): correlation with next season’s xwOBA allowed; baselines: results alone, Stuff alone, an even blend r = .51 at 75% Stuff vs. .31 (results alone), .50 (Stuff alone), .49 (even blend) Most of the gain is Stuff: results alone rank relievers far worse. Against the strongest single baseline (Stuff alone) the blend adds 4% to r, with no interval. Rule: Beats a baseline
- Partial A starter’s expected third time through beats a league-average guess Forward-testedTest: 105 starters: expected third-time xwOBA built from 2024–25 only (his passes, the league step and the shrinkage), scored on 2026 third-time results (60+ PAs); baseline: the league’s 2025 third-time xwOBA RMSE .0403 vs. .0420; r = .31 4% less error, no interval; one season, and 60 PAs is a noisy target. Rule: Beats a baseline
- Fail Pitch-type matchups add information beyond player quality and the platoon split Forward-testedTest: shrinkage set on 2024 → 2025, scored on 20,170 2026 pairs (305,778 pitches); baseline: overall quality + the league platoon split; 95% interval from 500 bootstrap resamples of pairs r = 0.0855 with pitch types vs. 0.0853 for quality + platoon (0.0789 for quality alone); what pitch types add, −0.0007 to +0.0012 in r: no detectable gain; calibration slope 0.91 Pitch type is a tiebreaker at most: nearly all the signal is player quality and the platoon split. Edges are scaled by 0.79 (set on 2024 → 2025) before they’re shown and still ran about 9% large on 2026. Rule: Beats a baseline
- Pass The league platoon split improves matchup predictions Forward-testedTest: same 2026 pairs; baseline: overall quality alone; 95% interval from 500 bootstrap resamples of pairs r = 0.0853 with the platoon split vs. 0.0789; gain +0.0017 to +0.0110 in r The league’s same-hand vs. opposite-hand gap, by batter side, pitcher hand and pitch group; it carries the matchup signal pitch types don’t. Rule: Beats a baseline
- Pass Green-light runners steal above break-even the next season Forward-testedTest: runners given a green light on one season’s rule (shrunk success, 2 posterior SD), all their steal attempts the next season; baselines: the league’s success rate and the 72% break-even; 95% binomial intervals, attempts treated as independent 2025 (leans in-sample): 397-for-492 (80.7%, 31 runners) vs. league 77.7%, break-even 72%; 2026: 238-for-290 (82.1%, 28 runners) vs. league 77.0%, break-even 72% Graded on 2026, the clean season (77.7% to 86.5%); 2025 leans in-sample (the league prior was measured on it). Green-light runners clear break-even easily; their edge over the league rate is a few points, from a few dozen runners. Rule: Beats a baseline
- Pass Toss-up runners steal at about break-even Forward-testedTest: fast runners who rarely run and whose own record is under break-even, called on one season’s rule, scored on all their attempts the next season; target: break-even 2025 (leans in-sample): 72-for-100 (72.0%, 9 runners) vs. league 77.7%, break-even 72%; 2026: 35-for-49 (71.4%, 9 runners) vs. league 77.0%, break-even 72% Small groups (100 attempts, 49 attempts): a few runners decide each row, so ‘about break-even’ is all it says. Rule: Calibration
- Open The below-break-even rule (2+ SD) finds runners who should stop running Forward-testedTest: runners whose shrunk success sits 2+ posterior SD under break-even, called on one season’s rule, scored the next 2025: nobody called; 2026: nobody called. Just-under (toss-up) group: 2025 (leans in-sample): 50-for-57 (87.7%, 6 runners) vs. league 77.7%, break-even 72% The rule has called nobody in any season, so it has no forward record yet: open, not a pass. The runners just under break-even, inside the noise, went on to steal above it (2025: 88%): a record under break-even this size is mostly noise. Rule: An effect exists
- Pass Runners the one-run rule would send steal well Forward-testedTest: runners the one-run rule clears (a run worth more than the out costs, 58% break-even), scored on all their attempts the next season, not late-and-close ones; baselines: the league’s success rate and the one-run break-even 2025 (leans in-sample): 1,411-for-1,780 (79.3%, 117 runners) vs. league 77.7%, break-even 58%; 2026: 1,438-for-1,806 (79.6%, 135 runners) vs. league 77.0%, break-even 58% Graded on 2026 (77.8% to 81.5%). Nearly every regular clears a 58% break-even (the league steals at 77%), so this says these runners steal well on all attempts, not that the late-game call itself is right: late-and-close attempts are too few to score. Rule: Beats a baseline
Health
- Partial A 1 mph fastball drop warns of arm injury In-sampleTest: 781 flagged outings, 2024–26 pooled; arm-IL placement within 30 days; intervals clustered by pitcher 1.80× (1.23–2.51) arm-IL risk; by season 2024: 1.05× (0.46–1.83), 2025: 2.61× (1.29–4.29), 2026: 2.02× (0.95–3.48) Pooled over the same three seasons the warning is used on: an in-sample check, and it doesn’t hold in every season (2024, 2026). Rule: A warning sign
- Partial A 1 mph fastball drop warns of arm injury in a season it wasn’t set on Forward-testedTest: the same rule, set on 2024–25, scored on 2026 outings only; intervals clustered by pitcher 2.02× (0.95–3.48) arm-IL risk (14 injuries); starters 6.03× (1.76–16.70) (5), relievers 1.38× (0.56–2.55) (10) The starter/reliever split was found by looking at 2024–26 together, so by role it is a check, not a clean forward test. For starters, the interval sits above 1. For relievers, the interval reaches 1. Rule: A warning sign
- Open A season-end fastball drop warns of injury the next spring In-sampleTest: 37 pitchers down 1 mph at season’s end vs. 655 who weren’t; 2024–25 season ends → an arm IL placement after the season's last day, through May 31 next season; pooled over those season ends 0.34× (0.04–1.26) arm-IL risk (5% vs. 16%; 2 injuries among the flagged) Too few cases (2 injuries) to tell; the interval 0.04–1.26 includes no effect, and its upper end (1.26×) sits below the in-season warning’s 1.80×, which argues against an effect that size. Offseason decisions don’t lean on it. Rule: A warning sign
- Partial Spin and arm-angle drift warn of arm injury In-sampleTest: same design, pooled 2024–26 spin 1.32× (0.60–2.30), arm angle 1.32× (0.93–1.82) Spin: interval reaches 1. Arm angle: interval reaches 1. Context only. Rule: A warning sign
- Fail Bat-speed drops warn of hitter injury In-sampleTest: 19,165 flagged games, pooled 2024–26 0.98× (0.89–1.08) No signal; we don’t use it. Rule: A warning sign
Open recommendations · the forward ledger
Each Decision Brief: what it predicts now, what it will be judged against, and when
| Decision | Our call | Prediction now | Judged against | Confidence | Graded on | Metric |
|---|---|---|---|---|---|---|
| Qualifying offer: Brandon Lowe | Extend the $23.15M qualifying offer by ≈ Nov 5. Expect him to decline: his market estimate ($30.8M a year for 3 years) beats the offer by $7.6M a year, and 12 of 14 comparable deals cleared it (86%); at the low end of his range ($21.8M a year) he could accept. If he declines, take the pick (about $8.6M net of his bonus); second base then goes to Nick Gonzales. Don't re-sign him above $13.5M a year under today's rules; his market estimate is $30.8M. | Brandon Lowe declines: the low end of his market ($21.8M × 3 years) is worth more than the one-year $23.15M offer | His answer is his choice, so it is graded as a forecast, not a decision | Medium | Nov 15, 2026 | If he declines: the compensation pick, and the contract he signs vs. our estimate (3 × $30.8M) |
| Rule 5 protection | Protect Termarr Johnson (2B, AAA, FV 45), Derek Diamond (SIRP, AAA, FV 40) and Keiner Delgado (SS, AA, FV 40) by Nov 17. Expose the rest; the most likely to be taken is Cy Nielson (AAA, risk 0.23; expected loss 0.03 long-term WAR, below the 0.06 that cutting Noah Murdock for a fourth spot would cost; the plan's rule protects at most three). | Protect Termarr Johnson, Derek Diamond, Keiner Delgado; expected loss among the 9 left exposed at notable pick risk 0.14 long-term WAR | Exposing everyone | Medium | Rule 5 draft at the end of the Winter Meetings (Dec 7–10, 2026); a lockout may disrupt it | Were any exposed players taken? Did the protected ones stay on track? |
| Tender or non-tender, and the third catcher | Tender everyone except Henry Davis: shop him first, and if nothing comes, release him by Nov 17: the plan's three Rule 5 protections, filed Nov 17, need his spot, and the non-tender deadline (Nov 20) falls after the filing. First line up the third catcher: re-sign Christian Bethancourt to a minor-league deal, before ≈ Nov 5. On the owners' proposed terms the call flips only if the floor money has no other use (tender Henry Davis, decide in spring: +$2.6M); at face value re-signing Christian Bethancourt still holds (+$372K, against −$400K for tendering and deciding in spring). | Non-tender Henry Davis; re-sign Christian Bethancourt to a minor-league deal (non-roster): $0.45M net vs. −$0.76M for tendering Henry Davis (today’s rules); a toss-up, inside $1.8M | Tendering everyone | Low | Nov 20, 2026 | Catcher PA by anyone other than the plan’s starter, and the non-tendered players’ 2027 WAR wherever they play; tendered players’ 2027 value vs. salary |
| Spend to the floor | Don't sign the list before Dec 1 at today's prices. Under today's rules none of it clears the market price of a win (0.83 wins per $10M against 1.11), and the three would cost $38.2M a year, $4.1M over the gap. No other use the plan measures clears it either: the best use not already in the plan, Jack Flaherty, mid-tier starter, buys 0.98 wins per $10M. If the new CBA sets the owners' floor, spend the $34.0M gap on short deals then: on their terms Jake Bauers, Jack Flaherty and Alex Vesia cost $33.6M a year and the whole list adds +3.2 wins, taking the plan to 84.8 wins and 56% playoff odds. | Hold until the rules are set: the list adds +3.2 wins for $38.2M a year at today’s prices, 0.83 wins per $10M against the market’s 1.11 | Spending to the proposed floor now | Medium | Dec 1, 2026 | Wins added per $10M by the signings made vs. the market rate, and payroll vs. any floor that is adopted |
| Fix third base | Acquire Isaac Paredes (HOU) for Jacob Gonzalez and Jhostynxon Garcia once Houston exercises his $13.35M option (≈ Nov 1–5), and close before Dec 1: +2.6 wins, taking the plan to 81.7 (80% range 70–94) and 44% playoff odds, for $12.6M of 2027 payroll and $16.4M of prospect value. His value is the bat; his glove rates below Jared Triolo's. On price alone the trade is short of the market price of a win (0.90 wins per $10M against 1.11); the case is that nothing else gets its wins: the next option without a draft-pick cost adds 1.0 fewer. He is under control only through 2027: third base reopens for 2028. | Isaac Paredes at third, Nick Gonzales at second: 81.7 wins vs. 79.1 with third base in-house | Third base in-house | Medium | End of 2027 | Pittsburgh 2B + 3B runs, batting plus fielding, vs. the in-house branch’s projection (a free agent leaving is his choice, so the in-house branch is the counterfactual) |
| Mitch Keller: keep, trade, or add a starter | Keep him for now, medicals first; revisit once he is cleared (he ended 2026 on the 60-day IL). Under today's rules the trade saves $13.3M in 2027 dollars against 1.2 wins over 2027–2028 worth $10.9M: net $2.4M for trading, but a club gains from the terms only if his medicals are clean. With the floor money spent either way (the Free-Agent Board's list measured on each branch, on the owners' proposed terms), keeping him comes to 84.8 wins and trading him 85.0, a toss-up. Adding a mid-tier starter, Jack Flaherty, adds +1.0 to +1.1 wins: his price doesn't beat the market price of a win, so it waits with the floor money. | Keep him: 81.7 wins vs. 81.0 if traded | Trading him this winter | Low | May 31, 2027 | Four-seam velocity vs. 2026, sinker usage, and his trade market once healthy |
| Extension: Paul Skenes | Stage it. By mid-November: medical and biomechanics review of the four-seam velocity drop and the arm-angle change (the club's medical data; Keystone has none). If the cause is benign, offer up to $22.6M a year for 5 years before Dec 1, when the CBA expires. If not, go year to year and reopen if his four-seamer averages 97.5 mph or more by May 2027. | Comparable deals put 5 years near $22.3M a year | Year to year through arbitration | Low | Dec 1, 2026 | Whether an offer was made, and at what annual value vs. our walk-away |
| 2027 starter hook and bullpen roles | Rotation (Winter Plan): Paul Skenes, Jared Jones, Braxton Ashcraft, Bubba Chandler and Mitch Keller. Two times through for Mitch Keller once his medicals clear. Let Braxton Ashcraft face the order a third time (a toss-up). Let Paul Skenes face it too, pending the review of his velocity drop. Jared Jones: a 22-batter leash (about 81 pitches) after his arm injury, not an open third time; past it, decide by matchup (a toss-up). Give Bubba Chandler development innings on a 22-batter leash (about 82 pitches), once through the top of the order a third time, at about 1.0 ± 1.2 runs against a two-times-through hook (a toss-up); the goal is first two passes at .306 xwOBA or better, not a third-time skill, pending the review of his velocity drop. Ladder: Mason Montgomery and Yohan Ramírez in the late innings (within noise of each other); Evan Sisk and Luke Weaver setting up (within noise of each other). Move Evan Sisk into the leverage ladder. Move Isaac Mattson out of it. | The hooks and leverage changes save ≈3 runs (≈0.3 W) against 2026 usage | 2026 usage | Medium | End of 2027 | Third-time-through batters faced and runs allowed vs. 2026 |
| 2027 ABS challenge policy | Keep challenging as the staff does now, with the break-even card as the written rule so the old grid isn't used: catchers own the defensive challenges; challenge a call when you're at least as sure as its count's break-even: 6%–32% with both challenges left before the 7th, 13%–53% with the last one before the 7th, 3%–17% from the 7th inning on. Early in the game, batters with the last challenge hold 0-0 and 0-1 through the 2nd and 1-1 through the 1st, unless the call is clear. No green lists. Against how clubs already challenge, the card is a toss-up (≈0 runs a season, 80% range −0.04 to +0.05, inside the plan's 1.9-run toss-up line). It would have held back none of Pittsburgh's 196 second-half challenges. Don't go back to the old count grid: in the forward test it cost about 9.4 runs per club a season, late-game exception included. | 2026 challenges −6.4 runs vs. average; 2026’s regressed accuracy gap 1.7 runs (mostly the 2026 catchers); with the plan’s 2027 catchers about 0.8 runs a season to win back through accuracy; the card itself adds +0.01 runs a club-season in the forward test (80% range −0.04 to +0.05) | 2026’s challenge habits | Low | End of 2027 | Challenge runs above average (2026: −6.4) first; success rate (2026: 47%) second, because holding low-value challenges raises the rate by itself |
Confidence is each brief’s own label. The models don’t produce a probability for these calls, so they can’t be scored for calibration yet; the predictions above are the plan’s numbers, so each call can be checked against what happens.
Guardrails · checked on every build
Each rule exists because a reviewer caught a mistake a front office would have caught. The fix for one player became a check for every player; the build fails if any rule is broken.
466 of 466 pass at the last build.
- Acquisitions77/77
- Consistency73/73
- Strategy56/56
- Development50/50
- Run prevention33/33
- Winter Plan29/29
- Free agents26/26
- Pitching22/22
- Player pages16/16
- Positional Depth14/14
- Health11/11
- Site11/11
- Organization9/9
- Track Record8/8
- Reproducibility7/7
- Park5/5
- Playing time5/5
- Rivals4/4
- Copy3/3
- Data3/3
- Season Review2/2
- Accessibility1/1
- Outlook1/1
Every guardrail (466)
- Pass The Winter Plan never acquires a player his club is unlikely to trade. Caught first: Murakami listed as a cheap trade target weeks after signingAcquisitions
- Pass The Winter Plan never acquires a player who missed the season, or one with an unknown talent cost. Caught first: Westburg recommended at third though he missed all of 2026Acquisitions
- Pass Every trade target carries an availability read, and no unlikely player ranks in the default top 10. Caught first: Murakami ranked as a top opportunityAcquisitions
- Pass Every free-agent price has a range that contains the estimate. Caught first: Bauers priced at one number with no range and no word on his OctoberAcquisitions
- Pass Every club's baseline and Pittsburgh's plan fit on a 40-man roster. Caught first: A club's 40-man came out at 55 because 60-day IL players were countedAcquisitions
- Pass Free-agent shopping lists pay a bench role no more than $6M and never sign a player who ended 2026 injured. Caught first: A $15.7M Arraez signed to sit on the bench; an injured Laureano signed to startAcquisitions
- Pass Pitch-shape and velocity goals come only from the pitcher's own history, never from the model's landscape. Caught first: “Add 3 inches of ride”: movement targets a pitcher had never shownDevelopment
- Pass A big-league velocity target never exceeds the pitcher's own best season. Caught first: Velocity targets above anything the pitcher had thrownDevelopment
- Pass Every development goal has a coach version and an ask level. Caught first: Coaches couldn't act on analyst languageDevelopment
- Pass No development plan for a player who won't be with the club in 2027 (pending free agent, non-tender, or a likely Caught first: Development plans for Lowe, Yates and other pending free agentsDevelopment
- Pass A stint that holds up the plan (still open, or under five games after it) puts the medical item first and gates every Caught first: Keller (60-day IL) and Jones (UCL) got pitch goals with no health itemDevelopment
- Pass A “keep the gain” item never praises velocity on a breaking ball or changeup. Caught first: “Keep the gain: slider velocity up” while the slider got worseDevelopment
- Pass A new-pitch idea is a pitch he hasn't thrown 100+ times, and no plan has two items about the same pitch. Caught first: “Develop a slider” for a pitcher who threw one for two yearsDevelopment
- Pass Big-league hitter targets are within a 90th-percentile one-year change (or his own best season). Caught first: Chase 45% → 30% and +4.5 mph bat speed: targets no hitter reaches in a yearDevelopment
- Pass A big-league “command first” goal needs bottom-quarter Location. Caught first: “Command first” for pitchers at the medianDevelopment
- Pass Published sentences use proper minus signs and ordinals, and never print a missing value. Caught first: “−0.0”, “21th” and hyphen minus signs in published textCopy
- Pass No one on the Free-Agent Board has a contract or an option he's expected to keep for 2027. Caught first: Luzardo, Hoerner, Sale and Muncy were on the Free-Agent Board after signing new dealsAcquisitions
- Pass No free-agent price runs past 1.15× the richest deal of his role in the training market. Caught first: A reliever priced above the record reliever contractAcquisitions
- Pass No position player is priced on a pitching projection. Caught first: Catchers and infielders priced as relieversAcquisitions
- Pass The third-base route plays third base in his own scenario, and the brief's realistic list only shows players who do. Caught first: Devers offered as the third-base fix while the plan played Termarr Johnson at thirdAcquisitions
- Pass The third-base brief's rationale matches what the chosen player is: a glove-first or a bat-first fix. Caught first: The third-base brief sold a glove while the plan bought a batAcquisitions
- Pass Every recommended trade names a package worth at least what the other club needs, without Pittsburgh's top three prospects. Caught first: Trades recommended at 'surplus to give up' with no players namedAcquisitions
- Pass Anyone who ended 2026 on the 60-day IL carries a medical flag wherever he's shown as a target. Caught first: Injured players shown as acquisition targets without a word about itAcquisitions
- Pass Franchise players, stars and no-trade players never show as likely or possible trade targets. Caught first: Juan Soto 'possible'; Acuña 'likely available'Acquisitions
- Pass A player is valued one way across the site: as a prospect (Trade Builder table) or a major leaguer, never both. Caught first: Basallo $35M on one page and $95M on anotherAcquisitions
- Pass Every free-agent shopping list fits on a 40-man, signs only players who make the 26-man, and keeps the plan's own second and third basemen. Caught first: Shopping lists that ran the 40-man past 40 and signed veterans to sit in Triple-AAcquisitions
- Pass 40-man removals never drop a prospect graded at or above the lowest prospect being protected, and never a guaranteed contract. Caught first: Rule 5: protecting A+ players while cutting a 45-FV armAcquisitions
- Pass An established starter (15+ starts in 2025 or 2026, or a $15M+ starter's contract) is never left out of a rotation that includes someone who isn't. Caught first: Gerrit Cole in the bullpen; Roki Sasaki in the minorsAcquisitions
- Pass The browser's package rule, Maximize's limits and the 40-man cut order match the pipeline (web/scripts/parity.mjs --pack: Caught first: Paredes cost Sanford ($18.5M) when $16.5M packages that open two 40-man spots met the ask; the browser and the plan had to agreeAcquisitions
- Pass No package priced after the Winter Plan sends a prospect the plan already trades, a player it lets go, or one who has left Caught first: Opportunity Finder and Roster Builder packages spent Wyatt Sanford after the plan had traded himAcquisitions
- Pass Every published package meets its ask and is the rule's own answer for that ask and pool: the least value within the tie Caught first: Packages took the fewest prospects, not the least value: Sanford ($18.5M) for a $16.0M askAcquisitions
- Pass Every Trade Builder major leaguer has a projection, or is marked as having none with a note that says so; a projection Caught first: Pablo López, Westburg and Steele valued at 0 WAR while their note said the projection leaned on 2024–25Acquisitions
- Pass No club within one projected win of the 50% contender line has a player marked unlikely because it 'expects to contend', Caught first: CLE at 49.7% read 'possible' and a 0.3-point odds change made its regulars 'unlikely'Acquisitions
- Pass A prospect with an MLB record is valued by the blend (w x engine + (1 - w) x table, w from his MLB record), so crossing the Caught first: Graded rookies' value jumped 3–6x when they crossed 130 PA or 50 IP (Mathews $9.5M → $40.3M)Acquisitions
- Pass Opportunity Finder rows carry the wins they add to the Winter Plan's roster and are ordered by them, with every player his Caught first: The Opportunity Finder ranked by noisy signal points and buried the biggest win-adders; then 'sort below the rest' put Witt #2Acquisitions
- Pass roster.json is written before the Winter Plan and reads nothing it writes (keystone_models.plan builds its sandbox from it), Caught first: roster.json read the plan that is built from it, so every build's Finder and Builder were measured against the previous planAcquisitions
- Pass The Roster Builder's Winter Plan start equals the decisions feed's recommended 2027 payroll under both CBA lenses, so the Caught first: The Roster Builder put the Winter Plan at $138.6M and $32.6M from the floor under the owners' lens; the decisions feed said $137.2M and $34.0MAcquisitions
- Pass The Finder's results-lag check is valued by the time-ordered joint model (opportunity_checks.gap_model: 2026 xRV on 2025 xRV Caught first: 'Results lag stuff' credited 0.76 of the gap as runs 'on top of his projection': mostly results regressing to the mean, graded by models that had seen the seasonAcquisitions
- Pass A player missing from the contract data is priced on the least control his MLB debut allows (trade.control_estimate) and Caught first: Simeon Woods Richardson (MLB debut 2022) was priced on six control seasons through 2032 as 'a rookie', and the Finder linked trades the Trade Builder couldn't openAcquisitions
- Pass No unsigned arbitration season is priced at the league minimum (a made-up salary): every one carries Contract Studio's Caught first: Arbitration seasons the contract data doesn't list were priced at the $780K minimum: Povich, Basso and Woods Richardson 20–40% too valuableAcquisitions
- Pass trade.json's missed-season shares are this build's measurement (trade.missed_pt, its definition published with it), measured Caught first: Missed-season playing time (0.42 hitters / 0.29 pitchers) was typed in, nothing reproduced it, and a 34-year-old got the 31-and-under shareAcquisitions
- Pass A Finder pitcher's 'Results lag stuff' reason appears only when his results check forecasts at least a run from the gap Caught first: Finder rows said 'Results lag stuff' while their own results check found no upside (Liberatore −2.7 runs, Singer −2.8)Acquisitions
- Pass Every Finder row's owners'-lens cost is published at both ends of the shadow price (floor money free, and face value), Caught first: The Finder priced salary under the owners' floor at shadow 0 only ('costs nothing'), against the site ruleAcquisitions
- Pass Every signed 2026 draftee not on the board or in the contract data is in trade.json's prospects, at his club (a Pittsburgh Caught first: 2026 draftees (Curiel, #5) were missing from the prospect pools, so the protected top three and every package ignored a class worth ~$80M to PittsburghAcquisitions
- Pass A 2026 draftee's value is his curve value × the table ÷ curve scale near his pick (trade.draft_scale), measured on every Caught first: Draftees were valued at the draft curve's own scale (Marohn, #140, $2.9M; the table runs ~0.6× there), and the published check hid it by comparing only the 2025 picks the board graded ('1.06× overall'), so the cheap draftees filled packages: Paredes cost Marohn + Garcia instead of Blanco Jr. + BarcoAcquisitions
- Pass No published JSON says 'FV ungraded': a draftee's fv_label reads after 'FV ' (trade.draft_label). Catches a page or move Caught first: Draftee labels printed 'FV' followed by 'ungraded, #140 pick' on /plan, the home page and three player pagesAcquisitions
- Pass The Trade Builder's load fetches only its slim slice (trade-plan.json, written after the plan and trade.json: the plan's Caught first: /trade server-rendered 1.3 MB: its load inlined plan.json, decisions.json and outlook.json to read a few fieldsAcquisitions
- Pass One keep rule for an ungraded first-round draftee (trade.draftee_protected, Keystone's rule): trade.json flags him 'keep'; Caught first: Minnesota's Roster Builder sent Vahn Lackey (#3 overall) and Cincinnati's sent Justin Lebron in 26 packages while /trade called another club's first-round draftee protectedAcquisitions
- Pass A published package says when it is one choice among equals: the Finder's trade costs carry ask_near (trade.near_packages: Caught first: The Paredes package flipped between Blanco Jr. + Barco and DeCaro + Barco on a $45K difference in a provisional draftee value, and nothing called it a toss-upAcquisitions
- Pass Every trade.json major leaguer's control runs season by season from 2027 with no gap (a guaranteed season he spends off Caught first: Yariel Rodríguez's contract started in 2028 on /trade ('$0 ’27 salary · 1 season of control', −$5.1M): a guaranteed 2027 off the 40-man was droppedAcquisitions
- Pass No trade.json string reads 'None' (a missing club printed into a sentence), and a player with no current club carries no Caught first: Team-less players carried 'Available at a price: None 40% playoff odds' and 'mutual option None decides' (a made-up 40%)Acquisitions
- Pass A missed-season projection cuts playing time for 2027 only: from 2028 his role's normal time (trade.missed_pt 'healthy' Caught first: Missed-season players kept the cut 2027 playing time in every later season (Westburg at 230 PA through 2034)Acquisitions
- Pass Every player the Trade Builder can receive from another club (trade.json major leaguers and prospects with a 2027 Caught first: The Trade Builder counted 623 of 706 other-club major leaguers at raw WAR with no displacement (Bregman +3.5 wins with Paredes already at third; the plan says 2.99)Acquisitions
- Pass Every Finder free agent the Free-Agent Board calls a likely or toss-up qualifying offer carries cost.qo with the pick Caught first: The Opportunity Finder showed no draft pick for Rogers (#1 pitcher, likely QO) or Suzuki (#1 hitter), and '−$780K in 2027' for Morris: a net payroll change printed as his salaryAcquisitions
- Pass Every club's plan.json sandbox carries cut_value (each player's long-term value in the cut order) and no_cut (the players a Caught first: The Roster Builder's 40-man cuts ignored the plan's cut values and never-release list: three free agents added cut Ronny Simon where the plan cuts Callihan, eight cut Nick YorkeAcquisitions
- Pass optimize.ts fitFor / choose / pack(fit) / fitReasons match keystone_models.trade on 840 seeded cases (the real needs table Caught first: Trade packages were the least prospect value that met the ask, whatever the other club needed; the fit rule had to pick the same package in the browser and the pipelineAcquisitions
- Pass Every fit-priced package carries its fit (a package to a club with a needs row); one chosen for fit costs no more than the Caught first: A package chosen for fit could pay any premium over the ask; the owner capped it at about 10%. Seven Finder rows then read '$−0.2M more' and 'picked for fit, +−$222K': the fit pick cost less than the 'least-value' package, which is a tie-break pickAcquisitions
- Pass Every published fit prospect's window is his arrival year and the two after that fall inside 2027–31, never clamped (his Caught first: The trade fit mostly swapped in the most distant long-shots: 34 of 79 fit-chosen prospects arrived in 2031 (scored on one season, Custodio's 2032 clamped into 2031), as Pittsburgh merely covered where the league is bare (+0.55 in 2031) read as a reason to send themAcquisitions
- Pass Every published package chosen for fit (opportunities.json cost.fit, plan.json package_fit) is clearly better for both clubs Caught first: The owner allowed up to about 10% more value only when the fit is clearly better for BOTH clubs, but the rule tested only the combined score: 8 of the Finder's 28 fit picks lowered Pittsburgh's side (David Sandlin's package sent Duce Gourson from a thin third base in place of Termarr Johnson) while the pages said the package 'fits both clubs clearly better'Acquisitions
- Pass Each published fit package is the rule's own answer on needs.json (trade.needs_table: the Finder against the Winter Plan's Caught first: Package reasons could be typed in; every fit reason has to come from needs.json's numbersAcquisitions
- Pass No fit-priced package sends a prospect from a position where Pittsburgh is open in one of his seasons (needs.json need 1 at Caught first: A package could send a prospect from a position where Pittsburgh has nothing above replacement while another package covered the askAcquisitions
- Pass Every club's hook calls and ladder use its 2027 staff: Pittsburgh's is the decisions feed's rotation and bullpen in Caught first: Hook calls were measured against the 2026 bullpen, Soto and Doval included, after the plan had let them goStrategy
- Pass Every hook call compares with the same relief bar: gap = expected third-time xwOBA − the bar, gap1 = first-time Caught first: Keller was called a tandem against the bridge relievers (.301) while every other call used the relief bar (.307)Strategy
- Pass Each club's shortened outings (two times through and tandems) and the batters its development and health Caught first: Tandems skipped the 60-inning bullpen cap (Arizona's calls added 160 relief innings); development leashes weren't countedStrategy
- Pass A starter's own third-time excess is shrunk by the k its year-over-year reliability implies, k = n̄(1 − r)/r from Caught first: Shrinkage k = 150 kept 41–67% of each starter's own third-time penalty though the page's own r = .066 implies k ≈ 2,000Strategy
- Pass Every graded starter carries a standard error on his gap, and a call within one standard error of a call line Caught first: Matchup vs. 'Third time OK' was a coin flip for three of five 2027 starters, and the page called it either wayStrategy
- Pass Every graded starter's age is his completed years on July 1 of the season planned, and no starter that age or Caught first: Kyle Harrison and Roki Sasaki, 25 on July 1, were aged 26 and handed hard hooksStrategy
- Pass Every club's 2027 bullpen is ranked by skill into a ladder (late innings, setup, middle) with handedness and an Caught first: No 2027 closer or setup man was named after Soto left; the roles table still ranked Soto firstStrategy
- Pass Reliever skill's Stuff share is the one that best predicted the next season on 2024 → 2025, and its 2025 → 2026 Caught first: Reliever skill was half Stuff by assumption; a Stuff-heavier weight predicted the next season betterStrategy
- Pass A back-to-back fatigue flag compares each back-to-back with his rested outings within two weeks, needs 5+ of Caught first: Mattson's back-to-back call used −0.6 mph while the flag and the note used −0.5, against a season baselineStrategy
- Pass Every leash's pitch count is the pitch count at the batter it stops before: a tandem 9 batters (the 10th batter's Caught first: Mlodzinski's tandem showed a 9-batter leash with the 19th batter's pitch count (71.6)Strategy
- Pass Every pitch-count bucket on the times-through-the-order chart has 300+ plate appearances. Caught first: The pitch-count curve's y-axis was stretched by a 25-PA bucketStrategy
- Pass Every development call carries its leash (batters and pitches), the run cost of that leash with its uncertainty, Caught first: Chandler's 'development' call had no goal, no leash and no stated costStrategy
- Pass Every 2027 rotation starter on an injured list in the plan carries it on his hook row, and every starter the Caught first: Keller's 60-day IL wasn't on his hook row, and the fallback starter's hook wasn't gradedStrategy
- Pass Every 2027 staff member (rotation and bullpen, every club) carries each of his 2025–26 arm injured-list stints Caught first: Ashcraft's Sep. arm IL, Jones's UCL stint and Sisk's elbow IL weren't on their hook or ladder rowsStrategy
- Pass A 2027 rotation starter back from a major arm injury (a 60-day arm stint in 2025–26, or the season before lost to Caught first: Jones, back from a UCL sprain that cost him 2025, was sent a third time with no batter or pitch capStrategy
- Pass Every arm behind the rotation is graded at the injury branch's starter innings, and each branch's shortened Caught first: Mlodzinski, the both-out fallback starter, was graded at 74 relief innings, not the branch's 105 starter innings, and his tandem broke the capStrategy
- Pass Every graded rung's skill uncertainty includes Stuff's year-to-year noise (its weight × Stuff's standard error Caught first: The ladder's ties counted only the xwOBA part of skill; Stuff, 75% of the weight, was left outStrategy
- Pass The forward test of expected third-time xwOBA uses a league third-time step and a shrinkage k set on 2024–25 only: Caught first: The third-time forward test was described as built from 2024–25 alone but used a league step and k that included 2026Strategy
- Pass Every club with a 2027 staff measures its hook calls against its 2027 pen; an arm with no 2026 relief record counts Caught first: For 11 clubs the relief bar fell back to the 2026 pen, departed arms included, because two 2027 arms had no relief recordStrategy
- Pass Every club's Bullpen Strategy turns wOBA into runs with the measured scale (matchup.conversions), the Matchup Caught first: Bullpen run values used a typed 1.24 wOBA per run while the Matchup Engine measured 1.195 on 2025–26: two scales for one conversionStrategy
- Pass Every club with a 2027 staff prices replacing its weakest rated arm: the Free-Agent Board's relievers (its own Caught first: /bullpen called Mattson 'the first arm to replace' while the Winter Plan kept him and priced no replacement; the departures had no run valueStrategy
- Pass Every graded rotation starter with prior seasons carries the same grade on 2024–25 alone (prior_only): its call Caught first: Keller's firm 'pull' rested on his injury season (.350 first two passes vs. about .319 in 2024–25); on 2024–25 alone it is a toss-upStrategy
- Pass Every club's relief bar is also published at the platoon mix a starter's third time presents (by his hand): the Caught first: The relief bar didn't adjust for the platoon mix: relievers face more same-side batters than a starter's third time presentsStrategy
- Pass Every Pittsburgh rotation starter with a Development Tracker velocity decline at MLB (development.json feed, Caught first: Skenes's 'third time OK' left out the velocity review the usage brief makes a conditionStrategy
- Pass The decisions feed is built from the current Winter Plan: same recommendation, wins and 40-man; nobody it removes is on its 2027 roster; every spent prospect is gone; moves run in date order and name real briefs. Caught first: Each module recomputed Pittsburgh's winter from the pre-plan roster, so pages contradicted the planConsistency
- Pass keystone_models.money holds its identities (walk-away zeroes surplus; below-floor dollars free at shadow 0 and at face at shadow 1; dates in order), the comp pick reproduces the draft curve, and the feed carries the same numbers. Caught first: The briefs disagreed on what a dollar under the proposed floor is worth; the comp pick was quoted gross of its bonusConsistency
- Pass No player the Winter Plan removes (non-tender, traded in a package, departing free agent) appears in the Lineup Lab's 2027 lineups, or in a brief's recommendation other than the brief that removes him. Caught first: A prospect the plan trades or a player it non-tenders could reappear in a 2027 lineup or a brief's recommendationConsistency
- Pass A prospect the plan already trades is in no post-plan package: roster-plan.json's packages (the Roster Builder's trades Caught first: Wyatt Sanford, spent on Paredes, sat in Pittsburgh's trade pool and the Roster Builder's prospect listConsistency
- Pass Catching's 2027 catchers (catching.json pirates) are the plan's catchers: no non-tendered or departing catcher, the feed's starter and backup in those roles, every catcher the plan counts on listed, and the non-tendered ones listed as leaving. The owners'-lens third-catcher verdict is the feed's (decision.owners), and the tandem weights by the plan's PA at catcher. Caught first: Henry Davis, non-tendered by the plan, was shown as the third catcher and the insuranceConsistency
- Pass No reliever the plan loses holds a bullpen role on Bullpen Strategy (bullpen.json relievers), and the hook calls cover only the plan's rotation. Caught first: Gregory Soto, a free agent, kept a 'High leverage' 2027 bullpen roleConsistency
- Pass A page that calls a 2027 reliever 'late-inning relief' agrees with Bullpen Strategy's ladder (bullpen.json ladder Caught first: Player pages and the Roster Builder called the plan's bullpen slots 1–4 'late-inning relief' (Mlodzinski, Dotel) while Bullpen Strategy's ladder named Ramírez late and Sisk setupConsistency
- Pass A player the plan removes is a Roster Builder candidate only as a re-sign (his own free agency), never as a Pittsburgh asset. Caught first: Gone players could be offered as Roster Builder additions as if still Pittsburgh'sConsistency
- Pass The ABS 'who may challenge' matrix (abs.json matrix) doesn't list a player the plan removes as an active 2027 challenger, and /abs takes Pittsburgh's 2027 catchers and departures from the decisions feed. Caught first: The ABS challenge matrix put a non-tendered catcher firstConsistency
- Pass The plan's published 2027 payroll is the feed's one-basis figure (keystone_models.money.payroll), so the floor gap is one number. Caught first: plan.json's 2027 payroll mixed RosterResource's arbitration figures with Keystone'sConsistency
- Pass The recommended moves keep the 40-man at 40 or fewer at every offseason deadline, in transaction order. Caught first: The Rule 5 filing ran at 41: the trade lands before Nov 17 and the non-tender after itConsistency
- Pass Every module that quotes the Winter Plan's projection quotes plan.json's recommended wins and odds (/start, the Command Center, the briefs, the Free-Agent Board, the Season Review's bridge, the Lineup Lab's scenarios), and every team-win total or playoff-odds figure in a brief's text is one the plan or the feed computes. Caught first: Summary pages quoted an older plan, and a brief could print a team-win total no model computedConsistency
- Pass The briefs, the Command Center's decide-now strip and /start say what the decisions feed says: the qualifying offer to Lowe, the third-base route and its package, Keller's call, the non-tenders, the Rule 5 protections, the third catcher and the Skenes deadline (before the lockout), each on the feed's dates. Caught first: Pages disagreed on what the winter does with Lowe, Paredes, Keller, Davis and SkenesConsistency
- Pass The plan's 2027 payroll and its gap to the owners' proposed floor are the feed's one-basis numbers on the Command Center (payroll card), /start, the floor brief and the Free-Agent Board's floor-list budget. Caught first: The floor gap read $57.7M, $45.9M or $34.0M depending on the pageConsistency
- Pass One Rule 5 count site-wide: the decisions feed, the Command Center (rule5_counts and the prospects card), the Prospects page (prospects.json rule5_eligible) and the Rule 5 brief agree on the eligible, first-year and upper-level counts. Caught first: Two Rule 5 counts on the site: 53 on the Prospects page, 54 on the home pageConsistency
- Pass One count of the winter's calls due by the CBA's expiry: the decide-now strip's own calls (keystone_models.narrative.calls), quoted the same in command.json, tour.json (and its plan stop) and briefs.json, and the three pages read it rather than counting for themselves. Caught first: Three counts of the calls due by Dec 1: 8 on the home page, 6 on /start, 7 on /briefsConsistency
- Pass When a branch the briefs offer (Lowe accepts or is re-signed, keep Keller and add a starter) or the floor list's signings fill the 40-man at the Rule 5 filing, the brief that offers it, the non-tender brief and the decide strip say the release has to come before the filing (plan.json forty_seq.fixes). When the plan itself needs its non-tender before the filing (decisions.json forty.fixes), the release is dated to the filing unconditionally and each branch quotes only the steps it needs beyond the plan's own (_forty_plan_steps). Caught first: The briefs, the decide strip and /start dropped the plan's 40-man sequencing: Davis must go before the Nov 17 filing if Lowe acceptsConsistency
- Pass A floor-list signing before the CBA expires is priced at today's market: the floor brief and the decide strip quote the list at the board's market prices with its overshoot of the gap, compare its wins per $10M with the market price of a win (money.DPW), and recommend signing before Dec 1 only the picks that clear it. Caught first: The floor brief priced a before-Dec 1 list at the owners'-terms prices (12% below today's market) and never compared it with the market rateConsistency
- Pass Wherever a brief or the decide-now strip values a branch or states a verdict on the owners' terms, it brackets it by both shadow prices of the floor money (free, and displacing an equal use), as money.walk_aways does: every such sentence names both ends, the QO brief's accept branch quotes both values, and the catcher call on the owners' terms is said at both ends. Caught first: The QO brief priced Lowe's accept branch on the owners' terms only with the floor money free (+$13.1M), though the same memo names a better use for it; the non-tender brief and the decide strip said 'on the owners' proposed terms, tender him' at shadow 0 onlyConsistency
- Pass Every use of 2027 money the plan measures (decisions.json spend rows other than the trade route and Lowe's, which have their own briefs) that beats the market price of a win gets an explicit call before the CBA expires, the same call in the floor brief's recommendation, the decide-now strip's floor row, /start's floor stop and the home page's free-agent card; the Keller brief's starter option uses the same condition. Caught first: The 'Spend to the floor' brief ran its market-rate test only on the Free-Agent Board's list, so Bubic (1.32 wins per $10M against 1.11) got no call before Dec 1 anywhere on the siteConsistency
- Pass The briefs rank uses of money on one convention: one-off talent costs (prospects sent, a draft pick given up) are in every row, so a re-sign of the qualifying-offer player counts the pick he would cost (narrative._spend_rows), and no brief quotes a 'before the pick' figure. Caught first: Lowe re-signed was quoted at 0.55 wins per $10M before his comp pick in one brief and 0.43 counting it in another, while Chisholm's row counted hisConsistency
- Pass The qualifying-offer answer compares like with like: one year of his market price (the Free-Agent Board's estimate) against the one-year offer; the QO brief states the per-year comparison, the decide strip and /start expect the same answer, and no page says the low end's multi-year total 'beats one year' as the reason. Caught first: The QO 'expect' rule compared a three-year total with a one-year offer, so a 2 × $12M player would 'decline' a $23.15M offerConsistency
- Pass The zone model's figure for Pittsburgh's third basemen is one number in both units wherever it appears: the third-base brief and /start's Team Defense card quote fielding.json team.zones (outs above expected and runs) for the same season. Caught first: Pittsburgh's 2026 third basemen in the zone model read −15.5 runs on /start and −20.1 outs in the third-base brief: one measure in two unitsConsistency
- Pass Each player the winter removes, adds, protects or trades away (decisions.json status) has that status on his player page (players/<pid>.json status27). Caught first: Player pages didn't say what the winter does with a player: Lowe's page omitted the qualifying offer, Davis's the non-tenderConsistency
- Pass The ABS brief, the Command Center edge and the /start stop quote abs.json `policy` (the state-cost card and its forward test), not a count list rebuilt from flat-cost break-evens. Caught first: The ABS brief told staff to hold early-count challenges, a rule that lost runs in a forward test once failures were priced by game stateConsistency
- Pass The ABS brief and the /start stop describe the old grid with its late-game exception (abs.json policy.forward.old_exception), the regressed accuracy as 2026 club accuracy (upside.regressed_basis; Pittsburgh's 2027-catcher version from abs_coach.with_catchers), and the late bar as 'at most' be_max. Caught first: The ABS brief calls the old grid 'early counts held all game' (the old page had a late-game exception, now scored: 9.4 runs, not 10.6) and says the regressed accuracy figure 'carries into 2027' (its catcher part is 2026's catchers)Consistency
- Pass Rule 5 rows in plan.json and command.json quote each player's whole 2026 season, as /prospects does. Caught first: The Rule 5 rows quoted Delgado's 75-PA Triple-A cameo (Perf+ 91.7) as his season; /prospects shows 98 over 528 PAConsistency
- Pass The Command Center's prospects card counts what /prospects' tiles count: prospects.json counts (push and stall, Caught first: The home page's prospects card said 9 ready to push and 6 stalling while /prospects said 8 and 5 (development prospects only)Consistency
- Pass A quoted sample of batters ('rests on N batters') is the count he defended there in the three seasons before the plan's (fielding.json players[pid].ratings[pos].n), in the briefs and in the plan's chain notes alike: one number for one thing, never the rating's weighted evidence (`sample`). Caught first: The QO brief said Lowe's first-base rating 'rests on 1,525 batters there, against 48,102 at second': the rating's weighted evidence, not a count (483 and 11,243), while the plan's chain note on /plan said 483Consistency
- Pass The third-catcher call names the plan's choice, never 'the pick' (the decide strip also carries the QO's compensation pick). If that catcher signs elsewhere, the non-tender brief's fallback is the plan's own rule over the other options (narrative._catcher_fallback: the best value within the toss-up line, then the fewest 40-man spots), with a tender or a 40-man cut only when that option needs one. When the plan's protections need the spot before the tender deadline, the brief and the decide strip call the move a release or trade, not a non-tender, and label the timing as Keystone's reading of the CBA. Caught first: The non-tender memo said 'at face value the pick still holds' beside the QO's compensation pick, told the club to tender Davis and cut Murdock if Bethancourt signed elsewhere though its own options ranked Herrera's minor-league deal first, and said 'non-tender by Nov 17' for a release before the tender deadlineConsistency
- Pass Only a health warning with an injured-list item (decisions.json health.warnings[].items kind 'il_now') is said as an injury ('on the 60-day IL', 'once his medicals clear', tour.json hook.pulls[].hurt, command.json bullpen.calls[].hurt); a velocity or arm-angle flag is a review. Caught first: Health warnings were all treated as injured-list cases: a velocity and arm-angle flag would have read 'ended 2026 on the 60-day IL' or 'once his medicals clear' the moment that pitcher got a shorter-outing callConsistency
- Pass A role a brief gives a plan player (to the bench, off the 26-man, to Triple-A, the rotation or the bullpen, and the tender memo's 'on the plan's' role) is his role in the plan (decisions.json roster_2027), outside sentences about another branch ('if', 'accept'). Caught first: The third-base memo said Jared Triolo 'goes to a reserve role off the 26-man' while the plan, the tender memo and /plan had him on the bench (415 PA): one role typed for every position moveConsistency
- Pass A printed change sits next to the base it is measured from and reconciles with the printed totals at display precision: the decide strip's and the QO brief's accept branch ('83.2 wins (+1.8 over the plan's 81.4)'), and each catcher-health branch in the non-tender memo against the base it prints ('projects B', 'From the plan's B'). Caught first: The non-tender memo printed 'opens on the IL 81.6 (−0.09)' with no base while every other memo's plan was 81.4 (the catching branches start from 81.7), and the decide strip printed 'If he accepts: 83.2 wins (+1.7)' beside a plan of 81.4Consistency
- Pass Every memo that sets wins per $10M against the market rate says the verdict of one test (narrative.market_gap: the wins the money buys against what it buys at the market price of a win, judged on the plan's toss-up line): the third-base memo and the decide strip's trade row on the trade's spend row, the floor memo on the list at today's prices. Caught first: The third-base memo called the trade 'a toss-up against the market price of a win' by its dollar surplus while the floor memo's test (what the same money buys at $9.0M a win) put it 0.55 wins short: two tests behind one comparisonConsistency
- Pass The QO memo, /start and the decide strip quote the plan's one estimate of Lowe's answer (decisions.json qo.market_test.extend: k of n comparable deals cleared the offer) and the memo's band is that count's 80% interval; the memo states his PNC fit (park.json fit_value, basis 're-sign') beside the re-sign ceiling, and the QO and third-base memos link the park page. Caught first: The QO memo put Lowe's chance of accepting in a coarse 1-in-10-to-half bucket (Low confidence) while /plan and the decisions feed quoted 12 of 14 comparable deals clearing the offer; it left out his PNC fit while the third-base memo priced Paredes's; and both linked no park pageConsistency
- Pass Where the chain sends the second baseman 'to the bench' but the plan still gives him a utility role's PA (narrative.gz_role), the briefs, /start and the decide strip say a utility role, never 'goes to the bench', 'benches' or 'keeps him playing'. Caught first: The QO memo, /start and the third-base memo said the accept branch sends Gonzales 'to the bench' though the plan gives him 535 PA there (309 at short), and pitched Lowe at first as what 'keeps Gonzales playing'Consistency
- Pass Fielding runs by position are credited where they were earned and add back to each team's Fielding Run Value. Caught first: A utility man's whole season was filed at one position (Jacob Gonzalez's shortstop leak hid at his main spot)Run prevention
- Pass The defensive-upgrade lists rank on 2024–26 fielding runs per full season, with a full season in the field. Caught first: Defensive upgrades ranked on one season of fielding runs (r ≈ .34 with the next)Run prevention
- Pass The 2024–26 weighting predicts the next season better than one season regressed the same way for fielders (the Caught first: A multi-season measure is only worth showing if it predicts better than one season; it was graded against a raw season (12.4), not one regressed the same way (8.4)Run prevention
- Pass Every fielder's “+ position” value is his 2024–26 fielding runs plus the adjustment for the positions he played. Caught first: Fielding runs compared across positions without the positional adjustmentRun prevention
- Pass Each club's 2026 → 2027 by-position view covers all eight fielding spots, names who earned 2026's runs, and stays plausible. Caught first: “Center field gives back 7 runs” when the same center fielder staysRun prevention
- Pass The depth chart's position ratings include arm, double-play and first-base receiving runs, not range alone. Caught first: Arm and double-play runs left out of the depth chart's fielding ratingsRun prevention
- Pass On every club's Catching page, each listed catcher (current and leaving) has a name and a 2027 projection behind the plate, and no pending free agent is listed as a current catcher. Caught first: Other clubs' Catching views listed 13 pending free agents as current catchers (three as the club's best) and showed raw player ids as namesRun prevention
- Pass /catching: a catcher the plan releases before the Rule 5 filing (plan.json forty_timeline.early) is listed as traded or released by that date, the third catcher on a minor-league deal carries the date he could elect minor-league free agency, every 2027 projection (every club) carries an 80% range around it, the projections' out-of-sample test is published and right-sized, the market lists every free-agent catcher on the board with the plan's options, and the page renders the split, the doubts and the depth's minor-league free agents. Caught first: Catching said “non-tender Henry Davis” with no date while the plan releases him before the Rule 5 filing; the projections carried no range; the market strip filled its last slots with unvalued catchers by player id, dropping the plan's own optionRun prevention
- Pass Every catcher's total is final-call framing + blocking + throwing + the cost of his failed challenges vs. average (2026), with no challenge-run term added on top of framing. Caught first: The Catching total added Savant's challenge runs to framing measured on final calls, counting each overturned challenge twiceRun prevention
- Pass /catching: the third-catcher option column wraps (short names, the rules detail on its own line, at most ~150 px under 700 px), the framing-drops table keeps its name column sticky, sentences built in a loop are joined with a space, and the bat-vs-glove clause is computed. Caught first: At 375 px the Catching third-catcher table's sticky option column was 939 px wide and covered every money cell; the framing-drops table scrolled with no sticky name; sentences ran together ('wins.He caught')Run prevention
- Pass Keystone's team outs above expected is checked against Savant's OAA as each team played, every season 2023–26, and agrees at r ≥ .55 (all balls and the part Savant also grades). Caught first: The team headline read +14 outs (8th) while Savant had the same 2026 players at −21 (24th); team_vs_frv was declared and never filledRun prevention
- Pass Expected outs are scored out of fold without a park feature; each park × zone term comes from visiting teams' balls only, and the published expected out is the model's plus that term. Caught first: An in-sample park feature absorbed the home team's defense (PNC's term turned a −9 into a +14)Run prevention
- Pass Each 2026 position is classed from Savant's OAA as the team played it next to the zone model: a spot Savant grades 2+ runs below the average club is never called fine or covered. Caught first: “Shortstop: weak gloves, covered by positioning” while Savant had Pittsburgh's shortstops at −13 as played, the team's worstRun prevention
- Pass The 2026 → 2027 change at each position is the 2027 starter's rating minus the 2026 regular's own 2027 rating there (both regressed), never a projection minus last season's total. Caught first: “Second base gives back 11 runs” compared Lowe's raw 2026 with Gonzales's regressed projection (like for like it's 2.5)Run prevention
- Pass Every club's 2027 defense is published by its plan's playing time (each spot's shares sum to one, the total is the sum of the spots), and the league file used for the rank matches each club's own figure. Caught first: The plan's 2027 starting eight projected −10.4 runs (30th) and no tile showed itRun prevention
- Pass A club's best glove is ranked on expected 2027 runs (rating × his share of the spot), with 2,000+ batters at that spot over three seasons. Caught first: Other clubs' “best glove” was a backup catcher's extrapolated rate (NYY: Ali Sánchez, “1.3 wins a season”)Run prevention
- Pass The Fielding Lab's market ranks each position on the 2027 rating there, from players with 2,000+ batters at the spot, none of them the club's own (Pittsburgh: its organization). Caught first: “Best gloves available” ranked a player by his all-position fielding runs under a position his own rating there didn't support (Dubón at SS)Run prevention
- Pass Every fielder the plan acquires to start is shown on both measures, Savant OAA and the zone model, by season at his 2027 position, with his arm there. Caught first: The third-base fix was vetted on Savant only while the leak was diagnosed on both measures (Paredes: −15 zone in 2026, arm 81.7 → 78.8)Run prevention
- Pass export_defense and export_fielding take a club's 40-man from keystone_models.org (today's official list), not the season-scoped statsapi roster. Caught first: Team Defense and the Fielding Lab read the season-scoped 2026 40-man, which drifts from today's after the World SeriesRun prevention
- Pass Team Defense and the Fielding Lab load the decisions feed and take Pittsburgh's 2027 roles and departures from it (roleOf, isGone). Caught first: Pittsburgh's 2027 roles on Team Defense and the Fielding Lab came from plan.json, not the decisions feedRun prevention
- Pass Outs above expected sum to zero across the league in every season and zone, and in each part of the team total on Caught first: Expected outs summed to +81 … +115 outs a season league-wide (2021–25), so '0 = average' was false for the average clubRun prevention
- Pass Every club's lede verdict on Savant vs. the zone model comes from the rank gap: 'agrees' / 'near' / 'close' only within 6 places, never at 10+; the figures match the team totals. Caught first: Team Defense told TB (Savant 13th, zone 1st), PHI (19th vs 30th), DET and LAA that the two measures agree, on the sign aloneRun prevention
- Pass The left-side item (3B + SS read together) names only the measures that have the side 2+ runs below the average club, and shows whenever third leaked and short wasn't fine on a measure that agrees. Caught first: “The left side leaked in 2026, on both measures” printed for TB (zone +30) and ATH (Savant +0.2)Run prevention
- Pass A departing regular catcher is called the best glove only when he out-rates every 2027 catcher; other clubs' starter at C is the catcher with the most 2027 time (within 5 points); no catcher is offered as a late-inning replacement. Caught first: CLE read “Catching loses its best glove” (+12.3) and offered Bailey, who catches 62%, as a late-inning replacement; 10 clubs offered backup catchers that wayRun prevention
- Pass The toss-up threshold comes from the forward test (z(2/3) × √(2k) × RMSE), every club carries it, in-house gains under it are flagged, and neither page types a threshold or the utility-glove verdict. Caught first: “Gaps under 5 runs are toss-ups” was typed in, then −2.5, +3.8 and +1-run late-inning gains were shown as findings; “the cheapest run prevention … a utility glove” printed for every clubRun prevention
- Pass Market and in-house ratings carry the share that comes from the player's own record there, o / (o + ballast), and are flagged as mostly the spectrum prior when it's under half and the spot isn't his main one. Caught first: Billy Cook (RF, 345 batters) and Andy Pages (RF market, +11.5) ranked first on ratings that are mostly their CF rating moved by the spectrum priorRun prevention
- Pass defense27.json carries every club's runs at each spot (matching its fielding.json), and Team Defense measures the 2027 total, each spot and the catching call against the average club from that file, not against zero. Caught first: Team Defense read the 2027 defense (“−6.0 runs a season”) and judged its holes from 0, though the average club projects about +10 (0 is an average fielder at every spot); the glossary typed “Avg ≈ +10”Run prevention
- Pass Team Defense prints Savant as played against the average club everywhere (never raw range runs), and the 2027 table's zone column sums to the zone map's total (the mapped zones; balls with no zone are noted apart). Caught first: “The range was −6.0 runs on Savant” (raw range runs) beside the zone model's centered figure, while the 2027 table showed the same spot at −3.3 against the average club; the 2027 table's zone column and the zone map's total differed (−3.1 vs −3.3)Run prevention
- Pass A park term pools visiting teams' balls only from seasons at the same ballpark (keystone_models.fielding.VENUE_ERA): recomputed for the Rays (2025 alone; 2026 with 2024, skipping 2025) and the Athletics (2026 with 2025, not Oakland). Caught first: Park terms were keyed to the home club: the Athletics' Oakland and Sacramento seasons and the Rays' Tropicana and Steinbrenner seasons were pooled into one parkRun prevention
- Pass Every club fielder with no position rating carries the reason the depth model gives none (too little MLB fielding at a Caught first: “No rating anywhere: Josue De Paula … spread over several spots” for a rookie with 22 batters, all in left field (unrated because statsapi lists him at DH)Run prevention
- Pass When a club's third baseman changes, each listed pitcher's 2027 effect at third is his planned innings × his 2026 balls Caught first: Pitchers' “runs lost at 3B” on 30–60 balls each, with no expected 2027 effect of the new third basemanRun prevention
- Pass A 2026 regular catcher who keeps 15%+ of the 2027 catching is a reserve, not a departure; the counterfactual Team Caught first: SD: “Catching loses its best glove … Fermin is a call-up, off the 26-man”, while the same item listed him catching 24% in 2027; Catching and Team Defense priced Davis's return on different swapsRun prevention
- Pass fielding.json carries the zone model's fit on Savant's OAA by position, club and fielder level, 2024–26, recomputed from Caught first: Third-base glove split read off a zone figure about 5× Savant's (Pittsburgh −27.5 outs vs. Savant −8; Paredes −20.7 vs. −3) with no check of the zone model's scaleRun prevention
- Pass /prospects reads its blocked list and its surplus / blocked / need tags from the depth model (depth.json's Winter Plan grid Caught first: The Prospects page's trade-candidate list said it 'lists, it doesn't rank' because no surplus model existed; once one did, a prospect whose board position the needs map lacks would drop out of the list and the tags without a word. Then the list called ten 35+–40+ prospects (6–10% chances of a regular) 'Surplus' while /depth, by the model's definition, had only Mangum and Horwitz: one word, two meaningsPositional Depth
- Pass opportunities.json needs_future is the depth model's thin and open spots from 2028 on (opportunity_checks.depth_needs on Caught first: The Opportunity Finder's needs were 2027 only: a target who covers a hole the depth model sees in 2028–31 carried no word of itPositional Depth
- Pass Where the Winter Plan's trade package is shown, its trade-fit reasons and premium are too, generated from the data: the Caught first: The Winter Plan and the third-base brief named the Paredes package without saying why those prospects: the trade fit and its premium were in plan.json but on no page a reader seesPositional Depth
- Pass The Outlook's simulated seasons are the same every time: two fresh simulations from the published projections Caught first: A rebuild of unchanged code moved other clubs' playoff odds by 3–5 pointsReproducibility
- Pass Every club's projected strength comes out the same twice in a row, and matches the published Outlook. Caught first: Houston's projection moved 0.2 wins between identical builds (a depth-chart tie broken by float noise)Reproducibility
- Pass Pittsburgh's hitter projections (the part that read switch hitters' side from hash order) and best lineups against Caught first: The Lineup Lab's lefty verdict changed from rebuild to rebuild (switch hitters' side came from hash order)Reproducibility
- Pass Every export that reads another export's file was written after it, so no page quotes an earlier build. Caught first: Availability quoted the previous build's playoff odds (the Outlook was exported after the modules that read it)Reproducibility
- Pass Every club's playoff odds quoted in an availability note match the current Outlook (within a point of rounding), Caught first: CLE shown as 53% ("expects to contend") on one page while the Outlook said 50%Reproducibility
- Pass Every club's win curve rises with wins, passes through its own simulated odds, tracks the simulation, and only Caught first: The Outlook's verdict ('buyer's team' vs. 'below the steep part') came down to Monte Carlo noiseOutlook
- Pass Lineup Lab calls rest on real samples: switch hitters bat from the opposite side, every platoon swap has the Caught first: Brannigan (1 MLB PA) platooned out the plan's second baseman; Lombard platooned in at short on 30 PA against lefties; the lefty verdict sat 0.0005 from its thresholdStrategy
- Pass Model code picks the same rows every build: the Stuff and Location fits read pitches in a fixed order, the Caught first: Two builds of the same code differed in 786 files: unordered rows fed model fits and list order, ties went to whichever row hashed first, and parallel float sums moved values across a rounding edgeReproducibility
- Pass Lists that come out of an unordered query are published in a fixed order (by player id or team), every club: Caught first: contracts.json, bullpen.json, call-ups.json, hitting-lab.json and pitch-lab.json lists reordered between identical buildsReproducibility
- Pass Every call-up candidate on the FanGraphs board carries his FV, the same number the Trade Builder uses. Caught first: Call-ups dropped FV for prospects who had debuted (Jhostynxon Garcia, Nick Yorke)Development
- Pass The call-ups rookie test is held out, and the depth chart's blend weight is one the held-out fits chose. Caught first: The rookie test scored a model on the players it was fit on, with their 2026 positionsDevelopment
- Pass A prospect promoted past the level he's judged on isn't tagged "ready to push", and his FV matches the board. Caught first: “Ready to push” for players already promoted past that level (Murf Gray)Development
- Pass No prospect gets tracking goals from a level he has since been promoted past. Caught first: Development goals measured against a level the player had already leftDevelopment
- Pass Pick values are net of control-year pay (below the gross value) and above zero. Caught first: Draft-pick value ignored the salaries paid in the control seasonsDevelopment
- Pass Perf+ is league-relative: within each level, no league's qualified hitters average more than 4 points off 100. Caught first: Perf+ compared PCL and Cal League lines with the rest of their levelDevelopment
- Pass A year-over-year change in a raw metric is measured net of the league's median change at that level (the feed Caught first: Six of eight 'clear' Location declines (Skenes, Keller, Mlodzinski) were the 2026 zone change, not the pitchersDevelopment
- Pass Every rate target (platoon splits included) carries the player's expected next season with no plan and beats it. Caught first: Prospect targets were hit by 36–48% of similar players with no plan at all (regression to the mean)Development
- Pass A rate goal checked at the All-Star break is 2+ standard errors from today at the sample he had by the 2026 break, Caught first: Most MLB targets were about one standard error of the sample a player has by the All-Star check; relievers never reach 250 battersDevelopment
- Pass Every feed entry for a player the winter removes (the decisions feed's gone, departed and likely minor-league free Caught first: Yates and Santana counted among the clear declines though they're leaving; Noah Davis (a likely minor-league free agent) tooDevelopment
- Pass Coach-card lines talk to the player ("you", never "he", "his" or "him", as in "more than his 2026 total"), keep Caught first: Coach cards switched between 'your' and 'his' mid-sentence and printed 'XwOBA'Development
- Pass Every Winter Plan position change to a fielding position, for a player who stays, has a Position goal. Caught first: The Winter Plan moved Gonzales back to second base and no development plan carried itDevelopment
- Pass development.json is dated by the data cutoff (meta.json data_through), not the build day. Caught first: development.json carried the build date, so identical data built different files on different daysDevelopment
- Pass When a velocity goal carries a Stuff decline's runs at stake, the velocity and shape goals together equal Pitch Lab's Caught first: Skenes's plan showed ≈10.0 runs in play against Pitch Lab's 9.2: the velocity goal carried the whole Stuff decline and the splitter's shape goal added its part againDevelopment
- Pass The persistence backtest measures Stuff in grade points on each season's own league scale and publishes both seasons Caught first: Stuff persistence (54% / 26%) was measured on raw production-model values, so the league's own +1 to +2 point drift a season read as change that heldDevelopment
- Pass A Position goal carries the outs above average it compares (his latest season at the new spot since 2024, his 2026 Caught first: Gonzales's coach card said his fielding at second 'was better than at your 2026 spot' as a fixed sentence, whatever the numbersDevelopment
- Pass A Platoon goal's 'now' is his 2026 xwOBA vs. LHP on the regression's own population (one season, 60+ PA vs. LHP and Caught first: Cruz's platoon target applied a one-season regression to a two-season (263 PA) gap, so 'no plan ≈ .309' was too optimisticDevelopment
- Pass An Approach goal for a big-leaguer exists only when the Hitting Lab's regressed swing-decision value (2025–26 pooled) is Caught first: Development's chase goals gated on raw one-season decision value and printed it as runs: O'Hearn's '−0.51 runs' was decision value the Hitting Lab regresses to −0.07 (Core)Development
- Pass A Health check goal quotes Health & Workload's in-season backtest for his role (starters: velo_1_sp; relievers: a Caught first: Chandler's velocity check cited only the two-injury winter test, not the starters' in-season signal or his arm-angle changeDevelopment
- Pass Every FSL walk-rate or strikeout-rate goal carries box-score targets for High-A and Double-A: the FSL target shifted by Caught first: FSL plans named a box-score check after a promotion with 'no level-adjusted target yet', though league K and BB rates by level existDevelopment
- Pass Every scenario hands out exactly one season of team PA and IP (replacement level included), and its published lineup, bench, call-ups and staff add up to it. Caught first: Team PA ran from 5,600 to 7,055 across scenarios; Maximize stacked bench bats into phantom winsPlaying time
- Pass No player plays more than his own capacity: a starter his starter PA (and the slot), a bench player his starter PA (catcher-starter PA at catcher), a call-up his call-up PA; a starter his rotation IP, a reliever his bullpen role's IP, a call-up arm his call-up IP. Caught first: Players credited with more playing time than they can play once shortfalls were spread aroundPlaying time
- Pass A bench player or call-up is worth his value at the positions he actually fills, not his best position. Caught first: Arraez credited 2.08 WAR on the bench at his second-base value while the plan's second baseman played every dayPlaying time
- Pass The recommended 26-man carries a backup catcher. Shortstop cover means a bench player who can play there (the engine never moves another starter to short); if no bench player can, none of them has an MLB shortstop record (300+ batters at SS), or shortstop time is left to replacement level, the plan's check must warn, and it must not warn when a proven cover takes all the time. Catcher time at replacement level must warn too. Caught first: Griffin (369 PA) was the plan's only shortstop: the bench's SS cover had no fielding rating and Triolo was off the 26-manPlaying time
- Pass No position player in Pittsburgh's sandbox with 300+ MLB batters in the field in 2024–26 and 100+ at some spot (or a listed fielding position) is valued at DH only (depth.Fielding.eligible: a spread-thin utility player keeps his listed group and every spot with 100+ batters). Caught first: Jhostynxon Garcia and Tyler Callihan (40-man, 300+ batters in the field) were valued DH-only because no single spot reached 300Playing time
- Pass No shopping-list pick displaces or benches another pick on the same list, every pick still adds his share to the Caught first: The floor list signed George Springer, then Jake Bauers 'replaced George Springer' (11 more self-replacements across ATH, CWS, MIA, SEA and TOR)Free agents
- Pass Every free agent a shopping list, the insurance options or the third-base comparison names is a free agent under the Caught first: Joe Ryan (4.033 years of service, a 2027 mutual option) and Skubal were offered as clean free-agent targetsFree agents
- Pass Shopping-list pitchers count against the group of the innings they pitch: a rotation spot is a starter (SP), a Caught first: Brady Singer, slotted into the bullpen, used the only starter slot and blocked Sandoval and every starter; then the floor list called David Peterson and Patrick Sandoval 'Bullpen' though all 173 of their innings were startsFree agents
- Pass Free-agent prices come from the full projection: recomputed from the published coefficients, every price equals the Caught first: Skubal priced at 5 × $29.6M (projection clipped to 3.3 WAR) while Framber Valdez got $36.5M on 3.2Free agents
- Pass Qualifying-offer flags go only to free agents who spent all of 2026 with one club (no trade, claim or release in the Caught first: Skubal (traded DET→LAD on Aug 2) would have carried a qualifying-offer pick cost; later Adrian Morejon was flagged 'likely' and charged a full pick on a $71K margin, a coin flip on his price bandFree agents
- Pass The Free-Agent Board quotes the plan's playing-time totals from plan.json, and the page hard-codes no PA figure. Caught first: The board's note hard-coded 'about 5,980 of a season's ~6,130 PA' after the engine moved to 5,491 of 6,102Free agents
- Pass Pittsburgh's floor lists spend the owners'-lens gap from the decisions feed's one-basis payroll, stay within it, and Caught first: The floor list's budget was $45.9M on a mixed payroll basis; on one basis the gap is about $34MFree agents
- Pass A shopping list's 40-man cuts never release a newly protected Rule 5 player, the plan's acquisition, $2M+ of 2027 Caught first: Shopping lists released Kris Bryant ($27M guaranteed), Javier Báez, Ke'Bryan Hayes and Miami's Owen Caissie (FV 45); later the Angels' Christian Moore, the #8 pick in 2024Free agents
- Pass Pittsburgh's own free agents who hit are measured with second base open (a pitcher's fit doesn't depend on it and Caught first: Lowe measured only at first base (+1.3) because the board pinned Gonzales at secondFree agents
- Pass Each plan branch's floor list searches candidates measured on that branch's own 40-man: re-measured here, every Caught first: The in-house third-base branches searched a pool fit to the recommended roster (Paredes at third), so they never saw Bohm or Suárez: +4.04 and +4.83 published vs. +4.37 and +5.19 on their own rosters; later they pinned the in-house third baseman, so Suárez could only be listed as 'Bench'Free agents
- Pass When the plan's rotation has room (replacement innings in the rotation), at least one free-agent starter measures Caught first: Starters were blocked from the floor list when a reliever signing took the rotation's one slot; nothing checked that a starter could win an open rotation spotFree agents
- Pass The walk-year spike test is a nested model: refit here from the published training deals, adding max(0, walk year Caught first: The walk-year 'spike test' was a slope of the model's own residuals on one of its regressors (zero by construction), and the page said 'the market paid for those seasons'Free agents
- Pass Pittsburgh's own qualifying-offer free agent: his row's comp pick and walk-away ceilings equal the decisions feed's Caught first: Lowe's row on the board showed a $8.72M comp pick copied from a stale decisions feed while draft.json and money.comp_pick said $8.69M; nothing compared them. Then the board called his owners'-terms re-sign a toss-up while the feed and the plan, testing the floor money's other uses, said let him goFree agents
- Pass Every list carries both prices: aav, spent and commit at its own lens (owners: today's estimate x the owners' Caught first: Owners'-lens lists put the x0.88 owners' price in picks[].aav and spent, and /plan read them as today's market prices (Bauers '2 yr x $15.6M'; the list at $33.8M, 0.98 W per $10M, vs. $38.4M today)Free agents
- Pass One medical rule site-wide (fa_market.medical: ended 2026 on an injured list or the 60-day IL, or missed most of the Caught first: The board turned Kris Bubic away ('Medical first: missed most of 2026, 55 IP') while the plan signed him as its mid-tier starter and used him to let Lowe goFree agents
- Pass A fit below zero is a depth-chart artifact (the lineup search reshuffles starters, or a forced 40-man cut loses Caught first: The board published negative fits (Houston + Miguel Rojas: −0.54 wins) as if a signing could cost winsFree agents
- Pass The board's dates are the calendar's (money.DATES) and the page renders them: the offer window, free agency, the Caught first: The board exported the winter's dates (qualifying offers, the answer, the CBA's expiry, the lockout) but never showed them, so the floor list had no dated windowFree agents
- Pass Every list carries its test at today's prices (before_cba: a deal signed before the CBA expires is signed at today's Caught first: The board's When line said the floor list 'is meant to be signed between Nov 5 and Dec 1' at the owners' prices, while the plan, the decide strip and the floor brief said wait for the CBA: at today's prices the list cost $38.2M, $4.1M over the room, at 0.82 wins per $10M against the market's 1.11Free agents
- Pass Each pick that displaces a base-roster player says where he ends up (replaces_to: the bench, the bullpen or the Caught first: Every hitter pick's role said it 'moves X to the bench' (38 times across the boards) while the same panel listed X off the 26-manFree agents
- Pass No list, under either lens, pays a bench role more than the bench cap at today's market estimate (aav_market). Caught first: The bench cap was applied to the owners' x0.88 price, so George Springer ($6.3M today) and Eugenio Suárez ($6.7M) were signed as 'Bench' under a $6M capFree agents
- Pass Pittsburgh's catcher-insurance panel names the plan's third-catcher call from the decisions feed Caught first: The catcher-insurance panel read decisions.catchers.third/.insurance (neither exists), so it never named the plan's third catcher (Christian Bethancourt), and quoted the no-depth loss (−0.9) as the plan'sFree agents
- Pass The board's leads come from the model's own statistics: the years model publishes t-statistics for its projection Caught first: The page called length 'following the projection' and the walk year 'moving the price' with no test, and said starters 'tend to show more value' though their discount was not clear (1.1 standard errors); the lens note offered a Skenes extension as the alternative use on every club's boardFree agents
- Pass At phone width (the page's max-width: 560px block) every table's sticky first column wraps at a set width Caught first: At 375 px the plan-branch table's sticky first column (a nowrap label, 353 px wide) covered its whole 343 px scroll box, so none of its other columns could be scrolled into viewFree agents
- Pass One definition of a free agent at third: the board's third-base panel lists only free agents with 1,000+ batters at Caught first: In the plan's in-house view the free-agent list signed Luis Arraez as its '3B starter' (10 batters at third in 2024–26) while the plan's fallback list at third, on the same page, left him out by its 1,000-batter line; the board's third-base panel listed him tooFree agents
- Pass A player released or elected to free agency in 2026 with no signing after (transactions, recomputed here) holds no Caught first: Michael Lorenzen's and Jeimer Candelario's club options read 'expected to be declined… the decision comes about five days after the World Series' on the board and their player pages after both had elected free agency; Max Kranick, who elected free agency, read 'under his club's control'Free agents
- Pass Every Pittsburgh own free agent on the board has a call: the qualifying-offer decision's walk-away and calls, or the Caught first: Gregory Soto's own-free-agent row had no re-sign call, the panel said the qualifying-offer decision covered him (he gets no offer), and nothing checked the plan's left-handed relief after he leavesFree agents
- Pass Every warning-sign row carries its distinct injuries and a pitcher-clustered interval, and its verdict is the one Caught first: 'Strong signal' at −1.5 and −2.0 mph rested on 9 and 3 injuries, with intervals that ignored repeat outingsHealth
- Pass A row with fewer than 10 distinct injuries publishes the exact interval that counts each injury once (recomputed Caught first: A bootstrap on 2 injuries published [0.00, 0.91] for the season-end drop, and the Track Record read it as 'got hurt less often'Health
- Pass health.json carries, by role (pitcher or hitter, never pooled) and arm body part, how often another arm placement Caught first: Recurrence base rates for the ledger's arm injuries (lat/teres, UCL) were never shownHealth
- Pass The velocity warning is tested by role, and the live check warns only where its role's test holds (a clustered Caught first: 79% of velocity warnings fired on relievers, where the warning doesn't predict injury; it works for startersHealth
- Pass The backtest publishes what the warning catches (arm placements seen, monitored and flagged, overall and for Caught first: The page never said what the warning catches: 15% of monitored arm placements, none of Pittsburgh'sHealth
- Pass The season-end test counts only placements after the regular season's last day (pitchers placed in between are Caught first: The 'winter' test counted September placements and was logged as a forward fail on 2 winter injuriesHealth
- Pass No stint is closed by another placement from the same club in the same season for the same body part (or none Caught first: 60-day transfers written as new placements split one injury into two stints (Gonzales 53 + 14 days)Health
- Pass A Pittsburgh pitcher left out of the season-end check because he came back from the IL within 45 days is listed Caught first: Kirby Yates and Evan Sisk, back from the IL in the last 45 days, vanished from the season-end tableHealth
- Pass A pitcher whose prior season was lost to the injured list (under 20 innings and a 90+ day stint that season) is Caught first: Jared Jones's season lost to the UCL (0 IP in 2025, 120 in 2026) showed as '—' and sorted last in the workload tableHealth
- Pass The outings before an 8-outing baseline are tested against a prior-season baseline as their own row (prior_base): Caught first: The velocity warning had no baseline for spring and April placements (104 of them) and the gap was disclosed, not testedHealth
- Pass An innings jump is judged on the whole percent the pages print: big_jump agrees with the rounded jump_pct. Caught first: Montgomery showed '+25%' (a 24.85% jump) but wasn't counted among the arms that threw a quarter more inningsHealth
- Pass Matchup shrinkage is estimated from the data, and predicted edges are calibrated (forward slope 0.7–1.3). Caught first: Matchup edges were twice too large: 120–150 pitches of assumed shrinkageStrategy
- Pass Every Hitting Lab row with a diagnosis carries a regressed estimate, and the lefty targets are ranked by it Caught first: Hitting Lab diagnosed hitters from raw 100-PA splits that barely repeatStrategy
- Pass ABS policy gives no individual accuracy to a role whose success hasn't been shown to repeat (its 95% range not wholly above 0), says so in those words, and uses no hard-coded rates. Caught first: ABS “green list” for batters whose challenge success doesn't repeatStrategy
- Pass Every green-light or run-smarter call on the Running Game page carries its value in runs. Caught first: Green lights with no sense of how much they're worthStrategy
- Pass Pull-air flags mark only right-handed hitters (switch hitters pull to right field most of the time). Caught first: Park page told teams to shop for right-handed contact while flagging nobodyStrategy
- Pass Every pooled sample is plate appearances (2026 + the pooling weight × 2025 against that hand), so it is never below Caught first: The Hitting Lab's 'pooled PA' was pitches ÷ 3.89 (Griffin: 249 in 2026, 'pooled' 239; 99.7 printed as 100 beside a 'under 100' tag), and an outside bat's panel showed his vs-LHP PA and raw values under 'vs RHP'Strategy
- Pass park.json rates every Roster Builder pitching candidate (pitchers_out) and every FA Board player (fa), with park Caught first: Park fit reached no ranking tool: outside pitchers were never evaluated, the Roster Builder and the FA Board showed no park term, and the team totals silently left out 622 PA and 236 IP of replacement playersStrategy
- Pass The forward test scores sit-on and lay-off flags apart and the page quotes both; every rival whose staff or Caught first: Rival Intel quoted '6 of 7' sit-on flags held beside lay-off flags it never tested, ranked a Cubs staff 70% gone on 2026 pitches, and counted Assad's club option as leaving though a declined option keeps him under Cubs controlRivals
- Pass For every club, a trade target in the Lineup Lab's what-if shows the prospects his club would want, when it would Caught first: Lineup Lab listed trade targets at salary onlyStrategy
- Pass ABS break-evens use the state-dependent failure cost (challenges left × inning), checked against an independent option value; the flat 0.21 is only a labeled sensitivity. Caught first: ABS break-evens used a flat 0.21-run cost per failed challenge, about 7× Savant's state-dependent cost, so the page told staff to hold early countsStrategy
- Pass Every club's challenge matrix comes from role × count × state success rates, each cell's call (and its early-inning holds and toss-ups) follows from its 80% range against the break-even, the range is at least what a club-game bootstrap gives, and no individual player gets his own row while the role's skill is unproven. Caught first: The ABS matrix gave batters one accuracy in every count: 1-2 showed 'challenge' (40% vs. 47% needed) and 2-0 'hold' (64% vs. 53%)Strategy
- Pass The ABS policy is forward-tested (fit before the split date, scored after) at both costs, the published value is that test's, and the page shows it. Caught first: The ABS policy's value was scored only in-sample and never shown on the page; at the flat cost the held challenges looked like savingsStrategy
- Pass On every club's ABS page, each role row equals the sum of its player table (challenges, overturns, runs), the roles add to the club's total, and the accuracy gap is minus the roles' runs. Caught first: Two run-accounting systems on /abs: the pitcher row (−1.2) contradicted the pitcher table (−0.1) and no player table added up to its roleConsistency
- Pass The ABS page and model card claim only what the data show: no edge-distance model, no catcher skill while its interval includes zero, and repeatability published with an interval. Caught first: /abs cited a pitch-level edge-distance model that doesn't exist and sold catcher accuracy as a skill on r = .12; the model card kept a '20-challenge prior' the code never usedStrategy
- Pass On every club's ABS page the 2026 and regressed overturn figures share one sign convention (+ = lost) and add up Caught first: Other clubs' /abs copy dropped signs: Colorado's 'shortfall of 1 overturns regresses to about 5' (an edge of 5), 'won at least as many' for clubs that lost overturns, and accuracy 'accounting for 6.6 of 3.3 runs'Consistency
- Pass Every club's zone-edge and pitch-group splits carry a mix-adjusted expectation (league rate in the same role, count and state) and an interaction z (the split's gap against the rest of the club's); Pittsburgh's recompute from the log; the page flags a split only on the interaction z past the multi-test line. Caught first: /abs flagged Pittsburgh's fastballs (z = −2.7) by testing the raw club rate against the raw league rate: a club below average everywhere flags its biggest group, and the role/count mix differed (against the rest of its own challenges, z = −1.0)Strategy
- Pass /abs: month gaps are rounded before the sign is chosen; volume ranks share ties (…_tie, printed 'T-'); the regressed accuracy figure is labeled 2026 club accuracy (Pittsburgh's 2027-catcher version beside it, abs_coach.with_catchers); rate-dot labels hang inward near the ends; sentences built in a loop are joined with a space. Caught first: /abs printed '−0' and '+0' month gaps, a tie broken alphabetically ('12th' vs. STL's '13th' on 573), '2027' on a regressed figure built on 2026's catchers, a 100% label past the screen edge, and leaver sentences run togetherConsistency
- Pass On every club's /abs a player still with the club who is a pending free agent carries pending_fa (tagged 'Leaving: free agent', as catcher_records has him) and never counts as active; another club's 2027 catchers come from its depth chart (catchers27, each with a record); the forward-test card states the held challenges' net and the rule's value with one sign convention, the pitcher count is labeled league-wide and the two-strike bar reads 'at most'. Caught first: Other clubs' /abs player tables tagged pending free agents “No longer with club” while the catchers panel called them free agents; the forward-test card set the rule's per-club range beside what its held challenges netted (−0.08); a league-wide pitcher count read as the club's; “under 17%” beside a card showing 17%Consistency
- Pass Projected arbitration salaries never fall, and never rise more than double (or $2M for small salaries) in a year. Caught first: Skenes's arbitration path jumped $10.4M → $21.9M in one year (separate fits per arbitration year)Acquisitions
- Pass The Winter Plan's acquisition adds within 0.3 wins of the best realistic candidate. Caught first: A +0.6-win controllable third baseman beat a +3.2-win one-year option because control was a hard preferenceAcquisitions
- Pass Non-tenders are exactly the arbitration players whose role value plus later-year upside falls short of salary, and the brief says so. Caught first: “Tender everyone” with High confidence while a player's value in his actual role didn't cover his salaryAcquisitions
- Pass The free-agent model's training ages are true ages at signing (within a few days of birth-date math). Caught first: RosterResource's age_at_signing is the age today, not at signing; the FA model trained on ages a year too oldAcquisitions
- Pass Opportunity targets who ended 2026 injured carry the medical flag and its score penalty, and the optimizer won't pick them. Caught first: Cole Ragans (60-day IL) ranked as the #1 trade target with no medical weightAcquisitions
- Pass One payroll number site-wide: Contract Studio's as-it-stands payroll (contracts.json payroll_basis), the Winter Plan's Caught first: The plan's $125.3M payroll mixed RosterResource's arbitration figures with Keystone's, and the floor gap read $57.7M, $45.9M or $34.0M depending on the pageAcquisitions
- Pass Every club's Contract Studio lists only players that club holds today: its controlled players and its own pending free Caught first: Dennis Santana and Marcell Ozuna, both released mid-season, listed as Pittsburgh free agents and controlled playersAcquisitions
- Pass Arbitration paths reproduce from their inputs with the raise cap only between arbitration years (a first arbitration Caught first: A pre-arbitration player's first arbitration year was capped at the minimum + $2M (Ashcraft and Chandler both $2.83M → $5.66M → $11.31M), and player options were floored at zero as if the club held them (Bichette $0 vs −$50.9M)Acquisitions
- Pass The Skenes extension is decided before the lockout (the CBA expiry, from calendar.ts), the deal zone is called only when Caught first: Contract Studio's Skenes card offered 6 years at ≤ $24.0M with 'Any time' as the deadline while the brief said 5 years, and the 5 → 6 year price jump came from a ±0.25 window edgeAcquisitions
- Pass The compensation pick is net of its signing bonus wherever it is quoted as the pick's worth: draft.json carries value, Caught first: Lowe's compensation pick shown at $12.7M gross of its ~$3.0M bonus; 164 re-drafted (unsigned) picks credited twiceDevelopment
- Pass Contract Studio's decision cards compute their verdicts from the Winter Plan's feed: no typed-in verdicts ('Close call', Caught first: Contract Studio's decision cards said 'Close call' on the qualifying offer and flagged no non-tender while the plan cut Henry DavisAcquisitions
- Pass Every season of every club's one-basis payroll (contracts.json payroll_basis) carries the non-player items: benefits Caught first: Contract Studio said Miami sat $106.7M below the floor in 2028: RosterResource had no 2028 row, so benefits, the bonus pool and 40-man minor-league salaries counted as $0Acquisitions
- Pass The browser's surplus engine (web/src/lib/surplus.ts) gives the pipeline's answer for every club's contracts: season Caught first: No permanent check kept Contract Studio's browser engine (surplus.ts) in step with the pipeline's; club options were each decided on their own, so San Diego still paid Nick Pivetta's 2028 player option after declining his 2027 club optionAcquisitions
- Pass Every club's contracts.json option seasons follow one backward decision (keystone_models.contracts.surplus_rows): no Caught first: Cleveland's Emmanuel Clase was charged a $2M buyout twice (both club options declined), and San Diego's payroll counted an $18M player option that ends with the club option before itAcquisitions
- Pass The owners'-proposal extension gain (keystone_models.extensions._owners, floor money at a shadow price) decides the Caught first: Under the owners' proposal the extension calculator gave Emmanuel Clase two answers (tiles −$11.0M against going year to year, the verdict “$9.2M at face value”): its owners' status quo declined each club option on its own and charged both $2M buyouts again (Pivetta off by $8.6M, 18 player-lengths by more than $0.2M)Acquisitions
- Pass Option chains with answers fixed outside the code under test: the hand-worked synthetic chains (_SYNTH: a declined club Caught first: The guardrails on option decisions compared the exported flags with the code under test, so reverting both twins to independent decisions would still pass (Pivetta's ended 2028 player option, Clase's one buyout)Acquisitions
- Pass Every club's projected arbitration salaries (contracts.json) are the arbitration model's path on the projection the Caught first: Contract Studio valued Jordan Westburg, Reese Olson and Gavin Stone (missed 2026) on their missed-season projections but priced their arbitration raises as if they produced 0 WAR (Westburg's 2029 at $4.61M, not $7.56M): $16.8M of surplus, not $13.6M, and the Winter Plan took it as his talent costAcquisitions
- Pass Contract Studio and the Draft page say what their data say: no {#if} block glued to the sentence before it (Svelte drops Caught first: Contract Studio's Keller card read '…playoff odds)and saves $13.3M' and 'about $0 under the owners' floor' (one end of the floor money's price); the Draft page printed the feed's raw 'Gonzales bench' and a typed 'second-best record' line; the payroll trajectory's tip said commitments 'drop fast'Acquisitions
- Pass The Winter Plan's talent cost for every third-base candidate is Contract Studio's surplus value of his contract Caught first: The Winter Plan valued a trade target's contract with its own surplus formula (club options only floored, no buyout, player and mutual options as written) while Contract Studio, the Trade Builder and the FA Board used anotherAcquisitions
- Pass The Keller card's money call (web/src/lib/surplus.ts keepTradeMoney; _keep_trade is its twin, and surplus_parity_ts Caught first: Contract Studio's Keller card called 'Keep' on money by valuing 2027 net of his replacement (the plan's engine, 0.68 W) but 2028 gross (his 1.11 WAR as if a replacement-level arm took the innings), against savings on the luxury-tax basis alone: on one basis the call flipsAcquisitions
- Pass Every club's first unsigned 2027 arbitration salary (contracts.json) is priced as the arbitration year his service Caught first: Adley Rutschman (4.0 years of service at the start of 2026, so 2027 is his third arbitration year) was priced as a second-year case ($10.1M, not $16.1M): the arbitration year added one for any service of 3+ years; 59 players on other clubs were priced a year earlyAcquisitions
- Pass Every pre-arbitration 2027 salary Keystone estimates (a debut-based control estimate, or an unlisted pre-arbitration Caught first: Estimated pre-arbitration seasons were priced at $803,400 in 2027 (the 2026 minimum grown 3%) while Contract Studio used $780K: Trevor McDonald, Cade Povich, Samy Natera Jr. and others carried two minimumsAcquisitions
- Pass No contracts.json player (every club, players and estimated) with seasons has an all-empty projection unless it is Caught first: Seattle's Carlos Vargas showed '0.0' WAR and '$0' surplus: a player with nothing to project him from read as a zero-WAR non-tenderAcquisitions
- Pass Every player on a club's 40-man today is in its contracts.json: a contract row (players), a pending free agent, a Caught first: Contract Studio listed 22 controlled Pittsburgh players and left out 40-man players with no RosterResource row (Wilber Dotel, Evan Sisk, Isaac Mattson, Brandon Eisert...) without saying soAcquisitions
- Pass Rival Intel's 2027 payrolls are Keystone's one basis (current rules): each rival's equals its roster.json payroll27, Caught first: Rival Intel compared rivals' payrolls with 'Pittsburgh $113.5M on the same basis (RosterResource)' while every other page put Pittsburgh's 2027 payroll at $126.7M as it stands and $138.6M under the planAcquisitions
- Pass The pick a qualifying-offer signing forfeits comes from the draft page's 2027 capital: the central case is the Round 2 Caught first: The qualifying-offer forfeit was typed in as picks #45–75, outside the draft page's own capital (Round 2 ≈ #54; Round 3 ≈ #90 if Lowe accepts)Acquisitions
- Pass A 2026 bonus is fitted to a pick only when it is within 10% of some 2026 slot's range: a bonus more than 10% under the Caught first: 'Bonus fits #' put Michael Gibson's $17,500 bonus at #311, though it is 9% of the smallest 2026 slotAcquisitions
- Pass No player who has left the organization appears in a Pittsburgh pool, list or package. Caught first: 13 of 93 Call-Ups players had left the organization; Hyun Seung Lee (traded Aug 3) sat in live trade packagesOrganization
- Pass Pittsburgh's own free agents on Contract Studio and the Free-Agent Board are players the organization holds today. Caught first: Dennis Santana (released Jul 29, on Arizona's 40-man) and Marcell Ozuna (released Aug 6) were listed as Pittsburgh's free agentsOrganization
- Pass Every player in the organization has a level, and the Command Center's level counts cover the whole organization. Caught first: Sixteen organization players had a NULL level (Fall League / winter-ball clubs); Delgado's Rule 5 risk came out 0.02Organization
- Pass The 40-man snapshot is no older than the newest transaction we hold, and every club's base roster is exactly today's Caught first: The Winter Plan's 40-man base read the season-scoped list; nobody checked it against the official 40-manOrganization
- Pass Rule 5 eligibility follows the CBA rule on known cases, agrees with FanGraphs' published dates, and one count is used site-wide. Caught first: Rule 5 eligibility covered only FanGraphs' list (8 of ~28); Sanford's and Moody's first years were a year earlyOrganization
- Pass Estimated option years left agree with FanGraphs' published count wherever both exist, and never claim a number Caught first: No option-year data: the plan sent players down 'option or outright' without knowing whichOrganization
- Pass The Winter Plan never spends a 40-man spot protecting a player every club passed on in the last 12 months Caught first: The Winter Plan protected Kyler Fedko, whom Minnesota released Sep 1 and every club passed onOrganization
- Pass A club's own pending free agents are players it holds today, and no club's Call-Ups board lists another club's Caught first: Dennis Santana, released in July and on Arizona's 40-man, was listed as a Pirates re-sign candidate; Boston, Chicago, Houston and San Francisco still listed pitchers their clubs had released or who had elected free agencyOrganization
- Pass The free-agent summary the Command Center and /start read is Pittsburgh's own floor list. Caught first: The Command Center's free-agent card showed Washington's list (the 30-club export overwrote Pittsburgh's summary)Consistency
- Pass The Winter Plan's wins and odds are the same in plan.json, the /start tour and the Command Center's sources. Caught first: Summary pages that quoted an older plan than the Winter Plan pageConsistency
- Pass The Command Center's 2027 card uses the Outlook's current projection for Pittsburgh as it stands. Caught first: The Command Center quoting an Outlook from an earlier runConsistency
- Pass The Outlook's projected standings sum to 2,430 wins, and the free-agent pool is fully allocated. Caught first: Projected standings that didn't add up to the games the league will playConsistency
- Pass /start's claim count is the Track Record's forward-tested claims, and matches it. Caught first: “N claims tested out of sample” counted in-sample and benchmark checksConsistency
- Pass Every player on the Winter Plan's 26-man shows the same role and WAR on his player page. Caught first: A player page and the Winter Plan disagreeing on a player's 2027 roleConsistency
- Pass /start's stops run in order of what is at stake (tour.json stops: the plan, then the winter decisions by 2027 wins and then dollars, then the in-game levers by wins); web/src/lib/tour.ts lists the same stops in the same order, each pinned to Pittsburgh. Caught first: The tour ran in a typed order (two product features and the smallest levers ahead of the Lowe decision and the floor money), and a remembered club opened another club's evidence under a Pittsburgh findingConsistency
- Pass The home page's decide-now strip carries every dated move in the decisions feed (the qualifying offer, the trade, the Rule 5 protections, the non-tenders, the third catcher) plus the floor money, Keller and Skenes, in deadline order, each with a brief that exists, and closes on the CBA's expiry. Caught first: The Command Center showed three hard deadlines and none of the winter's calls (Paredes, Davis and the Lowe branches appeared nowhere)Consistency
- Pass The briefs, /start and the Command Center carry none of the typed verdict phrases a review found; their comparison words come from the numbers they compare. Caught first: Typed verdicts on the narrative pages ('a plus at 2B', 'mostly his bat', 'bottom of the league by both measures', 'Neither grades nor Triple-A lines predict rookies well') outran or contradicted the numbersConsistency
- Pass /start's defense card quotes both ranks as computed: the zone model's from fielding.json (2026, third base) and Savant's from today's rosters (keystone_models.fielding.team_by_position, the source of defense.json), and its 'bottom three' headline holds only when both ranks are. Caught first: /start's Team Defense card said 'bottom of the league by both measures' while Savant ranked Pittsburgh's third basemen 28thConsistency
- Pass The ABS edge on the Command Center, the /start stake and the ABS brief's stakes are the count policy's own value at league success rates (keystone_models.narrative.abs_policy), not abs.json upside.runs (the accuracy gap); the brief labels the gap as such. Caught first: The ABS edge and tour stop scored the accuracy gap (6.4 runs, mostly regression) as the count grid's valueConsistency
- Pass The packet's page promise is enforced where it is measured (web/scripts/packet.sh counts each memo's printed pages and fails above two), the pages state that promise, and each memo's printed text stays within the budget that measured two pages (about 6,200 characters, the longest at 5,500 when it printed to 1.8 pages); method and long lists go to the brief's notes. Caught first: The packet promised 'one page each' and later 'a second at most' while the memos printed to 21 pages for 9Consistency
- Pass The third-base brief attributes to the trade only what differs between the alignments its wins compare (the in-house row against the plan): no second-base move when the same player is at second in both, and the glove change at third is quoted from the Fielding Lab's ratings. /start's chain stop shows the second-base give-back from the 2026 club. Caught first: The third-base brief credited the Paredes trade with moving Gonzales back to second (7.3 runs) when he plays second in the in-house row tooConsistency
- Pass Every /start and home-page link to a club-aware page carries ?team=PIT and a full reload: literal hrefs, the hrefs the home page's cards build in its script, and the anchors that render them. Caught first: /start's 'Also in Keystone' links to club-aware pages weren't pinned, so a remembered club opened another club's evidence; the home page's cards had no such checkConsistency
- Pass Every brief's confidence comes from computed tests (keystone_models.narrative.confidence called with values, never a literal True or False), as the module docstring and the glossary's scale promise. Caught first: Two briefs carried a typed confidence (the floor and ABS memos were always Medium, whatever their margins)Consistency
- Pass The narrative layer drops a stop or a brief, rather than failing the build, when a module it quotes is missing: the tour without bullpen.json (no hook stop), abs.json (no ABS stop), free-agents.json (no floor stop) or models.json (the scale line says less), the Keller brief when he isn't in contracts.json, the usage and ABS briefs without their modules. (tour_ranked_by_stake accepts a tour.json that leaves a stop out.) Caught first: The tour raised KeyError('tto') when bullpen.json was missing, and the Keller brief crashed if he left contracts.json: one missing input failed the whole buildConsistency
- Pass Every string in briefs.json (notes and questions included), tour.json and command.json's decide strip, call count, free-agent card and ABS edge passes realism's copy checks (proper minus signs and ordinals, no negative zero, no printed missing value). Caught first: The narrative outputs had no copy check: briefs.json notes and questions, tour.json and the decide strip were never scanned for '−0', hyphen minus signs or printed missing valuesConsistency
- Pass The home page loads command.json on the server (prerendered) and passes the page only the fields it shows, so the HTML doesn't carry the full file. Caught first: The home page inlined all of command.json (93KB: every Rule 5 row, the 40-man detail, every scenario's timeline) to read a few dozen numbersConsistency
- Pass Every rotation arm the plan's health warnings flag for velocity or arm angle (decisions.json health.warnings), or the Development Tracker flags for a velocity decline, has his third-time-through call in the pitching-usage brief said 'pending the review'. Caught first: The usage brief made Skenes's third time through wait on his velocity review but gave Bubba Chandler a short leash with no condition, though the same memo printed his late-season velocity (−1.3 mph) and arm-angle (−3.2°) warningConsistency
- Pass Every wins row the home page's glance prints (the 2026 club brought back, as it stands, the plan, plus the list) carries its 80% range in command.json, and the page renders it. Caught first: The home page's '2027, in wins' panel promised an 80% range on every row, but the 2026-club row had none (r: null)Consistency
- Pass On the narrative pages no prose relies on a space at the edge of a Svelte block ('… and {/if}', '{#if x} and …'), which Svelte trims; the space goes in an expression ({' '}) or outside the block. Caught first: /start printed '2.1 million pitches and550,000 plate appearances' (and earlier 'window;Lowe'): a space at a block edge, which Svelte trimsConsistency
- Pass The prerendered HTML of '/', '/start', '/briefs' and every brief passes realism's copy checks and the typed-verdict list, and /start's verdict phrases follow tour.json. Runs on web/build when it is newer than the JSON it prints (after `vite build`; scripts/deploy.sh runs it before deploying); a stale or missing build is skipped, since it shows an older build's numbers. Caught first: The rendered /start, home page and briefs were never read: the copy checks scanned JSON and Svelte source, so a sentence the page assembled (the ABS rank, the QO answer, Skenes's condition) could contradict tour.json unseenConsistency
- Pass Every graded player on the home page's org ladder carries FanGraphs' printed grade (command.json levels[].top fv_label: '45+', not the board's internal 47), and the page prints the label. Caught first: The org ladder printed FanGraphs' internal codes (Sanford 47, Plaz 42, Ramirez 37) for grades the board shows as 45+, 40+ and 35+Consistency
- Pass Every dead-weight pitch-mix change names the batter side(s) where the replacement has clearly been better. Caught first: Pitch Lab told Skenes to throw more sweepers to everyone; most of his changeups go to leftiesPitching
- Pass A fastball-to-secondary mix change never takes his fastballs below 35% of his pitches. Caught first: Mix changes that could hollow out a pitcher's fastball usagePitching
- Pass A new-pitch idea: never a pitch thrown 100+ times in 2024–26, never a 5th main pitch, 15+ comps, and it beats the pitch it would compete with. Caught first: Pitch Lab suggested an 8th pitch for Mlodzinski and a slider he'd thrown for two yearsPitching
- Pass A season-end warning is a velocity drop; arm-angle and spin shifts are shown as context only. Caught first: A season-end arm-angle shift counted as a warning the page itself called contextPitching
- Pass The published warning-sign backtest includes the offseason test, and the in-season test has its intervals. Caught first: The injury backtest used looser rules than the live warningPitching
- Pass Every pitch pair called out differs from the pitcher's own rate by 2.5+ standard errors, on 40+ swings and 100+ pairs. Caught first: “Lean on CH → 4S: +6 points” from 70 swingsPitching
- Pass A reliever is only flagged for back-to-back fatigue on 5+ back-to-back appearances. Caught first: A back-to-back fatigue call from three appearancesPitching
- Pass Stuff, Location and Pitching are centered on each season's league: qualified pitchers (500+ pitches) average 100 Caught first: The 2026 Location median was 91 (2025: 106): grades were centered on all seasons pooled, and 2026's zone movedPitching
- Pass The median pitcher's Location changes by under 2 points from one season to the next, and the Location model is Caught first: Every 2025 → 2026 Location fell about 15 points: a zone-definition change read as lost commandPitching
- Pass The Stuff landscape at a pitcher's own shape lands near his actual pitch graded by the same model, pitch by pitch (not Caught first: The fastball landscape graded a blank approach angle: Weaver's own four-seamer read 64 against a real 108Pitching
- Pass Every landscape ★ (best within 4") and ◇ (best anywhere) carries a reality check against the real pitches at that Caught first: The landscape's ★ promised +27 to +44 Stuff within 4 inches (Bachar's four-seamer 94 → 138) with no check against real pitchesPitching
- Pass Every pitch-design idea is graded against the pitch it competes with under every model, built as one coherent pitch Caught first: Pitch-design grades moved 10–20 points with how the pitch was built, and one fit disagreedPitching
- Pass Every dead-weight mix change rests on a batter side where the replacement wins by 2+ standard errors (empirical-Bayes Caught first: “Clearly better” on a 0.6 standard-error split; the plan valued a lefty-only shift with side-blind StuffPitching
- Pass Pitch Lab's Stuff trend and the Development feed's year-over-year Stuff change are the same number (one production Caught first: Skenes's 112 → 104 Stuff drop showed on Development but nowhere in Pitch Lab, in two different numbersPitching
- Pass Every 2026 Stuff level a page shows for a pitcher or a pitch is the published 2026 grade (stuff_pitcher / Caught first: Skenes read Stuff 105 on his row and 'Stuff 112 → 102' in his alert; Montgomery 115 in his header and 124 → 119 in his planPitching
- Pass Every staff pitcher's Stuff trend carries the change under a pitcher-held-out model (stuff.holdout) next to the Caught first: Stuff-trend alerts rested on one in-sample model: graded by a model that never saw him, Bachar's −6.7 was −4.3 (below the bar) and his ≈3.1 runs were inside model noisePitching
- Pass Every listed Stuff leader carries his 2026 grade under the pitcher-held-out model (pitchlab.holdout_grades, the Caught first: League Stuff leaders listed Tyler Rogers's 140 first: a model that never saw him grades him 79 (his −61° slot has no neighbours)Pitching
- Pass Every Pitch Lab staff row's Stuff percentile is against the 2026 league's pitchers with 500+ pitches: their percent Caught first: Stuff percentile bars for pitchers under 500 pitches were ranked within the Pirates staff (Curtis 97 read 17th; 38th against the league)Pitching
- Pass Every branch of the Lowe → Gonzales → third-base chain is in plan.json with wins, range, odds, payroll against the floor, 40-man, Gonzales's role, Lowe's position and the comp pick; the plan row is the recommended scenario; each row that names a scenario matches it. Caught first: The Winter Plan never followed Lowe staying through to Gonzales, re-signing him, or putting him at firstWinter Plan
- Pass The 2026 club brought back keeps the 2026 holders of second and third base where they played; its waterfall chains (each step = the one before plus its change) from that baseline to the recommended plan; and each step names exactly the lineup moves that happen in it. Caught first: 'The 2026 club brought back' re-sorted Lowe to third, where he has never played, and its waterfall gave the Gonzales move to the wrong stepWinter Plan
- Pass The chain's reverse alignments swap the players they name (Lowe with the third baseman beside him), and agree with the scenario's own alternatives where both price the same swap. Caught first: 'The reverse is a toss-up (−0.2)' described an O'Hearn/Horwitz swap; the Lowe/Paredes reverse costs about a winWinter Plan
- Pass The Lowe re-sign ceiling, under both CBA lenses, is money.walk_aways of his projected WAR net of the comp pick (net of its bonus) against the plan's payroll without him, and the decisions feed quotes the same numbers. Caught first: The re-sign walk-away left out the compensation pick a re-sign gives upWinter Plan
- Pass Every Winter Plan projection (status quo, each scenario, each alternative alignment, each chain row, each Keller branch, every other club's baseline) carries the Outlook's 80% range for its own win total; alignments inside the toss-up line are labeled toss-ups. Caught first: Projected wins and odds shipped as single numbers with no rangeWinter Plan
- Pass Every scenario's 2027 payroll is money.payroll of its own 40-man (one luxury-tax basis), both lenses, and its floor gap is the owners' terms; each move's payroll effect sums with the others to the scenario's change from today's roster when nothing else moves. Caught first: plan.json's payroll mixed RosterResource's arbitration figures with Keystone's; the floor gap was $46M on one page and $34M on anotherWinter Plan
- Pass Every scenario's move list extends the qualifying offer, names the pending free agents who leave, and lists each 2026 regular who opens at another position (Gonzales from third to second) or loses his spot to a move; every move carries a date window, and the list runs in date order. Caught first: The moves list started at Nov 17: no qualifying offer, no Lowe exit, no Gonzales move from third to secondWinter Plan
- Pass The Keller trade keeps half of each remaining season on the luxury-tax basis; its savings are one number per season (the keep-minus-trade payroll on the one basis) in plan.json and the decisions feed; the Keller branches are all there, the signed starter is a clean free agent by the Free-Agent Board's test, and each branch's note is written from its own starter innings. Caught first: The Keller trade saved $9.2M on the plan, $18.4M in the Builder and $7.7M on a correct luxury-tax basisWinter Plan
- Pass Every third-base candidate is published with the rule's reasons, the route is the best candidate who fits, a declined option under six years of service is described as arbitration, and the 2028 successor isn't a prospect the trade sends away. Caught first: The third-base table cut to ten and hid the only other candidate who fit the rule; a declined option was called free agencyWinter Plan
- Pass Every owners'-terms surplus on the third-base panel (the route's trade and each free-agent fallback) carries both ends of the shadow price: the floor money free (`owners`, shadow 0) and at face value (`owners_at_face`, shadow 1), the face-value end never above the free end, and the page prints both. When the sign flips between the ends, the break-even shadow price (owners_breakeven: the share of face value a below-floor dollar can cost before the deal turns negative) is published and equals owners ÷ (owners − owners_at_face), and the page quotes it instead of 'positive only if the floor money is free'. Caught first: The third-base panel quoted the trade's and the free agents' surplus on the owners' terms with the floor money free only (Jazz Chisholm Jr. +$50.4M, no face-value end)Winter Plan
- Pass Each use of the money the plan measures carries 2027 wins per $10M (wins ÷ (payroll change + talent cost)); Lowe's and the trade's wins are the chain rows' differences; and the owners'-terms re-sign verdict follows the comparison it quotes. Caught first: The plan's headline left out what the floor money buys; the Lowe owners'-terms verdict stopped at 'only if the floor money has no better use'Winter Plan
- Pass Every scenario counts three or more catchers available (40-man or non-roster) who are not on an injured list today, two on the 26-man; the check marks each available catcher's injured list and fails below three healthy; a non-roster catcher it counts is in the organization and either under contract for 2027 or re-signed by a move in the plan; a 26-man catcher on an injured list today makes the check warn and name him; and the third-catcher pick follows its own numbers (the most value net of cost, or within the toss-up line the option that ties up the least). No catching decision is fine when no catcher is hurt. Caught first: Non-tendering Henry Davis left two catchers, one coming off the 60-day IL, and the catchers check stayed greenWinter Plan
- Pass The catching decision's numbers hold together: the plan's Endy branches are published as the engine rates the Triple-A catchers and with them at replacement level, each branch's wins are the headline plus its change, the hurt-catcher branches never add wins, and the replacement-level view never loses less; each option's net value under each lens is its expected wins × that lens's price of a win, minus its cost, plus the later arbitration years' option (a spring tender: its own policy, written in its label); and the tendered catcher's later years carry the same option value as his arbitration row, positive while he has later arbitration years. Caught first: The Endy branches showed only the engine's generous Triple-A ratings (−0.30 W for a lost season), and nothing checked that the tender kept its option value or that net value added upWinter Plan
- Pass Each arbitration player's later years valued as options are worth at least their point estimate when every later season is worth more than its salary on the point projection (the option can only add the right to walk away), and something whenever there are later years; the later years are the contract's arbitration seasons after 2027. Caught first: A good year raised the arbitration salary but a bad one never lowered it, so Skenes's and Jones's later years were worth less as options than as point estimatesWinter Plan
- Pass Every scenario publishes its 40-man count at each deadline in transaction order (plan.forty_sequence: adds before the Rule 5 filing, frees after it, the tightest case), never over 40 at any of them, ending at the scenario's 40-man; a non-tender the sequence brings forward is dated before the filing in the move list. Caught first: The Rule 5 filing ran at 41: the trade or Lowe's acceptance lands before Nov 17 and the non-tender after itWinter Plan
- Pass Every protected player is eligible and off the 40-man today, meets the rule (pick risk 0.3+ or FV 50+) at the risk rule5_risk gives his row, and wasn't passed over by every club; no exposed player's expected loss (risk × long-term value) tops a protected one's; a protected player on an injured list today stays in the minors in every scenario; each protection's 'today' verdict follows its break-even against the first cut; and no exposed player the plan measured at a toss-up or more in 2027 wins is left off without being added. Caught first: Protections read the FanGraphs board only, scored Delgado from a winter-ball club, and put Termarr Johnson, on the full-season IL, on the MLB benchWinter Plan
- Pass In every scenario the health check covers the whole 26-man and the protected prospects: each one on an injured list today (major or minor league), carrying a Health & Workload warning, or with an availability note for a missed 2026 is listed as a warning with its source; the check warns exactly when one is. Caught first: The plan's health check looked only at the rotation's 60-day IL: Endy Rodríguez, Bubba Chandler's warning and Termarr Johnson's minor-league IL never reached a decisionWinter Plan
- Pass No published scenario leaves a gain above the toss-up line on the table by promoting one bench or call-up hitter (not held in the minors) into a lineup spot he can play, the rest of the depth chart re-sorted by the engine. Caught first: The in-house third-base row started Termarr Johnson (0 MLB PA at 3B) while Jared Triolo went to Triple-A: the swap search never moved a bench or call-up hitter into the lineupWinter Plan
- Pass Under today's rules, while fewer than the plan's maximum are protected, no exposed eligible player (not passed over by every club) has an expected loss above what a further protection's 40-man spot costs: nothing while the plan's 40-man has an open spot, else the next player in the cut order; each exposed row in the table carries that marginal cost. Caught first: The plan ended at 39 of 40 and priced the open spot at zero, yet left Keiner Delgado (the player it named most likely to be taken) exposedWinter Plan
- Pass Lowe's expected answer is computed from his market, a year for a year: the Free-Agent Board's estimated AAV against the one-year offer (a multi-year total against one year would pass almost any market). The call is 'clear' only when the whole AAV range sits on one side of the offer, and an unclear call says so in its text; the recommended scenario leads with the answer, and the decisions feed quotes it. Since he might accept, the offer itself is tested: accepting is worth the accepts row's 2027 wins over the plan at money.dpw less what its payroll change costs (today's rules and both owners' ends), declining brings the net comp pick, so extending pays above the break-even odds −accept ÷ (pick − accept); the odds of declining are the Free-Agent Board's qo_odds for him and the text quotes the break-even and the call. Caught first: Lowe's expected answer to the qualifying offer was typed in ('declines') while the market numbers that decide it sat in the same functionWinter Plan
- Pass Every scenario (and every other club's baseline) publishes who would be cut next and each sandbox player's long-term value; the cut order is monotone: no player removed carries a higher long value (max(2027 WAR, call-up value) + long-term value ÷ $10M) than one the plan keeps as its next cut. A removed player's long value is published with the removal and re-measured on the plan's engine (other clubs' sandboxes hold only the trimmed roster, so the sandbox can't price their cuts). No player nobody controls (a pending free agent whose free agency the contract data confirm: plan.uncontrolled) carries later seasons of club control (his cut value is at most his prospect value), and the recommended plan's next cuts are the Rule 5 cut order's first rungs. Caught first: Other clubs' 40-man cut order released young big-leaguers under club control (2027 WAR + prospect value only); the next cuts were never shownWinter Plan
- Pass Every published cut value (plan.json and each club's sandbox.cut_value) is at least half the intrinsic value of the player's later seasons of club control, measured straight from the control mart: for each pre-arbitration or arbitration season 2028–30 with a projection, max(0, projected WAR × money.dpw − salary) discounted to 2027 (salary at least the minimum when pre-arbitration or unknown). plan.ctl_value keeps a season only if it pays, less the same option on a replacement player; that difference is never under half the season's intrinsic value, whatever the projection's spread, so a cut value under the bound means control fell out of the cut key. Players nobody controls (plan.uncontrolled) are skipped. Pittsburgh's sandbox must hold a player whose bound tops his prospect value, so the check has a case to test. Caught first: The 40-man cut order counted 2027 WAR and prospect value only, so a young big-leaguer under club control could go ahead of a veteran in his last year; no check outside the cut-value code would see control drop out of the keyWinter Plan
- Pass Every third-base candidate's talent cost is Contract Studio's surplus of his contract (contracts.surplus_pv over the Trade Builder's seasons and projection, floored at zero) and his ask is trade.need_for with the overpay (an overpaid contract's ask is a salary dump), as the Trade Builder, Finder and Roster Builder price it. Caught first: The plan priced Chapman's ask as a prospect package while the Roster Builder priced him as a salary dump; Garcia's talent cost was $27.0M on the plan and $24.6M in Contract StudioWinter Plan
- Pass No signing the plan measures (the Keller branches' starter, the third-base free-agent fallbacks, the free-agent catchers) is a free agent the Free-Agent Board leaves off its lists for his medicals (plan.hurt_fa, its test). Caught first: The plan's 'clean' mid-tier starter (Bubic) was a player the Free-Agent Board flags for his medicals firstWinter Plan
- Pass When the plan lets a catcher go who caught half or more of a rotation pitcher's 2026 pitches, the catching decision names the pairing with the plan's catchers' share of the same pitches, the counts are Statcast's, and the closest pairing is listed first. Caught first: The decision page never said the non-tendered Henry Davis caught 97% of Paul Skenes's 2026 pitchesWinter Plan
- Pass Every recommended-rotation starter with a Health & Workload warning (Keller aside: he has his own branches) has a priced branch with him opening on the injured list, quoting health.json's measured rate (unflagged pitcher-seasons) as context and not multiplying it into an expected change (his projected innings already include a typical pitcher's missed time); every protected prospect held in the minors for his medicals who gets call-up time in the headline has a branch without it. Caught first: The health check listed Bubba Chandler's warning and Termarr Johnson's injured list without pricing either; the headline counted Termarr's call-up timeWinter Plan
- Pass A non-tender the plan brings ahead of the Rule 5 filing is dated from its move everywhere: the decisions feed's move ends before the deadline, the 40-man fixes name the release, the non-tender brief is due that day, and Contract Studio's card dates itself from the move's window (not the deadline). Caught first: Contract Studio dated Davis's release at the Nov 20 non-tender deadline while the plan and the brief said before the Nov 17 Rule 5 filingWinter Plan
- Pass Every arbitration player on the plan's roster has his published net measured in his role there (the third catcher's health-weighted value aside), and no player's tender call would flip between today's roster and the plan's. Caught first: Tender values were valued in each player's role on today's roster, not the plan'sWinter Plan
- Pass The Keller decision branch comes from a computed call: today's-rules savings against the wins lost (2027 from the engine, 2028 at the same share of his projection), the acquirer's medical test, and the recommended key's Keller branch matches it. Caught first: 'Keep Keller' was hard-coded: the plan's recommended key never weighed the tradeWinter Plan
- Pass No player page carries a percentile without a qualifying sample (500+ pitches, 300+ PA), every qualified player has his percentiles, and each page publishes the threshold it used. Caught first: 253 pitcher pages showed 'Keystone Stuff … 0th pct' and 308 hitters with under 300 PA (some with 30) carried full percentilesPlayer pages
- Pass Every player the decisions feed touches shows the feed's status, why and branch on his page (status27.winter); every 2027 role comes from the feed's roster (role, position, WAR); the qualifying offer, the non-tender, the Rule 5 calls, the prospects spent and the trade route carry the feed's numbers; each brief linked exists. Caught first: Lowe's page left out the qualifying offer, Davis's the non-tender, Diamond's the Rule 5 protection, and Diamond read 'on the 40-man' though he wasn'tPlayer pages
- Pass Every player whose 2027 role or position differs between the qualifying offer's two answers (plan.json, the scenarios the feed names) shows the other answer's role on his page. Caught first: Gonzales's page showed his move to second base as settled, though it holds only if Lowe declines the qualifying offerPlayer pages
- Pass Every player in the organization today has a page marked Pittsburgh org at his keystone_models.org level; every player who left it in 2026 (the decisions feed's departed list) has a page that says so and isn't marked Pittsburgh's. Caught first: Emmanuel Chapman's page (released Aug 9) still said PIT and Pittsburgh org; Chun Hsi Lin and Jeffrey Bustos had no pagesPlayer pages
- Pass A two-way player's page keeps both halves: pitching and hitting sections, the two-way projection role, and every depth-chart unit he holds (status27.roles when more than one); a role list never drops a unit. Caught first: Ohtani's page and LAD's baseline treated him as a pitcher only (2.8 WAR in his role against a 7.3 projection)Player pages
- Pass The zone map, the location map and the development panel derive their default side or level synchronously (no $effect setting state), so the server-rendered page shows the right side; the zone map's calls carry their noise (each side has sd and k) and a page's development plan is loaded with the page. Caught first: The prerendered zone map read in/away backwards for every right-handed hitter and printed 'HB'; the location panel was empty until hydrationPlayer pages
- Pass A page's prospect grade is FanGraphs' published label (board c_fv), and every Pittsburgh prospect in the Prospect Pipeline carries its read (Perf+, trend, tag) on his page. Caught first: Prospect pages printed 'FV 47' (the trade tools' number) where FanGraphs publishes 45+, and '0.199/0.336/0.319' linesPlayer pages
- Pass Every page's 2027 projection carries the playing time behind it (PA and/or IP from proj_war), so the tile can say what it assumes. Caught first: 'Projected 2027 WAR … full season' sat over a 39-IP Marcel projection and a smaller number than the role WAR beside itPlayer pages
- Pass Every player page was written after the files export_player_status and export_players read (decisions, plan, briefs, park, free agents, prospects, every club's baseline), so no page quotes an earlier build. Caught first: Player pages could quote a previous build's winter: their status is written from the feed, the briefs, the Park Fit and the Free-Agent BoardPlayer pages
- Pass Every contract status a player page can show (his own control years, his comps' 2027 status) has a label in the page's map (players/[id]/+page.svelte statusLabel, Comps.svelte ST), so no raw code reaches the page. Caught first: Lowe's page printed 'Tyler O'Neill … post_opt_out $16.5M': a raw contract codePlayer pages
- Pass Each zone map's sd is the strike-zone cells' run-value spread for that batter side (export_players), and ZoneMap.svelte tests the raw gap (the shown, shrunk gap × (n + k) / n) against a signed bar set for the extreme of nine cells from a seeded bootstrap of the league's in-zone pitches (export.zone_crit, Bonferroni 0.05 / 9 a side): attack only a cell past the low bar, call damage only past the high one. Caught first: The zone map's standard errors used the all-pitch run-value spread on the shrunk gap (16% too high at 400 pitches, 30% too low at 60), |z| would have told pitchers to attack a cell 2 standard errors above average, a 2-SE bar on the worst of nine cells fires on one map in five from noise, and skewed run values let high cells pass a normal bar 2–3× too oftenPlayer pages
- Pass Every development goal that cites a tracked-level percentile ('ranks in the 19th percentile of Triple-A hitters') is on a page whose tracked-level bar (milb_pct) shows the same number at the same level: one number for one thing. A bar reads higher-is-better, so for chase, strikeouts and walks it is the complement (within ties). Caught first: Prospect pages had no Triple-A percentiles although development.py ranks Triple-A hitters (150+ PA) for its goalsPlayer pages
- Pass A player page shows the "This winter" panel (status27.winter.show) whenever the winter does something with him or a linked brief is his own decision or names him, and the page gates the panel on that flag; a brief that never names him stays a header link with its due date. Caught first: Evan Sisk's, Isaac Mattson's, Braxton Ashcraft's and Jared Jones's pages showed only the pitching-usage brief's title, though it makes a call about each of them ('Move Evan Sisk into the leverage ladder')Player pages
- Pass Every pending free agent with a 2027 option on the Free-Agent Board carries it on his page (kind, salary, the board's call, the feed's options window, and whether a release since ended the contract), and the page's contract note names the option before it can say no club controls his 2027. Caught first: Kenley Jansen's page printed 'Club option $12.0M' over 'A pending free agent: no club controls his 2027' (54 pages with an undecided 2027 option), and Lourdes Gurriel Jr.'s, released Sep 18, still listed his $14.0M club option as livePlayer pages
- Pass On every page whose PNC Park line uses the plan's playing time (park group 'plan'), that playing time is the Winter Plan role's on the same page, within 1 PA. Caught first: Ronny Simon's PNC Park line read '… wins over 249 PA' beside a Winter Plan role of call-up depth at 78 PA (park.json written before the plan)Player pages
- Pass Player-page text is in words and in time: feed and board strings pass through text.ts words (ISO dates, service time in years and days), ages count to calendar.ts TODAY, each development trend's number names its month and sample, and the winter headline speaks in the plan's voice. Caught first: Keegan Thompson's caution read 'Outrighted 2026-06-10 … at most 4.006', five Oct 21 birthdays read a year young (ages counted to Oct 20), Keller's development panel showed August's 16-PA walk rate (25.0%) as if it were his season ('Aug 26' read as a day), and the winter panel said 'Non-tendered' and 'Traded to Houston' weeks before either can happenPlayer pages
- Pass Every need and surplus score in depth.json and needs.json is a number in [0, 1]. Caught first: Trade fit needs a need and a surplus score it can weigh: anything outside [0, 1] would distort a package's rationalePositional Depth
- Pass depth.json exists for all 30 clubs, every variant has every position group for every season 2027–31, and needs.json Caught first: A club or season missing from the grid reads as 'no need' to the Trade BuilderPositional Depth
- Pass No player the club no longer holds is counted: Pittsburgh's plan grid has nobody the Winter Plan lets go or trades Caught first: Departed players have been counted before (13 departed players on Call-Ups; Hyun Seung Lee in live packages): a gone player would fake depth at his positionPositional Depth
- Pass Each season: one player per lineup slot, at most five starters and seven relievers, no player in two lineup slots Caught first: An assignment that put two players in one slot (or one player in two) would overstate a club's depthPositional Depth
- Pass Pittsburgh's 2027 Winter Plan grid starts every plan lineup starter at the plan's position (decisions.json Caught first: The grid's 2027 lineup must be the Winter Plan's, or say why not: two pages naming different third basemenPositional Depth
- Pass needs.json's [need, surplus] for every club, group and season equals the club's default grid in depth.json Caught first: needs.json is what the Trade Builder and the Finder read: it must be the grids' own numbersPositional Depth
- Pass Every slot's status and need follow from its expected WAR and bar (covered ≥ bar, below ≥ half, thin above 0, open Caught first: A score must follow from its own numbers: a 'covered' slot below the bar would hide a needPositional Depth
- Pass depth.json, every club's depth.json and needs.json are newer than decisions.json and trade.json, which they read. Caught first: A page that reads another export must be written after it (availability once quoted the previous build's odds)Positional Depth
- Pass Pittsburgh's as-it-stands grid counts every major leaguer contracts.json lists with a 2027–31 season (players and Caught first: Pittsburgh's depth must count the contracts Contract Studio shows: one control table, two pagesPositional Depth
- Pass A surplus player who has a slot elsewhere is blocked at his best spot: in each of his surplus seasons the player holding Caught first: Chains of moves counted as surplus: with no third baseman, Griffin to third, Cruz to short and Mangum to center read as a shortstop surplus (0.18) while short was below the bar, and a center-field surplus (0.13) behind Mangum, below the bar too; the plan's own trade fit read themPositional Depth
- Pass Every player whose contract projection sums two roles (proj_war prole with '+') is aged role by role, and no player is Caught first: Two-way players were aged on their combined WAR: proj_war carries one figure for Ohtani's hitting plus pitching ('H+PS'), and dividing it by PA for his hitter row and by IP for his pitcher row counted the combined decline on both rows (DH 2.75 → 0.82 by 2029, out of the Dodgers' rotation after 2028)Positional Depth
- Pass The readiness test scores every 2025 AAA hitter who reached the majors (any PA, weighted by PA); the survivor-only Caught first: The readiness model was fit only on call-ups who reached 100 MLB PA, which raised its intercept by about .008Development
- Pass An average Double-A line's readiness sits at least 90% of the translated gap below an average Triple-A line's, and Caught first: A High-A line rated almost the same as a Triple-A call-up: the translated-line shrink erased the level gapDevelopment
- Pass The call-up test scores the engine's own formula (translations.engine_value) on every call-up weighted by PA, and Caught first: The rookie test scored a blend the depth chart doesn't run (position credit inside the 60%), on survivors onlyDevelopment
- Pass Every depth-chart value on /call-ups is shown with the starter at the same position. Caught first: Call-Ups put a hitter's depth-chart value at one position next to the plan's starter at another (Yorke's 3B vs. 2B Gonzales)Development
- Pass Every hitter on the plan's 26-man or call-up list with under 250 MLB PA (2024–26) appears in call-ups.json Caught first: The Winter Plan's own call-ups (Termarr Johnson, Brannigan, Flores Jr.) were hidden from Call-Ups, and a prospect it trades had no flagDevelopment
- Pass Each pitcher's projected strikeout and walk rates sit between his translated line and his level's average Caught first: Small High-A pitching samples were regressed toward the MLB average, so a 114-BF reliever outranked a full Double-A seasonDevelopment
- Pass Every prospect's readiness tag reads his whole season (all levels), small sample only under the minimum, and his Caught first: A 75-PA Triple-A cameo set Delgado's level and 18 full seasons were tagged 'Small sample'Development
- Pass Hitters' Perf+ takes out the park index only at the weight its mover test supports (prospects.park_mover: hitters Caught first: Greensboro's park index was taken out of Perf+ in full though it hadn't been tested; the first test of it measured the player's own seasonDevelopment
- Pass Age vs. level uses decimal ages on July 1 (birth dates): the mart's age_dec matches the birth date for every 2026 Caught first: Whole-year ages flipped the 'youngest producer' tile and bunched 30 DSL players at −0.6Development
- Pass An org rank on /prospects is Pittsburgh's list only: no two prospects share one, and an arrival's rank on another Caught first: Arrivals carried another club's list rank as '#7 in org': two #7s, two #17s, two #31sDevelopment
- Pass Every player in the organization today, off the 40-man and below the majors, is on /prospects: in the table or Caught first: 'Every Pittsburgh minor leaguer' left out 14 organization players with no 2026 lineDevelopment
- Pass A player most of whose 2026 line came in another organization is labelled with it and left out of the Caught first: Late signings' other-club seasons counted as Pittsburgh development results (Fedko's St. Paul line in 'Ready to push'); rookie-ball clubs had no parentDevelopment
- Pass /prospects and /call-ups load the Winter Plan's calls from the decisions feed (loadDecisions), never plan.json. Caught first: The Prospects and Call-Ups pages took the plan's Rule 5 and trade calls from plan.json instead of the decisions feedConsistency
- Pass One age line (validation.grade.dev_age, 26 on July 1): an ungraded player that old is org depth, never tagged push, Caught first: Ungraded 26-year-olds were neither prospects nor org depth, and the Stalling tile named only one kind of exclusionDevelopment
- Pass Each graded development prospect's grade read compares his expected Perf+ with the median for his FanGraphs grade Caught first: The performance-vs-grade view was declined, though every input was on the pageDevelopment
- Pass Every club's headline bat (call-ups.json best_bat) is its best contact-quality estimate among call-ups: 'vet' marks Caught first: A 34-year-old with an MLB debut in 2018 and 1,300 PA before 2024 was billed as the best tracked bat in a club's upper minorsDevelopment
- Pass /call-ups' internal options at C, 2B, 3B and SS (call-ups.json internal) rank everyone at the position by one Caught first: The internal-options panel ranked a shortstop on his center-field value and a second baseman on his DH value; then it left the plan's own third-base call-up (Yorke) and Termarr Johnson, both rated at third, off the 3B listDevelopment
- Pass Each hitter's 80% range matches its evidence: contact-quality rows from cq_se (wider under 150 tracked PA), read Caught first: Readiness ranges were the AAA test's at every level and sample: High-A lines and 139-PA samples got AAA-sized bandsDevelopment
- Pass The decisions feed's 2028 third-base successor carries the same value at third (WAR/600) as /call-ups' depth-chart Caught first: The plan named Gourson the 3B successor at one value while /call-ups rated him at anotherConsistency
- Pass Every call-ups.json plan_callups row carries what plan.Engine rates him on: basis 'aaa' exactly when the engine blends Caught first: The plan-call-ups panel said its thin-record hitters were rated from Triple-A; the engine rated Flores Jr., Endy Rodríguez and Yorke on their MLB recordsConsistency
- Pass Every 2026 draftee value /prospects can show is the trade pool's: roster.json prospects[].draft carries trade.json's Caught first: Prospect Pipeline showed 2026 draftees at the draft curve's raw value (Curiel $41.5M in the Path) beside the trade pool's scaled value ($34.5M in the table); then its range came from draft.json × one point scale ($25.5M–$47.9M) while the pool's was the band × the scale's range ($22.6M–$54.1M)Consistency
- Pass call-ups.json internal_calls lists the same players as internal, leaves out prospects the plan trades, carries each Caught first: The internal-options panel ranked Yorke over Termarr Johnson (.292 vs. .289, ranges ±.015) and a Double-A catcher against Triple-A bats with no toss-up labelDevelopment
- Pass The published factors are the season-matched ones for 2026 lines (translations.hitter_factors), the blind test's Caught first: Translation factors pooled raw across 2025 and 2026 mixed two run environments: the AAA−AA gap moved from .008 to .024 with the season the pairs came fromDevelopment
- Pass No /prospects or /call-ups row is both a likely minor-league free agent (milb_fa.likely) and on a first contract Caught first: Draven Zeigler and Yulian Quintana were both first-contract players (Rule 5 'Dec 2028') and 'veterans on a minor-league deal' ('FA in Nov?')Organization
- Pass One position per player: prospects.json (rows and the no-line list) prints keystone_models.org.display_pos, the Caught first: Keiner Delgado was a shortstop on the Rule 5 board and the home page but a second baseman in /prospects' table and PathConsistency
- Pass /prospects' Rule 5 panel says what the filing needs (decisions forty.fixes, and the accepts branch's extra Caught first: /prospects' 40-man meter read 'full with the plan's 3 protections' without the release the plan makes first; Delgado's 'Protect' tooltip gave where he plays, not why; the chart plotted another club's season as a Pittsburgh prospectDevelopment
- Pass Every FanGraphs board row with no MLB id is named where prospects are priced: content/blocked.ts BOARD_NO_ID (read Caught first: 13 FanGraphs board prospects with no MLB id (Pittsburgh's Neomar Urbina, 35+) entered no pool, and no page said they were missingData
- Pass Every Track Record claim names one of the written rules (keystone_models.ledger.RULES), and the page publishes those rules. Caught first: The Track Record's verdicts were typed in: 30 of 43 were literal strings that couldn't change with the dataTrack Record
- Pass No Track Record claim passes inside its own noise: the time-ordered Stuff edge, the leak-free opportunity flag, the Caught first: A forward 'pass' for the opportunity flags rested on Stuff grades whose 2025 model had seen 2026; sequencing passed 'doesn't repeat' with an interval above zeroTrack Record
- Pass The Track Record's rookie-rating row states the design and blend weight the call-up model actually uses (translations.json rookie_test). Caught first: The rookie row said '75% AAA … in-sample' after the call-up model moved to a held-out 60/40 blendTrack Record
- Pass The model-card page reads the time-ordered Stuff test (track-record.json stuff_forward) and labels the cross-fit year-over-year rows as stability, not prediction. Caught first: The Stuff model card led with 'predicts better than results' from cross-fit correlations whose model had seen the scored seasonTrack Record
- Pass The Season Review's record tests are published (forward errors, the no-information baseline, intervals on each record's Caught first: The Season Review headlined '88.7-win talent' from BaseRuns alone, and subtracted a park-aware fielding number from a park-blind contact gap ('mostly homers')Track Record
- Pass A claim labelled forward is a forecast: built on earlier seasons and scored on a later one. Year-to-year repeat Caught first: The forward count included year-to-year correlations and a test whose flags were picked by Stuff grades that had seen the scored seasonTrack Record
- Pass Every 'superseded' marker in the decision log (content/product.ts) names an entry that exists, and no entry quotes a Caught first: The decision log kept stale entries (75/25 rookies, 'tender everyone', halved matchup edges) with no superseded markerCopy
- Pass The personas, the prioritization rubric and the success metrics (content/product.ts PERSONAS, PROBLEMS, METRICS) Caught first: The Product page's personas and rubric quoted the plan in typed copy: two Rule 5 protections 'both in Triple-A' when the plan had three, '8 eligible', and 'no public tracking below Triple-A' beside 'the FSL is tracked'Copy
- Pass Every raw dataset on disk is in data/raw/MANIFEST.json with every season it has on disk (keystone_pipeline.manifest's own grouping), and meta.json carries the per-source dates /data shows. Caught first: The raw MANIFEST listed 62 of 78 datasets and missed seasons, while /data claimed full provenanceData
- Pass Every Decision Brief a blocked analysis says it would change (content/blocked.ts briefs) is a brief that exists. Caught first: The blocked-by-data list read as a disclaimer, not tied to the decisions it would changeData
- Pass No Track Record claim or ledger row prints a hyphen-minus for a negative number or a negative zero, and no note Caught first: A Track Record note said 'gains -1.3% of the error' (an ASCII hyphen, and a loss written as a gain)Track Record
- Pass When a page owner publishes a forward test (abs.json policy.forward, fielding.json model.rating_forward), the Track Caught first: The ABS row printed the overturned challenges' gross run value as the first policy's worth and left out the published forward test; the fielding-rating forward test sat unusedTrack Record
- Pass For every club, the run-timing line's cause implies the same direction as the record's gap to its run Caught first: The Season Review explained 11 clubs' run timing with a cause pointing the other way (Colorado's record 'trailed' because runs 'leaked in lopsided games')Season Review
- Pass Each club-season's park-adjusted hitter and pitcher contact runs (diagnostics.contact) exist and re-split the Caught first: The Season Review printed per-side contact runs (+31 hitters / −6 pitchers) with PNC Park in them, though Statcast's home team and every park's own gap were in the dataSeason Review
- Pass Every park row carries the effect against an average park (the lead number, the page's default sort) and the Caught first: Outside bats were scored against their 2026 club's park, though every WAR on the site is park-adjusted, so the 'biggest gainers' were mostly leaving pitcher's parksPark
- Pass Each PNC index used in the calculation is shrunk toward 100 by its own noise (never past 100, never further from Caught first: Park factors were used raw: a triples index on 13 events moved a 'biggest gainer' by 2.4 runs, and the note counted Savant's comparison sample as plate appearances at PNCPark
- Pass The park page's Pittsburgh hitters are the Winter Plan's 2027 hitters (decisions feed), the hitters the winter Caught first: The Pittsburgh park panel listed Lowe and Davis, who are leaving, and left out the plan's acquisitionPark
- Pass The park page prices every Winter Plan branch (the plan's own wins, from the feed's chain), the staff's side, and Caught first: Park fit was never counted against the plan: Paredes's cost and Lowe's gain were invisiblePark
- Pass The bin model keeps each park's own level: its PNC ratio by side stays within 0.05 of the unshrunk ratio and Caught first: The spray-aware home-run factor shrank every park's bin rates straight toward the league, so PNC's own level came out ×0.94 for right-handed hitters (0.78 unshrunk, Savant 0.70) and Paredes's pull penalty was cut about 3.5×Park
- Pass Each rival dossier has the club's level (with a rank) and each pitch type against that level, the within-club Caught first: 'Hunt against their staff' mixed how good a staff is with which pitch to sit on, and the lineup panel's matcher could never fireRivals
- Pass Every one of each rival's pending free agents is exported with the FA Board's projection (1+ WAR listed in full, Caught first: The departing-WAR tile summed a list cut at six names (the Cubs understated by 3.1 WAR) and used 2026 fWAR where the FA Board uses projectionsRivals
- Pass The rivals page reads the plan's wins from the decisions feed, opens on the rival closest to Pittsburgh, keeps Caught first: Rival Intel opened on the weakest club, ignored 2027, and printed 'Pittsburgh vs. CIN'Rivals
- Pass Every regressed Hitting Lab estimate carries a posterior SD, the chance it is past the diagnosis line matches Caught first: Diagnosis tags were shown as certain, though Gonzales's 'bat-to-ball' tag was a coin flip (P ≈ .51)Strategy
- Pass Each club-table run column (decisions, contact, handedness mix) is measured against the league for that pitcher Caught first: The handedness mix was measured against the both-hands mean, so an average lineup scored about −8 runs against lefties and the lede blamed Pittsburgh's handedness for runs it didn't loseStrategy
- Pass The Hitting Lab exports every outside hitter with 100+ PA against left-handers, each with the matchup added back Caught first: 'Who fixes it' cut the pool to 40 before filtering, ranked platoon-neutral skill as 'handles LHP', and hid the plan's own acquisitionStrategy
- Pass The Hitting Lab reads 2027 roles and departures from the decisions feed, shows each hitter's uncertainty and Caught first: The Hitting Lab featured Lowe and Davis with no 2027 status and drew its contact axis arrow pointing downStrategy
- Pass Every runs figure built from decision value uses the measured factor: actual run value per 100 pitches regressed Caught first: Swing-decision value was quoted as runs, though each choice is scored against its alternative and so counts every run about twice: the lede's −13 decision runs against lefties were about −6.5Strategy
- Pass Every green-lit runner has 4+ attempts and a shrunk success rate at or above the break-even. Caught first: Green lights for runners who were 1-for-1 or 0-for-0 against a 74% break-evenStrategy
- Pass No starter 25 or younger gets a pull or tandem call; those are development calls. Caught first: Starters 24 and 25 years old handed a hard hook from one season of third-time resultsStrategy
- Pass Each club's shorter leashes (two times through and tandems) stay within the bullpen's extra-innings capacity. Caught first: Shorter leashes that added 88 relief innings with no capacity checkStrategy
- Pass Lineup what-ifs carry each hitter's batting side, so the page never guesses it. Caught first: “One right-handed bat who hits lefties” named a left-handed hitterStrategy
- Pass Pittsburgh's headline playoff odds equal its row in the simulated standings. Caught first: The Outlook header and its own standings table showed different playoff oddsConsistency
- Pass Every hitter the Winter Plan acquires appears in the park-fit table. Caught first: The Winter Plan's acquisition was missing from the park-fit tableConsistency
- Pass ABS role totals add up to the club's own challenge total, and the pitch-level log stays within 10% of it. Caught first: Three different challenge totals for the same club on one pageConsistency
- Pass Every Track Record claim says how it was tested (forward, held-out, benchmark, in-sample or build check). Caught first: “41 claims tested out of sample” counted benchmark and in-sample checksConsistency
- Pass Matchup edges carry the league platoon split: in the 2026 forward test the model rates same-side matchups better for the pitcher than opposite-side ones (as they are), and the platoon model predicts at least as well as quality alone. Caught first: The Matchup Engine shrank every hitter's platoon split toward zero and rated same-side matchups worse for the pitcher than opposite-side onesStrategy
- Pass The backtest carries bootstrap intervals for what the platoon split and the pitch-type layer add, and the page states the pitch-type call only when its interval clears zero. Caught first: “Lean on the four-seam” for every hitter from a pitch-type layer the forward test can't tell from zeroStrategy
- Pass The matchup grid's 2027 bullpen comes from the decisions feed, and every plan reliever with enough MLB pitches (400+ in 2025–26, 150+ in 2026) has a profile in matchups.json. Caught first: The 'Pittsburgh bullpen' grid listed 2026 relievers who had left (Soto, Doval, Santana, Lawrence)Strategy
- Pass matchups.json's pitches per plate appearance and wOBA points per run are the ones measured on the profile seasons (matchup.conversions), and the page labels them as measured. Caught first: The matchup result card turned runs per 100 pitches into runs and wOBA per plate appearance with typed constants (3.9 pitches, 1.24)Strategy
- Pass Sequencing publishes the placebo and arsenal-tunnel test (whiff, chase, run value, a 2025 → 2026 forward test with unrounded gains, seeded draws), makes no pair 'lean on' call, and its answer to "does the order matter?" is computed from every channel. Caught first: Pair-level sequencing calls rested on a tunnel effect that a random pitch from another at-bat reproducedPitching
- Pass Every pitch pair carries standard errors; a run-value flag needs 2.5 SE on 100+ pairs; repeats are marked; the table's minimum is one exported constant. Caught first: Run value 'vs. his avg' was colored hot and cold on noise, and the pairs table mixed same-pitch repeats with tunnelsPitching
- Pass Sequencing lists today's 40-man pitchers (keystone_models.org) with their 2027 status from the decisions feed; the ones with too few pairs are listed, not dropped. Caught first: The sequencing list came from the season's 40-man: two departing free agents shown unflagged, a 2027 bullpen arm dropped silentlyPitching
- Pass Predictability is scored within seasons with stray types dropped, and the cost test is stacked over seasons with a bootstrap interval. Caught first: Predictability ranked pitchers partly on volume and stray pitch tags, and its null test had no intervalPitching
- Pass Every club's runners carry official 2024–26 SB/CS (MLB Stats API), success regressed with a measured prior (30+ attempts), and each call agrees with its rule at the break-even the calls use. Caught first: Both Pittsburgh running calls came from one season of Savant's partial steal counts and reversed on three seasons of official recordsStrategy
- Pass Running Game publishes a forward test of both calls; a call whose flagged runners beat the break-even the next season is shown as a flag, not a call; the one-run break-even sits below the expected-runs one for a steal of second. Caught first: The red-flag rule failed a leak-free forward test, and the one-run break-even was missingStrategy
- Pass No green light on a record under the break-even (any club; those are toss-ups with no run value), and the forward test is published by subgroup with copy that matches it. Caught first: Gonzales green-lit and 'worth up to +0.3 runs' at 12-for-20 against a 72% break-even: the 92-attempt prior, not his record, made the callStrategy
- Pass No below-break-even flag within 2 posterior SDs of the break-even (any club; sd = sqrt(s(1 − s) / (weighted attempts Caught first: Four 'below break-even' flags sat 0.03–0.18 SD under the line, and the Colorado lede called them below break-even while each row said toss-upStrategy
- Pass Pitcher rows carry the share of their running-game opportunities with the club; team steal counts are official; Pittsburgh's staff total is share-weighted. Caught first: 'Who opponents run on' credited Kirby Yates's Angels innings to Pittsburgh, and team ranks credited traded players' seasons to their last clubStrategy
- Pass Pittsburgh's runners and pitchers carry their 2027 status from the decisions feed (a 2026 departure the feed misses, Caught first: Running Game described the 2026 roster: departing players unflagged and the 2027 lineup's baserunning unseenConsistency
- Pass A page's as-of stamp comes from the data (meta.json, the module's own file), never a typed calendar date, and a Caught first: 'Projections & contracts as of Oct 20, 2026' was typed into six module headers and the countdowns ran from a typed TODAYSite
- Pass Every tour stop carries ?team=PIT, and the layout honours a link's ?team= on every navigation, not only the first. Caught first: Tour stops opened the club picked earlier on a client-side navigation (initClub ran once), putting another club's evidence under a Pittsburgh findingSite
- Pass Every literal internal link in the Svelte sources points at a route or a static file, a brief link names a brief Caught first: Links to /track-record (a 404) and to /briefs#qo-lowe, /contracts#floor anchors that didn't existSite
- Pass The model-card page shows the Opportunity Finder's backtest only on its own card; a card with no panel of its Caught first: Five model cards (Park Fit, Rival Intel, Sequencing, Running Game, Prospect Pipeline) showed the Opportunity Finder's backtest as their ownSite
- Pass A page whose load reads more than 250 KB of published JSON runs that load on the server (+page.server.ts calling Caught first: /plan prerendered at 1.2 MB and /prospects at 1.0 MB: their universal loads inlined free-agents.json, outlook.json and the decisions feed whole to show a few fieldsSite
- Pass Every published JSON file is inside its budget (keystone_models.realism_ui.PAYLOAD): a page's file 1 MB, a club's Caught first: The published data grew to 50 MB (players 13 MB, other clubs 31 MB) and /opportunities prerendered at 575 KB with no budget to say when a file had grown too bigSite
- Pass A rotated y-axis title reads bottom to top (rotate(-90)), so its arrow points the way the values grow. Caught first: Rotated y-axis titles read top to bottom with '→' pointing down while values rose upward (Draft, Prospects, Pitch Lab, Bullpen, movement plot)Site
- Pass The shared picker is a combobox the arrow keys drive, the segmented control is a radio group with one tab stop Caught first: The player picker took only Enter on the first hit and the segmented toggles had no arrow keys; ids from Math.random broke label links after hydrationAccessibility
- Pass Team-aware pages don't name the Winter Plan for another club without a Pittsburgh check, and every page that Caught first: Other clubs' views read 'the Winter Plan's team projection', and the Dodgers' Lineup Lab and 2027 Outlook (93.5 W) left out Ohtani's bat without a word (only the Roster Builder said so)Site
- Pass Every catching.json (Pittsburgh and the 29 other clubs) carries each catcher's plain count behind the plate in Caught first: Catching said 'Yainer Diaz, 42,529 batters caught' (he caught 10,814 in 2024–26) and set its 2,000-batter glove bar in those units: the count was the rating's 5/4/3-weighted evidence, about 4× the real numberSite
- Pass The home ABS card and /abs compute the 2027-catcher figure with one formula (lib/abs27.ts, abs_coach.with_catchers), Caught first: The Command Center said 'about 1.7 runs carries into 2027' of the ABS accuracy gap while /abs called 1.7 2026's figure (mostly the 2026 catchers) and put 2027 at about 0.8 runsSite
- Pass Feed strings that carry ISO dates (move notes, minor-league free-agent bases) go through text.ts words() on /plan Caught first: 'Estimate: outrighted 2026-09-07 with major-league time since 2013' printed as an ISO date on /catching, /plan and the non-tender briefSite