Skip to content

fix(cli): refuse a newer database schema with an actionable error - #134

Merged
azlekov merged 1 commit into
developfrom
fix/migration-version-gate
Sep 2, 2026
Merged

fix(cli): refuse a newer database schema with an actionable error#134
azlekov merged 1 commit into
developfrom
fix/migration-version-gate

Conversation

@azlekov

@azlekov azlekov commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

An older dirad meeting a dira.db written by a newer version fails sqlx's strict migration validation with a bare VersionMissing(<number>) and respawn-loops under launchd — the only diagnosis is a cryptic number in the log. This matters because dira update --version <older> is a documented recovery flow, and it affects every migration, not just new ones.

The policy decision (DIRASH-0035)

Strict validation stays. The evaluated alternative — Migrator::set_ignore_missing(true) — would let the older binary run against a schema written by a future version: newer migrations may add required columns or change semantics, so a clean startup refusal would be traded for undefined runtime behavior on the event log that feeds billing and identity. That contradicts the codebase's standing doctrine (doctor reports and never repairs, DIRASH-0022; a replacement daemon is never started on optimism, D-0019). The respawn loop is supervision working as configured; the bug was the message.

What changed

  • Store::open catches MigrateError::VersionMissing and returns a new Error::SchemaNewer naming the db path, the unknown migration, the cause, and both recovery paths (dira update, or dira update --version <the writer's version>).
  • Test: migrates a real store, stamps a future version into _sqlx_migrations, asserts reopen refuses with the actionable message.
  • Decision record .zavet/decisions/DIRASH-0035 documents why strict is correct and why ignore_missing was rejected.

Testing

cargo test -p dira-core: 308 passed, 0 failed. Clippy -D warnings clean, fmt clean. Based on develop; merges cleanly with #133 (its Store::open hunks don't overlap).

🤖 Generated with Claude Code

…t a bare version number

Store::open keeps strict migration validation — an older binary must never run
against a schema written by a newer one (undefined behavior on the billing-critical
event log beats no startup exactly never). But the refusal now says what happened
and how to recover: Error::SchemaNewer names the db path, the unknown migration,
and both fixes (dira update, or pinning back to the version that wrote it), instead
of sqlx VersionMissing respawn-looping under launchd with a cryptic number.

Records DIRASH-0035 (ignore_missing rejected; strict is the correct half, the
message was the broken half).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Asen Lekov <asenlekoff@gmail.com>
@azlekov
azlekov merged commit e315d3c into develop Sep 2, 2026
6 checks passed
@azlekov
azlekov deleted the fix/migration-version-gate branch September 2, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant