@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.
Files changed (213) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +389 -0
  3. package/agents/architect.md +92 -0
  4. package/agents/builder.md +122 -0
  5. package/agents/code-reviewer.md +107 -0
  6. package/agents/concept-designer.md +207 -0
  7. package/agents/craft-reviewer.md +132 -0
  8. package/agents/critic.md +130 -0
  9. package/agents/doc-writer.md +85 -0
  10. package/agents/dreamer.md +129 -0
  11. package/agents/e2e-runner.md +89 -0
  12. package/agents/gotcha-hunter.md +127 -0
  13. package/agents/prototype-builder.md +193 -0
  14. package/agents/prototype-codifier.md +204 -0
  15. package/agents/prototype-reviewer.md +163 -0
  16. package/agents/security-reviewer.md +108 -0
  17. package/agents/spec-reviewer.md +94 -0
  18. package/agents/tracer.md +98 -0
  19. package/agents/wireframer.md +109 -0
  20. package/commands/abort.md +25 -0
  21. package/commands/bugfix.md +151 -0
  22. package/commands/evolve.md +118 -0
  23. package/commands/feature.md +236 -0
  24. package/commands/forge.md +100 -0
  25. package/commands/greenfield.md +185 -0
  26. package/commands/hotfix.md +98 -0
  27. package/commands/refactor.md +147 -0
  28. package/commands/resume.md +25 -0
  29. package/commands/setup.md +201 -0
  30. package/commands/status.md +27 -0
  31. package/commands/task-force.md +110 -0
  32. package/commands/validate.md +12 -0
  33. package/dist/__tests__/active-manifest.test.js +272 -0
  34. package/dist/__tests__/copy.test.js +96 -0
  35. package/dist/__tests__/gate-check.test.js +384 -0
  36. package/dist/__tests__/wiki.test.js +472 -0
  37. package/dist/__tests__/work-manifest.test.js +304 -0
  38. package/dist/active-manifest.js +229 -0
  39. package/dist/cli.js +158 -0
  40. package/dist/copy.js +124 -0
  41. package/dist/gate-check.js +326 -0
  42. package/dist/hooks.js +60 -0
  43. package/dist/init.js +140 -0
  44. package/dist/manifest.js +90 -0
  45. package/dist/merge.js +77 -0
  46. package/dist/paths.js +36 -0
  47. package/dist/uninstall.js +216 -0
  48. package/dist/update.js +158 -0
  49. package/dist/verify-manifest.js +65 -0
  50. package/dist/verify.js +98 -0
  51. package/dist/wiki-ui.js +310 -0
  52. package/dist/wiki.js +364 -0
  53. package/dist/work-manifest.js +798 -0
  54. package/hooks/config/gate-requirements.json +79 -0
  55. package/hooks/hooks.json +143 -0
  56. package/hooks/scripts/analyze-telemetry.sh +114 -0
  57. package/hooks/scripts/gate-enforcer.sh +164 -0
  58. package/hooks/scripts/pre-compact.sh +90 -0
  59. package/hooks/scripts/session-start.sh +81 -0
  60. package/hooks/scripts/telemetry.sh +41 -0
  61. package/hooks/scripts/wiki-lint.sh +87 -0
  62. package/hooks/templates/AGENTS.md.template +48 -0
  63. package/hooks/templates/CLAUDE.md.template +45 -0
  64. package/package.json +55 -0
  65. package/protocols/README.md +40 -0
  66. package/protocols/codex.md +151 -0
  67. package/protocols/graphify.md +156 -0
  68. package/references/common/agent-coordination.md +65 -0
  69. package/references/common/coding-standards.md +54 -0
  70. package/references/common/feature-tracking.md +21 -0
  71. package/references/common/io-protocol.md +36 -0
  72. package/references/common/phases.md +57 -0
  73. package/references/common/quality-gates.md +130 -0
  74. package/references/common/skill-authoring.md +154 -0
  75. package/references/common/skill-compliance.md +30 -0
  76. package/references/python/standards.md +44 -0
  77. package/references/react/standards.md +61 -0
  78. package/references/typescript/standards.md +42 -0
  79. package/rules/common/forge-system.md +59 -0
  80. package/rules/common/git-workflow.md +40 -0
  81. package/rules/common/guardrails.md +37 -0
  82. package/rules/common/quality-gates.md +18 -0
  83. package/rules/common/security.md +50 -0
  84. package/rules/common/skill-selection.md +78 -0
  85. package/rules/common/testing.md +58 -0
  86. package/rules/common/verification.md +39 -0
  87. package/skills/build-pr-workflow/SKILL.md +301 -0
  88. package/skills/build-pr-workflow/references/pr-template.md +62 -0
  89. package/skills/build-pr-workflow/references/subagent-merge.md +47 -0
  90. package/skills/build-pr-workflow/references/worktree-setup.md +125 -0
  91. package/skills/build-prototype/SKILL.md +264 -0
  92. package/skills/build-scaffold/SKILL.md +340 -0
  93. package/skills/build-tdd/SKILL.md +89 -0
  94. package/skills/build-wireframe/SKILL.md +110 -0
  95. package/skills/build-wireframe/assets/baseline-template.html +486 -0
  96. package/skills/build-wireframe/references/demo-walkthroughs.md +170 -0
  97. package/skills/build-wireframe/references/gotchas.md +188 -0
  98. package/skills/build-wireframe/references/legend-lines.md +141 -0
  99. package/skills/concept-slides/SKILL.md +192 -0
  100. package/skills/deliver-db-migration/SKILL.md +466 -0
  101. package/skills/deliver-deploy/SKILL.md +407 -0
  102. package/skills/deliver-onboarding/SKILL.md +198 -0
  103. package/skills/deliver-onboarding/references/document-templates.md +393 -0
  104. package/skills/deliver-onboarding/templates/getting-started.md +122 -0
  105. package/skills/discover-codebase-analysis/SKILL.md +448 -0
  106. package/skills/discover-requirements/SKILL.md +418 -0
  107. package/skills/discover-requirements/templates/prd.md +99 -0
  108. package/skills/discover-requirements/templates/technical-spec.md +123 -0
  109. package/skills/discover-requirements/templates/user-stories.md +76 -0
  110. package/skills/harden/SKILL.md +214 -0
  111. package/skills/iterate-prototype/SKILL.md +241 -0
  112. package/skills/plan-architecture/SKILL.md +457 -0
  113. package/skills/plan-architecture/templates/adr-template.md +52 -0
  114. package/skills/plan-architecture/templates/api-contract.md +99 -0
  115. package/skills/plan-architecture/templates/db-schema.md +81 -0
  116. package/skills/plan-architecture/templates/system-design.md +111 -0
  117. package/skills/plan-brainstorm/SKILL.md +433 -0
  118. package/skills/plan-design-system/SKILL.md +279 -0
  119. package/skills/plan-task-decompose/SKILL.md +454 -0
  120. package/skills/quality-code-review/SKILL.md +286 -0
  121. package/skills/quality-security-audit/SKILL.md +292 -0
  122. package/skills/quality-security-audit/references/audit-report-template.md +89 -0
  123. package/skills/quality-security-audit/references/owasp-checks.md +178 -0
  124. package/skills/quality-test-execution/SKILL.md +435 -0
  125. package/skills/quality-test-plan/SKILL.md +297 -0
  126. package/skills/quality-test-plan/references/test-type-guide.md +263 -0
  127. package/skills/quality-test-plan/templates/e2e-test-plan.md +72 -0
  128. package/skills/quality-test-plan/templates/integration-test-plan.md +74 -0
  129. package/skills/quality-test-plan/templates/load-test-plan.md +111 -0
  130. package/skills/quality-test-plan/templates/smoke-test-plan.md +68 -0
  131. package/skills/quality-test-plan/templates/unit-test-plan.md +56 -0
  132. package/skills/quality-uiux/SKILL.md +481 -0
  133. package/skills/support-debug/SKILL.md +464 -0
  134. package/skills/support-dream/SKILL.md +213 -0
  135. package/skills/support-gotcha/SKILL.md +249 -0
  136. package/skills/support-runtime-reachability/SKILL.md +190 -0
  137. package/skills/support-runtime-reachability/scripts/__fixtures__/case-01-passes-app-use/src/app.ts +7 -0
  138. package/skills/support-runtime-reachability/scripts/__fixtures__/case-01-passes-app-use/src/handlers/cases.ts +7 -0
  139. package/skills/support-runtime-reachability/scripts/__fixtures__/case-02-orphan-no-app-use/src/app.ts +8 -0
  140. package/skills/support-runtime-reachability/scripts/__fixtures__/case-02-orphan-no-app-use/src/handlers/cases.ts +7 -0
  141. package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/App.tsx +5 -0
  142. package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/components/RingingBanner.tsx +7 -0
  143. package/skills/support-runtime-reachability/scripts/__fixtures__/case-03-orphan-import-only/src/hooks/useTwilio.ts +6 -0
  144. package/skills/support-runtime-reachability/scripts/__fixtures__/case-04-jsx-component-rendered/src/App.tsx +5 -0
  145. package/skills/support-runtime-reachability/scripts/__fixtures__/case-04-jsx-component-rendered/src/components/MyComp.tsx +3 -0
  146. package/skills/support-runtime-reachability/scripts/__fixtures__/case-05-jsx-component-not-rendered/src/App.tsx +3 -0
  147. package/skills/support-runtime-reachability/scripts/__fixtures__/case-05-jsx-component-not-rendered/src/components/Orphan.tsx +3 -0
  148. package/skills/support-runtime-reachability/scripts/__fixtures__/case-06-class-instantiated/src/lib/Service.ts +6 -0
  149. package/skills/support-runtime-reachability/scripts/__fixtures__/case-06-class-instantiated/src/main.ts +4 -0
  150. package/skills/support-runtime-reachability/scripts/__fixtures__/case-07-class-not-instantiated/src/lib/Lonely.ts +5 -0
  151. package/skills/support-runtime-reachability/scripts/__fixtures__/case-07-class-not-instantiated/src/main.ts +2 -0
  152. package/skills/support-runtime-reachability/scripts/__fixtures__/case-08-default-export-imported-and-called/src/handler.ts +3 -0
  153. package/skills/support-runtime-reachability/scripts/__fixtures__/case-08-default-export-imported-and-called/src/main.ts +3 -0
  154. package/skills/support-runtime-reachability/scripts/__fixtures__/case-09-default-export-orphan/src/handler.ts +3 -0
  155. package/skills/support-runtime-reachability/scripts/__fixtures__/case-09-default-export-orphan/src/main.ts +2 -0
  156. package/skills/support-runtime-reachability/scripts/__fixtures__/case-10-aliased-named-export/src/lib.ts +5 -0
  157. package/skills/support-runtime-reachability/scripts/__fixtures__/case-10-aliased-named-export/src/main.ts +3 -0
  158. package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/lib/index.ts +1 -0
  159. package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/lib/internal.ts +3 -0
  160. package/skills/support-runtime-reachability/scripts/__fixtures__/case-11-re-export-chain/src/main.ts +3 -0
  161. package/skills/support-runtime-reachability/scripts/__fixtures__/case-12-test-only-caller/src/util.test.ts +5 -0
  162. package/skills/support-runtime-reachability/scripts/__fixtures__/case-12-test-only-caller/src/util.ts +3 -0
  163. package/skills/support-runtime-reachability/scripts/__fixtures__/case-13-gated-pending-annotation/src/future.ts +4 -0
  164. package/skills/support-runtime-reachability/scripts/__fixtures__/case-14-untraceable-annotation/src/decorated.ts +4 -0
  165. package/skills/support-runtime-reachability/scripts/__fixtures__/case-15-untraceable-empty/src/lazy.ts +4 -0
  166. package/skills/support-runtime-reachability/scripts/__fixtures__/case-16-python-module/src/lib.py +15 -0
  167. package/skills/support-runtime-reachability/scripts/__fixtures__/case-16-python-module/src/main.py +5 -0
  168. package/skills/support-runtime-reachability/scripts/__fixtures__/case-17-router-use/src/parent.ts +5 -0
  169. package/skills/support-runtime-reachability/scripts/__fixtures__/case-17-router-use/src/routes/cases.ts +5 -0
  170. package/skills/support-runtime-reachability/scripts/__fixtures__/case-18-shadowed-name-fp/src/lib/foo.ts +3 -0
  171. package/skills/support-runtime-reachability/scripts/__fixtures__/case-18-shadowed-name-fp/src/other.ts +8 -0
  172. package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/handlers/cases.ts +4 -0
  173. package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/handlers/users.ts +4 -0
  174. package/skills/support-runtime-reachability/scripts/__fixtures__/case-19-same-name-different-module/src/main.ts +5 -0
  175. package/skills/support-runtime-reachability/scripts/__fixtures__/case-20-aliased-import-usage/src/handlers/cases.ts +3 -0
  176. package/skills/support-runtime-reachability/scripts/__fixtures__/case-20-aliased-import-usage/src/main.ts +4 -0
  177. package/skills/support-runtime-reachability/scripts/__fixtures__/case-21-mixed-default-and-named/src/lib.ts +5 -0
  178. package/skills/support-runtime-reachability/scripts/__fixtures__/case-21-mixed-default-and-named/src/main.ts +5 -0
  179. package/skills/support-runtime-reachability/scripts/__fixtures__/case-22-dynamic-import-then-caller/src/lib.ts +3 -0
  180. package/skills/support-runtime-reachability/scripts/__fixtures__/case-22-dynamic-import-then-caller/src/main.ts +8 -0
  181. package/skills/support-runtime-reachability/scripts/__fixtures__/case-23-dynamic-import-with-space/src/lib.ts +3 -0
  182. package/skills/support-runtime-reachability/scripts/__fixtures__/case-23-dynamic-import-with-space/src/main.ts +7 -0
  183. package/skills/support-runtime-reachability/scripts/check.mjs +638 -0
  184. package/skills/support-runtime-reachability/scripts/check.test.mjs +244 -0
  185. package/skills/support-skill-validator/SKILL.md +194 -0
  186. package/skills/support-skill-validator/references/false-positives.md +59 -0
  187. package/skills/support-skill-validator/references/validation-checks.md +280 -0
  188. package/skills/support-system-guide/SKILL.md +311 -0
  189. package/skills/support-task-force/SKILL.md +265 -0
  190. package/skills/support-task-force/references/dispatch-pattern.md +178 -0
  191. package/skills/support-task-force/references/synthesis-template.md +126 -0
  192. package/skills/support-wiki-bootstrap/SKILL.md +37 -0
  193. package/skills/support-wiki-lint/SKILL.md +196 -0
  194. package/skills/support-wiki-lint/scripts/lint.mjs +488 -0
  195. package/skills/support-wiki-lint/scripts/lint.test.mjs +196 -0
  196. package/templates/README.md +23 -0
  197. package/templates/aiwiki/CLAUDE.md.template +78 -0
  198. package/templates/aiwiki/schemas/architecture.md +118 -0
  199. package/templates/aiwiki/schemas/convention.md +112 -0
  200. package/templates/aiwiki/schemas/decision.md +144 -0
  201. package/templates/aiwiki/schemas/gotcha.md +118 -0
  202. package/templates/aiwiki/schemas/oracle.md +105 -0
  203. package/templates/aiwiki/schemas/session.md +125 -0
  204. package/templates/manifests/bugfix.yaml +41 -0
  205. package/templates/manifests/feature.yaml +69 -0
  206. package/templates/manifests/greenfield.yaml +61 -0
  207. package/templates/manifests/hotfix.yaml +45 -0
  208. package/templates/manifests/refactor.yaml +44 -0
  209. package/templates/manifests/v5/SCHEMA.md +327 -0
  210. package/templates/manifests/v5/feature.yaml +77 -0
  211. package/templates/manifests/v6/SCHEMA.md +199 -0
  212. package/templates/wiki-html/dream-detail.html +378 -0
  213. 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 |