Skip to content

doctor: compare stored migration checksums, not just versions #138

Closed

Description

@TusanHomichi

Existing issue check

  • I searched open and closed issues. None found.

Problem or outcome

doctor reports migrations by version only (crates/consolebook-server/src/doctor.rs:170-179). It never compares the stored _sqlx_migrations checksums with the embedded migrations, and serve refuses to start when they differ. Found while proving #136 (2026-10-15). In a copy of a seeded database with migration 16's stored checksum zeroed:

  • doctor printed ok migrations 16 applied, up to date and exited 0;
  • serve exited 1 with running database migrations: migration 16 was previously applied but has been modified.

So the read-only diagnostic misses exactly the condition that stops the service. An operator who runs doctor before restarting after an upgrade, as the operations guide suggests, would be told everything is fine.

Outcome

doctor compares each applied migration's stored checksum with the embedded one, and reports any mismatch or unknown applied version as a failure. It names the version and says what it means: the database was migrated by a different build of this migration. It stays read-only (ADR 0016).

Acceptance criteria

  • A test with a tampered stored checksum makes doctor report a failure and exit non-zero. A positive control on an intact database stays ok.
  • Unchanged: doctor opens nothing for writing, and its read-only test passes.

Related

#136, ADR 0016, tests/upgrade_compat.rs (#136 pins the released checksums).

Activity

  1. TusanHomichi commented on Oct 15, 2026

    @TusanHomichi
    MemberAuthor

    Selected (2026-10-15): the maintainer said "lets do 126 and 138 first", ahead of a 0.3.0 release. Work proceeds under the standing PR permission: an issue-linked branch, an independent review, the full local proof, then merge.

  2. TusanHomichi commented on Oct 15, 2026

    @TusanHomichi
    MemberAuthor

    Review and decision (2026-10-15). Independent review of 249b2a3: 0 blocking. It confirmed from sqlx-core 0.9 itself that there is no history where doctor says ok while serve refuses, and that startup's decisions and wording are unchanged.

    It also found the inverse mismatch, which predates this change. doctor FAILs on pending: N and on a database with no _sqlx_migrations table, yet serve starts on both: it applies the pending migrations, or creates the table. A pending FAIL is what an operator sees after installing a new binary and running doctor before restarting.

    Integrator decision: parity in both directions. Pending migrations and a database with no migration history yet become a warn that says what the service will do on start. Only the refusals stay fail. This is backed by a doctor/serve parity test, the operations guide sentence is corrected, and the change is noted in the CHANGELOG. The review's nits are also applied: message wording, the read-only test's claim, an ordering comment, a zombie process in a test, and a README line wrap.

    The startup ordering problem the implementation surfaced is filed as #142.

  3. added 3 commits that reference this issue on Oct 15, 2026
    e3e9e79
    ee46ad8
    8d403e5
  4. added a commit that references this issue on Oct 15, 2026
    296a81a
  5. TusanHomichi commented on Oct 15, 2026

    @TusanHomichi
    MemberAuthor

    Merged in #144 as 296a81a6439cfc526d461e5f4d0a2348a1d33f53 (squash; single parent 1dfb945). The tree 6a642bc8 is identical to the proven head 8d403e5.

    • Local full proof: 7/7 gates; 309 Rust tests; 62/62 browser; receipt sha256 4916711e….
    • Hosted: fmt-clippy-test, build-x86_64, build-aarch64, and CodeQL all passed.
    • Codex: P1 (ADR) and P2 (populated database with no history) were fixed and resolved, and the new head drew no further findings.
    • ADR 0029 records the verdict contract.
    • Startup now refuses an unknown version or a missing history before sqlx runs. The remaining checksum and unfinished-row ordering is tracked in startup: refuse a bad migration history before backing up or migrating anything #142.

    Authority: the maintainer's selection and standing PR permission.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions