Developer guide
Database migration safety
Reconcile migration files, metadata, and applied database state without wrecking a developer database.
OpenCircle treats its migration files as committed history and the database's own migration table as the record of what actually ran — related, but never interchangeable. A clean merge does not prove a long-lived local database can safely replay the merged sequence.
Treat the migration record as one system
Inspect all four parts together before touching any of them: the SQL migration file, its journal entry, its schema snapshot, and the target database's own migration table. The generator compares your schema against the last committed snapshot, not the live database, so renaming a file is never a substitute for actually reconciling.
Before synchronizing a schema branch
Answer this first: has the incoming migration already been applied to the database you intend to keep? If you don't know, stop and inspect the SQL, journal, snapshot chain, and database ledger before picking a repair — never infer the answer from whether the app currently boots.
The incoming migration has not been applied
Regenerate it on top of the updated parent history: back up the original SQL, rebuild the migration against the merged schema, compare the two, and stop if the regenerated version is empty or materially different. Apply the result to an isolated instance and validate the chain before trusting it.
The incoming migration has already been applied
Don't regenerate or edit its SQL — the retained database already ran that exact statement. Instead, rename it to the next free number, keep its SQL byte-for-byte, move its journal entry into the new sequence, and chain its snapshot after the current parent. Reconciling the database's own ledger afterward is a separate, deliberate operator decision, never an automated guess.
Forbidden shortcuts
- Don't push a schema directly instead of generating a reviewed migration.
- Don't edit or delete the SQL of an already-applied migration.
- Don't mutate the database's migration table without explicit approval.
- Don't run a repair script without reading it first.
- Don't assume matching migration numbers mean matching SQL, or that a successful boot means the history is coherent.
Validate before continuing
opencircle db check python3 -m json.tool packages/db/src/migrations/meta/_journal.json
Also confirm migration numbers and tags are unique, journal entries are contiguous, every snapshot points to the right parent, and no conflict markers remain — only then apply the result to an isolated instance, never straight to a long-lived default database.