Editing the body of an already-released installer migration drifts its computed checksum (it hashes plan.toString()). The integrity guard then hard-aborted every prior install on upgrade with "applied migration checksum changed" — a 100% reproducible blocker (v1.3.0, all platforms). Already-applied migrations are filtered out of `pending` and never re-run, so a drifted checksum is functionally inert. ADR-0008 anticipates checksum-mismatch state as something the install-state layer must handle gracefully (plan -> apply -> recover/report), not abort on. This supersedes the published-checksum allowlist merged in #674 (per-release maintenance debt — every historical checksum hand-pinned, still throws for any unregistered value) with a general, self-healing recovery: - Replace the throwing guard with non-fatal `collectAppliedChecksumDrift`, surfaced on `plan.checksumDrift`. - Reconcile drifted stored checksums durably on the next state write (`reconcileDriftedChecksums`), idempotently (no perpetual writes). - Relocate the "shipped migration bodies are immutable" rule to a CI baseline test that locks every shipped migration's checksum and fails on body drift — where #615 should have been caught, instead of blocking users. Removes #674's legacyChecksums field, per-migration checksum pins, published-checksums.json fixture, and compat test. Fixes #670 Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -121,14 +121,17 @@ Required fields:
|
||||
}
|
||||
```
|
||||
|
||||
The checksum is calculated from the migration definition. If an applied
|
||||
migration's checksum changes, the installer must warn and refuse to silently
|
||||
re-run it. Fix-forward migrations should use a new migration id.
|
||||
The checksum is calculated from the migration definition.
|
||||
|
||||
Migration records may pin a stable `checksum` and list `legacyChecksums` for
|
||||
checksums already written by published packages. This is only for compatibility
|
||||
with released install state; new behavior should still ship as a new migration
|
||||
id rather than mutating an already-applied migration in place.
|
||||
An already-applied migration is never re-run, so a drifted checksum is
|
||||
tolerated at runtime: it is collected in `plan.checksumDrift` and reconciled
|
||||
into install state on the next write, rather than aborting the user's upgrade
|
||||
(this unblocks upgrades — see issue #670).
|
||||
|
||||
The "shipped migration bodies are immutable" rule is enforced in CI by a
|
||||
committed checksum-baseline test in `tests/installer-migrations.test.cjs`.
|
||||
If you need to change the behaviour of a released migration, add a NEW
|
||||
fix-forward migration id instead of editing the shipped body.
|
||||
|
||||
## Migration Record
|
||||
|
||||
|
||||
Reference in New Issue
Block a user