migration-surgeon
Schema migration surgeon: diffs two schema states (SQL DDL or Prisma), then generates the complete package nobody writes by hand - forward migration, rollback, pre/post validation queries and a risk p
SKILL.mdskills/data/migration-surgeon/SKILL.md
GitHub/migrate
Schema migrations are open-heart surgery. This one comes with rollback, validation and a risk protocol - as a generated file package, never as execution.
What this is for
- From two schema states the package emerges that nobody writes by hand: forward migration, tested rollback, validation queries, risk protocol with explicit data-loss warnings.
PROTECTION RULE - never execute, never copy into target project without approval
This skill NEVER executes a migration against a database. It generates files exclusively. No access to live databases.
The migration package is ALWAYS first created in migration-<date>/ in the
current working directory and shown to the user - never written directly
into the target project. Only after explicit user approval may the package
additionally be copied into the target project (edit action, no script).
What You Must Do When Invoked
During analysis, assign a confidence level to each finding: proven (confirmed by evidence), likely (strong signal, needs review), or suspected (weak signal).
If /migrate -help or /migrate -h (without further arguments) is invoked:
output the ## Usage section unchanged and stop.
Otherwise follow these steps in order, skipping none.
Step 1 - Help check
If invoked with -help or -h, output the ## Usage section unchanged and stop.
Step 2 - Clarify target
Clarify -OldSchema + -NewSchema (files or directories) and the
SQL dialect (postgres|mysql|sqlite|mssql - required, ask if unknown; for
Prisma read from the datasource block). Get confirmation.
Step 3 - Diff
& "<SKILL_DIR>/scripts/schema-diff.ps1" -OldSchema "<old>" -NewSchema "<new>"
Format mix (errors, exit code != 0): forward message, stop. Identical schemas (0 changes): report "No changes" - do not generate an empty package.
Step 4 - Rename clarification
Present each renameCandidate to the user individually (rename = data preserved;
drop+add = data lost - that is the entire difference). Without user response:
treat as drop+add, but mark RED in the risk protocol.
Step 5 - Risk classification
Classify each change:
- lossless: add table/column/index, widen column.
- lossy: remove column/table, narrow type, add NOT NULL on existing data, add UNIQUE on existing data.
- lock-risky: operations that can hold long locks on large tables (name dialect-specifically).
Step 6 - Generate package (5 files, migration-<date>/)
01-forward.sql: constraint-safe order (columns first, then FKs; drops last). Lossy steps individually, with comment-block WARNING before each. NOT NULL introduction as three-step (nullable column + backfill placeholder + SET NOT NULL), backfill as marked TODO with suggestion.02-rollback.sql: exact reversal in reverse order. Non-reversible steps (dropped data) comment as such - rollback restores the schema, data only via backup (notice block at top).03-validate-pre.sql: counts before migration, checks for new constraints (how many existing rows violate the future NOT NULL/UNIQUE NOW - run before migration), orphan checks for new FKs.04-validate-post.sql: counts after migration for comparison.00-protocol.md: diff summary, classification of each change with evidence (diff entry), data-loss section PROMINENT (even if empty: explicitly state "no lossy operations detected"), recommended order (pre-validate -> backup -> forward -> post-validate), open questions (renames without answer, unparsed statements).
unparsed not empty: read the raw texts of both states and diff manually,
mark as "manually checked" in the protocol instead of ignoring.
Dialect feature missing (e.g. sqlite cannot DROP COLUMN before 3.35):
generate dialect-specific alternative (e.g. table rebuild) or mark as
manual work.
Evidence requirement: each generated migration line must be traceable to a diff entry - generate nothing that the diff does not show.
Step 7 - Summarize
State the package path, summarize the risk protocol, ALWAYS explicitly mention data-loss warnings (even if none exist).
Usage
/migrate # interactive
/migrate <old> <new> <dialect> # diff + generate package
/migrate -help