migration-patterns — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited migration-patterns (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Assume: the service is running, writes are arriving, you cannot take a maintenance window. Most production migrations live here.
Never couple a schema change to a code change in the same deploy. They fail independently, and you need each to be reversible independently.
The safe three-phase dance for any non-trivial change:
Each phase is a separate deploy. Each is independently revertable.
ALTER TABLE ... ADD COLUMN ... NULL. No lock (or brief, depending on engine).NOT NULL with no default on a large table — full-table rewrite, long lock. Use a default (cheap if metadata-only in your engine) or expand/migrate/contract: add nullable → backfill → add NOT NULL constraint.ALTER TABLE ... RENAME COLUMN while code is live. Callers break.CREATE INDEX CONCURRENTLY — no table lock. Monitor for failure.ALGORITHM=INPLACE, LOCK=NONE.CREATE INDEX on a hot table without CONCURRENTLY / online algorithm.NOT VALID (Postgres) so new rows are checked.VALIDATE CONSTRAINT later during low traffic.UPDATE ... WHERE condition on the whole table in one shot. It will bite.Sketch:
-- in a loop, with checkpointing and sleep
UPDATE users
SET email_lower = LOWER(email)
WHERE id > $last_id
AND id <= $last_id + 10000
AND email_lower IS NULL;When writers must update both old and new:
Before switching reads:
Every migration has a reverse. Write both up and down migrations. For destructive ops (drops, renames), the reverse might be "restore from backup" — state that explicitly, and get a snapshot before you run it.
DELETE FROM ... WHERE ... to "clean up" at scale — use batched archival instead.CREATE INDEX without CONCURRENTLY on a live Postgres table — locks writes.SELECT * in backfill queries — read only what you need.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.