670f57c309
decode_secondaries's stick-breaking only guarantees valid secondary slots sum to <= e_sec, leaving a shortfall that rollout.py silently dumped into that step's edep. Rescale the valid slots by one common per-row factor instead, so they sum to exactly e_sec whenever n_sec > 0: this spreads any shortfall proportionally across all secondaries rather than concentrating it in whichever slot is last by energy rank (which would let that one low-energy secondary balloon and distort the shower's topology). Rows where every valid slot decodes to ~zero fall back to an even split. n_sec == 0 rows are unchanged (still nothing to carry the budget, so rollout.py's edep top-up still applies there) — narrowed the related caveat in load_rollout_vs_truth's docstring to just that case. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>