Originally created by: Akarsh-Hegde
Every existing user's daemon crash-loops on upgrade to any build containing [#250]:
Caused by:
migration 1 was previously applied but has been modified
Error: failed to run migrations
(Reported live by a user on 1.43.0 → 1.46.0 — meridian status showed "loaded but not running" while the log repeated meridian daemon starting every ~30 s as launchd restarted it.)
sqlx records a SHA-384 checksum of each migration's bytes in _sqlx_migrations when it's applied, and re-validates every applied migration on startup. [#250] ("update file headers… tagline") rewrote line 1 of all 34 shipped migrations — only a comment, no schema — but sqlx hashes the whole file, so every checksum changed. Existing DBs hold the old checksums; the new binary ships the new files → mismatch → run() aborts → daemon panics before the poll loop.
(The error names "migration 1" only because it's the first mismatch checked; all 34 are broken — so reverting a single file just moves the error to migration 2.)
This keeps [#250]'s headers. Before running migrations, setup_db now calls reconcile_migration_checksums(), which:
_sqlx_migrations table yet).migrator.iter()), rewrites the stored checksum to match and logs a warn! naming the version.run() proceed and apply any genuinely new migrations as normal.Every stuck install self-heals on its next daemon start — no revert, no user action, no migrate-db dance — and it's forward-proof against any future accidental reformat.
Trade-off (called out honestly): this weakens sqlx's tamper-detection — a genuine SQL change to a shipped migration is now accepted with a warning rather than blocked. The warn! is the audit trail, and the "never edit a shipped migration" rule remains the real guard.
reconcile_repairs_drifted_checksum: applies migrations, corrupts a stored checksum, asserts run() then fails (reproducing the crash), runs reconcile, asserts run() succeeds.reconcile_is_noop_on_fresh_db: reconcile on a DB with no _sqlx_migrations table is a clean no-op.Full suite green: 256 lib tests + integration, clippy -D warnings and fmt clean.
Supersedes the closed [#260] (which reverted the headers). This is the "keep the tagline, fix the checksums" approach instead.
https://claude.ai/code/session_013mv3epyceLahz9Cue1mtPj
Generated by Claude Code
Ticket changed by: Akarsh-Hegde
Originally posted by: adityaharishch
🎉 This PR is included in version 1.48.1 🎉
The release is available on:
v1.48.1Your semantic-release bot 📦🚀