$npx -y skills add Rune-kit/rune --skill dbDatabase workflow specialist. Generates migration files with rollback scripts, detects breaking schema changes, and validates query parameterization.
| 1 | # db |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | 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. |
| 6 | |
| 7 | ## Triggers |
| 8 | |
| 9 | - `/rune db` — manual invocation when schema changes are planned |
| 10 | - Called by `cook` (L1): schema change detected in diff |
| 11 | - Called by `deploy` (L2): pre-deploy migration safety check |
| 12 | - Called by `audit` (L2): database health dimension |
| 13 | |
| 14 | ## Calls (outbound) |
| 15 | |
| 16 | - `scout` (L2): find schema files, migration files, ORM config |
| 17 | - `verification` (L3): run migration in test environment if configured |
| 18 | - `hallucination-guard` (L3): verify SQL syntax and ORM method names |
| 19 | |
| 20 | ## Called By (inbound) |
| 21 | |
| 22 | - `cook` (L1): schema change detected in diff |
| 23 | - `deploy` (L2): pre-deploy migration safety check |
| 24 | - `audit` (L2): database health dimension |
| 25 | |
| 26 | ## References |
| 27 | |
| 28 | - `references/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. |
| 29 | |
| 30 | ## Executable Steps |
| 31 | |
| 32 | ### Step 1 — Discovery |
| 33 | |
| 34 | Invoke `scout` to locate: |
| 35 | - Schema definition files: `*.sql`, `schema.prisma`, `models.py`, `*.migration.ts`, `db/migrate/*.rb` |
| 36 | - Migration directory and existing migration files (to determine next migration number) |
| 37 | - ORM in use: **Prisma** | **TypeORM** | **SQLAlchemy/Alembic** | **Django ORM** | **ActiveRecord** | **raw SQL** | **unknown** |
| 38 | - Database type: **PostgreSQL** | **MySQL** | **SQLite** | **MongoDB** | **unknown** |
| 39 | |
| 40 | If ORM cannot be determined with confidence, fall back to generic SQL migration format. |
| 41 | |
| 42 | ### Step 2 — Diff Analysis |
| 43 | |
| 44 | Read current schema and compare against previous version (git diff if available): |
| 45 | - List all **added** columns, tables, indexes, constraints |
| 46 | - List all **removed** columns, tables, indexes |
| 47 | - List all **modified** columns (type changes, nullability changes, default changes) |
| 48 | - List all **renamed** columns or tables |
| 49 | |
| 50 | ### Step 3 — Breaking Change Detection |
| 51 | |
| 52 | Classify each change by impact: |
| 53 | |
| 54 | | Change | Classification | Why | |
| 55 | |--------|---------------|-----| |
| 56 | | ADD COLUMN NOT NULL without DEFAULT | **BREAKING** | Fails on existing rows | |
| 57 | | DROP COLUMN | **BREAKING** | Irreversible data loss | |
| 58 | | RENAME COLUMN or TABLE | **BREAKING** | Breaks all existing queries | |
| 59 | | CHANGE column type (e.g. VARCHAR→INT) | **BREAKING** | Data truncation risk | |
| 60 | | ADD COLUMN nullable | SAFE | Existing rows get NULL | |
| 61 | | ADD TABLE | SAFE | No impact on existing data | |
| 62 | | ADD INDEX | SAFE (but may lock table) | Lock risk on large tables | |
| 63 | | DROP INDEX | SAFE | Slight query slowdown | |
| 64 | | DROP TABLE | **BREAKING** | Irreversible data loss | |
| 65 | |
| 66 | For any **BREAKING** change: output `BREAKING: [change description]` and require explicit user confirmation before generating migration. |
| 67 | |
| 68 | <HARD-GATE> |
| 69 | Migration adding NOT NULL column to existing table without DEFAULT value = BLOCK. |
| 70 | Column rename or type change on data-bearing table = BREAKING — emit warning and require confirmation before proceeding. |
| 71 | Empty downgrade/rollback function = BLOCK — every migration MUST have a working down/rollback path. |
| 72 | </HARD-GATE> |
| 73 | |
| 74 | ### Step 4 — Migration Generation |
| 75 | |
| 76 | For each schema change, generate a migration file with **up** (apply) and **down** (rollback) scripts. |
| 77 | |
| 78 | **Prisma:** |
| 79 | ```typescript |
| 80 | // migrations/[timestamp]_[description]/migration.sql |
| 81 | -- Up |
| 82 | ALTER TABLE "users" ADD COLUMN "avatar_url" TEXT; |
| 83 | |
| 84 | -- Down (in separate migration file or comment) |
| 85 | ALTER TABLE "users" DROP COLUMN "avatar_url"; |
| 86 | ``` |
| 87 | |
| 88 | **Django / Alembic:** |
| 89 | ```python |
| 90 | def upgrade(): |
| 91 | op.add_column('users', sa.Column('avatar_url', sa.Text(), nullable=True)) |
| 92 | |
| 93 | def downgrade(): |
| 94 | op.drop_column('users', 'avatar_url') |
| 95 | # NEVER leave downgrade() empty — HARD-GATE blocks this |
| 96 | ``` |
| 97 | |
| 98 | **TypeORM:** |
| 99 | ```typescript |
| 100 | public async up(queryRunner: QueryRunner): Promise<void> { |
| 101 | await queryRunner.addColumn('users', new TableColumn({ |
| 102 | name: 'avatar_url', type: 'text', isNullable: true |
| 103 | })); |
| 104 | } |
| 105 | public async down(queryRunner: QueryRunner): Promise<void> { |
| 106 | await queryRunner.dropColumn('users', 'avatar_url'); |
| 107 | } |
| 108 | ``` |
| 109 | |
| 110 | **Raw SQL:** |
| 111 | ```sql |
| 112 | -- up.sql |
| 113 | ALTER TABLE users ADD COLUMN avatar_url TEXT; |
| 114 | -- down.sql |
| 115 | ALTER TABLE users DROP COLUMN avatar_url; |
| 116 | ``` |
| 117 | |
| 118 | Use `hallucination-guard` to verify syntax of generated SQL and ORM method names before writing. |
| 119 | |
| 120 | ### Step 5 — Index Analysis |
| 121 | |
| 122 | For every new table or column added, check: |
| 123 | - Foreign key columns without index → flag `MISSING_INDEX: [column] — |