@cleocode/skills 2.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/dispatch-config.json +404 -0
- package/index.d.ts +178 -0
- package/index.js +405 -0
- package/package.json +14 -0
- package/profiles/core.json +7 -0
- package/profiles/full.json +10 -0
- package/profiles/minimal.json +7 -0
- package/profiles/recommended.json +7 -0
- package/provider-skills-map.json +97 -0
- package/skills/_shared/cleo-style-guide.md +84 -0
- package/skills/_shared/manifest-operations.md +810 -0
- package/skills/_shared/placeholders.json +433 -0
- package/skills/_shared/skill-chaining-patterns.md +237 -0
- package/skills/_shared/subagent-protocol-base.md +223 -0
- package/skills/_shared/task-system-integration.md +232 -0
- package/skills/_shared/testing-framework-config.md +110 -0
- package/skills/ct-cleo/SKILL.md +490 -0
- package/skills/ct-cleo/references/anti-patterns.md +19 -0
- package/skills/ct-cleo/references/loom-lifecycle.md +136 -0
- package/skills/ct-cleo/references/orchestrator-constraints.md +55 -0
- package/skills/ct-cleo/references/session-protocol.md +162 -0
- package/skills/ct-codebase-mapper/SKILL.md +82 -0
- package/skills/ct-contribution/SKILL.md +521 -0
- package/skills/ct-contribution/templates/contribution-init.json +21 -0
- package/skills/ct-dev-workflow/SKILL.md +423 -0
- package/skills/ct-docs-lookup/SKILL.md +66 -0
- package/skills/ct-docs-review/SKILL.md +175 -0
- package/skills/ct-docs-write/SKILL.md +108 -0
- package/skills/ct-documentor/SKILL.md +231 -0
- package/skills/ct-epic-architect/SKILL.md +305 -0
- package/skills/ct-epic-architect/references/bug-epic-example.md +172 -0
- package/skills/ct-epic-architect/references/commands.md +201 -0
- package/skills/ct-epic-architect/references/feature-epic-example.md +210 -0
- package/skills/ct-epic-architect/references/migration-epic-example.md +244 -0
- package/skills/ct-epic-architect/references/output-format.md +92 -0
- package/skills/ct-epic-architect/references/patterns.md +284 -0
- package/skills/ct-epic-architect/references/refactor-epic-example.md +412 -0
- package/skills/ct-epic-architect/references/research-epic-example.md +226 -0
- package/skills/ct-epic-architect/references/shell-escaping.md +86 -0
- package/skills/ct-epic-architect/references/skill-aware-execution.md +195 -0
- package/skills/ct-grade/SKILL.md +230 -0
- package/skills/ct-grade/agents/analysis-reporter.md +203 -0
- package/skills/ct-grade/agents/blind-comparator.md +157 -0
- package/skills/ct-grade/agents/scenario-runner.md +134 -0
- package/skills/ct-grade/eval-viewer/__pycache__/generate_grade_review.cpython-314.pyc +0 -0
- package/skills/ct-grade/eval-viewer/generate_grade_review.py +1138 -0
- package/skills/ct-grade/eval-viewer/generate_grade_viewer.py +544 -0
- package/skills/ct-grade/eval-viewer/generate_review.py +283 -0
- package/skills/ct-grade/eval-viewer/grade-review.html +1574 -0
- package/skills/ct-grade/eval-viewer/viewer.html +219 -0
- package/skills/ct-grade/evals/evals.json +94 -0
- package/skills/ct-grade/references/ab-test-methodology.md +150 -0
- package/skills/ct-grade/references/domains.md +137 -0
- package/skills/ct-grade/references/grade-spec.md +236 -0
- package/skills/ct-grade/references/scenario-playbook.md +234 -0
- package/skills/ct-grade/references/token-tracking.md +120 -0
- package/skills/ct-grade/scripts/__pycache__/audit_analyzer.cpython-314.pyc +0 -0
- package/skills/ct-grade/scripts/__pycache__/run_ab_test.cpython-314.pyc +0 -0
- package/skills/ct-grade/scripts/__pycache__/run_all.cpython-314.pyc +0 -0
- package/skills/ct-grade/scripts/__pycache__/token_tracker.cpython-314.pyc +0 -0
- package/skills/ct-grade/scripts/audit_analyzer.py +279 -0
- package/skills/ct-grade/scripts/generate_report.py +283 -0
- package/skills/ct-grade/scripts/run_ab_test.py +504 -0
- package/skills/ct-grade/scripts/run_all.py +287 -0
- package/skills/ct-grade/scripts/setup_run.py +183 -0
- package/skills/ct-grade/scripts/token_tracker.py +630 -0
- package/skills/ct-grade-v2-1/SKILL.md +237 -0
- package/skills/ct-grade-v2-1/agents/analysis-reporter.md +203 -0
- package/skills/ct-grade-v2-1/agents/blind-comparator.md +157 -0
- package/skills/ct-grade-v2-1/agents/scenario-runner.md +179 -0
- package/skills/ct-grade-v2-1/evals/evals.json +74 -0
- package/skills/ct-grade-v2-1/grade-viewer/__pycache__/build_op_stats.cpython-314.pyc +0 -0
- package/skills/ct-grade-v2-1/grade-viewer/__pycache__/generate_grade_review.cpython-314.pyc +0 -0
- package/skills/ct-grade-v2-1/grade-viewer/build_op_stats.py +174 -0
- package/skills/ct-grade-v2-1/grade-viewer/eval-analysis.json +41 -0
- package/skills/ct-grade-v2-1/grade-viewer/eval-report.md +34 -0
- package/skills/ct-grade-v2-1/grade-viewer/generate_grade_review.py +1023 -0
- package/skills/ct-grade-v2-1/grade-viewer/generate_grade_viewer.py +548 -0
- package/skills/ct-grade-v2-1/grade-viewer/grade-review-eval.html +613 -0
- package/skills/ct-grade-v2-1/grade-viewer/grade-review.html +1532 -0
- package/skills/ct-grade-v2-1/grade-viewer/viewer.html +620 -0
- package/skills/ct-grade-v2-1/manifest-entry.json +31 -0
- package/skills/ct-grade-v2-1/references/ab-testing.md +233 -0
- package/skills/ct-grade-v2-1/references/domains-ssot.md +156 -0
- package/skills/ct-grade-v2-1/references/grade-spec-v2.md +167 -0
- package/skills/ct-grade-v2-1/references/playbook-v2.md +393 -0
- package/skills/ct-grade-v2-1/references/token-tracking.md +202 -0
- package/skills/ct-grade-v2-1/scripts/generate_report.py +419 -0
- package/skills/ct-grade-v2-1/scripts/run_ab_test.py +493 -0
- package/skills/ct-grade-v2-1/scripts/run_scenario.py +396 -0
- package/skills/ct-grade-v2-1/scripts/setup_run.py +207 -0
- package/skills/ct-grade-v2-1/scripts/token_tracker.py +175 -0
- package/skills/ct-memory/SKILL.md +84 -0
- package/skills/ct-orchestrator/INSTALL.md +61 -0
- package/skills/ct-orchestrator/README.md +69 -0
- package/skills/ct-orchestrator/SKILL.md +380 -0
- package/skills/ct-orchestrator/manifest-entry.json +19 -0
- package/skills/ct-orchestrator/orchestrator-prompt.txt +17 -0
- package/skills/ct-orchestrator/references/SUBAGENT-PROTOCOL-BLOCK.md +66 -0
- package/skills/ct-orchestrator/references/autonomous-operation.md +167 -0
- package/skills/ct-orchestrator/references/lifecycle-gates.md +98 -0
- package/skills/ct-orchestrator/references/orchestrator-compliance.md +271 -0
- package/skills/ct-orchestrator/references/orchestrator-handoffs.md +85 -0
- package/skills/ct-orchestrator/references/orchestrator-patterns.md +164 -0
- package/skills/ct-orchestrator/references/orchestrator-recovery.md +113 -0
- package/skills/ct-orchestrator/references/orchestrator-spawning.md +271 -0
- package/skills/ct-orchestrator/references/orchestrator-tokens.md +180 -0
- package/skills/ct-research-agent/SKILL.md +226 -0
- package/skills/ct-skill-creator/.cleo/.context-state.json +13 -0
- package/skills/ct-skill-creator/.cleo/logs/cleo.2026-03-07.1.log +24 -0
- package/skills/ct-skill-creator/.cleo/tasks.db +0 -0
- package/skills/ct-skill-creator/SKILL.md +356 -0
- package/skills/ct-skill-creator/agents/analyzer.md +276 -0
- package/skills/ct-skill-creator/agents/comparator.md +204 -0
- package/skills/ct-skill-creator/agents/grader.md +225 -0
- package/skills/ct-skill-creator/assets/eval_review.html +146 -0
- package/skills/ct-skill-creator/eval-viewer/__pycache__/generate_review.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/ct-skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/ct-skill-creator/manifest-entry.json +17 -0
- package/skills/ct-skill-creator/references/dynamic-context.md +228 -0
- package/skills/ct-skill-creator/references/frontmatter.md +83 -0
- package/skills/ct-skill-creator/references/invocation-control.md +165 -0
- package/skills/ct-skill-creator/references/output-patterns.md +86 -0
- package/skills/ct-skill-creator/references/provider-deployment.md +175 -0
- package/skills/ct-skill-creator/references/schemas.md +430 -0
- package/skills/ct-skill-creator/references/workflows.md +28 -0
- package/skills/ct-skill-creator/scripts/__init__.py +1 -0
- package/skills/ct-skill-creator/scripts/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/aggregate_benchmark.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/generate_report.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/improve_description.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/init_skill.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/quick_validate.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/run_eval.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/run_loop.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/__pycache__/utils.cpython-314.pyc +0 -0
- package/skills/ct-skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/ct-skill-creator/scripts/generate_report.py +326 -0
- package/skills/ct-skill-creator/scripts/improve_description.py +247 -0
- package/skills/ct-skill-creator/scripts/init_skill.py +306 -0
- package/skills/ct-skill-creator/scripts/package_skill.py +110 -0
- package/skills/ct-skill-creator/scripts/quick_validate.py +97 -0
- package/skills/ct-skill-creator/scripts/run_eval.py +310 -0
- package/skills/ct-skill-creator/scripts/run_loop.py +328 -0
- package/skills/ct-skill-creator/scripts/utils.py +47 -0
- package/skills/ct-skill-validator/SKILL.md +178 -0
- package/skills/ct-skill-validator/agents/ecosystem-checker.md +151 -0
- package/skills/ct-skill-validator/assets/valid-skill-example.md +13 -0
- package/skills/ct-skill-validator/evals/eval_set.json +14 -0
- package/skills/ct-skill-validator/evals/evals.json +52 -0
- package/skills/ct-skill-validator/manifest-entry.json +20 -0
- package/skills/ct-skill-validator/references/cleo-ecosystem-rules.md +163 -0
- package/skills/ct-skill-validator/references/validation-rules.md +168 -0
- package/skills/ct-skill-validator/scripts/__init__.py +0 -0
- package/skills/ct-skill-validator/scripts/__pycache__/audit_body.cpython-314.pyc +0 -0
- package/skills/ct-skill-validator/scripts/__pycache__/check_ecosystem.cpython-314.pyc +0 -0
- package/skills/ct-skill-validator/scripts/__pycache__/generate_validation_report.cpython-314.pyc +0 -0
- package/skills/ct-skill-validator/scripts/__pycache__/validate.cpython-314.pyc +0 -0
- package/skills/ct-skill-validator/scripts/audit_body.py +242 -0
- package/skills/ct-skill-validator/scripts/check_ecosystem.py +169 -0
- package/skills/ct-skill-validator/scripts/check_manifest.py +172 -0
- package/skills/ct-skill-validator/scripts/generate_validation_report.py +442 -0
- package/skills/ct-skill-validator/scripts/validate.py +422 -0
- package/skills/ct-spec-writer/SKILL.md +189 -0
- package/skills/ct-stickynote/README.md +14 -0
- package/skills/ct-stickynote/SKILL.md +46 -0
- package/skills/ct-task-executor/SKILL.md +296 -0
- package/skills/ct-validator/SKILL.md +216 -0
- package/skills/manifest.json +469 -0
- package/skills.json +281 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Migration Epic Example: Database Schema Migration with Rollback
|
|
2
|
+
|
|
3
|
+
This example demonstrates a multi-phase migration epic with safety checkpoints and rollback capability.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Scenario
|
|
8
|
+
|
|
9
|
+
Application needs to migrate from single-tenant to multi-tenant schema:
|
|
10
|
+
- Add `tenant_id` to all relevant tables
|
|
11
|
+
- Update all queries to include tenant context
|
|
12
|
+
- Maintain backwards compatibility during rollout
|
|
13
|
+
- Enable rollback at each phase
|
|
14
|
+
|
|
15
|
+
**Risk Level**: High (production data, requires rollback plan)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Step 1: Create the Migration Epic
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
{{TASK_ADD_CMD}} "EPIC: Multi-Tenant Schema Migration" \
|
|
23
|
+
--type epic \
|
|
24
|
+
--size large \
|
|
25
|
+
--priority high \
|
|
26
|
+
--phase core \
|
|
27
|
+
--labels "migration,database,multi-tenant,v2.0" \
|
|
28
|
+
--description "Migrate from single-tenant to multi-tenant schema. Phases: (1) Schema changes with dual-write, (2) Data backfill, (3) Query migration, (4) Cleanup. Each phase has rollback capability. Zero downtime required." \
|
|
29
|
+
--acceptance "All tables have tenant_id" \
|
|
30
|
+
--acceptance "All queries tenant-aware" \
|
|
31
|
+
--acceptance "Rollback tested at each phase" \
|
|
32
|
+
--acceptance "Zero data loss" \
|
|
33
|
+
--acceptance "Zero downtime" \
|
|
34
|
+
--notes "Migration plan approved by DBA. Target: Q1 2026."
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Annotation**: Migration epics are `large` due to multi-phase nature. Labels include `migration` for filtering. Acceptance criteria emphasize safety (rollback, zero data loss).
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Step 2: Create Tasks by Phase
|
|
42
|
+
|
|
43
|
+
### Phase A: Schema Preparation (Wave 0)
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# T1: Add nullable tenant_id columns (Wave 0)
|
|
47
|
+
{{TASK_ADD_CMD}} "Add nullable tenant_id columns to tables" \
|
|
48
|
+
--type task \
|
|
49
|
+
--size medium \
|
|
50
|
+
--priority high \
|
|
51
|
+
--parent {{EPIC_ID}} \
|
|
52
|
+
--phase setup \
|
|
53
|
+
--labels "migration,schema,phase-a" \
|
|
54
|
+
--description "Add tenant_id column as NULLABLE to users, projects, tasks tables. Create index. No application changes yet." \
|
|
55
|
+
--acceptance "Columns added to all tables" \
|
|
56
|
+
--acceptance "Indexes created" \
|
|
57
|
+
--acceptance "Existing queries still work" \
|
|
58
|
+
--files "migrations/001_add_tenant_id.sql"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Annotation**: First migration task is ADDITIVE ONLY. Never modify existing columns in Wave 0.
|
|
62
|
+
|
|
63
|
+
### Phase B: Dual-Write Implementation (Wave 1)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# T2: Implement dual-write logic (Wave 1 - depends on T1)
|
|
67
|
+
{{TASK_ADD_CMD}} "Implement dual-write for tenant_id" \
|
|
68
|
+
--type task \
|
|
69
|
+
--size medium \
|
|
70
|
+
--priority high \
|
|
71
|
+
--parent {{EPIC_ID}} \
|
|
72
|
+
--phase core \
|
|
73
|
+
--depends {{T1_ID}} \
|
|
74
|
+
--labels "migration,dual-write,phase-b" \
|
|
75
|
+
--description "Update write operations to populate tenant_id from context. Existing data unchanged. New records get tenant_id." \
|
|
76
|
+
--acceptance "New records have tenant_id populated" \
|
|
77
|
+
--acceptance "Existing records unchanged" \
|
|
78
|
+
--acceptance "Feature flag controls dual-write" \
|
|
79
|
+
--files "src/lib/db/tenant-context.ts,src/lib/db/models/*.ts"
|
|
80
|
+
|
|
81
|
+
# T3: Create rollback procedure for Phase B (Wave 1 - parallel with T2)
|
|
82
|
+
{{TASK_ADD_CMD}} "Create Phase B rollback procedure" \
|
|
83
|
+
--type task \
|
|
84
|
+
--size small \
|
|
85
|
+
--priority high \
|
|
86
|
+
--parent {{EPIC_ID}} \
|
|
87
|
+
--phase core \
|
|
88
|
+
--depends {{T1_ID}} \
|
|
89
|
+
--labels "migration,rollback,phase-b" \
|
|
90
|
+
--description "Document and test rollback: disable dual-write flag, verify system functions without tenant_id writes." \
|
|
91
|
+
--acceptance "Rollback procedure documented" \
|
|
92
|
+
--acceptance "Rollback tested in staging" \
|
|
93
|
+
--files "docs/migration/phase-b-rollback.md"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Phase C: Data Backfill (Wave 2)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# T4: Backfill existing data (Wave 2 - depends on T2, T3)
|
|
100
|
+
{{TASK_ADD_CMD}} "Backfill tenant_id for existing records" \
|
|
101
|
+
--type task \
|
|
102
|
+
--size large \
|
|
103
|
+
--priority high \
|
|
104
|
+
--parent {{EPIC_ID}} \
|
|
105
|
+
--phase core \
|
|
106
|
+
--depends {{T2_ID}},{{T3_ID}} \
|
|
107
|
+
--labels "migration,backfill,phase-c" \
|
|
108
|
+
--description "Batch update existing records to populate tenant_id based on ownership rules. Use batched updates to avoid locks. Verify completeness." \
|
|
109
|
+
--acceptance "All records have tenant_id" \
|
|
110
|
+
--acceptance "No NULL tenant_id remaining" \
|
|
111
|
+
--acceptance "Backfill script idempotent" \
|
|
112
|
+
--files "scripts/backfill-tenant-id.ts,migrations/002_backfill_tenant.sql"
|
|
113
|
+
|
|
114
|
+
# T5: Validate backfill completeness (Wave 2 - depends on T4)
|
|
115
|
+
{{TASK_ADD_CMD}} "Validate backfill completeness" \
|
|
116
|
+
--type task \
|
|
117
|
+
--size small \
|
|
118
|
+
--priority high \
|
|
119
|
+
--parent {{EPIC_ID}} \
|
|
120
|
+
--phase testing \
|
|
121
|
+
--depends {{T4_ID}} \
|
|
122
|
+
--labels "migration,validation,phase-c" \
|
|
123
|
+
--description "Run validation queries to ensure no NULL tenant_id remains. Compare record counts pre/post migration." \
|
|
124
|
+
--acceptance "Zero NULL tenant_id records" \
|
|
125
|
+
--acceptance "Record counts match" \
|
|
126
|
+
--files "scripts/validate-migration.ts"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Phase D: Query Migration (Wave 3)
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# T6: Update read queries to use tenant context (Wave 3 - depends on T5)
|
|
133
|
+
{{TASK_ADD_CMD}} "Update queries to include tenant context" \
|
|
134
|
+
--type task \
|
|
135
|
+
--size medium \
|
|
136
|
+
--priority high \
|
|
137
|
+
--parent {{EPIC_ID}} \
|
|
138
|
+
--phase core \
|
|
139
|
+
--depends {{T5_ID}} \
|
|
140
|
+
--labels "migration,queries,phase-d" \
|
|
141
|
+
--description "Update all database queries to filter by tenant_id from context. Use repository pattern for consistency." \
|
|
142
|
+
--acceptance "All queries filter by tenant" \
|
|
143
|
+
--acceptance "No cross-tenant data leakage" \
|
|
144
|
+
--acceptance "Query performance acceptable" \
|
|
145
|
+
--files "src/lib/db/repositories/*.ts"
|
|
146
|
+
|
|
147
|
+
# T7: Security audit for tenant isolation (Wave 3 - parallel with T6)
|
|
148
|
+
{{TASK_ADD_CMD}} "Audit tenant isolation" \
|
|
149
|
+
--type task \
|
|
150
|
+
--size medium \
|
|
151
|
+
--priority critical \
|
|
152
|
+
--parent {{EPIC_ID}} \
|
|
153
|
+
--phase testing \
|
|
154
|
+
--depends {{T5_ID}} \
|
|
155
|
+
--labels "migration,security,audit,phase-d" \
|
|
156
|
+
--description "Security audit: verify no query paths can access cross-tenant data. Test with multiple tenant contexts." \
|
|
157
|
+
--acceptance "No cross-tenant data access possible" \
|
|
158
|
+
--acceptance "Security review documented" \
|
|
159
|
+
--files "docs/security/tenant-isolation-audit.md"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Phase E: Cleanup (Wave 4 - Final)
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# T8: Make tenant_id NOT NULL (Wave 4 - depends on T6, T7)
|
|
166
|
+
{{TASK_ADD_CMD}} "Enforce NOT NULL constraint on tenant_id" \
|
|
167
|
+
--type task \
|
|
168
|
+
--size small \
|
|
169
|
+
--priority medium \
|
|
170
|
+
--parent {{EPIC_ID}} \
|
|
171
|
+
--phase polish \
|
|
172
|
+
--depends {{T6_ID}},{{T7_ID}} \
|
|
173
|
+
--labels "migration,schema,cleanup,phase-e" \
|
|
174
|
+
--description "After validation, add NOT NULL constraint to tenant_id columns. Point of no easy rollback." \
|
|
175
|
+
--acceptance "NOT NULL constraint added" \
|
|
176
|
+
--acceptance "No constraint violations" \
|
|
177
|
+
--files "migrations/003_enforce_tenant_not_null.sql"
|
|
178
|
+
|
|
179
|
+
# T9: Remove feature flags and legacy code (Wave 4 - depends on T8)
|
|
180
|
+
{{TASK_ADD_CMD}} "Remove migration feature flags" \
|
|
181
|
+
--type task \
|
|
182
|
+
--size small \
|
|
183
|
+
--priority low \
|
|
184
|
+
--parent {{EPIC_ID}} \
|
|
185
|
+
--phase polish \
|
|
186
|
+
--depends {{T8_ID}} \
|
|
187
|
+
--labels "migration,cleanup,phase-e" \
|
|
188
|
+
--description "Remove dual-write feature flags, legacy single-tenant code paths. Document migration completion." \
|
|
189
|
+
--acceptance "Feature flags removed" \
|
|
190
|
+
--acceptance "Legacy code removed" \
|
|
191
|
+
--acceptance "Migration documented as complete" \
|
|
192
|
+
--files "src/lib/db/models/*.ts,docs/migration/completion.md"
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Step 3: Start Session
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
{{TASK_SESSION_START_CMD}} \
|
|
201
|
+
--scope epic:{{EPIC_ID}} \
|
|
202
|
+
--name "Multi-Tenant Migration" \
|
|
203
|
+
--agent ct-epic-architect \
|
|
204
|
+
--auto-start
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Dependency Graph
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
T1 (Add Columns)
|
|
213
|
+
├──> T2 (Dual-Write)
|
|
214
|
+
│ └──> T4 (Backfill)
|
|
215
|
+
│ └──> T5 (Validate)
|
|
216
|
+
│ ├──> T6 (Update Queries)
|
|
217
|
+
│ │ └──> T8 (NOT NULL)
|
|
218
|
+
│ │ └──> T9 (Cleanup)
|
|
219
|
+
│ └──> T7 (Security Audit)
|
|
220
|
+
│ └──> T8 (NOT NULL)
|
|
221
|
+
└──> T3 (Rollback Procedure)
|
|
222
|
+
└──> T4 (Backfill)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Migration Phases Summary
|
|
228
|
+
|
|
229
|
+
| Phase | Tasks | Rollback | Risk |
|
|
230
|
+
|-------|-------|----------|------|
|
|
231
|
+
| A: Schema | T1 | Drop columns | Low |
|
|
232
|
+
| B: Dual-Write | T2, T3 | Disable flag | Low |
|
|
233
|
+
| C: Backfill | T4, T5 | Restore backup | Medium |
|
|
234
|
+
| D: Queries | T6, T7 | Revert code | Medium |
|
|
235
|
+
| E: Cleanup | T8, T9 | Complex restore | High |
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Critical Safety Notes
|
|
240
|
+
|
|
241
|
+
1. **Each phase has checkpoint**: Don't proceed until validation passes
|
|
242
|
+
2. **Rollback tested before proceeding**: T3 creates rollback before T4 executes
|
|
243
|
+
3. **Security audit before cleanup**: T7 must pass before T8 (NOT NULL)
|
|
244
|
+
4. **Point of no return**: T8 (NOT NULL) is difficult to rollback - ensure confidence
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Epic Output File Format
|
|
2
|
+
|
|
3
|
+
Template for epic creation output files.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Output File Location
|
|
8
|
+
|
|
9
|
+
Write to `{{OUTPUT_DIR}}/{{DATE}}_epic-{{FEATURE_SLUG}}.md`
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Template
|
|
14
|
+
|
|
15
|
+
```markdown
|
|
16
|
+
# Epic: {{EPIC_TITLE}}
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
| Field | Value |
|
|
21
|
+
|-------|-------|
|
|
22
|
+
| Epic ID | {{EPIC_ID}} |
|
|
23
|
+
| Parent | {{PARENT_ID or "None (root)"}} |
|
|
24
|
+
| Phase | {{PHASE}} |
|
|
25
|
+
| Size | large |
|
|
26
|
+
| Priority | {{PRIORITY}} |
|
|
27
|
+
| Labels | {{LABELS}} |
|
|
28
|
+
|
|
29
|
+
## Description
|
|
30
|
+
|
|
31
|
+
{{EPIC_DESCRIPTION}}
|
|
32
|
+
|
|
33
|
+
## Task Breakdown
|
|
34
|
+
|
|
35
|
+
| ID | Title | Type | Size | Phase | Depends | Ready |
|
|
36
|
+
|----|-------|------|------|-------|---------|-------|
|
|
37
|
+
| {{EPIC_ID}} | {{EPIC_TITLE}} | epic | large | {{PHASE}} | - | - |
|
|
38
|
+
| {{T1_ID}} | {{T1_TITLE}} | task | {{SIZE}} | {{PHASE}} | - | Yes |
|
|
39
|
+
| {{T2_ID}} | {{T2_TITLE}} | task | {{SIZE}} | {{PHASE}} | {{T1_ID}} | No |
|
|
40
|
+
| {{T3_ID}} | {{T3_TITLE}} | task | {{SIZE}} | {{PHASE}} | {{T1_ID}} | No |
|
|
41
|
+
| {{T4_ID}} | {{T4_TITLE}} | task | {{SIZE}} | {{PHASE}} | {{T2_ID}},{{T3_ID}} | No |
|
|
42
|
+
| {{T5_ID}} | {{T5_TITLE}} | task | {{SIZE}} | {{PHASE}} | {{T4_ID}} | No |
|
|
43
|
+
|
|
44
|
+
## Dependency Graph
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
{{T1_ID}}
|
|
48
|
+
├──> {{T2_ID}}
|
|
49
|
+
│ └──> {{T4_ID}}
|
|
50
|
+
└──> {{T3_ID}}
|
|
51
|
+
└──> {{T4_ID}}
|
|
52
|
+
└──> {{T5_ID}}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Critical Path
|
|
56
|
+
|
|
57
|
+
{{T1_ID}} → {{T2_ID}} → {{T4_ID}} → {{T5_ID}}
|
|
58
|
+
|
|
59
|
+
(T3 runs parallel to T2, both converge at T4)
|
|
60
|
+
|
|
61
|
+
## Parallel Opportunities (Wave Analysis)
|
|
62
|
+
|
|
63
|
+
| Wave | Tasks | Can Parallelize |
|
|
64
|
+
|------|-------|-----------------|
|
|
65
|
+
| 0 | {{T1_ID}} | - |
|
|
66
|
+
| 1 | {{T2_ID}}, {{T3_ID}} | Yes (independent) |
|
|
67
|
+
| 2 | {{T4_ID}} | No (convergence) |
|
|
68
|
+
| 3 | {{T5_ID}} | No (final) |
|
|
69
|
+
|
|
70
|
+
## Session Started
|
|
71
|
+
|
|
72
|
+
- Session ID: {{SESSION_ID}}
|
|
73
|
+
- Scope: `epic:{{EPIC_ID}}`
|
|
74
|
+
- First Ready Task: {{T1_ID}}
|
|
75
|
+
|
|
76
|
+
## Acceptance Criteria
|
|
77
|
+
|
|
78
|
+
1. All child tasks completed
|
|
79
|
+
2. Integration tests pass
|
|
80
|
+
3. Documentation updated
|
|
81
|
+
4. Code reviewed and merged
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Manifest Entry Format
|
|
87
|
+
|
|
88
|
+
Append ONE line (no pretty-printing) to `{{MANIFEST_PATH}}`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{"id":"epic-{{FEATURE_SLUG}}-{{DATE}}","file":"{{DATE}}_epic-{{FEATURE_SLUG}}.md","title":"Epic Created: {{FEATURE_NAME}}","date":"{{DATE}}","status":"complete","topics":["epic","planning","{{DOMAIN}}"],"key_findings":["Created Epic {{EPIC_ID}} with {{N}} child tasks","Dependency chain: {{T1}} -> {{T2}}/{{T3}} -> {{T4}} -> {{T5}}","Wave 0 (parallel start): [{{T1_ID}}]","Wave 1 (parallel): [{{T2_ID}}, {{T3_ID}}]","Critical path: {{T1}} -> {{T2}} -> {{T4}} -> {{T5}}","Session started: {{SESSION_ID}}"],"actionable":true,"needs_followup":["{{FIRST_READY_TASK_ID}}"],"linked_tasks":["{{EPIC_ID}}","{{ALL_TASK_IDS}}"]}
|
|
92
|
+
```
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Epic Patterns Reference
|
|
2
|
+
|
|
3
|
+
Detailed patterns for specialized epic types.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Research Epic Pattern
|
|
8
|
+
|
|
9
|
+
When the work type is classified as research:
|
|
10
|
+
|
|
11
|
+
### Research Wave Structure
|
|
12
|
+
|
|
13
|
+
| Wave | Task Type | Purpose |
|
|
14
|
+
|------|-----------|---------|
|
|
15
|
+
| Wave 0 | Scope Definition | Define research questions, boundaries, success criteria |
|
|
16
|
+
| Wave 1+ | Investigation (parallel) | Multiple parallel investigation tasks for sources/aspects |
|
|
17
|
+
| Final Wave | Synthesis | Aggregate findings, create recommendations, link to future work |
|
|
18
|
+
|
|
19
|
+
### Research Epic Types
|
|
20
|
+
|
|
21
|
+
| Type | When | Structure |
|
|
22
|
+
|------|------|-----------|
|
|
23
|
+
| Exploratory | Investigating unknowns | Questions -> Literature + Alternatives + Feasibility -> Synthesis -> Recommendations |
|
|
24
|
+
| Decision | Comparing options | Criteria -> Option A + B + C (parallel) -> Matrix -> Recommendation |
|
|
25
|
+
| Codebase Analysis | Understanding existing code | Architecture -> Dependencies + Data Flows -> Pain Points -> Improvements |
|
|
26
|
+
|
|
27
|
+
### Research-Specific Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Initialize research outputs directory
|
|
31
|
+
{{TASK_RESEARCH_INIT_CMD}}
|
|
32
|
+
|
|
33
|
+
# Create research epic with research-specific labels
|
|
34
|
+
{{TASK_ADD_CMD}} "Research: {{TOPIC}}" \
|
|
35
|
+
--type epic \
|
|
36
|
+
--size medium \
|
|
37
|
+
--labels "research,{{TYPE}},{{DOMAIN}}" \
|
|
38
|
+
--phase core \
|
|
39
|
+
--description "Research questions: ..." \
|
|
40
|
+
--acceptance "Findings documented in research outputs; Recommendations actionable"
|
|
41
|
+
|
|
42
|
+
# Query prior research before starting
|
|
43
|
+
{{TASK_RESEARCH_LIST_CMD}} --status complete --topic {{DOMAIN}}
|
|
44
|
+
{{TASK_RESEARCH_SHOW_CMD}} {{ID}} # Key findings only
|
|
45
|
+
{{TASK_RESEARCH_PENDING_CMD}} # Incomplete work
|
|
46
|
+
|
|
47
|
+
# Link research to task after completion
|
|
48
|
+
{{TASK_LINK_CMD}} {{TASK_ID}} {{RESEARCH_ID}}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Research Task Atomicity
|
|
52
|
+
|
|
53
|
+
Each research task SHOULD address exactly ONE research question:
|
|
54
|
+
- **Good**: "What authentication options exist for SvelteKit?"
|
|
55
|
+
- **Bad**: "Research authentication and authorization"
|
|
56
|
+
|
|
57
|
+
### Research Output Integration
|
|
58
|
+
|
|
59
|
+
- Subagents write findings to `{{OUTPUT_DIR}}/`
|
|
60
|
+
- Subagents append entry to `{{MANIFEST_PATH}}` with `linked_tasks: ["{{TASK_ID}}"]`
|
|
61
|
+
- Orchestrator reads only manifest summaries (key_findings) for context efficiency
|
|
62
|
+
- Use `{{TASK_RESEARCH_INJECT_CMD}}` to get subagent protocol block
|
|
63
|
+
|
|
64
|
+
### Synthesis vs Investigation Tasks
|
|
65
|
+
|
|
66
|
+
| Type | Parallel? | Dependencies | Output |
|
|
67
|
+
|------|-----------|--------------|--------|
|
|
68
|
+
| Investigation | Yes | Scope definition only | Raw findings |
|
|
69
|
+
| Synthesis | No | All investigation tasks | Conclusions, recommendations |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Bug Epic Pattern
|
|
74
|
+
|
|
75
|
+
When work is classified as bug fix:
|
|
76
|
+
|
|
77
|
+
### Bug Severity to Priority Mapping
|
|
78
|
+
|
|
79
|
+
| Severity | Priority | Indicators |
|
|
80
|
+
|----------|----------|------------|
|
|
81
|
+
| Critical | critical | Data loss, security, system down |
|
|
82
|
+
| High | high | Core feature broken, workaround difficult |
|
|
83
|
+
| Medium | medium | Feature degraded, workaround exists |
|
|
84
|
+
| Low | low | Cosmetic, edge case |
|
|
85
|
+
|
|
86
|
+
### Bug Wave Structure
|
|
87
|
+
|
|
88
|
+
| Wave | Task Type | Purpose |
|
|
89
|
+
|------|-----------|---------|
|
|
90
|
+
| Wave 0 | Investigation | Root cause analysis |
|
|
91
|
+
| Wave 1 | Fix | Implement solution |
|
|
92
|
+
| Wave 2 | Regression Test | Verify fix, add test coverage |
|
|
93
|
+
|
|
94
|
+
### Bug-Specific Labels
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
{{TASK_ADD_CMD}} "Fix: {{BUG_DESCRIPTION}}" \
|
|
98
|
+
--type epic \
|
|
99
|
+
--labels "bug,severity:{{LEVEL}},{{DOMAIN}}" \
|
|
100
|
+
--priority {{MAPPED_PRIORITY}}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Brownfield Epic Pattern
|
|
106
|
+
|
|
107
|
+
When working in existing codebases (refactoring, modernization, migrations):
|
|
108
|
+
|
|
109
|
+
### Brownfield vs Greenfield Classification
|
|
110
|
+
|
|
111
|
+
| Indicator | Greenfield | Brownfield |
|
|
112
|
+
|-----------|------------|------------|
|
|
113
|
+
| Code exists | No | Yes |
|
|
114
|
+
| Tests exist | No | May exist |
|
|
115
|
+
| Users exist | No | Yes (production impact) |
|
|
116
|
+
| Rollback needed | No | Yes (critical) |
|
|
117
|
+
| Dependencies | None | Many (existing systems) |
|
|
118
|
+
|
|
119
|
+
### Brownfield Wave 0: Impact Analysis (MANDATORY)
|
|
120
|
+
|
|
121
|
+
**Every brownfield epic MUST start with impact analysis:**
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# T1: Impact analysis task (Wave 0)
|
|
125
|
+
{{TASK_ADD_CMD}} "Analyze impact and dependencies" \
|
|
126
|
+
--type task \
|
|
127
|
+
--size medium \
|
|
128
|
+
--priority critical \
|
|
129
|
+
--parent {{EPIC_ID}} \
|
|
130
|
+
--phase setup \
|
|
131
|
+
--labels "brownfield,analysis,wave-0" \
|
|
132
|
+
--description "Document all files, functions, and integration points affected. Create dependency graph. Identify external systems." \
|
|
133
|
+
--acceptance "Dependency map documented" \
|
|
134
|
+
--acceptance "All integration points identified" \
|
|
135
|
+
--acceptance "Risk areas flagged"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Brownfield Wave 0: Regression Baseline (MANDATORY)
|
|
139
|
+
|
|
140
|
+
**Create tests BEFORE any modifications:**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# T2: Regression baseline task (Wave 0)
|
|
144
|
+
{{TASK_ADD_CMD}} "Create regression test baseline" \
|
|
145
|
+
--type task \
|
|
146
|
+
--size medium \
|
|
147
|
+
--priority high \
|
|
148
|
+
--parent {{EPIC_ID}} \
|
|
149
|
+
--phase setup \
|
|
150
|
+
--labels "brownfield,testing,wave-0,regression-risk" \
|
|
151
|
+
--description "Write tests for ALL current behaviors BEFORE changes. These verify no regressions during work." \
|
|
152
|
+
--acceptance "Current behavior fully tested" \
|
|
153
|
+
--acceptance "Edge cases covered" \
|
|
154
|
+
--acceptance "Tests pass against current code"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Brownfield Safety Patterns
|
|
158
|
+
|
|
159
|
+
| Pattern | Purpose | Implementation |
|
|
160
|
+
|---------|---------|----------------|
|
|
161
|
+
| **Strangler Fig** | Gradual replacement | New code parallel to legacy, shift traffic gradually |
|
|
162
|
+
| **Feature Flags** | Rollback capability | Gate new behavior, instant rollback |
|
|
163
|
+
| **Dual-Write** | Data migration safety | Write to both old/new, verify consistency |
|
|
164
|
+
| **Shadow Mode** | Risk-free testing | New code runs but doesn't affect users |
|
|
165
|
+
|
|
166
|
+
### Brownfield-Specific Labels
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
--labels "brownfield,refactor,regression-risk"
|
|
170
|
+
--labels "brownfield,migration,rollback-checkpoint"
|
|
171
|
+
--labels "brownfield,cleanup,tech-debt"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Rollback Checkpoints
|
|
175
|
+
|
|
176
|
+
Every brownfield epic MUST document rollback at each wave:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Rollback documentation task (parallel with implementation)
|
|
180
|
+
{{TASK_ADD_CMD}} "Document Wave N rollback procedure" \
|
|
181
|
+
--type task \
|
|
182
|
+
--size small \
|
|
183
|
+
--priority high \
|
|
184
|
+
--parent {{EPIC_ID}} \
|
|
185
|
+
--labels "brownfield,rollback" \
|
|
186
|
+
--description "Document and test rollback procedure for this wave. Must be tested in staging." \
|
|
187
|
+
--acceptance "Rollback procedure documented" \
|
|
188
|
+
--acceptance "Tested in staging environment"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Brownfield Verification Gates
|
|
192
|
+
|
|
193
|
+
After brownfield task completion:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Regression tests still pass
|
|
197
|
+
{{TASK_VERIFY_CMD}} {{TASK_ID}} --gate testsPassed
|
|
198
|
+
|
|
199
|
+
# Cleanup/tech debt addressed
|
|
200
|
+
{{TASK_VERIFY_CMD}} {{TASK_ID}} --gate cleanupDone
|
|
201
|
+
|
|
202
|
+
# Security review for auth/data changes
|
|
203
|
+
{{TASK_VERIFY_CMD}} {{TASK_ID}} --gate securityPassed
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Brownfield Anti-Patterns
|
|
207
|
+
|
|
208
|
+
| Anti-Pattern | Problem | Solution |
|
|
209
|
+
|--------------|---------|----------|
|
|
210
|
+
| **Big-bang cutover** | High risk, no rollback | Gradual migration with feature flags |
|
|
211
|
+
| **No regression tests** | Can't verify no breakage | Baseline tests before any changes |
|
|
212
|
+
| **Undocumented rollback** | Stuck if issues arise | Document rollback at each phase |
|
|
213
|
+
| **Modifying and testing together** | Tests may pass broken code | Tests first, then modifications |
|
|
214
|
+
|
|
215
|
+
**See [refactor-epic-example.md](refactor-epic-example.md) for complete brownfield refactoring example.**
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Refactor Epic Pattern
|
|
220
|
+
|
|
221
|
+
For code modernization, architectural improvements, and tech debt reduction:
|
|
222
|
+
|
|
223
|
+
### Refactor Wave Structure
|
|
224
|
+
|
|
225
|
+
| Wave | Task Type | Purpose |
|
|
226
|
+
|------|-----------|---------|
|
|
227
|
+
| Wave 0 | Impact Analysis + Regression Baseline | Understand scope, create safety net |
|
|
228
|
+
| Wave 1 | New Implementation (parallel) | Build new code alongside legacy |
|
|
229
|
+
| Wave 2 | Adapter/Integration | Create bridge between old and new |
|
|
230
|
+
| Wave 3 | Gradual Migration | Shift traffic/users incrementally |
|
|
231
|
+
| Wave 4 | Validation + Cleanup | Verify migration, remove legacy |
|
|
232
|
+
|
|
233
|
+
### Refactor Safety Rules
|
|
234
|
+
|
|
235
|
+
1. **Never modify existing code in Wave 0** - Analysis only
|
|
236
|
+
2. **New code is ADDITIVE in Wave 1** - Don't touch legacy yet
|
|
237
|
+
3. **Feature flags control all behavior changes** - Instant rollback
|
|
238
|
+
4. **Test rollback at every phase** - Before production deployment
|
|
239
|
+
5. **Remove legacy code LAST** - Only after validation complete
|
|
240
|
+
|
|
241
|
+
### Refactor-Specific Commands
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Create refactor epic with lifecycle tracking
|
|
245
|
+
{{TASK_ADD_CMD}} "EPIC: Refactor {{COMPONENT}}" \
|
|
246
|
+
--type epic \
|
|
247
|
+
--size large \
|
|
248
|
+
--priority high \
|
|
249
|
+
--epic-lifecycle planning \
|
|
250
|
+
--labels "refactor,brownfield,{{DOMAIN}}" \
|
|
251
|
+
--description "Modernize {{COMPONENT}}. Strangler fig pattern with feature flags." \
|
|
252
|
+
--acceptance "New implementation complete" \
|
|
253
|
+
--acceptance "All users migrated" \
|
|
254
|
+
--acceptance "Legacy code removed" \
|
|
255
|
+
--acceptance "Rollback tested at each phase"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**See [refactor-epic-example.md](refactor-epic-example.md) for complete example.**
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Task Naming Conventions
|
|
263
|
+
|
|
264
|
+
### Pattern: "{Verb} {Object} {Qualifier}"
|
|
265
|
+
|
|
266
|
+
**Good:**
|
|
267
|
+
- "Create user authentication schema"
|
|
268
|
+
- "Implement JWT validation middleware"
|
|
269
|
+
- "Write integration tests for auth flow"
|
|
270
|
+
- "Add error handling to API endpoints"
|
|
271
|
+
|
|
272
|
+
**Bad:**
|
|
273
|
+
- "Auth stuff"
|
|
274
|
+
- "Part 1"
|
|
275
|
+
- "Fix things"
|
|
276
|
+
- "TBD item"
|
|
277
|
+
|
|
278
|
+
### Numbered Sequences
|
|
279
|
+
|
|
280
|
+
For clearly sequential work:
|
|
281
|
+
- "1. Define data model"
|
|
282
|
+
- "2. Create API endpoints"
|
|
283
|
+
- "3. Build UI components"
|
|
284
|
+
- "4. Add integration tests"
|