Block Unsafe Database Migrations

Catches migrations that lock or rewrite large tables, build blocking indexes, or run full-table backfills, and suggests phased rollouts.

What it flags

Flaggedmigrations/add_order_status.sql
ALTER TABLE orders ADD COLUMN status text;

-- Updates every row, then locks orders for a full scan and an index build
UPDATE orders SET status = 'shipped' WHERE shipped_at IS NOT NULL;
UPDATE orders SET status = 'pending' WHERE shipped_at IS NULL;

ALTER TABLE orders ALTER COLUMN status SET NOT NULL;

CREATE INDEX orders_status_idx ON orders (status);
Passesmigrations/add_order_status_phased.sql
-- Migration 1: nullable column, no table rewrite
ALTER TABLE orders ADD COLUMN status text;

-- Backfill from a job in small batches, then:

-- Migration 2: on its own, outside a transaction
CREATE INDEX CONCURRENTLY orders_status_idx ON orders (status);

-- Migration 3: NOT VALID skips checking existing rows
ALTER TABLE orders ADD CONSTRAINT orders_status_not_null
  CHECK (status IS NOT NULL) NOT VALID;

-- Migration 4: VALIDATE allows writes; SET NOT NULL then skips the scan
ALTER TABLE orders VALIDATE CONSTRAINT orders_status_not_null;
ALTER TABLE orders ALTER COLUMN status SET NOT NULL;
ALTER TABLE orders DROP CONSTRAINT orders_status_not_null;

Why it matters

Migrations run against production during a deploy, often while traffic is high. In PostgreSQL, an ALTER TABLE that needs an ACCESS EXCLUSIVE lock waits behind any long-running query on the table, and every query that arrives afterwards queues behind it, so a change that is instant on a laptop can stall all reads and writes on a busy table. A plain CREATE INDEX blocks writes for the whole build, and a single-statement backfill holds row locks and writes a burst of WAL for the entire table. None of this shows up against the small databases used in tests.

Agent instructions

cubic checks every pull request against these instructions. Paste them into AGENTS.md or Cursor rules and your AI coding tool follows them while it writes code.

AGENTS.md

Add this section to AGENTS.md at the repository root. Codex, Cursor, and other AI coding tools read it.

## Block Unsafe Database Migrations

Review database migrations for operations that can lock large tables, rewrite full tables, run long backfills, create blocking indexes, or require full table scans. Prefer phased rollouts, concurrent indexes, nullable columns followed by backfills, batched data changes, and explicit rollback or recovery plans for risky schema changes.

Checks every changed file.

Related agents

Included in the Node.js, Django, Ruby on Rails, Go, Spring Boot, and PostgreSQL code review standards.

Run this agent on every pull request

cubic reviews every pull request against the agents you turn on and comments on the lines that break them.

Catch this in your code