@atlashub/smartstack-cli 1.35.0 → 1.36.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/package.json +1 -1
- package/templates/skills/_shared.md +7 -7
- package/templates/skills/application/steps/step-04-backend.md +17 -17
- package/templates/skills/application/steps/step-05-frontend.md +4 -1
- package/templates/skills/application/templates-backend.md +8 -8
- package/templates/skills/application/templates-frontend.md +8 -8
- package/templates/skills/gitflow/_shared.md +188 -53
- package/templates/skills/gitflow/phases/abort.md +28 -16
- package/templates/skills/gitflow/phases/cleanup.md +13 -9
- package/templates/skills/gitflow/phases/status.md +16 -17
- package/templates/skills/gitflow/steps/step-commit.md +11 -5
- package/templates/skills/gitflow/steps/step-finish.md +43 -33
- package/templates/skills/gitflow/steps/step-init.md +7 -2
- package/templates/skills/gitflow/steps/step-merge.md +24 -10
- package/templates/skills/gitflow/steps/step-pr.md +42 -28
- package/templates/skills/gitflow/steps/step-start.md +19 -13
- package/templates/skills/gitflow/templates/config.json +7 -4
- package/templates/skills/ralph-loop/SKILL.md +57 -11
- package/templates/skills/ralph-loop/steps/step-00-init.md +170 -30
- package/templates/skills/ralph-loop/steps/step-01-task.md +243 -40
- package/templates/skills/ralph-loop/steps/step-02-execute.md +142 -24
- package/templates/skills/ralph-loop/steps/step-03-commit.md +140 -36
- package/templates/skills/ralph-loop/steps/step-04-check.md +128 -44
- package/templates/skills/ralph-loop/steps/step-05-report.md +175 -88
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: step-01-task
|
|
3
|
-
description: Load or create tasks from prd.json
|
|
3
|
+
description: Load or create tasks from prd.json (v2 schema)
|
|
4
4
|
next_step: steps/step-02-execute.md
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ next_step: steps/step-02-execute.md
|
|
|
8
8
|
|
|
9
9
|
## YOUR TASK:
|
|
10
10
|
|
|
11
|
-
Load the current task from prd.json or create initial task breakdown.
|
|
11
|
+
Load the current task from prd.json or create initial task breakdown with categories, dependencies, and acceptance criteria.
|
|
12
12
|
|
|
13
13
|
**ULTRA THINK about task decomposition.**
|
|
14
14
|
|
|
@@ -20,9 +20,9 @@ Load the current task from prd.json or create initial task breakdown.
|
|
|
20
20
|
|
|
21
21
|
**If `.ralph/prd.json` exists:**
|
|
22
22
|
- Read and parse the file
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- Skip to step
|
|
23
|
+
- Verify `$version` is `"2.0.0"` (if not, STOP - run step-00 migration first)
|
|
24
|
+
- Find the next eligible task (see step 5)
|
|
25
|
+
- Skip to step 5
|
|
26
26
|
|
|
27
27
|
**If `.ralph/prd.json` does NOT exist:**
|
|
28
28
|
- Continue to step 2 (create tasks)
|
|
@@ -35,42 +35,162 @@ Load the current task from prd.json or create initial task breakdown.
|
|
|
35
35
|
- What order should they be executed?
|
|
36
36
|
- What are the success criteria for each?
|
|
37
37
|
- What files will be modified?
|
|
38
|
+
- What layer does each task belong to?
|
|
39
|
+
- What dependencies exist between tasks?
|
|
40
|
+
|
|
41
|
+
**Check for BA handoff source:**
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# If a handoff document exists, use it to derive tasks
|
|
45
|
+
HANDOFF=$(find . -path "*development-handoff*" -name "*.md" | head -1)
|
|
46
|
+
BA_OUTPUT=$(find . -path ".claude/output/ba/*" -name "4-*.md" | head -1)
|
|
47
|
+
SOURCE_PATH=${HANDOFF:-$BA_OUTPUT}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**If handoff found:**
|
|
51
|
+
- Read the handoff document
|
|
52
|
+
- Derive tasks from its specifications (per-layer breakdown)
|
|
53
|
+
- Set `source.type = "ba-handoff"` and `source.handoff_path`
|
|
54
|
+
- Look for FRD and BRD in the same directory
|
|
55
|
+
|
|
56
|
+
**If no handoff:**
|
|
57
|
+
- Generate task breakdown from `{task_description}`
|
|
58
|
+
- Set `source = null`
|
|
38
59
|
|
|
39
60
|
**Generate task breakdown:**
|
|
40
61
|
|
|
41
|
-
For `{task_description}`, identify 3-
|
|
62
|
+
For `{task_description}`, identify **3-30 subtasks** organized by category.
|
|
63
|
+
|
|
64
|
+
**Task categories (use SmartStack layer order):**
|
|
65
|
+
|
|
66
|
+
| Category | Description | Examples |
|
|
67
|
+
|----------|-------------|---------|
|
|
68
|
+
| `domain` | Domain entities and value objects | Create entities, enums, interfaces |
|
|
69
|
+
| `application` | CQRS handlers, DTOs, validators | Commands, Queries, DTOs, FluentValidation |
|
|
70
|
+
| `infrastructure` | EF Core, external services | DbContext configs, migrations, services |
|
|
71
|
+
| `api` | Controllers, middleware | REST endpoints, filters, middleware |
|
|
72
|
+
| `frontend` | React pages, components, hooks | Pages, API services, React Query hooks |
|
|
73
|
+
| `i18n` | Translations | Translation JSON files |
|
|
74
|
+
| `test` | Unit and integration tests | xUnit tests, React testing library |
|
|
75
|
+
| `validation` | Build, lint, MCP checks | dotnet build, pnpm build, MCP validate |
|
|
76
|
+
| `other` | Anything else | Documentation, configuration |
|
|
42
77
|
|
|
43
78
|
**Example for "implement user authentication":**
|
|
44
79
|
```json
|
|
45
80
|
{
|
|
46
81
|
"tasks": [
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
82
|
+
{
|
|
83
|
+
"id": 1,
|
|
84
|
+
"description": "Create User entity in SmartStack.Domain/Entities/Business/",
|
|
85
|
+
"status": "pending",
|
|
86
|
+
"category": "domain",
|
|
87
|
+
"dependencies": [],
|
|
88
|
+
"acceptance_criteria": "Entity compiles with all required properties per handoff spec"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": 2,
|
|
92
|
+
"description": "Add User DbSet to ApplicationDbContext and create EF Core configuration",
|
|
93
|
+
"status": "pending",
|
|
94
|
+
"category": "infrastructure",
|
|
95
|
+
"dependencies": [1],
|
|
96
|
+
"acceptance_criteria": "DbContext compiles, configuration maps all properties"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"id": 3,
|
|
100
|
+
"description": "Create EF Core migration for User table",
|
|
101
|
+
"status": "pending",
|
|
102
|
+
"category": "infrastructure",
|
|
103
|
+
"dependencies": [2],
|
|
104
|
+
"acceptance_criteria": "Migration applies without errors, 3 files present"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"id": 4,
|
|
108
|
+
"description": "Implement IPasswordService and IJwtService",
|
|
109
|
+
"status": "pending",
|
|
110
|
+
"category": "application",
|
|
111
|
+
"dependencies": [1],
|
|
112
|
+
"acceptance_criteria": "Services compile, follow existing patterns"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": 5,
|
|
116
|
+
"description": "Create CQRS Commands: LoginCommand + RegisterCommand with handlers",
|
|
117
|
+
"status": "pending",
|
|
118
|
+
"category": "application",
|
|
119
|
+
"dependencies": [4],
|
|
120
|
+
"acceptance_criteria": "Handlers compile, validators defined"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"id": 6,
|
|
124
|
+
"description": "Create AuthController with login/register endpoints",
|
|
125
|
+
"status": "pending",
|
|
126
|
+
"category": "api",
|
|
127
|
+
"dependencies": [5],
|
|
128
|
+
"acceptance_criteria": "Endpoints respond correctly, Swagger displays them"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": 7,
|
|
132
|
+
"description": "Write unit tests for User entity and validators",
|
|
133
|
+
"status": "pending",
|
|
134
|
+
"category": "test",
|
|
135
|
+
"dependencies": [5],
|
|
136
|
+
"acceptance_criteria": "All tests pass, >80% coverage on new code"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": 8,
|
|
140
|
+
"description": "Run dotnet build, dotnet test, MCP validate_conventions",
|
|
141
|
+
"status": "pending",
|
|
142
|
+
"category": "validation",
|
|
143
|
+
"dependencies": [6, 7],
|
|
144
|
+
"acceptance_criteria": "Build succeeds, all tests pass, MCP validation clean"
|
|
145
|
+
}
|
|
55
146
|
]
|
|
56
147
|
}
|
|
57
148
|
```
|
|
58
149
|
|
|
59
|
-
|
|
150
|
+
**Task count validation:**
|
|
151
|
+
- MINIMUM: 3 tasks (anything less is too coarse)
|
|
152
|
+
- MAXIMUM: 30 tasks (anything more needs re-grouping)
|
|
153
|
+
- If over 30, merge related subtasks into larger units
|
|
154
|
+
|
|
155
|
+
### 3. Create prd.json (v2)
|
|
60
156
|
|
|
61
157
|
**Write `.ralph/prd.json`:**
|
|
62
158
|
|
|
63
159
|
```json
|
|
64
160
|
{
|
|
161
|
+
"$version": "2.0.0",
|
|
65
162
|
"feature": "{task_description}",
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
163
|
+
"status": "in_progress",
|
|
164
|
+
"created": "{ISO_TIMESTAMP}",
|
|
165
|
+
"updated_at": "{ISO_TIMESTAMP}",
|
|
166
|
+
"metadata": {metadata},
|
|
167
|
+
"config": {
|
|
168
|
+
"max_iterations": {max_iterations},
|
|
169
|
+
"completion_promise": "{completion_promise}",
|
|
170
|
+
"current_iteration": 1
|
|
171
|
+
},
|
|
172
|
+
"source": {source_object_or_null},
|
|
173
|
+
"tasks": [{generated_tasks_with_all_fields}],
|
|
174
|
+
"history": []
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**IMPORTANT: Every task MUST have ALL fields:**
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"id": 1,
|
|
182
|
+
"description": "...",
|
|
183
|
+
"status": "pending",
|
|
184
|
+
"category": "domain|application|infrastructure|api|frontend|i18n|test|validation|other",
|
|
185
|
+
"dependencies": [],
|
|
186
|
+
"acceptance_criteria": "...",
|
|
187
|
+
"started_at": null,
|
|
188
|
+
"completed_at": null,
|
|
189
|
+
"iteration": null,
|
|
190
|
+
"commit_hash": null,
|
|
191
|
+
"files_changed": { "created": [], "modified": [] },
|
|
192
|
+
"validation": null,
|
|
193
|
+
"error": null
|
|
74
194
|
}
|
|
75
195
|
```
|
|
76
196
|
|
|
@@ -81,6 +201,8 @@ For `{task_description}`, identify 3-10 subtasks.
|
|
|
81
201
|
|
|
82
202
|
## Task: {task_description}
|
|
83
203
|
## Started: {timestamp}
|
|
204
|
+
## Schema: v2.0.0
|
|
205
|
+
## Source: {source_type or "direct"}
|
|
84
206
|
|
|
85
207
|
---
|
|
86
208
|
|
|
@@ -93,27 +215,102 @@ Starting fresh implementation.
|
|
|
93
215
|
(To be updated after each iteration)
|
|
94
216
|
```
|
|
95
217
|
|
|
96
|
-
### 4.
|
|
218
|
+
### 4. Validate Task Integrity
|
|
97
219
|
|
|
98
|
-
**
|
|
220
|
+
**After creation, verify:**
|
|
99
221
|
|
|
100
222
|
```javascript
|
|
101
|
-
|
|
223
|
+
// Check all tasks have required fields
|
|
224
|
+
const requiredFields = ['id', 'description', 'status', 'category',
|
|
225
|
+
'dependencies', 'acceptance_criteria', 'started_at', 'completed_at',
|
|
226
|
+
'iteration', 'commit_hash', 'files_changed', 'validation', 'error'];
|
|
227
|
+
|
|
228
|
+
for (const task of prd.tasks) {
|
|
229
|
+
for (const field of requiredFields) {
|
|
230
|
+
if (!(field in task)) {
|
|
231
|
+
ERROR: "Task ${task.id} missing field: ${field}";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check dependency references are valid
|
|
237
|
+
const taskIds = prd.tasks.map(t => t.id);
|
|
238
|
+
for (const task of prd.tasks) {
|
|
239
|
+
for (const dep of task.dependencies) {
|
|
240
|
+
if (!taskIds.includes(dep)) {
|
|
241
|
+
ERROR: "Task ${task.id} depends on non-existent task ${dep}";
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Check no circular dependencies
|
|
247
|
+
// (simple: a task cannot depend on a task with higher or equal id)
|
|
248
|
+
for (const task of prd.tasks) {
|
|
249
|
+
for (const dep of task.dependencies) {
|
|
250
|
+
if (dep >= task.id) {
|
|
251
|
+
ERROR: "Task ${task.id} has forward/circular dependency on task ${dep}";
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Check task count
|
|
257
|
+
if (prd.tasks.length < 3 || prd.tasks.length > 30) {
|
|
258
|
+
WARNING: "Task count ${prd.tasks.length} outside recommended range (3-30)";
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 5. Find Current Task
|
|
263
|
+
|
|
264
|
+
**Find the next eligible task:**
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
function findNextTask(tasks) {
|
|
268
|
+
for (const task of tasks) {
|
|
269
|
+
if (task.status !== 'pending') continue;
|
|
270
|
+
|
|
271
|
+
// Check all dependencies are completed
|
|
272
|
+
const depsOk = task.dependencies.every(depId => {
|
|
273
|
+
const dep = tasks.find(t => t.id === depId);
|
|
274
|
+
return dep && dep.status === 'completed';
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Check if any dependency failed (→ block this task)
|
|
278
|
+
const depsBlocked = task.dependencies.some(depId => {
|
|
279
|
+
const dep = tasks.find(t => t.id === depId);
|
|
280
|
+
return dep && (dep.status === 'failed' || dep.status === 'blocked');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
if (depsBlocked) {
|
|
284
|
+
task.status = 'blocked';
|
|
285
|
+
task.error = `Blocked by failed dependency`;
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (depsOk) return task;
|
|
290
|
+
}
|
|
291
|
+
return null; // No eligible tasks
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const currentTask = findNextTask(prd.tasks);
|
|
102
295
|
```
|
|
103
296
|
|
|
104
|
-
**If
|
|
105
|
-
-
|
|
106
|
-
-
|
|
297
|
+
**If no eligible task found:**
|
|
298
|
+
- Check if all tasks are completed → skip to step-05 (report)
|
|
299
|
+
- Check if remaining tasks are all blocked → report as partial, step-05
|
|
300
|
+
- Otherwise → unexpected state, STOP
|
|
107
301
|
|
|
108
302
|
**Store in state:**
|
|
109
303
|
```
|
|
110
304
|
{current_task_id} = currentTask.id
|
|
111
305
|
{current_task_description} = currentTask.description
|
|
112
|
-
{
|
|
306
|
+
{current_task_category} = currentTask.category
|
|
307
|
+
{current_task_criteria} = currentTask.acceptance_criteria
|
|
308
|
+
{tasks_completed} = tasks.filter(t => t.status === 'completed').length
|
|
113
309
|
{tasks_total} = tasks.length
|
|
310
|
+
{tasks_blocked} = tasks.filter(t => t.status === 'blocked').length
|
|
114
311
|
```
|
|
115
312
|
|
|
116
|
-
###
|
|
313
|
+
### 6. Read Previous Progress
|
|
117
314
|
|
|
118
315
|
**If iteration > 1:**
|
|
119
316
|
|
|
@@ -123,23 +320,26 @@ Read `.ralph/progress.txt` to understand:
|
|
|
123
320
|
- Files that were modified
|
|
124
321
|
- Issues encountered
|
|
125
322
|
|
|
126
|
-
**
|
|
323
|
+
**Also read `history[]` from prd.json for structured context.**
|
|
127
324
|
|
|
128
|
-
###
|
|
325
|
+
### 7. Show Task Status
|
|
129
326
|
|
|
130
327
|
**Display current state:**
|
|
131
328
|
|
|
132
329
|
```
|
|
133
330
|
╔══════════════════════════════════════════════════════════════════╗
|
|
134
|
-
║ ITERATION {current_iteration} / {max_iterations}
|
|
331
|
+
║ ITERATION {current_iteration} / {max_iterations} ║
|
|
135
332
|
╠══════════════════════════════════════════════════════════════════╣
|
|
136
|
-
║ Progress: {tasks_completed} / {tasks_total} tasks complete
|
|
137
|
-
║
|
|
138
|
-
║
|
|
139
|
-
║
|
|
333
|
+
║ Progress: {tasks_completed} / {tasks_total} tasks complete ║
|
|
334
|
+
║ Blocked: {tasks_blocked} ║
|
|
335
|
+
║ ║
|
|
336
|
+
║ Current Task: ║
|
|
337
|
+
║ [{current_task_id}] {current_task_description} ║
|
|
338
|
+
║ Category: {current_task_category} ║
|
|
339
|
+
║ Criteria: {current_task_criteria} ║
|
|
140
340
|
╠══════════════════════════════════════════════════════════════════╣
|
|
141
|
-
║ Previous Learnings:
|
|
142
|
-
║ {summary from progress.txt}
|
|
341
|
+
║ Previous Learnings: ║
|
|
342
|
+
║ {summary from progress.txt} ║
|
|
143
343
|
╚══════════════════════════════════════════════════════════════════╝
|
|
144
344
|
|
|
145
345
|
-> Executing task...
|
|
@@ -157,7 +357,10 @@ Task Loaded:
|
|
|
157
357
|
| Iteration | {current_iteration} / {max_iterations} |
|
|
158
358
|
| Task ID | {current_task_id} |
|
|
159
359
|
| Task | {current_task_description} |
|
|
360
|
+
| Category | {current_task_category} |
|
|
361
|
+
| Criteria | {current_task_criteria} |
|
|
160
362
|
| Progress | {tasks_completed} / {tasks_total} |
|
|
363
|
+
| Blocked | {tasks_blocked} |
|
|
161
364
|
|
|
162
365
|
-> Executing...
|
|
163
366
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: step-02-execute
|
|
3
|
-
description: Execute ONE task
|
|
3
|
+
description: Execute ONE task with dependency checks and rich tracking
|
|
4
4
|
next_step: steps/step-03-commit.md
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -20,21 +20,68 @@ Execute exactly ONE task from prd.json. Do NOT batch multiple tasks.
|
|
|
20
20
|
2. **ATOMIC CHANGES** - Changes should be complete and working
|
|
21
21
|
3. **USE MCP** - Validate with SmartStack MCP as needed
|
|
22
22
|
4. **DOCUMENT** - Track what you're doing
|
|
23
|
+
5. **CHECK DEPENDENCIES** - Verify all dependencies are met before starting
|
|
24
|
+
6. **TRACK FILES** - Record every file created or modified
|
|
23
25
|
|
|
24
26
|
---
|
|
25
27
|
|
|
26
28
|
## EXECUTION SEQUENCE:
|
|
27
29
|
|
|
28
|
-
### 1.
|
|
30
|
+
### 1. Verify Dependencies
|
|
31
|
+
|
|
32
|
+
**BEFORE starting, check all dependencies are satisfied:**
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const prd = readJSON('.ralph/prd.json');
|
|
36
|
+
const task = prd.tasks.find(t => t.id === {current_task_id});
|
|
37
|
+
|
|
38
|
+
for (const depId of task.dependencies) {
|
|
39
|
+
const dep = prd.tasks.find(t => t.id === depId);
|
|
40
|
+
if (!dep || dep.status !== 'completed') {
|
|
41
|
+
echo `❌ BLOCKED: Task ${task.id} depends on task ${depId} (status: ${dep?.status || 'missing'})`;
|
|
42
|
+
task.status = 'blocked';
|
|
43
|
+
task.error = `Dependency task ${depId} not completed (${dep?.status})`;
|
|
44
|
+
writeJSON('.ralph/prd.json', prd);
|
|
45
|
+
STOP - return to step-01 to find next eligible task
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Mark Task as In-Progress
|
|
51
|
+
|
|
52
|
+
**Update prd.json immediately:**
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
task.status = 'in_progress';
|
|
56
|
+
task.started_at = new Date().toISOString();
|
|
57
|
+
prd.updated_at = task.started_at;
|
|
58
|
+
writeJSON('.ralph/prd.json', prd);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 3. Understand the Task
|
|
29
62
|
|
|
30
63
|
**ULTRA THINK:**
|
|
31
64
|
|
|
32
65
|
- What exactly needs to be done?
|
|
33
66
|
- What files need to be created/modified?
|
|
34
|
-
- What are the
|
|
67
|
+
- What are the acceptance criteria? → `{current_task_criteria}`
|
|
35
68
|
- What patterns should be followed?
|
|
69
|
+
- What category is this? → `{current_task_category}`
|
|
70
|
+
|
|
71
|
+
**Category-specific guidance:**
|
|
36
72
|
|
|
37
|
-
|
|
73
|
+
| Category | MCP Tools | Patterns |
|
|
74
|
+
|----------|-----------|----------|
|
|
75
|
+
| `domain` | `validate_conventions` | Entity base class, IHasData, audit fields |
|
|
76
|
+
| `application` | `validate_conventions`, `scaffold_extension` | CQRS, MediatR, FluentValidation |
|
|
77
|
+
| `infrastructure` | `check_migrations`, `suggest_migration` | EF Core config, HasData seeding |
|
|
78
|
+
| `api` | `scaffold_routes`, `validate_security` | Controller conventions, authorization |
|
|
79
|
+
| `frontend` | `validate_frontend_routes`, `scaffold_frontend_extension` | React patterns, hooks |
|
|
80
|
+
| `i18n` | - | 4-language JSON structure |
|
|
81
|
+
| `test` | `scaffold_tests`, `analyze_test_coverage` | xUnit, test naming conventions |
|
|
82
|
+
| `validation` | `validate_conventions` | Build, test, lint checks |
|
|
83
|
+
|
|
84
|
+
### 4. Explore Context (if needed)
|
|
38
85
|
|
|
39
86
|
**Use subagents sparingly:**
|
|
40
87
|
|
|
@@ -50,7 +97,7 @@ If exploration needed:
|
|
|
50
97
|
- Grep for code search
|
|
51
98
|
- Read for file contents
|
|
52
99
|
|
|
53
|
-
###
|
|
100
|
+
### 5. Execute Implementation
|
|
54
101
|
|
|
55
102
|
**Implement the task:**
|
|
56
103
|
|
|
@@ -60,6 +107,13 @@ If exploration needed:
|
|
|
60
107
|
- Add appropriate logging
|
|
61
108
|
- Handle errors properly
|
|
62
109
|
|
|
110
|
+
**Track every file operation:**
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
{files_created} = [] // Accumulate as you create files
|
|
114
|
+
{files_modified} = [] // Accumulate as you modify files
|
|
115
|
+
```
|
|
116
|
+
|
|
63
117
|
**Use TodoWrite to track sub-steps:**
|
|
64
118
|
|
|
65
119
|
```
|
|
@@ -69,32 +123,68 @@ If task has multiple parts:
|
|
|
69
123
|
3. Mark completed when done
|
|
70
124
|
```
|
|
71
125
|
|
|
72
|
-
###
|
|
126
|
+
### 6. Validate with MCP
|
|
73
127
|
|
|
74
|
-
**After implementation, validate:**
|
|
128
|
+
**After implementation, validate based on category:**
|
|
75
129
|
|
|
76
130
|
```
|
|
131
|
+
# Always run general validation
|
|
77
132
|
mcp__smartstack__validate_conventions:
|
|
78
133
|
checks: ["all"]
|
|
134
|
+
|
|
135
|
+
# Category-specific validation
|
|
136
|
+
if category == "infrastructure":
|
|
137
|
+
mcp__smartstack__check_migrations
|
|
138
|
+
|
|
139
|
+
if category == "api":
|
|
140
|
+
mcp__smartstack__validate_security
|
|
141
|
+
|
|
142
|
+
if category == "frontend":
|
|
143
|
+
mcp__smartstack__validate_frontend_routes
|
|
144
|
+
|
|
145
|
+
if category == "test":
|
|
146
|
+
mcp__smartstack__analyze_test_coverage
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Record validation result:**
|
|
150
|
+
```
|
|
151
|
+
{validation_result} = "passed" | "failed: {reason}"
|
|
79
152
|
```
|
|
80
153
|
|
|
81
154
|
**If validation fails:**
|
|
82
155
|
- Fix the issues
|
|
83
156
|
- Re-validate
|
|
84
157
|
- Do NOT proceed until valid
|
|
158
|
+
- If cannot fix: set `{validation_result} = "failed: {reason}"`
|
|
159
|
+
|
|
160
|
+
### 7. Check Acceptance Criteria
|
|
161
|
+
|
|
162
|
+
**Verify against `{current_task_criteria}`:**
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
ULTRA THINK: Does the implementation satisfy the acceptance criteria?
|
|
166
|
+
|
|
167
|
+
Criteria: {current_task_criteria}
|
|
168
|
+
|
|
169
|
+
✅ Met / ❌ Not met (explain why)
|
|
170
|
+
```
|
|
85
171
|
|
|
86
|
-
|
|
172
|
+
**If criteria NOT met:**
|
|
173
|
+
- Continue working until met
|
|
174
|
+
- If impossible to meet: document in `{task_error}`
|
|
175
|
+
|
|
176
|
+
### 8. Run Quick Tests
|
|
87
177
|
|
|
88
178
|
**If applicable:**
|
|
89
179
|
|
|
90
180
|
```bash
|
|
91
|
-
# For backend changes
|
|
92
|
-
dotnet build
|
|
181
|
+
# For backend changes (domain, application, infrastructure, api)
|
|
182
|
+
dotnet build --no-restore 2>&1
|
|
93
183
|
|
|
94
184
|
# For frontend changes
|
|
95
185
|
npm run lint && npm run typecheck
|
|
96
186
|
|
|
97
|
-
# For
|
|
187
|
+
# For test category
|
|
98
188
|
dotnet test --filter "FullyQualifiedName~{relevant_test}"
|
|
99
189
|
```
|
|
100
190
|
|
|
@@ -103,17 +193,33 @@ dotnet test --filter "FullyQualifiedName~{relevant_test}"
|
|
|
103
193
|
- Re-run until passing
|
|
104
194
|
- Document what was fixed
|
|
105
195
|
|
|
106
|
-
###
|
|
196
|
+
### 9. Update Task State in prd.json
|
|
107
197
|
|
|
108
|
-
**
|
|
198
|
+
**Persist tracking data BEFORE committing:**
|
|
109
199
|
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
200
|
+
```javascript
|
|
201
|
+
const prd = readJSON('.ralph/prd.json');
|
|
202
|
+
const task = prd.tasks.find(t => t.id === {current_task_id});
|
|
203
|
+
|
|
204
|
+
task.files_changed = {
|
|
205
|
+
created: {files_created},
|
|
206
|
+
modified: {files_modified}
|
|
207
|
+
};
|
|
208
|
+
task.validation = {validation_result};
|
|
209
|
+
|
|
210
|
+
// If task failed
|
|
211
|
+
if ({task_failed}) {
|
|
212
|
+
task.status = 'failed';
|
|
213
|
+
task.error = '{failure_reason}';
|
|
214
|
+
task.completed_at = new Date().toISOString();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
prd.updated_at = new Date().toISOString();
|
|
218
|
+
writeJSON('.ralph/prd.json', prd);
|
|
115
219
|
```
|
|
116
220
|
|
|
221
|
+
**Note: `task.status` stays `"in_progress"` until step-03 confirms the commit. Only `"failed"` is set here if the task cannot be completed.**
|
|
222
|
+
|
|
117
223
|
---
|
|
118
224
|
|
|
119
225
|
## IMPORTANT CONSTRAINTS:
|
|
@@ -121,7 +227,9 @@ dotnet test --filter "FullyQualifiedName~{relevant_test}"
|
|
|
121
227
|
### What TO DO:
|
|
122
228
|
- Implement exactly what the task describes
|
|
123
229
|
- Follow existing patterns
|
|
124
|
-
- Validate changes
|
|
230
|
+
- Validate changes with MCP
|
|
231
|
+
- Track all file operations
|
|
232
|
+
- Check acceptance criteria
|
|
125
233
|
- Write minimal, clean code
|
|
126
234
|
|
|
127
235
|
### What NOT TO DO:
|
|
@@ -129,6 +237,7 @@ dotnet test --filter "FullyQualifiedName~{relevant_test}"
|
|
|
129
237
|
- Don't refactor unrelated code
|
|
130
238
|
- Don't add "nice to have" features
|
|
131
239
|
- Don't skip validation
|
|
240
|
+
- Don't forget to track files
|
|
132
241
|
|
|
133
242
|
---
|
|
134
243
|
|
|
@@ -140,9 +249,11 @@ Task Executed:
|
|
|
140
249
|
| Action | Details |
|
|
141
250
|
|--------|---------|
|
|
142
251
|
| Task | [{current_task_id}] {current_task_description} |
|
|
252
|
+
| Category | {current_task_category} |
|
|
143
253
|
| Files Created | {files_created} |
|
|
144
254
|
| Files Modified | {files_modified} |
|
|
145
|
-
| Validation |
|
|
255
|
+
| Validation | {validation_result} |
|
|
256
|
+
| Acceptance | ✅ Criteria met |
|
|
146
257
|
| Tests | ✅ Passed |
|
|
147
258
|
|
|
148
259
|
-> Committing changes...
|
|
@@ -154,10 +265,11 @@ Task Executed:
|
|
|
154
265
|
|
|
155
266
|
**If task cannot be completed:**
|
|
156
267
|
|
|
157
|
-
1. Document the blocker
|
|
158
|
-
2.
|
|
159
|
-
3.
|
|
160
|
-
4. Proceed to step-03 to save progress
|
|
268
|
+
1. Document the blocker in `task.error`
|
|
269
|
+
2. Set `task.status = "failed"` in prd.json
|
|
270
|
+
3. Update progress.txt with learnings
|
|
271
|
+
4. Proceed to step-03 to save progress (commit what was done)
|
|
272
|
+
5. step-04 will handle blocked downstream tasks
|
|
161
273
|
|
|
162
274
|
**If build fails:**
|
|
163
275
|
|
|
@@ -166,6 +278,12 @@ Task Executed:
|
|
|
166
278
|
3. Re-build until success
|
|
167
279
|
4. Then proceed
|
|
168
280
|
|
|
281
|
+
**If validation fails:**
|
|
282
|
+
|
|
283
|
+
1. Fix validation issues
|
|
284
|
+
2. Re-validate until clean
|
|
285
|
+
3. If unfixable: document in `task.error`, set `task.validation = "failed: {reason}"`
|
|
286
|
+
|
|
169
287
|
---
|
|
170
288
|
|
|
171
289
|
## NEXT STEP:
|