migrations-safetylisted
Install: claude install-skill voidcorp-core/void-harness
# migrations-safety — voidcorp craftsman edition
A "simple" `ALTER TABLE ADD COLUMN NOT NULL DEFAULT 'x'` on a 10M-row Postgres table locks writes for minutes. A "harmless" `RENAME COLUMN` breaks active requests. This skill encodes the lessons so the first migration in a new project gets them too.
**Attribution**: see `.source`. Foundation: GoCardless "Zero-Downtime Postgres Migrations" + Strong Migrations (Ruby) + Drizzle docs + Neon branching.
---
## The two-phase change pattern
Risky DDL goes through TWO migrations + a deploy step in between:
```
1. Migration A — backwards-compatible schema change
(add nullable column / add new column / drop NOT NULL constraint)
2. Deploy code that handles both shapes (old AND new)
3. Backfill (batched, with progress logs)
4. Migration B — tighten the constraint
(add NOT NULL / drop legacy column / rename / type swap)
5. Deploy code that uses only the new shape
```
Doing it in one migration = lock contention + downtime.
---
## Migration PR body — mandatory template
Every migration PR includes:
```markdown
## Migration safety
- **Table affected**: <name>
- **Approximate row count**: <number or "< 1k" / "10k–100k" / "100k–1M" / "1M+">
- **Locking impact**: <AccessExclusiveLock / ShareLock / RowExclusiveLock>
- Estimated lock duration: <seconds / minutes — be conservative>
- Acceptable during business hours: <yes / no — if no, schedule>
- **Backfill strategy**: <none / batched 10k per tx / online via pgroll>
- **Rollback