# Migrations — Derived Rules > Derives from `domains/data/first-principles.md` P4 (Migration Safety), P5 (Reversibility via core C5). ## Every Change is a Migration (P4) - No manual schema changes. No `ALTER TABLE` in a shell. Every change is a versioned migration file. - Migrations are code: reviewed, tested, committed. - The migration tool is the only way to change the schema (`prisma migrate`, `alembic`, `flyway`, `golang-migrate`). ## Forward and Reverse (P5 Reversibility, core C5) - Every migration has an `up` and a `down`. The `down` reverses the `up`. - A migration without a `down` is irreversible. Irreversible migrations are rare and flagged. - Test the `down` in CI. A `down` that fails is a migration that cannot be rolled back. ## Expand, Migrate, Contract (P5) For non-breaking schema changes: 1. **Expand**: add the new column/ table (nullable, no constraint). Deploy. Old code still works. 2. **Migrate**: backfill data, run the data migration. Deploy. Both old and new code work. 3. **Contract**: add constraints, remove the old column. Deploy after all code uses the new schema. Never do all three in one migration. Each step is its own deploy. ## Avoid Destructive Changes (P4) - Never `DROP COLUMN` in a migration that could be in use. Expand-contract first. - Never `DROP TABLE` without confirming no code references it. - Never `ALTER TYPE` in a way that locks the table on a large dataset. Use a phased approach. ## Backward Compatibility (P5, P1) - A migration must not break the running code. Old code reads the new schema (with expand). - The schema is always compatible with the previous code version. Two-version compatibility. - A breaking migration is deployed in lockstep with the code, with a maintenance window. ## Testing Migrations (P3 Determinism via testing P3) - Run migrations on a copy of production data in CI. A migration that works on dev may fail on prod scale. - Test the `down` on the migrated state, not just the `up`. - Test with the largest table sizes you have. `ALTER TABLE` on 10 rows is fast; on 10M rows, it may lock. ## What Violates Migration Safety | Violation | Principle | |-----------|-----------| | Manual `ALTER TABLE` in prod | P4 | | Migration with no `down` | P5 Reversibility | | `DROP COLUMN` in the same deploy as the new code | P4, P5 | | No migration test on prod-scale data | P3 Determinism | | A migration that locks a table for 10 minutes | P4 (downtime) |