1. Symptom
Without a gate, a build could ship with Last Run broken on one language or one control scheme, a story graph that still referenced unreachable chapters, or a cloud save that clobbered a newer local file. Playtesting one machine in one language hid that.
2. Player impact
Wrong-language Last Run, gamepad cells that never saw the tutorial, or a cloud restore that ate progress are player-facing failures. They are not “Steam being down.” They are missing checks before the depot goes live.
3. Reproduction
Read package.json scripts qa:release:logic and qa:release. Run the logic target in CI or locally; it must be allowed to fail. The development log for v0.4.89–v0.4.91 states Last Run Electron EN/ES × KBM/gamepad 4/4 and qa:release green as the pass condition. Do not paste Steam Guard, builder logins, or Partner IDs into public notes.
4. System ownership
Scripts: qa:release:logic and qa:release. Cloud: play/systems/steam-cloud.js (remote file name, debounce, backup before overwrite). Saves: save-schema / state. Last Run harness: last-run-qa-runner.js. Versioning of the marketing/game label is a separate documented pipeline and is not this incident.
5. Incorrect assumption
If it ran on the developer’s PC, it is ready for Steam. Cloud sync is “Steam’s problem.” One Last Run pass in English on mouse covers Spanish and gamepad. Store presence equals release engineering.
6. Root cause
Release is a matrix: language × input × save/cloud × story graph × packaged exe. A single playthrough samples one cell. Autosave-before-load and cloud overwrite are ordering bugs; they only show up with two machines or a New Game after a cloud file exists. Without a named npm script that fails the build, those cells stay optional.
7. Minimal fix
Make qa:release:logic blocking (tests + validate-release + story graph). Add Electron cells for Last Run language × device. Document cloud rules: do not clobber before load; New Game must upload the new run; refuse unknown future schemas. Keep Steamworks admin data out of public case studies.
8. Regression test
qa:release:logic is the automated bundle. last-run-qa-runner.js encodes the 4-cell Last Run matrix. steam-cloud.js is covered by steam-cloud-flush tests in the log. This Academy page does not re-run those binaries.
9. Release validation
Development log 15 Aug 2026, v0.4.89 (persistence/cloud/story graph) and v0.4.91 (qa:release green, Last Run harness). Public Steam page remains store.steampowered.com/app/4901100/. No depot passwords or Partner IDs are published here.
10. Generalized lesson
Shipping is a checklist that can fail, not a screenshot of the store. Encode language, input, and persistence as cells. Never put Steamworks admin identity in educational write-ups. AI that “just uploads the build” skips the only tests that catch Last Run and cloud ordering.
Public evidence
- package.json scripts qa:release and qa:release:logic (unit + story-graph + validate-release + Electron QA).
- CONTRABAND development log, 15 Aug 2026, v0.4.89–v0.4.91.
- play/systems/steam-cloud.js (public behavior only: named save file, debounce, backup).