---
key: release.migration-rehearsal-prodcopy
title: 2026-07-12 — Release path rehearses migrations on a prod-DB copy before promoting (#315)
status: active
since: '2026-07-12'
supersedes: none
superseded-by: none
rule: Before promoting a migration-bearing release, rehearse the new image's migrations against a throwaway copy of the latest prod backup (`scripts/migration-smoke.sh`), gating PASS on the migrator's completion log line rather than HTTP readiness alone.
signals: 'migration rehearsal, prod-copy smoke test, DatabaseMigratorService · paths: `scripts/migration-smoke.sh` · issues: #315'
mechanics: '`docs/ci-cd.md` → Migration-on-prod-copy smoke; `scripts/migration-smoke.sh`'
---

The CI `migrations` job proves a migration is well-formed against a **fresh, empty** DB (model-drift +
apply-to-fresh, per provider). That is necessary but not sufficient: it never exercises the migration —
or ErsatzTV's startup data steps (`DatabaseMigratorService` → `DbInitializer` + `PopulatePathHashes`
over the real `MediaFile` table) — against the **accumulated prod SQLite**, where row volume and
historical values differ. A migration green on a fresh DB can still fail or corrupt on prod, discovered
only mid-deploy after the container recreates.

Decision: before promoting a migration-bearing release, **rehearse** the new image's migrations against
a **throwaway copy of the latest prod backup** via `scripts/migration-smoke.sh` — boot the new image
against the copy, gate PASS on the `Done applying database migrations` log line (the migrator is a
`BackgroundService` running concurrently with Kestrel, so HTTP-readiness alone does *not* prove
migrations finished), FAIL on early container exit / a migration exception / timeout / not serving
afterwards. Always operates on a copy, never the live DB. Home: the script + docs are ours; wiring it
into the Komodo **pre-deploy** step (which already produces the backup) is a server-management concern.
Rationale: data-plane rigor — catch a bad migration on a disposable copy, not on live prod data.
See `docs/ci-cd.md` → Migration-on-prod-copy smoke. Cross-repo wiring tracked in server-management.
