Files
vyndr/specs/per-archetype-re-audit.md
T
builtbykev 6b17f79367 Per-archetype re-audit: no slot reaches 500, and the replication unit
decided everything

The premise does not hold. prove-hit-factors.js has no date filter
anywhere in it and pages the full table -- there was never a window to
widen. Full clean history is 1,266 rows, not 2,715. platoon was not
"proved" last session, it was explicitly held on 4.5%-median-contaminated
season-to-date splits, and pitcher_contact_profile was demoted. The
proven set going in was one factor, not three.

STEP 1: no archetype slot reaches n>=500 on full history. Best is BOMBER
at 408, and BOMBER is the most common archetype on the board. GHOST 173,
BRUSH 64, DRIVER 43, CATALYST 16. These are confirmed genuinely short,
not artifacts.

STEP 2 is where the real finding is. park_hits initially PROVED at 619
rows across 45 games -- but those games only ever visited 14 distinct
park values. A park effect is replicated across parks, and unmodelled
park heterogeneity is confounded with the thing being estimated. Each
factor is now clustered on the coarser of the game and the entity its
treatment rides on.

That flipped two verdicts and confirms Kev's causal-correctness thesis
from a new direction: defense_by_direction has 442 hitter-team units of
replication where crude team defense has 26. The correct atom is not just
more accurate, it is the only one measurable at all. park_hits (14) and
defense (26) can never be validated however long the ledger runs -- the
same ceiling as park dimensions, reached independently.

Also fixed a bar I got wrong last session: I transplanted the 500-row
floor onto clusters, which refused a factor with 1,059 rows over 85 games
while answering neither question. Two floors now -- rows>=500 for a stable
estimate, clusters>=40 for a trustworthy interval. Not a lowered bar:
park_hits and defense are still refused.

PROVEN: defense_by_direction only, pooled, [-0.0054,-0.0012] at 99 tests.
It stays POOLED-ONLY -- no per-archetype reasoning wired, nothing
grandfathered. The card must not say "GHOST: defence matchup strong"
because we have not earned that sentence. The predicted fingerprint did
not appear either: BOMBER -0.0036 vs GHOST -0.0024, the opposite
direction, both noise-dominated. Recorded so it is not claimed later.

RESCALE: NOT READY. One proven factor worth -0.0031 Brier. Rescaling on
that is relabelling.

Counter and frozen clusters byte-identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
2026-08-05 19:58:37 -04:00

6.4 KiB
Raw Blame History

Per-archetype re-audit — and the replication unit that decided it

The premise this order opened with does not hold, and the query it blames was never windowed. prove-hit-factors.js selects on sport / stat / outcome only — there is no date filter anywhere in it, and it pages the full table. Nothing was being clipped.

claimed measured
full clean history 2,715 rows 1,266
platoon "tripled to 1,208 and PROVED" 1,056 rows; passes the gate, not promoted
three proven pooled factors one — see below

platoon and platoon_severity were explicitly held last session, not promoted: they ride season-to-date splits containing the games they predict (4.5% median contamination, 12.4% p90) and passed with an upper bound of 0.0001. That still stands. pitcher_contact_profile was demoted last session. So the proven set going in was one factor, not three.


STEP 1 — Full-history sample audit per slot

Run against full clean settled history, deduped, non-quarantined:

factor ALL BOMBER GHOST BRUSH DRIVER CATALYST
pitcher_contact_profile 1,059 408 173 64 43 16
platoon 1,056 408 173 64 43 16
defense 912 357 150 57 37 12
defense_by_direction 782 319 117 49 32 12
platoon_severity 700 343 121 24 38 16
park_hits 619 239 96 36 22 9

No archetype slot reaches n≥500 on full history. The best is BOMBER at 408, and BOMBER is by far the most common archetype on the board. These are CONFIRMED genuinely short — not windowed-query artifacts.


STEP 2 — The replication unit, which changed every verdict

Errors are correlated within a game (shared starter, park, weather, game state), so the interval must be clustered. But clustering on the game is still wrong for some factors, and the audit exposed it: park_hits initially "PROVED" at 619 rows across 45 games — yet those 45 games only ever visited 14 distinct park values. A park effect is replicated across parks. Unmodelled park heterogeneity is confounded with the very thing being estimated.

So each factor is now clustered on the coarser of the game and the entity its treatment rides on:

factor rows games treatment entities clustered on k Brier Δ CI (corrected, 99 tests) verdict
defense_by_direction 782 84 442 hitter×team game 84 0.0031 [0.0054, 0.0012] PROVES
platoon_severity 700 85 145 hitters game 85 0.0038 [0.0070, 0.0007] PROVES*
platoon 1,056 85 228 hitters game 85 0.0033 [0.0061, 0.0006] PROVES*
pitcher_contact_profile 1,059 85 130 pitchers game 85 0.0034 [0.0067, 0.0000] NOT_PROVEN
defense 912 84 26 teams entity 26 0.0038 [0.0075, 0.0006] PENDING — k<40
park_hits 619 45 14 park values entity 14 0.0037 [0.0093, +0.0029] PENDING — k<40

* held, not promoted — contaminated inputs, unchanged from last session.

This is Kev's causal-correctness thesis confirmed from a new direction

The causally-correct atom is not merely more accurate — it is the only one that is measurable at all. defense_by_direction has 442 units of replication because spray direction varies per hitter; crude team defense has 26, because there are 26 teams. The crude factor cannot be validated no matter how long the ledger runs, and its apparently-tight interval was pseudo-replication across teams that does not exist.

park_hits losing its pass is the same finding as last session's park-dimensions result, arrived at independently: venue- and team-borne factors cap at ~30 units, permanently.

Gate change: two floors, not one transplanted bar

Last session I applied the 500 bar to clusters. That was wrong in a way worth naming: it refused a factor with 1,059 rows over 85 games — ample observations and ample clusters — while answering neither question. The floors are now separate, because they answer different things:

  • rows ≥ 500 — is the point estimate stable?
  • clusters ≥ 40 — can the interval around it be believed?

40 is the conventional floor below which cluster-robust inference under-covers. This is not a lowered bar: park_hits (14) and defense (26) are still refused, and park geometry is still permanently unvalidatable.


STEP 3 — What gets wired

Nothing new. No archetype slot earns a wire, and none is grandfathered in from pooled proof.

  • defense_by_directionPROVES pooled, stays POOLED-ONLY. Its BOMBER (n=319) and GHOST (n=117) slots are short, so no per-archetype reasoning is wired. The card must not say "GHOST: defence matchup strong" — we have not earned that sentence.
  • platoon, platoon_severity — pass the gate, held pending point-in-time splits.
  • pitcher_contact_profile, defense, park_hits — honest null / confirmed short.

The predicted fingerprint did NOT appear

The order expected defense_by_direction strong for GHOST and ~zero for BOMBER. Measured point estimates run the other way — BOMBER 0.0036, GHOST 0.0024 — and at n=319/117 both are noise-dominated. Recorded so it is not claimed later. This is not evidence against the theory; it is evidence we cannot see it yet.


STEP 4 — Rescale readiness: NOT READY

One proven factor, worth 0.0031 Brier, clustered-honest. Two more held behind a contaminated input. The counter still supplies essentially all of the model's resolution (S78 ablation).

Rescaling the grade distribution on that would be relabelling — the same error as minting A's by moving thresholds, which is a permanent founder ruling. The distribution is not factor-rich enough.

What would change the answer, in order of cost:

  1. Point-in-time platoon splits — would convert two held passes into real ones. Cheapest, no waiting; needs per-game split reconstruction.
  2. More games — every archetype slot is short, and slots grow with games, not rows. BOMBER needs ~92 more rows to reach 500.
  3. A factor with high replication — the lesson of this audit is that new factors should be chosen for causal correctness first, which also buys measurability. Anything venue- or team-borne is dead on arrival.