Finding #
Save format v20 intentionally stopped accepting the pre-v20 MachineMode spellings (DayJob, Research, Concealment, Operations). Because SaveState is deserialized before migrate_save_state runs, any ordinary v19 save containing those enum values fails at parse time and never reaches the v19 migration arm.
This directly violates the binding player contract:
wiki/vision/player-contract.md:22-24: “Saves survive updates: formats are versioned and migrated, never abandoned.” The page classifies violations as highest severity at lines 9-13.crates/misaligned-core/src/work_grid.rs:18-32:MachineModederivesDeserializewith only the new variants and no aliases/custom migration shape.crates/misaligned-core/src/save.rs:342-347: JSON deserialization happens before migration.crates/misaligned-core/src/save.rs:360-362: the code acknowledges that pre-v20 saves with old spellings fail at parse.wiki/mechanics/machine-work.md:108-109: the current spec says save parity was dropped, which conflicts with the higher-level continuity law.
wiki/mechanics/sim-mechanics.md:343 is also stale (version “currently 19”) and continues to describe additive migration through v19.
Expected #
A v19 save with each old mode spelling loads into v20 without losing the player’s world. The migration should deterministically map:
DayJob→WorkConcealment→LieResearch→ThinkOperations→Think
Add fixture coverage that serializes representative pre-v20 JSON with all four old spellings and proves it loads/resaves using only the new vocabulary. Repair the conflicting spec/knowledge text in the same landing.
Scope note #
This is about forward save continuity, not restoring the separately deferred legacy line-based format.
Resolution (2026-07-11) #
Landed on main as 0bbe729d ("Restore pre-v20 machine-mode save parity via serde aliases").
- Serde aliases on
MachineMode(crates/misaligned-core/src/work_grid.rs) decodeDayJob-> Work;Research,Operations, and v12'sSocial-> Think;Concealment-> Lie. Spellings verified against the pre-collapse enum (git show 8f5504a9^). Resaves emit only the collapsed vocabulary; no SAVE_VERSION bump needed. - New fixture test
save::tests::pre_v20_mode_spellings_load_and_resave_with_collapsed_vocabularypins a v19 save with all four retired spellings (parse, migrate, mapping, clean resave) plus a v12Socialcase. - Prose repaired in the same landing: save.rs version history and v19/v12 migration-arm comments, machine-work.md Stage 1 note (records the violation and restoration), sim-mechanics.md save-version paragraph (now v26, blanket-load promise restored), CLAUDE.md guardrail.
- Observed run: terminal agent binary loaded a doctored v19 save carrying
DayJobunder an isolated HOME, reported "Game loaded!", and resaved v26 with only new spellings.