Context
0124 left open how MikroORM migrations, including migrations shipped in packages, reach the runner (DP12 and FW4). The owner answered on 2026-10-20: gen produces the migrations, and the runner applies them. The owner also set expand-and-contract rules and a forward-only policy (DP13 and DP14, mem L443–444, L355–356).Decision
- Package migrations (FW4 a). Gen pulls the migrations shipped in packages into the host’s migration stream.
- Ordered SQL (DP12 a). Gen writes ordered SQL files. Encore’s runner applies them in SaaS. On-prem runs them as a pre-upgrade job.
- Safety (DP13 a).
- expand-and-contract, with destructive steps deferred to a later release;
- lock and statement timeouts on every migration;
- concurrent index builds in their own migration;
- a squawk lint in CI;
- backfills run as queue jobs (0148).
- Forward fix only (DP14). Data is never rolled back by a migration. A bad migration is fixed by a new migration.
Consequences
- An on-prem upgrade runs migrations as a job before the new code starts, so a failed migration stops the upgrade.
- Destructive changes take two releases, so a rollback never meets a dropped column.
Enforcement
planned — the squawk lint in CI, the lock and statement timeouts in the migration runner, andstackra gen --check for stale SQL.
The upgrade runbook is a final-pass item (runbooks/upgrade.mdx).
Alternatives
- Migrations applied by MikroORM at boot: not chosen; the runner is Encore in SaaS and a job on-prem.
- Rolling back data: rejected by DP14.
Supersedes and sources
Supersedes: none. Amends: 0097, 0124. Sources: owner answers FW4 a (stackra-decisions-2026-10-19.md L355), DP12 a (L356), DP13 a and DP14 (L443–444), all 2026-10-20.