feat(migrations): replay idempotent SQL files instead of a checksum ledger - #45
Merged
TheGreatAxios merged 3 commits intoSep 27, 2026
Conversation
TheGreatAxios
commented
Sep 25, 2026
TheGreatAxios
left a comment
Contributor
Author
There was a problem hiding this comment.
Self-review: an independent critique pass found a lock regression, where replayed ADD COLUMN/CREATE INDEX took AccessExclusive/Share locks. Fixed with catalog guards and covered by a lock_timeout test. Stale ledger docs and comments are also fixed. Out of scope: databases built by code older than 0.1.0 (with principal_mail but no uid) are not supported. The 0.1.0 runner always applied all six migrations atomically.
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
2 times, most recently
from
September 25, 2026 17:52
171feed to
b215b4e
Compare
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 25, 2026 22:55
b215b4e to
f7f8c46
Compare
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 26, 2026 00:31
f7f8c46 to
a57522b
Compare
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 26, 2026 01:28
a57522b to
2c8dbdc
Compare
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 26, 2026 01:36
2c8dbdc to
b52fcdb
Compare
TheGreatAxios
added this pull request to stack #47
September 26, 2026 01:58
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 26, 2026 02:40
b52fcdb to
1aa2597
Compare
TheGreatAxios
removed this pull request from stack #47
September 26, 2026 02:40
TheGreatAxios
added this pull request to stack #50
September 26, 2026 02:40
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 27, 2026 00:45
1aa2597 to
7db02fb
Compare
runMailboxMigrations replays every migrations/*.sql file in filename order on each run, the same way Interchange runMigrations does, and the files ship in the tarball. Every column, index and backfill is guarded on the catalog, so a replay rewrites no row and takes no lock that blocks mail reads or writes. mailbox_state is seeded only when it is created, and uid and modseq each become NOT NULL only while nullable. A pre-0.1.0 database keeps each message's folder and \Seen from its pre-native management table, which 0005 then drops only when it has exactly that table's columns. A new migration drops the 0.1.0 ledger, and MigrationChecksumError is gone. An upgrade test migrates a database with the published 0.1.0 runner, writes, files and flags mail through 0.1.0, then runs the new runner twice and asserts every row, column and index is unchanged.
The README opens with what the package is and where it plugs into Interchange, lists each route's grant, and adds an upgrade section for 0.1 hosts. Setup, test and internals move to CONTRIBUTING.
TheGreatAxios
force-pushed
the
cl-9243-mailbox-ship-idempotent-sql-migration-files-and-drop-the
branch
from
September 27, 2026 01:23
7db02fb to
1c96a52
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
migrations/*.sql(added tofiles).runMailboxMigrationsreplays every file in filename order on each run under an advisory lock, the way InterchangerunMigrationsand@corbits/memorydo. The embedded SQL,migrationChecksumandMigrationChecksumErrorare deleted.DOblock. A replay rewrites no row and takes noprincipal_mail/mailbox_statelock that blocks mail reads or writes.mailbox_stateonly when it creates the table, and copies each message's folder and\Seenfrom a pre-0.1.0"mailbox"."mailbox"table before 0005 drops it. Because every file replays on each boot, 0005 drops"mailbox"."mailbox"only when its columns are exactly the pre-0.1.0 set, and 0007 drops the ledger only when it has exactly the 0.1.0 columns, so a host's own table under either name survives. 0005 setsuidandmodseqNOT NULL, each only while nullable. 0001 no longer creates the pre-native"mailbox"."mailbox"table.0007_drop_migrations_ledger.sqldrops"mailbox"."corbits_mailbox_migrations". A 0.1.0 database upgrades on its next boot with no manual step.src/db.ts(the repo has no eslint).Verification
tests/upgrade-from-0.1.0.test.ts: migrates with the published@corbits/mailbox@0.1.0runner (a devDependency alias), writes mail through 0.1.0's persist, folder move and a\Seenflag, then runs the new runner twice. Every row, column and index stays identical, and the ledger is gone.\Seensurvive for read, archived, trashed and untouched rows."mailbox"."mailbox"(the seven pre-0.1.0 state columns plus one of its own) and"mailbox"."corbits_mailbox_migrations", replays, and asserts both survive.lock_timeout = 2swhile another transaction holds ROW EXCLUSIVE on both tables.npm pack --dry-runlists all 7 SQL files.--frozen-lockfile, build, typecheck, tests against Postgres, and the Node consumer smoke test.Closes CL-9243