# D20. Format versions migrate; renaming is a command (6 Oct 2026)

Testers' projects must never break when the core evolves. The format version is in `course.json`; every format change ships with a migration (a pure step on the raw files, in `@elabora/core`) and a fixture course in the older version. Elabora reads an older course migrated in memory (validation and builds work at once) and writes the migration only when asked (`elabora migrate`), when an edit goes through Elabora, when the app opens the course or when the library imports it: always as one `system` change after a backup version, so it can be undone, and never mixed into AI work. A migration edits values in the text of each file, keeping the author's formatting (agents and people write compact JSON, one block per line), so a migrated course differs by its migrated values only. A newer format is refused rather than half-read. Ids stay permanent; renaming one is a command that rewrites every reference and carries the learner-state key, rather than a free edit that would orphan progress.
*Revisit if:* a migration needs to change binary files or to ask the author (then an interactive migration in the app, with the same journal entry).
