@jamie-tam/forge 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/agents/architect.md +92 -0
- package/agents/builder.md +122 -0
- package/agents/code-reviewer.md +107 -0
- package/agents/concept-designer.md +207 -0
- package/agents/craft-reviewer.md +132 -0
- package/agents/critic.md +130 -0
- package/agents/doc-writer.md +85 -0
- package/agents/dreamer.md +129 -0
- package/agents/e2e-runner.md +89 -0
- package/agents/gotcha-hunter.md +127 -0
- package/agents/prototype-builder.md +193 -0
- package/agents/prototype-codifier.md +204 -0
- package/agents/prototype-reviewer.md +163 -0
- package/agents/security-reviewer.md +108 -0
- package/agents/spec-reviewer.md +94 -0
- package/agents/tracer.md +98 -0
- package/agents/wireframer.md +109 -0
- package/commands/abort.md +25 -0
- package/commands/bugfix.md +151 -0
- package/commands/evolve.md +118 -0
- package/commands/feature.md +236 -0
- package/commands/forge.md +100 -0
- package/commands/greenfield.md +185 -0
- package/commands/hotfix.md +98 -0
- package/commands/refactor.md +147 -0
- package/commands/resume.md +25 -0
- package/commands/setup.md +201 -0
- package/commands/status.md +27 -0
- package/commands/task-force.md +110 -0
- package/commands/validate.md +12 -0
- package/dist/__tests__/active-manifest.test.js +272 -0
- package/dist/__tests__/copy.test.js +96 -0
- package/dist/__tests__/gate-check.test.js +384 -0
- package/dist/__tests__/wiki.test.js +472 -0
- package/dist/__tests__/work-manifest.test.js +304 -0
- package/dist/active-manifest.js +229 -0
- package/dist/cli.js +158 -0
- package/dist/copy.js +124 -0
- package/dist/gate-check.js +326 -0
- package/dist/hooks.js +60 -0
- package/dist/init.js +140 -0
- package/dist/manifest.js +90 -0
- package/dist/merge.js +77 -0
- package/dist/paths.js +36 -0
- package/dist/uninstall.js +216 -0
- package/dist/update.js +158 -0
- package/dist/verify-manifest.js +65 -0
- package/dist/verify.js +98 -0
- package/dist/wiki-ui.js +310 -0
- package/dist/wiki.js +364 -0
- package/dist/work-manifest.js +798 -0
- package/hooks/config/gate-requirements.json +79 -0
- package/hooks/hooks.json +143 -0
- package/hooks/scripts/analyze-telemetry.sh +114 -0
- package/hooks/scripts/gate-enforcer.sh +164 -0
- package/hooks/scripts/pre-compact.sh +90 -0
- package/hooks/scripts/session-start.sh +81 -0
- package/hooks/scripts/telemetry.sh +41 -0
- package/hooks/scripts/wiki-lint.sh +87 -0
- package/hooks/templates/AGENTS.md.template +48 -0
- package/hooks/templates/CLAUDE.md.template +45 -0
- package/package.json +55 -0
- package/protocols/README.md +40 -0
- package/protocols/codex.md +151 -0
- package/protocols/graphify.md +156 -0
- package/references/common/agent-coordination.md +65 -0
- package/references/common/coding-standards.md +54 -0
- package/references/common/feature-tracking.md +21 -0
- package/references/common/io-protocol.md +36 -0
- package/references/common/phases.md +57 -0
- package/references/common/quality-gates.md +130 -0
- package/references/common/skill-authoring.md +154 -0
- package/references/common/skill-compliance.md +30 -0
- package/references/python/standards.md +44 -0
- package/references/react/standards.md +61 -0
- package/references/typescript/standards.md +42 -0
- package/rules/common/forge-system.md +59 -0
- package/rules/common/git-workflow.md +40 -0
- package/rules/common/guardrails.md +37 -0
- package/rules/common/quality-gates.md +18 -0
- package/rules/common/security.md +50 -0
- package/rules/common/skill-selection.md +78 -0
- package/rules/common/testing.md +58 -0
- package/rules/common/verification.md +39 -0
- package/skills/build-pr-workflow/SKILL.md +301 -0
- package/skills/build-pr-workflow/references/pr-template.md +62 -0
- package/skills/build-pr-workflow/references/subagent-merge.md +47 -0
- package/skills/build-pr-workflow/references/worktree-setup.md +125 -0
- package/skills/build-prototype/SKILL.md +264 -0
- package/skills/build-scaffold/SKILL.md +340 -0
- package/skills/build-tdd/SKILL.md +89 -0
- package/skills/build-wireframe/SKILL.md +110 -0
- package/skills/build-wireframe/assets/baseline-template.html +486 -0
- package/skills/build-wireframe/references/demo-walkthroughs.md +170 -0
- package/skills/build-wireframe/references/gotchas.md +188 -0
- package/skills/build-wireframe/references/legend-lines.md +141 -0
- package/skills/concept-slides/SKILL.md +192 -0
- package/skills/deliver-db-migration/SKILL.md +466 -0
- package/skills/deliver-deploy/SKILL.md +407 -0
- package/skills/deliver-onboarding/SKILL.md +198 -0
- package/skills/deliver-onboarding/references/document-templates.md +393 -0
- package/skills/deliver-onboarding/templates/getting-started.md +122 -0
- package/skills/discover-codebase-analysis/SKILL.md +448 -0
- package/skills/discover-requirements/SKILL.md +418 -0
- package/skills/discover-requirements/templates/prd.md +99 -0
- package/skills/discover-requirements/templates/technical-spec.md +123 -0
- package/skills/discover-requirements/templates/user-stories.md +76 -0
- package/skills/harden/SKILL.md +214 -0
- package/skills/iterate-prototype/SKILL.md +241 -0
- package/skills/plan-architecture/SKILL.md +457 -0
- package/skills/plan-architecture/templates/adr-template.md +52 -0
- package/skills/plan-architecture/templates/api-contract.md +99 -0
- package/skills/plan-architecture/templates/db-schema.md +81 -0
- package/skills/plan-architecture/templates/system-design.md +111 -0
- package/skills/plan-brainstorm/SKILL.md +433 -0
- package/skills/plan-design-system/SKILL.md +279 -0
- package/skills/plan-task-decompose/SKILL.md +454 -0
- package/skills/quality-code-review/SKILL.md +286 -0
- package/skills/quality-security-audit/SKILL.md +292 -0
- package/skills/quality-security-audit/references/audit-report-template.md +89 -0
- package/skills/quality-security-audit/references/owasp-checks.md +178 -0
- package/skills/quality-test-execution/SKILL.md +435 -0
- package/skills/quality-test-plan/SKILL.md +297 -0
- package/skills/quality-test-plan/references/test-type-guide.md +263 -0
- package/skills/quality-test-plan/templates/e2e-test-plan.md +72 -0
- package/skills/quality-test-plan/templates/integration-test-plan.md +74 -0
- package/skills/quality-test-plan/templates/load-test-plan.md +111 -0
- package/skills/quality-test-plan/templates/smoke-test-plan.md +68 -0
- package/skills/quality-test-plan/templates/unit-test-plan.md +56 -0
- package/skills/quality-uiux/SKILL.md +481 -0
- package/skills/support-debug/SKILL.md +464 -0
- package/skills/support-dream/SKILL.md +213 -0
- package/skills/support-gotcha/SKILL.md +249 -0
- package/skills/support-runtime-reachability/SKILL.md +190 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-01-passes-app-use/src/app.ts +7 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-01-passes-app-use/src/handlers/cases.ts +7 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-02-orphan-no-app-use/src/app.ts +8 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-02-orphan-no-app-use/src/handlers/cases.ts +7 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/App.tsx +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/components/RingingBanner.tsx +7 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/hooks/useTwilio.ts +6 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-04-jsx-component-rendered/src/App.tsx +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-04-jsx-component-rendered/src/components/MyComp.tsx +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-05-jsx-component-not-rendered/src/App.tsx +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-05-jsx-component-not-rendered/src/components/Orphan.tsx +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-06-class-instantiated/src/lib/Service.ts +6 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-06-class-instantiated/src/main.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-07-class-not-instantiated/src/lib/Lonely.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-07-class-not-instantiated/src/main.ts +2 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-08-default-export-imported-and-called/src/handler.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-08-default-export-imported-and-called/src/main.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-09-default-export-orphan/src/handler.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-09-default-export-orphan/src/main.ts +2 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-10-aliased-named-export/src/lib.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-10-aliased-named-export/src/main.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/lib/index.ts +1 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/lib/internal.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/main.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-12-test-only-caller/src/util.test.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-12-test-only-caller/src/util.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-13-gated-pending-annotation/src/future.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-14-untraceable-annotation/src/decorated.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-15-untraceable-empty/src/lazy.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-16-python-module/src/lib.py +15 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-16-python-module/src/main.py +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-17-router-use/src/parent.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-17-router-use/src/routes/cases.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-18-shadowed-name-fp/src/lib/foo.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-18-shadowed-name-fp/src/other.ts +8 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/handlers/cases.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/handlers/users.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/main.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-20-aliased-import-usage/src/handlers/cases.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-20-aliased-import-usage/src/main.ts +4 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-21-mixed-default-and-named/src/lib.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-21-mixed-default-and-named/src/main.ts +5 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-22-dynamic-import-then-caller/src/lib.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-22-dynamic-import-then-caller/src/main.ts +8 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-23-dynamic-import-with-space/src/lib.ts +3 -0
- package/skills/support-runtime-reachability/scripts/__fixtures__/case-23-dynamic-import-with-space/src/main.ts +7 -0
- package/skills/support-runtime-reachability/scripts/check.mjs +638 -0
- package/skills/support-runtime-reachability/scripts/check.test.mjs +244 -0
- package/skills/support-skill-validator/SKILL.md +194 -0
- package/skills/support-skill-validator/references/false-positives.md +59 -0
- package/skills/support-skill-validator/references/validation-checks.md +280 -0
- package/skills/support-system-guide/SKILL.md +311 -0
- package/skills/support-task-force/SKILL.md +265 -0
- package/skills/support-task-force/references/dispatch-pattern.md +178 -0
- package/skills/support-task-force/references/synthesis-template.md +126 -0
- package/skills/support-wiki-bootstrap/SKILL.md +37 -0
- package/skills/support-wiki-lint/SKILL.md +196 -0
- package/skills/support-wiki-lint/scripts/lint.mjs +488 -0
- package/skills/support-wiki-lint/scripts/lint.test.mjs +196 -0
- package/templates/README.md +23 -0
- package/templates/aiwiki/CLAUDE.md.template +78 -0
- package/templates/aiwiki/schemas/architecture.md +118 -0
- package/templates/aiwiki/schemas/convention.md +112 -0
- package/templates/aiwiki/schemas/decision.md +144 -0
- package/templates/aiwiki/schemas/gotcha.md +118 -0
- package/templates/aiwiki/schemas/oracle.md +105 -0
- package/templates/aiwiki/schemas/session.md +125 -0
- package/templates/manifests/bugfix.yaml +41 -0
- package/templates/manifests/feature.yaml +69 -0
- package/templates/manifests/greenfield.yaml +61 -0
- package/templates/manifests/hotfix.yaml +45 -0
- package/templates/manifests/refactor.yaml +44 -0
- package/templates/manifests/v5/SCHEMA.md +327 -0
- package/templates/manifests/v5/feature.yaml +77 -0
- package/templates/manifests/v6/SCHEMA.md +199 -0
- package/templates/wiki-html/dream-detail.html +378 -0
- package/templates/wiki-html/dreams-list.html +155 -0
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deliver-db-migration
|
|
3
|
+
description: "Use when a change adds, alters, or drops database schema elements or edits ORM schema files (Prisma, Drizzle, Alembic, etc.)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deliver: Database Migration
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Migrations can corrupt data or cause downtime. This skill enforces generate → test forward → test rollback → test forward again → verify data integrity, before deploy.
|
|
11
|
+
|
|
12
|
+
**Core Principle:** Every migration is reversible until proven otherwise. If you cannot write a rollback, you cannot deploy the migration.
|
|
13
|
+
|
|
14
|
+
## The Iron Laws of Database Migration
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Every migration MUST have a rollback script.
|
|
18
|
+
NEVER modify a migration that has been deployed to any environment.
|
|
19
|
+
ALWAYS test rollback before deploying the forward migration.
|
|
20
|
+
NEVER run destructive operations (DROP, TRUNCATE) without explicit user confirmation.
|
|
21
|
+
NEVER assume seed data is idempotent -- verify it.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- Architecture artifacts include database schema changes
|
|
27
|
+
- A feature requires new tables, columns, indexes, or constraints
|
|
28
|
+
- An existing schema needs modification (rename, type change, removal)
|
|
29
|
+
- Data needs to be transformed as part of a schema change
|
|
30
|
+
- Database needs to be seeded with initial data
|
|
31
|
+
|
|
32
|
+
**Do NOT use when:**
|
|
33
|
+
- Application code changes only (no schema changes)
|
|
34
|
+
- Query optimization only (no DDL changes)
|
|
35
|
+
- Read-only reporting changes
|
|
36
|
+
|
|
37
|
+
## I/O Contract
|
|
38
|
+
|
|
39
|
+
| Field | Value |
|
|
40
|
+
|---|---|
|
|
41
|
+
| **Requires** | DB schema from `aiwiki/architecture/db-schema.md` (prototype-driven flow, written by harden) OR `.forge/work/{type}/{name}/architecture/db-schema.md` (non-prototype fallback, written by plan-architecture) |
|
|
42
|
+
| **Produces** | Migration files (forward + rollback) in project's migration directory |
|
|
43
|
+
| **Feeds into** | `deliver-deploy` (migrations run during deployment) |
|
|
44
|
+
| **Updates** | `.forge/work/{type}/{name}/manifest.yaml`: migration status, file paths |
|
|
45
|
+
|
|
46
|
+
### Input Verification
|
|
47
|
+
|
|
48
|
+
Before starting, read and verify:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
.forge/work/{type}/{name}/
|
|
52
|
+
architecture/
|
|
53
|
+
db-schema.md -> Must contain the target schema state
|
|
54
|
+
manifest.yaml -> Must exist, feature in progress
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Also verify:
|
|
58
|
+
- Project's migration tool is identified (Prisma, Knex, Alembic, Flyway, Django, TypeORM, etc.)
|
|
59
|
+
- Database connection is available for testing
|
|
60
|
+
- Current schema state is known (check existing migrations)
|
|
61
|
+
|
|
62
|
+
### Output Artifacts
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
{project-migration-directory}/
|
|
66
|
+
{timestamp}_{description}.{ext} -> Forward migration
|
|
67
|
+
{timestamp}_{description}_rollback.{ext} -> Rollback migration (or inline down() method)
|
|
68
|
+
|
|
69
|
+
.forge/work/{type}/{name}/
|
|
70
|
+
manifest.yaml -> Updated with migration status
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Migration Tool Detection
|
|
74
|
+
|
|
75
|
+
Detect the project's migration framework from project structure:
|
|
76
|
+
|
|
77
|
+
| Indicator | Framework | Migration Directory |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `prisma/schema.prisma` | Prisma | `prisma/migrations/` |
|
|
80
|
+
| `knexfile.js` / `knexfile.ts` | Knex.js | `migrations/` |
|
|
81
|
+
| `alembic.ini` / `alembic/` | Alembic (SQLAlchemy) | `alembic/versions/` |
|
|
82
|
+
| `flyway.conf` / `flyway/` | Flyway | `sql/` or `flyway/sql/` |
|
|
83
|
+
| `manage.py` + Django | Django | `{app}/migrations/` |
|
|
84
|
+
| `ormconfig.json` / TypeORM config | TypeORM | `src/migrations/` |
|
|
85
|
+
| `sequelize` in package.json | Sequelize | `migrations/` |
|
|
86
|
+
| `drizzle.config.ts` | Drizzle | `drizzle/` |
|
|
87
|
+
| `src/db/migrations/` exists | Custom/raw SQL | `src/db/migrations/` |
|
|
88
|
+
| `supabase/` directory | Supabase | `supabase/migrations/` |
|
|
89
|
+
|
|
90
|
+
If no migration tool is detected, ASK the user. Do not guess.
|
|
91
|
+
|
|
92
|
+
## The Migration Pipeline
|
|
93
|
+
|
|
94
|
+
### Phase 1: Schema Diff Analysis
|
|
95
|
+
|
|
96
|
+
**Purpose:** Understand exactly what needs to change, and classify the risk level.
|
|
97
|
+
|
|
98
|
+
1. **Read Current Schema State**
|
|
99
|
+
- Examine existing migrations to understand current state
|
|
100
|
+
- If ORM has introspection (e.g., `prisma db pull`), use it
|
|
101
|
+
- Document the "before" state clearly
|
|
102
|
+
|
|
103
|
+
2. **Read Target Schema State**
|
|
104
|
+
- From `aiwiki/architecture/db-schema.md` (prototype-driven flow, written by harden) OR `.forge/work/{type}/{name}/architecture/db-schema.md` (non-prototype fallback, written by plan-architecture)
|
|
105
|
+
- This is the "after" state
|
|
106
|
+
|
|
107
|
+
3. **Compute the Diff**
|
|
108
|
+
- List every change: new tables, new columns, modified columns, removed columns, new indexes, new constraints, removed elements
|
|
109
|
+
- For each change, classify:
|
|
110
|
+
|
|
111
|
+
| Risk Level | Operations | Handling |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| **Safe** | ADD column (nullable), ADD table, ADD index | Proceed normally |
|
|
114
|
+
| **Moderate** | ADD column (NOT NULL with default), RENAME column, ADD constraint | Test with existing data |
|
|
115
|
+
| **Dangerous** | DROP column, DROP table, CHANGE column type, TRUNCATE | Require explicit user confirmation |
|
|
116
|
+
| **Critical** | DROP database, DROP multiple tables, data type narrowing | Double confirmation, mandatory backup |
|
|
117
|
+
|
|
118
|
+
4. **Flag Dangerous Operations**
|
|
119
|
+
```
|
|
120
|
+
MIGRATION RISK ASSESSMENT
|
|
121
|
+
-------------------------
|
|
122
|
+
[SAFE] ADD TABLE: payments
|
|
123
|
+
[SAFE] ADD COLUMN: users.stripe_customer_id (VARCHAR, nullable)
|
|
124
|
+
[MODERATE] ADD COLUMN: orders.total_amount (DECIMAL, NOT NULL, default 0.00)
|
|
125
|
+
[DANGEROUS] DROP COLUMN: orders.legacy_price
|
|
126
|
+
-> Contains data in 4,231 rows. Requires confirmation.
|
|
127
|
+
[DANGEROUS] CHANGE TYPE: products.price FROM INTEGER TO DECIMAL
|
|
128
|
+
-> Potential precision changes. Verify data conversion.
|
|
129
|
+
|
|
130
|
+
ACTION REQUIRED: 2 dangerous operations need user confirmation before proceeding.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Phase 1.5: Codex Mode Check
|
|
134
|
+
|
|
135
|
+
Now that the schema diff and risk classification are known, run the Codex consent flow from `protocols/codex.md`. The selected mode applies for the rest of this skill's invocation.
|
|
136
|
+
|
|
137
|
+
- **Takeover:** Dispatch Codex with the schema diff, target schema, and existing migration conventions to generate forward migration, rollback, and migration README. Claude reviews, then runs the 5-step test sequence (Phase 4).
|
|
138
|
+
- **Verify** or **Skip / Codex unavailable:** Proceed with Phases 2-3 below to generate migrations manually. Codex will review Claude's generated migrations before Phase 4 (Verify only).
|
|
139
|
+
|
|
140
|
+
### Phase 2: Generate Forward Migration
|
|
141
|
+
|
|
142
|
+
**Purpose:** Create the migration that moves the schema from current state to target state.
|
|
143
|
+
|
|
144
|
+
1. **Use the Project's Migration Tool**
|
|
145
|
+
- If tool supports auto-generation (Prisma, Alembic, Django), use it
|
|
146
|
+
- Review the auto-generated migration for correctness
|
|
147
|
+
- If tool does not auto-generate, write migration manually
|
|
148
|
+
|
|
149
|
+
2. **Migration File Standards**
|
|
150
|
+
- Clear, descriptive name: `20260325_add_payments_table.sql`
|
|
151
|
+
- Comments explaining WHY each change exists (not just WHAT)
|
|
152
|
+
- Group related changes logically
|
|
153
|
+
- Handle NULL/default values explicitly for existing data
|
|
154
|
+
|
|
155
|
+
3. **Data Migration (when needed)**
|
|
156
|
+
- If schema change requires data transformation, include it
|
|
157
|
+
- Example: splitting a `full_name` column into `first_name` + `last_name`
|
|
158
|
+
- Data migration runs AFTER schema change, BEFORE dropping old column
|
|
159
|
+
- Data migration MUST be idempotent (safe to run multiple times)
|
|
160
|
+
|
|
161
|
+
4. **Ordering Matters**
|
|
162
|
+
```
|
|
163
|
+
Correct order for destructive changes:
|
|
164
|
+
1. Add new columns/tables
|
|
165
|
+
2. Migrate data from old to new
|
|
166
|
+
3. Update application code to use new columns
|
|
167
|
+
4. (After deployment verified) Drop old columns in SEPARATE migration
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Prefer multi-step migrations over single destructive ones.
|
|
171
|
+
|
|
172
|
+
### Phase 3: Generate Rollback Migration
|
|
173
|
+
|
|
174
|
+
**Purpose:** Create the migration that reverses the forward migration exactly.
|
|
175
|
+
|
|
176
|
+
1. **Every Forward Operation Has a Reverse**
|
|
177
|
+
|
|
178
|
+
| Forward Operation | Rollback Operation |
|
|
179
|
+
|---|---|
|
|
180
|
+
| CREATE TABLE | DROP TABLE |
|
|
181
|
+
| ADD COLUMN | DROP COLUMN |
|
|
182
|
+
| DROP COLUMN | ADD COLUMN (with data restoration if possible) |
|
|
183
|
+
| RENAME COLUMN | RENAME COLUMN (reverse) |
|
|
184
|
+
| ADD INDEX | DROP INDEX |
|
|
185
|
+
| ADD CONSTRAINT | DROP CONSTRAINT |
|
|
186
|
+
| ALTER COLUMN TYPE | ALTER COLUMN TYPE (original) |
|
|
187
|
+
| INSERT seed data | DELETE seed data (by known identifiers) |
|
|
188
|
+
|
|
189
|
+
2. **Data Preservation in Rollbacks**
|
|
190
|
+
- If forward migration drops a column, rollback CANNOT restore the data
|
|
191
|
+
- This must be documented: "ROLLBACK WARNING: Data in column X will not be restored"
|
|
192
|
+
- Suggest: before dropping columns, create a data backup step
|
|
193
|
+
- If framework supports it, store dropped column data in a temporary table
|
|
194
|
+
|
|
195
|
+
3. **Rollback File Standards**
|
|
196
|
+
- Named to clearly associate with forward migration
|
|
197
|
+
- Comments explaining what this rolls back and any data loss implications
|
|
198
|
+
- If rollback is impossible (e.g., lossy type conversion), document explicitly
|
|
199
|
+
|
|
200
|
+
4. **When Rollback Is Not Possible**
|
|
201
|
+
- Some operations are truly irreversible (data deletion, lossy type conversion)
|
|
202
|
+
- Document this clearly in the migration file AND in the deploy plan
|
|
203
|
+
- Require user acknowledgment: "This migration cannot be rolled back. Data backup is required before proceeding."
|
|
204
|
+
- Ensure a database backup step is added to the deploy plan
|
|
205
|
+
|
|
206
|
+
### Phase 3.5: Codex Migration Verify
|
|
207
|
+
|
|
208
|
+
After both migrations are generated, check the mode recorded at Phase 1.5. If **Verify** was selected, dispatch Codex to review the forward migration, rollback migration, and README for correctness, reversibility, and convention alignment. Address any CRITICAL findings before proceeding to Phase 4. If **Takeover** was selected, skip this step (Codex already generated the migrations). If **Skip**, do nothing. Do NOT re-run the consent flow. See **Codex Integration** section below for full details.
|
|
209
|
+
|
|
210
|
+
### Phase 4: Test the Migration
|
|
211
|
+
|
|
212
|
+
**Purpose:** Verify the migration works correctly in all scenarios before deployment.
|
|
213
|
+
|
|
214
|
+
This is the critical phase. Do NOT skip any step.
|
|
215
|
+
|
|
216
|
+
#### Test 1: Forward Migration on Clean Database
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
1. Start with empty database (or known baseline schema)
|
|
220
|
+
2. Run all existing migrations to reach current state
|
|
221
|
+
3. Run the new forward migration
|
|
222
|
+
4. Verify: schema matches target state
|
|
223
|
+
5. Verify: no errors in migration output
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Test 2: Rollback Migration
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
1. Starting from state after Test 1 (migration applied)
|
|
230
|
+
2. Run the rollback migration
|
|
231
|
+
3. Verify: schema matches pre-migration state
|
|
232
|
+
4. Verify: no errors in rollback output
|
|
233
|
+
5. Verify: application still works with old schema
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Test 3: Forward Again (Idempotency Check)
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
1. Starting from state after Test 2 (rolled back)
|
|
240
|
+
2. Run the forward migration again
|
|
241
|
+
3. Verify: schema matches target state
|
|
242
|
+
4. Verify: migration is idempotent (no "already exists" errors)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### Test 4: Forward Migration with Seed Data
|
|
246
|
+
|
|
247
|
+
```
|
|
248
|
+
1. Start with database containing seed/test data
|
|
249
|
+
2. Run the forward migration
|
|
250
|
+
3. Verify: existing data is preserved (count rows before and after)
|
|
251
|
+
4. Verify: data transformations applied correctly
|
|
252
|
+
5. Verify: constraints are satisfied (no orphaned foreign keys)
|
|
253
|
+
6. Verify: no duplicate data created
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
#### Test 5: Seed Data Idempotency (Docker Environments)
|
|
257
|
+
|
|
258
|
+
**This is a commonly missed issue in Docker environments:**
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
1. Run seed script once -> verify data
|
|
262
|
+
2. Run seed script again -> verify NO duplicate data
|
|
263
|
+
3. Run seed script a third time -> verify data is still correct
|
|
264
|
+
|
|
265
|
+
Common failure: seed script uses INSERT without checking existence,
|
|
266
|
+
causing duplicate rows on container restart.
|
|
267
|
+
|
|
268
|
+
Fix: Use INSERT ... ON CONFLICT DO NOTHING (Postgres)
|
|
269
|
+
or INSERT IGNORE (MySQL)
|
|
270
|
+
or merge/upsert pattern
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### Test Results
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
MIGRATION TEST RESULTS
|
|
277
|
+
----------------------
|
|
278
|
+
[PASS] Forward migration on clean DB
|
|
279
|
+
[PASS] Rollback migration
|
|
280
|
+
[PASS] Forward migration after rollback (idempotency)
|
|
281
|
+
[PASS] Forward migration with seed data (4,231 rows preserved)
|
|
282
|
+
[PASS] Seed data idempotency (no duplicates after 3 runs)
|
|
283
|
+
[WARN] Rollback will lose data in: orders.legacy_price (acknowledged by user)
|
|
284
|
+
|
|
285
|
+
MIGRATION READY FOR DEPLOYMENT
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Phase 5: Documentation and Handoff
|
|
289
|
+
|
|
290
|
+
1. **Update Feature Manifest**
|
|
291
|
+
```yaml
|
|
292
|
+
migration:
|
|
293
|
+
status: tested
|
|
294
|
+
forward: "migrations/20260325_add_payments_table.sql"
|
|
295
|
+
rollback: "migrations/20260325_add_payments_table_rollback.sql"
|
|
296
|
+
risk_level: moderate
|
|
297
|
+
data_loss_on_rollback: ["orders.legacy_price"]
|
|
298
|
+
tested:
|
|
299
|
+
clean_db: pass
|
|
300
|
+
rollback: pass
|
|
301
|
+
idempotency: pass
|
|
302
|
+
with_data: pass
|
|
303
|
+
seed_idempotency: pass
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
2. **Migration README (in migration directory)**
|
|
307
|
+
```markdown
|
|
308
|
+
## Migration: Add Payments Table
|
|
309
|
+
**Date**: 2026-03-25
|
|
310
|
+
**Feature**: add-payment-processing
|
|
311
|
+
**Risk Level**: Moderate
|
|
312
|
+
|
|
313
|
+
### Changes
|
|
314
|
+
- Creates `payments` table with columns: id, user_id, amount, status, created_at
|
|
315
|
+
- Adds `stripe_customer_id` column to `users` table (nullable)
|
|
316
|
+
- Drops `legacy_price` column from `orders` table
|
|
317
|
+
|
|
318
|
+
### Rollback Notes
|
|
319
|
+
- `orders.legacy_price` data cannot be restored after rollback
|
|
320
|
+
- Ensure data backup before deploying if this column has needed data
|
|
321
|
+
|
|
322
|
+
### Dependencies
|
|
323
|
+
- Requires Stripe integration to be configured (but migration is independent)
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
3. **Hand Off to deliver-deploy**
|
|
327
|
+
- Migration files are ready in the project's migration directory
|
|
328
|
+
- Deploy skill will execute them as part of the deployment pipeline
|
|
329
|
+
- Rollback scripts are available if deployment needs to be reversed
|
|
330
|
+
|
|
331
|
+
## Common Migration Patterns
|
|
332
|
+
|
|
333
|
+
### Adding a Required Column to Existing Table
|
|
334
|
+
|
|
335
|
+
**Wrong:**
|
|
336
|
+
```sql
|
|
337
|
+
ALTER TABLE users ADD COLUMN email VARCHAR(255) NOT NULL;
|
|
338
|
+
-- Fails if table has existing rows without email
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Right (two-step):**
|
|
342
|
+
```sql
|
|
343
|
+
-- Migration 1: Add nullable column
|
|
344
|
+
ALTER TABLE users ADD COLUMN email VARCHAR(255);
|
|
345
|
+
|
|
346
|
+
-- Migration 2 (after backfilling data): Add NOT NULL constraint
|
|
347
|
+
UPDATE users SET email = 'unknown@placeholder.com' WHERE email IS NULL;
|
|
348
|
+
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Renaming a Column Safely
|
|
352
|
+
|
|
353
|
+
**Wrong:**
|
|
354
|
+
```sql
|
|
355
|
+
ALTER TABLE users RENAME COLUMN name TO full_name;
|
|
356
|
+
-- Breaks all application code referencing 'name' immediately
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Right (three-step, zero-downtime):**
|
|
360
|
+
```sql
|
|
361
|
+
-- Migration 1: Add new column, copy data
|
|
362
|
+
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
|
|
363
|
+
UPDATE users SET full_name = name;
|
|
364
|
+
|
|
365
|
+
-- Deploy: Update app code to write to both, read from full_name
|
|
366
|
+
|
|
367
|
+
-- Migration 2 (after app deployed): Drop old column
|
|
368
|
+
ALTER TABLE users DROP COLUMN name;
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Changing Column Type
|
|
372
|
+
|
|
373
|
+
```sql
|
|
374
|
+
-- Safe approach: add new column, migrate data, swap
|
|
375
|
+
ALTER TABLE products ADD COLUMN price_decimal DECIMAL(10,2);
|
|
376
|
+
UPDATE products SET price_decimal = price::DECIMAL / 100.0;
|
|
377
|
+
|
|
378
|
+
-- After verification:
|
|
379
|
+
ALTER TABLE products DROP COLUMN price;
|
|
380
|
+
ALTER TABLE products RENAME COLUMN price_decimal TO price;
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Red Flags -- STOP and Reconsider
|
|
384
|
+
|
|
385
|
+
| Thought | Reality |
|
|
386
|
+
|---|---|
|
|
387
|
+
| "It's just adding a column" | Adding a NOT NULL column to a million-row table can lock it for minutes. |
|
|
388
|
+
| "We don't need rollback for this" | You ALWAYS need rollback. This is not negotiable. |
|
|
389
|
+
| "I'll fix the migration file" | If it has been deployed anywhere, create a new migration instead. |
|
|
390
|
+
| "Seed data will be fine" | Docker restarts will re-run seeds. Test for duplicates. |
|
|
391
|
+
| "The ORM handles rollback" | Verify it. Auto-generated rollbacks are often incomplete. |
|
|
392
|
+
| "DROP is fine, nobody uses that column" | Verify with data queries. "Nobody uses it" is an assumption. |
|
|
393
|
+
| "We can restore from backup" | Restoring a full backup for one column is overkill. Plan properly. |
|
|
394
|
+
| "Testing on my local DB is enough" | Test with production-like data volumes and constraints. |
|
|
395
|
+
|
|
396
|
+
## Framework-Specific Notes
|
|
397
|
+
|
|
398
|
+
### Prisma
|
|
399
|
+
- Use `prisma migrate dev` for development, `prisma migrate deploy` for production
|
|
400
|
+
- Prisma auto-generates rollback in the migration SQL
|
|
401
|
+
- Check `_prisma_migrations` table for applied migrations
|
|
402
|
+
- Watch for: Prisma shadow database requirements
|
|
403
|
+
|
|
404
|
+
### Alembic (SQLAlchemy)
|
|
405
|
+
- Always implement both `upgrade()` and `downgrade()`
|
|
406
|
+
- Use `alembic downgrade -1` to test rollback
|
|
407
|
+
- Use `--autogenerate` but ALWAYS review the output
|
|
408
|
+
- Watch for: Alembic cannot detect table renames (sees drop + create)
|
|
409
|
+
|
|
410
|
+
### Django
|
|
411
|
+
- Use `makemigrations` then review before `migrate`
|
|
412
|
+
- `migrate {app} {previous_number}` for rollback
|
|
413
|
+
- `RunPython` operations need `reverse_code` parameter
|
|
414
|
+
- Watch for: Django circular migration dependencies
|
|
415
|
+
|
|
416
|
+
### Knex.js
|
|
417
|
+
- Implement both `up()` and `down()` in migration file
|
|
418
|
+
- Use `knex migrate:rollback` to test
|
|
419
|
+
- Watch for: Knex does not auto-generate migrations
|
|
420
|
+
|
|
421
|
+
### TypeORM
|
|
422
|
+
- Implement both `up()` and `down()` in migration class
|
|
423
|
+
- Use `typeorm migration:revert` to test rollback
|
|
424
|
+
- Watch for: TypeORM sync mode can bypass migrations (disable in production)
|
|
425
|
+
|
|
426
|
+
## Codex Integration
|
|
427
|
+
**Modes:** Verify or Takeover | **Protocol:** `protocols/codex.md`
|
|
428
|
+
|
|
429
|
+
- **Verify:** Claude generates migrations, Codex reviews for correctness.
|
|
430
|
+
- **Takeover:** Codex generates forward + rollback migrations, Claude reviews before testing.
|
|
431
|
+
|
|
432
|
+
**When:** After Claude has analyzed the schema diff and classified risk (Phase 1), but before generating migration files (Phase 2-3).
|
|
433
|
+
|
|
434
|
+
**Context to pass:**
|
|
435
|
+
- Path to `.forge/work/{type}/{name}/architecture/db-schema.md` (target schema)
|
|
436
|
+
- Path to current migration files (for convention matching)
|
|
437
|
+
- Schema diff summary from Phase 1
|
|
438
|
+
|
|
439
|
+
**What Codex generates:**
|
|
440
|
+
- Forward migration file (Phase 2)
|
|
441
|
+
- Rollback migration file (Phase 3)
|
|
442
|
+
- Migration README
|
|
443
|
+
|
|
444
|
+
**Prompt focus:** "Generate forward and rollback migration files matching the project's migration tool conventions. The forward migration must implement the schema diff. The rollback must reverse every forward operation. Follow the existing migration naming and style conventions."
|
|
445
|
+
|
|
446
|
+
**Presentation:** Claude reviews generated migrations for correctness, then runs the 5-step test sequence (Phase 4) regardless of who generated the migration.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Integration with Other Skills
|
|
451
|
+
|
|
452
|
+
- **plan-architecture** produces the `db-schema.md` that this skill consumes
|
|
453
|
+
- **deliver-deploy** executes the migrations this skill produces
|
|
454
|
+
- **support-debug** is invoked if migration testing reveals issues
|
|
455
|
+
- **support-gotcha** records migration lessons (especially the Docker seed issue)
|
|
456
|
+
- **quality-test-execution** verifies application behavior with the new schema
|
|
457
|
+
|
|
458
|
+
## Quick Reference
|
|
459
|
+
|
|
460
|
+
| Phase | Key Actions | Gate Criteria |
|
|
461
|
+
|---|---|---|
|
|
462
|
+
| **1. Schema Diff** | Compare current vs target, classify risk | Risk assessment complete, dangerous ops confirmed |
|
|
463
|
+
| **2. Forward Migration** | Generate migration using project's tool | Migration file created, follows standards |
|
|
464
|
+
| **3. Rollback Migration** | Generate reverse migration | Rollback exists for every forward operation |
|
|
465
|
+
| **4. Testing** | 5-step test sequence | All 5 tests pass |
|
|
466
|
+
| **5. Documentation** | Update manifest, create migration README | Manifest updated, handoff to deploy ready |
|