From rune
Generates database migration files with rollback scripts, detects breaking schema changes, and validates query parameterization. Supports Prisma, Django ORM, SQLAlchemy/Alembic, PostgreSQL, MySQL.
npx claudepluginhub rune-kit/rune --plugin @rune/analyticsThis skill uses the workspace's default tool permissions.
Database workflow specialist. Handles the parts of database work that cause production incidents — breaking schema changes, migrations without rollback, raw SQL injection vectors, and missing indexes on growing tables. Acts as a pre-deploy gate for any schema change, and generates correct migration files (up + down) for common ORMs.
Plans safe database schema migrations with zero-downtime strategies, rollback procedures, data validation, and version tracking for PostgreSQL, MySQL, and SQLite.
Generates safe, reversible database migrations from schema diffs and model changes for PostgreSQL, MySQL, Prisma, Django, Rails, Laravel.
Generates migration files with up/down scripts for schema changes in Knex, Prisma, TypeORM, or Drizzle projects. Detects framework, verifies intent, and ensures rollback safety.
Share bugs, ideas, or general feedback.
Database workflow specialist. Handles the parts of database work that cause production incidents — breaking schema changes, migrations without rollback, raw SQL injection vectors, and missing indexes on growing tables. Acts as a pre-deploy gate for any schema change, and generates correct migration files (up + down) for common ORMs.
/rune db — manual invocation when schema changes are plannedcook (L1): schema change detected in diffdeploy (L2): pre-deploy migration safety checkaudit (L2): database health dimensionscout (L2): find schema files, migration files, ORM configverification (L3): run migration in test environment if configuredhallucination-guard (L3): verify SQL syntax and ORM method namescook (L1): schema change detected in diffdeploy (L2): pre-deploy migration safety checkaudit (L2): database health dimensionreferences/scaling-reference.md — Index strategies, query optimization, N+1 prevention, connection pooling, read replicas, partitioning, sharding, denormalization. Load when scaling, performance, or indexing context detected.Invoke scout to locate:
*.sql, schema.prisma, models.py, *.migration.ts, db/migrate/*.rbIf ORM cannot be determined with confidence, fall back to generic SQL migration format.
Read current schema and compare against previous version (git diff if available):
Classify each change by impact:
| Change | Classification | Why |
|---|---|---|
| ADD COLUMN NOT NULL without DEFAULT | BREAKING | Fails on existing rows |
| DROP COLUMN | BREAKING | Irreversible data loss |
| RENAME COLUMN or TABLE | BREAKING | Breaks all existing queries |
| CHANGE column type (e.g. VARCHAR→INT) | BREAKING | Data truncation risk |
| ADD COLUMN nullable | SAFE | Existing rows get NULL |
| ADD TABLE | SAFE | No impact on existing data |
| ADD INDEX | SAFE (but may lock table) | Lock risk on large tables |
| DROP INDEX | SAFE | Slight query slowdown |
| DROP TABLE | BREAKING | Irreversible data loss |
For any BREAKING change: output BREAKING: [change description] and require explicit user confirmation before generating migration.
For each schema change, generate a migration file with up (apply) and down (rollback) scripts.
Prisma:
// migrations/[timestamp]_[description]/migration.sql
-- Up
ALTER TABLE "users" ADD COLUMN "avatar_url" TEXT;
-- Down (in separate migration file or comment)
ALTER TABLE "users" DROP COLUMN "avatar_url";
Django / Alembic:
def upgrade():
op.add_column('users', sa.Column('avatar_url', sa.Text(), nullable=True))
def downgrade():
op.drop_column('users', 'avatar_url')
# NEVER leave downgrade() empty — HARD-GATE blocks this
TypeORM:
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.addColumn('users', new TableColumn({
name: 'avatar_url', type: 'text', isNullable: true
}));
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.dropColumn('users', 'avatar_url');
}
Raw SQL:
-- up.sql
ALTER TABLE users ADD COLUMN avatar_url TEXT;
-- down.sql
ALTER TABLE users DROP COLUMN avatar_url;
Use hallucination-guard to verify syntax of generated SQL and ORM method names before writing.
For every new table or column added, check:
MISSING_INDEX: [column] — add index for JOIN performanceCONSIDER_INDEXFor existing tables with new query patterns:
SORT_INDEX_MISSINGScan migration files and any raw SQL files for injection vectors:
# BAD: string interpolation in SQL
query = f"SELECT * FROM users WHERE email = '{email}'"
# GOOD: parameterized
query = "SELECT * FROM users WHERE email = %s"
cursor.execute(query, (email,))
Finding: SQL_INJECTION_RISK — [file:line] — string interpolation in query — use parameterized query
Update or create .rune/schema-changelog.md with a human-readable entry:
## [date] — [migration name]
- Added: [column list]
- Removed: [column list — note if data was migrated]
- Breaking: [yes/no] — [details if yes]
- Rollback: [migration name or "manual"]
Emit structured report:
## DB Report: [scope]
### Schema Changes
- [SAFE|BREAKING] [change description]
### Breaking Changes Requiring Confirmation
- BREAKING: [description] — requires explicit approval before migration runs
### Generated Files
- [migration file path] (up + down)
### Index Recommendations
- MISSING_INDEX: [table.column] — [reason]
### Query Safety
- SQL_INJECTION_RISK: [file:line] — [description]
- Clean: [list of checked files with no issues]
### Verdict: PASS | WARN | BLOCK
## DB Report: schema.prisma diff
### Schema Changes
- SAFE: Added users.avatar_url (TEXT, nullable)
- BREAKING: Renamed users.created → users.created_at
### Breaking Changes Requiring Confirmation
- BREAKING: Column rename users.created → users.created_at
Impact: all queries referencing 'created' will break
Confirm before proceeding? [yes/no]
### Generated Files
- migrations/20260224_add_avatar_url/migration.sql (up + down)
### Index Recommendations
- MISSING_INDEX: users.email — high-cardinality FK, add for login query performance
### Verdict: BLOCK (breaking change unconfirmed)
| Gate | Requires | If Missing |
|---|---|---|
| ORM Gate | ORM identified before migration generation | Fall back to raw SQL format + note |
| Breaking Gate | User confirmation before proceeding on BREAKING changes | BLOCK and await response |
| Rollback Gate | Working down() / rollback script before writing migration | BLOCK — prompt for rollback logic |
| Safety Gate | hallucination-guard verified SQL before Write | Re-verify or flag as unverified |
Known failure modes for this skill. Check these before declaring done.
| Failure Mode | Severity | Mitigation |
|---|---|---|
| Empty downgrade() written silently | CRITICAL | HARD-GATE: never write empty rollback — always prompt for rollback logic |
| NOT NULL column added without DEFAULT on existing table | CRITICAL | HARD-GATE: BLOCK and explain that this will fail on existing rows |
| Migration generated for wrong ORM (TypeORM syntax in Django project) | HIGH | hallucination-guard verifies method names match detected ORM |
| Index recommendations skipped on large tables | MEDIUM | Always run Step 5 — never skip index analysis |
| Schema changelog not updated after migration | LOW | Step 7 runs always — log INFO if skipped due to no .rune/ directory |
| Artifact | Format | Location |
|---|---|---|
| Migration file (up) | SQL or ORM-specific | migrations/<timestamp>_<name>/ |
| Rollback script (down) | SQL or ORM-specific | same migration directory |
| Schema changelog entry | Markdown | .rune/schema-changelog.md |
| Index recommendations | Structured list | inline (DB Report) |
| DB Report with verdict | Markdown (PASS/WARN/BLOCK) | inline |
~2000-6000 tokens input, ~800-2000 tokens output. Sonnet for migration generation quality.
Scope guardrail: db generates and validates migrations — it does not run them in production. Execution is delegated to verification in test environments only.