Clutch shifts: an honest refusal, not a fabricated split
Descriptive only
How to read this figure
There is no chart here; status is not_buildable, and the value is the reason plus the where_the_grain_actually_lives and fields_needed blocks that scope the fix.
Published finding
This measurement cannot be published from the committed inputs. player_boxscores.parquet is FULL-GAME aggregate; it carries no period/clutch grain, so late-game per-36 SHIFTS cannot be computed from it without fabricating the split.
What it means
Rather than manufacture 'clutch' stats off full-game rows, the module refuses and documents exactly why: the per-period player box lines exist in the raw cache, but the ingest step sums them into one full-game row per player and discards the period grain. It even names the fields a re-ingest would need -- a period column (late-game = period >= 4) plus the box stats and minutes at that grain -- so the fix is specified, just out of scope for a read-only showcase.
Caveats and confounds
The period grain is discarded upstream at ingest (ingest_boxscores.py sums quarter files into one full-game row); recovering it is a data-layer re-ingest, out of scope for this module.