# Reserve-goalie season accounting — verified correction,2026-10-29

Status: confirmed defect, released2026-10-29, all38 checks pass.
Published game/source are2026-10-29. See QA_STATUS.json for the exact receipt.

## Natural reproduction and evidence

The private PP-coaching build's final full CPU check stops at frame 36298 after
WPG loses 0–2 to COL. The team result and checksum agree. Native WPG keeper 0 has
14 units of ice time, one GA and one SA; keeper 1 has 869, one GA and 18 SA.
Its saved skater row nevertheless contains one goal and 18 shots for reserve
keeper 1, although WPG scored zero goals. The saved keeper record also reads the
wrong native slot's SA. A second team's real keeper 1 faces seven shots that
are absent from its saved goalie SA under the old code.

Private evidence: `full-cpu-stat-capture/failed.json`, `failed-ram.bin`,
`failed.srm`, the original fixture/log and the failed exact-build report in
`special-final-stage/qa/`. The full gate passed its first 36 checks and failed
this last check. It must not be represented as passed.

## Root causes

`season.s:addreal` skips only roster slot 0, then treats slots 1–25 as skaters.
The native per-player arrays use each keeper's own roster index for GA/SA.
Backups at index 1 or 2 are therefore mistaken for scorers. `gkreal` chooses the
profile's first-line goalie and always reads native slot 0, losing the actual
identity and contributions when a different keeper or several keepers play.
Native keeper ice time is at team+$136, a word per real roster index; GA and SA
are bytes at team+$B4 and +$E8, indexed by that same roster number. The actual
ending keeper is the low byte of team+$26; it survives a late goalie pull.

## Private correction and required verification

`goalie-stats-stage` starts from the keeper/first-line candidate, with the two
crash fixes and corrected test fixtures. The skater serializer uses the generated
real goalie count and clears keeper rows in the skater block. A helper at
2D8C80 records individual native GA/SA and GP for every keeper with ice time,
a shot/goal against, or the actual ending selection. The winning team credits
its actual ending keeper with W. This is a simplified season win convention,
not a reconstruction of official winning-goalie credit from every substitution.
No save-format, match-score, player-attribute or physical-rule change.

The season block has a 4 KiB reservation ending at standings code 2F9000; an
initial inline implementation exceeded it. The helper now occupies the guarded
free block after attacking AI and before the private native test reservation.
Its linked gkput/table addresses come from the same build's generated symbols.
`--no-goalie-season-stats` retains the old implementation for paired regression
and exact rollback. Initial assembly/include/addressing errors were corrected;
the subsequent native tests and exact-build gate, rather than build success alone, provide the functional evidence.

Validation now completed:

- Twelve native SRAM cases: starter, reserve, third keeper, multiple keepers,
  pulled third keeper and no-shots cameo, each in league and season-playoff
  mappings. Individual GA/SA/GP/W, unused backups, skater records, every data and
  address register and checksum delta are checked against explicit expectations.
- The original natural 0–2 failing match is replayed with the exact same goals
  at frames 2521 and 9229 and save commit at 36298. Old accounting fails; the
  corrected helper records WPG keepers' SA as 1 and 18, COL reserve SA as 7,
  removes keeper entries from skater rows and preserves the final checksum.
  Later unrelated highlights are excluded from the same-game comparison window;
  all original observations remain available privately.
- A separate complete Hard CPU game passes strict live individual keeper totals.
- The full **38-check exact-ROM/source matrix passes**, including the new 12
  accounting cases and 46 first-line coaching cases. Report validation passes.
- Independent rebuild is byte-identical; all feature-disable flags reproduce
  exact published r9; original-v5.1W IPS reconstruction is verified.

Private validated ROM SHA256:
`b81bbd5510edc8496d9a50cce269dee653067977f6ae05b3ca89cdf3ad20bd8c`.
Full receipt: `goalie-stats-stage/qa/qa_report.json`; paired reproduction:
`goalie-stat-match-comparison/results.json`; build proof: `build-proof.json`.

Version2026-10-29 is released at the user's request. The separate AI strength target is still unfinished;
this correction is functionally verified but not a claim of 35 wins in 50.
