specsmd 0.1.9 → 0.1.11
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/flows/fire/agents/builder/skills/run-execute/scripts/complete-run.js +43 -41
- package/flows/fire/agents/builder/skills/run-execute/scripts/init-run.js +12 -10
- package/flows/fire/agents/orchestrator/agent.md +19 -5
- package/flows/fire/agents/orchestrator/skills/project-init/SKILL.md +1 -1
- package/flows/fire/agents/orchestrator/skills/route/SKILL.md +1 -1
- package/flows/fire/agents/orchestrator/skills/status/SKILL.md +607 -13
- package/flows/fire/commands/fire-builder.md +1 -1
- package/flows/fire/commands/fire-planner.md +1 -1
- package/flows/fire/commands/fire.md +1 -1
- package/flows/fire/memory-bank.yaml +29 -12
- package/package.json +1 -1
- package/flows/fire/agents/orchestrator/skills/project-migrate/SKILL.md +0 -234
|
@@ -248,25 +248,22 @@ function completeCurrentItem(rootPath, runId, params = {}) {
|
|
|
248
248
|
const { statePath, runLogPath } = validateFireProject(rootPath, runId);
|
|
249
249
|
const state = readState(statePath);
|
|
250
250
|
|
|
251
|
-
|
|
251
|
+
// Find run in active runs list
|
|
252
|
+
const activeRuns = state.runs?.active || [];
|
|
253
|
+
const runIndex = activeRuns.findIndex(r => r.id === runId);
|
|
254
|
+
|
|
255
|
+
if (runIndex === -1) {
|
|
252
256
|
throw fireError(
|
|
253
|
-
|
|
257
|
+
`Run "${runId}" not found in active runs.`,
|
|
254
258
|
'COMPLETE_040',
|
|
255
259
|
'The run may have already been completed or was never started.'
|
|
256
260
|
);
|
|
257
261
|
}
|
|
258
262
|
|
|
259
|
-
|
|
260
|
-
throw fireError(
|
|
261
|
-
`Run ID mismatch. Active run is "${state.active_run.id}" but trying to complete "${runId}".`,
|
|
262
|
-
'COMPLETE_041',
|
|
263
|
-
`Complete the active run "${state.active_run.id}" first.`
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
|
|
263
|
+
const activeRun = activeRuns[runIndex];
|
|
267
264
|
const completedTime = new Date().toISOString();
|
|
268
|
-
const workItems =
|
|
269
|
-
const currentItemId =
|
|
265
|
+
const workItems = activeRun.work_items || [];
|
|
266
|
+
const currentItemId = activeRun.current_item;
|
|
270
267
|
|
|
271
268
|
// Find and mark current item as completed
|
|
272
269
|
let currentItemIndex = -1;
|
|
@@ -297,12 +294,13 @@ function completeCurrentItem(rootPath, runId, params = {}) {
|
|
|
297
294
|
}
|
|
298
295
|
}
|
|
299
296
|
|
|
300
|
-
// Update
|
|
301
|
-
|
|
302
|
-
|
|
297
|
+
// Update active run in list
|
|
298
|
+
activeRun.work_items = workItems;
|
|
299
|
+
activeRun.current_item = nextItem ? nextItem.id : null;
|
|
300
|
+
state.runs.active[runIndex] = activeRun;
|
|
303
301
|
|
|
304
302
|
// Update run log
|
|
305
|
-
updateRunLog(runLogPath,
|
|
303
|
+
updateRunLog(runLogPath, activeRun, completionParams, completedTime, false);
|
|
306
304
|
|
|
307
305
|
// Save state
|
|
308
306
|
writeState(statePath, state);
|
|
@@ -335,25 +333,32 @@ function completeRun(rootPath, runId, params = {}) {
|
|
|
335
333
|
const { statePath, runLogPath } = validateFireProject(rootPath, runId);
|
|
336
334
|
const state = readState(statePath);
|
|
337
335
|
|
|
338
|
-
if
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
336
|
+
// Initialize runs structure if needed
|
|
337
|
+
if (!state.runs) {
|
|
338
|
+
state.runs = { active: [], completed: [] };
|
|
339
|
+
}
|
|
340
|
+
if (!Array.isArray(state.runs.active)) {
|
|
341
|
+
state.runs.active = [];
|
|
342
|
+
}
|
|
343
|
+
if (!Array.isArray(state.runs.completed)) {
|
|
344
|
+
state.runs.completed = [];
|
|
344
345
|
}
|
|
345
346
|
|
|
346
|
-
|
|
347
|
+
// Find run in active runs list
|
|
348
|
+
const runIndex = state.runs.active.findIndex(r => r.id === runId);
|
|
349
|
+
|
|
350
|
+
if (runIndex === -1) {
|
|
347
351
|
throw fireError(
|
|
348
|
-
`Run
|
|
349
|
-
'
|
|
350
|
-
|
|
352
|
+
`Run "${runId}" not found in active runs.`,
|
|
353
|
+
'COMPLETE_040',
|
|
354
|
+
'The run may have already been completed or was never started.'
|
|
351
355
|
);
|
|
352
356
|
}
|
|
353
357
|
|
|
358
|
+
const activeRun = state.runs.active[runIndex];
|
|
354
359
|
const completedTime = new Date().toISOString();
|
|
355
|
-
const workItems =
|
|
356
|
-
const scope =
|
|
360
|
+
const workItems = activeRun.work_items || [];
|
|
361
|
+
const scope = activeRun.scope || 'single';
|
|
357
362
|
|
|
358
363
|
// Mark all items as completed
|
|
359
364
|
for (const item of workItems) {
|
|
@@ -363,11 +368,11 @@ function completeRun(rootPath, runId, params = {}) {
|
|
|
363
368
|
}
|
|
364
369
|
}
|
|
365
370
|
|
|
366
|
-
|
|
367
|
-
|
|
371
|
+
activeRun.work_items = workItems;
|
|
372
|
+
activeRun.current_item = null;
|
|
368
373
|
|
|
369
374
|
// Update run log
|
|
370
|
-
updateRunLog(runLogPath,
|
|
375
|
+
updateRunLog(runLogPath, activeRun, completionParams, completedTime, true);
|
|
371
376
|
|
|
372
377
|
// Build completed run record
|
|
373
378
|
const completedRun = {
|
|
@@ -378,15 +383,12 @@ function completeRun(rootPath, runId, params = {}) {
|
|
|
378
383
|
intent: i.intent,
|
|
379
384
|
mode: i.mode,
|
|
380
385
|
})),
|
|
386
|
+
started: activeRun.started,
|
|
381
387
|
completed: completedTime,
|
|
382
388
|
};
|
|
383
389
|
|
|
384
|
-
// Get existing runs history or initialize
|
|
385
|
-
const existingRuns = state.runs || { completed: [] };
|
|
386
|
-
const existingCompleted = Array.isArray(existingRuns.completed) ? existingRuns.completed : [];
|
|
387
|
-
|
|
388
390
|
// Check for duplicate (idempotency)
|
|
389
|
-
const alreadyRecorded =
|
|
391
|
+
const alreadyRecorded = state.runs.completed.some(r => r.id === runId);
|
|
390
392
|
|
|
391
393
|
// Update work item status in intents
|
|
392
394
|
if (Array.isArray(state.intents)) {
|
|
@@ -405,11 +407,11 @@ function completeRun(rootPath, runId, params = {}) {
|
|
|
405
407
|
}
|
|
406
408
|
}
|
|
407
409
|
|
|
408
|
-
//
|
|
409
|
-
state.
|
|
410
|
-
|
|
411
|
-
completed
|
|
412
|
-
}
|
|
410
|
+
// Remove from active runs and add to completed
|
|
411
|
+
state.runs.active.splice(runIndex, 1);
|
|
412
|
+
if (!alreadyRecorded) {
|
|
413
|
+
state.runs.completed.push(completedRun);
|
|
414
|
+
}
|
|
413
415
|
|
|
414
416
|
// Save state
|
|
415
417
|
writeState(statePath, state);
|
|
@@ -317,13 +317,15 @@ function initRun(rootPath, workItems, scope) {
|
|
|
317
317
|
// Read state
|
|
318
318
|
const state = readState(statePath);
|
|
319
319
|
|
|
320
|
-
//
|
|
321
|
-
if (state.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
320
|
+
// Initialize runs structure if needed
|
|
321
|
+
if (!state.runs) {
|
|
322
|
+
state.runs = { active: [], completed: [] };
|
|
323
|
+
}
|
|
324
|
+
if (!Array.isArray(state.runs.active)) {
|
|
325
|
+
state.runs.active = [];
|
|
326
|
+
}
|
|
327
|
+
if (!Array.isArray(state.runs.completed)) {
|
|
328
|
+
state.runs.completed = [];
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
// Generate run ID (checks both history AND file system)
|
|
@@ -345,14 +347,14 @@ function initRun(rootPath, workItems, scope) {
|
|
|
345
347
|
status: index === 0 ? 'in_progress' : 'pending',
|
|
346
348
|
}));
|
|
347
349
|
|
|
348
|
-
//
|
|
349
|
-
state.
|
|
350
|
+
// Add to active runs list (supports multiple parallel runs)
|
|
351
|
+
state.runs.active.push({
|
|
350
352
|
id: runId,
|
|
351
353
|
scope: detectedScope,
|
|
352
354
|
work_items: stateWorkItems,
|
|
353
355
|
current_item: workItems[0].id,
|
|
354
356
|
started: startTime,
|
|
355
|
-
};
|
|
357
|
+
});
|
|
356
358
|
|
|
357
359
|
// Save state
|
|
358
360
|
writeState(statePath, state);
|
|
@@ -22,7 +22,7 @@ You are the **Orchestrator Agent** for FIRE (Fast Intent-Run Engineering).
|
|
|
22
22
|
When user invokes this agent:
|
|
23
23
|
|
|
24
24
|
<step n="1" title="Load Configuration">
|
|
25
|
-
<action>Read `.specsmd/fire/
|
|
25
|
+
<action>Read `.specsmd/fire/memory-bank.yaml` for schema</action>
|
|
26
26
|
</step>
|
|
27
27
|
|
|
28
28
|
<step n="2" title="Check Initialization">
|
|
@@ -79,23 +79,37 @@ You are the **Orchestrator Agent** for FIRE (Fast Intent-Run Engineering).
|
|
|
79
79
|
```yaml
|
|
80
80
|
project:
|
|
81
81
|
name: "project-name"
|
|
82
|
-
|
|
82
|
+
fire_version: "0.1.8"
|
|
83
83
|
|
|
84
84
|
workspace:
|
|
85
85
|
type: brownfield
|
|
86
86
|
structure: monolith
|
|
87
|
-
|
|
87
|
+
autonomy_bias: balanced
|
|
88
88
|
|
|
89
89
|
intents:
|
|
90
90
|
- id: user-auth
|
|
91
|
+
title: "User Authentication"
|
|
91
92
|
status: in_progress
|
|
92
93
|
work_items:
|
|
93
94
|
- id: login-endpoint
|
|
94
95
|
status: completed
|
|
96
|
+
complexity: medium
|
|
97
|
+
mode: confirm
|
|
95
98
|
- id: session-management
|
|
96
99
|
status: pending
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
complexity: medium
|
|
101
|
+
mode: confirm
|
|
102
|
+
|
|
103
|
+
runs:
|
|
104
|
+
active: [] # List of active runs (supports multiple parallel runs)
|
|
105
|
+
completed:
|
|
106
|
+
- id: run-001
|
|
107
|
+
work_items:
|
|
108
|
+
- id: login-endpoint
|
|
109
|
+
intent: user-auth
|
|
110
|
+
mode: confirm
|
|
111
|
+
status: completed
|
|
112
|
+
completed: "2026-01-19T12:00:00Z"
|
|
99
113
|
```
|
|
100
114
|
|
|
101
115
|
</state_schema>
|
|
@@ -9,7 +9,7 @@ Initialize a new FIRE project by detecting workspace type and setting up standar
|
|
|
9
9
|
</objective>
|
|
10
10
|
|
|
11
11
|
<triggers>
|
|
12
|
-
- User runs `/fire` on uninitialized project
|
|
12
|
+
- User runs `/specsmd-fire` on uninitialized project
|
|
13
13
|
- No `.specs-fire/state.yaml` exists
|
|
14
14
|
</triggers>
|
|
15
15
|
|
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: status
|
|
3
|
-
description: Display current FIRE project status
|
|
4
|
-
version:
|
|
3
|
+
description: Display current FIRE project status and validate integrity of intents, work items, and runs.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
<objective>
|
|
8
|
-
Display current FIRE project status.
|
|
8
|
+
Display current FIRE project status and validate integrity across state.yaml and file system.
|
|
9
|
+
Detect inconsistencies and offer interactive resolution.
|
|
9
10
|
</objective>
|
|
10
11
|
|
|
11
12
|
<triggers>
|
|
12
|
-
- User runs `/fire status`
|
|
13
|
+
- User runs `/specsmd-fire status`
|
|
13
14
|
- User asks "what's the status?"
|
|
15
|
+
- User asks to "check" or "validate" the project state
|
|
14
16
|
</triggers>
|
|
15
17
|
|
|
18
|
+
<degrees_of_freedom>
|
|
19
|
+
**LOW** — Report facts accurately. Never auto-fix without user confirmation.
|
|
20
|
+
</degrees_of_freedom>
|
|
21
|
+
|
|
22
|
+
<llm critical="true">
|
|
23
|
+
<mandate>NEVER auto-fix inconsistencies — ALWAYS ask user first</mandate>
|
|
24
|
+
<mandate>ALWAYS scan file system — state.yaml may be incomplete</mandate>
|
|
25
|
+
<mandate>Report ALL findings before offering fixes</mandate>
|
|
26
|
+
<mandate>state.yaml is source of truth for status — frontmatter may be stale</mandate>
|
|
27
|
+
</llm>
|
|
28
|
+
|
|
16
29
|
<flow>
|
|
17
30
|
<step n="1" title="Read State">
|
|
18
31
|
<action>Read .specs-fire/state.yaml</action>
|
|
32
|
+
<check if="state.yaml not found">
|
|
33
|
+
<output>No FIRE project found. Run `/specsmd-fire` to initialize.</output>
|
|
34
|
+
<exit/>
|
|
35
|
+
</check>
|
|
19
36
|
</step>
|
|
20
37
|
|
|
21
38
|
<step n="2" title="Display Status">
|
|
@@ -25,6 +42,7 @@ Display current FIRE project status.
|
|
|
25
42
|
**Project**: {project.name}
|
|
26
43
|
**Workspace**: {workspace.type} / {workspace.structure}
|
|
27
44
|
**Autonomy**: {workspace.autonomy_bias}
|
|
45
|
+
**Version**: {project.fire_version}
|
|
28
46
|
|
|
29
47
|
## Intents
|
|
30
48
|
|
|
@@ -39,13 +57,18 @@ Display current FIRE project status.
|
|
|
39
57
|
|
|
40
58
|
{/for}
|
|
41
59
|
|
|
42
|
-
## Active
|
|
60
|
+
## Active Runs
|
|
43
61
|
|
|
44
|
-
{if
|
|
62
|
+
{if runs.active is array and has items}
|
|
63
|
+
{for each active_run in runs.active}
|
|
64
|
+
- **Run**: {active_run.id} | **Scope**: {active_run.scope}
|
|
65
|
+
- **Current Item**: {active_run.current_item}
|
|
66
|
+
- **Started**: {active_run.started}
|
|
67
|
+
{/for}
|
|
68
|
+
{else if active_run exists (legacy singular)}
|
|
45
69
|
- **Run**: {active_run.id}
|
|
46
70
|
- **Work Item**: {active_run.work_item}
|
|
47
71
|
- **Started**: {active_run.started}
|
|
48
|
-
- **Mode**: {active_run.mode}
|
|
49
72
|
{else}
|
|
50
73
|
No active run.
|
|
51
74
|
{/if}
|
|
@@ -54,11 +77,546 @@ Display current FIRE project status.
|
|
|
54
77
|
|
|
55
78
|
- Intents: {total_intents} ({completed_intents} completed)
|
|
56
79
|
- Work Items: {total_work_items} ({completed_work_items} completed)
|
|
57
|
-
- Runs: {total_runs}
|
|
80
|
+
- Runs: {total_runs} completed
|
|
81
|
+
</output>
|
|
82
|
+
</step>
|
|
83
|
+
|
|
84
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
85
|
+
<!-- INTEGRITY VALIDATION (NEW) -->
|
|
86
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
87
|
+
|
|
88
|
+
<step n="3" title="Scan File System">
|
|
89
|
+
<critical>
|
|
90
|
+
File system may have artifacts not tracked in state.yaml.
|
|
91
|
+
state.yaml may reference artifacts that no longer exist on disk.
|
|
92
|
+
</critical>
|
|
93
|
+
|
|
94
|
+
<substep n="3a" title="Scan Intents">
|
|
95
|
+
<action>Glob: .specs-fire/intents/*/brief.md</action>
|
|
96
|
+
<action>Extract intent IDs from directory names</action>
|
|
97
|
+
<action>Store as: intents_on_disk[]</action>
|
|
98
|
+
</substep>
|
|
99
|
+
|
|
100
|
+
<substep n="3b" title="Scan Work Items">
|
|
101
|
+
<action>Glob: .specs-fire/intents/*/work-items/*.md</action>
|
|
102
|
+
<action>Exclude design docs (*-design.md)</action>
|
|
103
|
+
<action>Extract work item IDs and parent intents</action>
|
|
104
|
+
<action>Store as: work_items_on_disk[]</action>
|
|
105
|
+
</substep>
|
|
106
|
+
|
|
107
|
+
<substep n="3c" title="Scan Runs">
|
|
108
|
+
<action>Glob: .specs-fire/runs/run-*/run.md</action>
|
|
109
|
+
<action>Extract run IDs from directory names</action>
|
|
110
|
+
<action>For each run, check which artifacts exist:</action>
|
|
111
|
+
<substep>plan.md, test-report.md, review-report.md, walkthrough.md</substep>
|
|
112
|
+
<action>Store as: runs_on_disk[] with artifact_flags</action>
|
|
113
|
+
</substep>
|
|
114
|
+
</step>
|
|
115
|
+
|
|
116
|
+
<step n="4" title="Compare File System vs State">
|
|
117
|
+
<substep n="4a" title="Find Orphaned Artifacts (on disk but not in state)">
|
|
118
|
+
<action>Compare intents_on_disk with state.intents</action>
|
|
119
|
+
<action>Compare work_items_on_disk with state work_items</action>
|
|
120
|
+
<action>Compare runs_on_disk with state.runs.completed + state.runs.active</action>
|
|
121
|
+
|
|
122
|
+
<check if="intent on disk but not in state">
|
|
123
|
+
<add_issue type="orphaned_intent" severity="warning">
|
|
124
|
+
Intent '{id}' exists on disk but not tracked in state.yaml
|
|
125
|
+
</add_issue>
|
|
126
|
+
</check>
|
|
127
|
+
|
|
128
|
+
<check if="work item on disk but not in state">
|
|
129
|
+
<add_issue type="orphaned_work_item" severity="warning">
|
|
130
|
+
Work item '{id}' exists on disk but not tracked in state.yaml
|
|
131
|
+
</add_issue>
|
|
132
|
+
</check>
|
|
133
|
+
|
|
134
|
+
<check if="run folder on disk but not in state">
|
|
135
|
+
<add_issue type="orphaned_run" severity="warning">
|
|
136
|
+
Run '{id}' exists on disk but not tracked in state.yaml
|
|
137
|
+
</add_issue>
|
|
138
|
+
</check>
|
|
139
|
+
</substep>
|
|
140
|
+
|
|
141
|
+
<substep n="4b" title="Find Missing Files (in state but not on disk)">
|
|
142
|
+
<check if="intent in state but no brief.md on disk">
|
|
143
|
+
<add_issue type="missing_intent_file" severity="error">
|
|
144
|
+
Intent '{id}' tracked but brief.md not found on disk
|
|
145
|
+
</add_issue>
|
|
146
|
+
</check>
|
|
147
|
+
|
|
148
|
+
<check if="work item in state but no .md file on disk">
|
|
149
|
+
<add_issue type="missing_work_item_file" severity="error">
|
|
150
|
+
Work item '{id}' tracked but file not found on disk
|
|
151
|
+
</add_issue>
|
|
152
|
+
</check>
|
|
153
|
+
|
|
154
|
+
<check if="completed run in state but no folder on disk">
|
|
155
|
+
<add_issue type="missing_run_folder" severity="error">
|
|
156
|
+
Run '{id}' marked complete but folder not found on disk
|
|
157
|
+
</add_issue>
|
|
158
|
+
</check>
|
|
159
|
+
</substep>
|
|
160
|
+
</step>
|
|
161
|
+
|
|
162
|
+
<step n="5" title="Validate Status Cascade">
|
|
163
|
+
<critical>
|
|
164
|
+
Status must cascade correctly:
|
|
165
|
+
- Run completes work item → work item should be "completed"
|
|
166
|
+
- All work items completed → intent should be "completed"
|
|
167
|
+
- Any work item in_progress → intent should be "in_progress"
|
|
168
|
+
</critical>
|
|
169
|
+
|
|
170
|
+
<substep n="5a" title="Work Item Status Check">
|
|
171
|
+
<action>For each work item in state:</action>
|
|
172
|
+
|
|
173
|
+
<check if="work item in runs.completed but status != completed">
|
|
174
|
+
<add_issue type="status_mismatch" severity="error">
|
|
175
|
+
Work item '{id}' was completed in run '{run_id}' but status is '{current_status}'
|
|
176
|
+
Expected: completed
|
|
177
|
+
</add_issue>
|
|
178
|
+
</check>
|
|
179
|
+
|
|
180
|
+
<check if="work item in runs.active as current_item but status != in_progress">
|
|
181
|
+
<add_issue type="status_mismatch" severity="warning">
|
|
182
|
+
Work item '{id}' is currently executing in run '{run_id}' but status is '{current_status}'
|
|
183
|
+
Expected: in_progress
|
|
184
|
+
</add_issue>
|
|
185
|
+
</check>
|
|
186
|
+
|
|
187
|
+
<check if="work item status is completed but not found in any completed run">
|
|
188
|
+
<add_issue type="status_unverifiable" severity="warning" needs_code_check="true">
|
|
189
|
+
Work item '{id}' marked as completed but no completed run found
|
|
190
|
+
May have been done outside FIRE or run data is missing
|
|
191
|
+
</add_issue>
|
|
192
|
+
</check>
|
|
193
|
+
</substep>
|
|
194
|
+
|
|
195
|
+
<substep n="5b" title="Intent Status Check">
|
|
196
|
+
<action>For each intent in state:</action>
|
|
197
|
+
|
|
198
|
+
<derive_expected_status>
|
|
199
|
+
IF any work_item.status == "in_progress":
|
|
200
|
+
expected = "in_progress"
|
|
201
|
+
ELSE IF all work_items.status == "completed":
|
|
202
|
+
expected = "completed"
|
|
203
|
+
ELSE IF all work_items.status == "pending":
|
|
204
|
+
expected = "pending"
|
|
205
|
+
ELSE: # mixed pending/completed
|
|
206
|
+
expected = "in_progress"
|
|
207
|
+
</derive_expected_status>
|
|
208
|
+
|
|
209
|
+
<check if="intent.status != expected_status">
|
|
210
|
+
<add_issue type="intent_status_mismatch" severity="error">
|
|
211
|
+
Intent '{title}' has status '{current}' but should be '{expected}'
|
|
212
|
+
Based on work item statuses: {breakdown}
|
|
213
|
+
</add_issue>
|
|
214
|
+
</check>
|
|
215
|
+
</substep>
|
|
216
|
+
</step>
|
|
217
|
+
|
|
218
|
+
<step n="6" title="Validate Run Artifact Completeness">
|
|
219
|
+
<substep n="6a" title="Check Completed Runs">
|
|
220
|
+
<action>For each run in runs.completed (or runs_on_disk marked complete):</action>
|
|
221
|
+
|
|
222
|
+
<required_artifacts>
|
|
223
|
+
- run.md (mandatory)
|
|
224
|
+
- plan.md (mandatory for all modes)
|
|
225
|
+
- test-report.md (mandatory after tests)
|
|
226
|
+
- walkthrough.md (mandatory after completion)
|
|
227
|
+
</required_artifacts>
|
|
228
|
+
|
|
229
|
+
<optional_artifacts>
|
|
230
|
+
- review-report.md (created by code-review skill)
|
|
231
|
+
</optional_artifacts>
|
|
232
|
+
|
|
233
|
+
<check if="completed run missing required artifact">
|
|
234
|
+
<add_issue type="incomplete_run_artifacts" severity="warning">
|
|
235
|
+
Run '{id}' is marked complete but missing: {missing_artifacts}
|
|
236
|
+
</add_issue>
|
|
237
|
+
</check>
|
|
238
|
+
</substep>
|
|
239
|
+
|
|
240
|
+
<substep n="6b" title="Check Active Runs">
|
|
241
|
+
<action>For each run in runs.active:</action>
|
|
242
|
+
|
|
243
|
+
<check if="active run folder does not exist">
|
|
244
|
+
<add_issue type="active_run_missing" severity="error">
|
|
245
|
+
Active run '{id}' has no folder on disk
|
|
246
|
+
Run may have been deleted or never initialized properly
|
|
247
|
+
</add_issue>
|
|
248
|
+
</check>
|
|
249
|
+
|
|
250
|
+
<check if="active run has no run.md">
|
|
251
|
+
<add_issue type="active_run_corrupted" severity="error">
|
|
252
|
+
Active run '{id}' folder exists but run.md is missing
|
|
253
|
+
Run initialization may have failed
|
|
254
|
+
</add_issue>
|
|
255
|
+
</check>
|
|
256
|
+
</substep>
|
|
257
|
+
</step>
|
|
258
|
+
|
|
259
|
+
<step n="7" title="Detect Stale Runs">
|
|
260
|
+
<action>For each active run:</action>
|
|
261
|
+
<action>Calculate age: now - active_run.started</action>
|
|
262
|
+
|
|
263
|
+
<check if="active run started more than 24 hours ago">
|
|
264
|
+
<add_issue type="stale_run" severity="info" needs_user_decision="true">
|
|
265
|
+
Active run '{id}' was started {age} ago
|
|
266
|
+
Current item: {current_item}
|
|
267
|
+
Artifacts present: {artifact_list}
|
|
268
|
+
May be abandoned or work was done outside FIRE
|
|
269
|
+
</add_issue>
|
|
270
|
+
</check>
|
|
271
|
+
|
|
272
|
+
<check if="active run has plan.md but no test-report.md and age > 1 hour">
|
|
273
|
+
<add_issue type="interrupted_run" severity="warning" needs_user_decision="true">
|
|
274
|
+
Run '{id}' appears interrupted mid-execution
|
|
275
|
+
Has: plan.md
|
|
276
|
+
Missing: test-report.md, walkthrough.md
|
|
277
|
+
Execution may have been stopped before completion
|
|
278
|
+
</add_issue>
|
|
279
|
+
</check>
|
|
280
|
+
</step>
|
|
281
|
+
|
|
282
|
+
<step n="8" title="Check Frontmatter Sync">
|
|
283
|
+
<note>state.yaml is source of truth. Frontmatter may drift.</note>
|
|
284
|
+
|
|
285
|
+
<action>For each work item with status in state.yaml:</action>
|
|
286
|
+
<action>Read work item file, parse frontmatter</action>
|
|
287
|
+
|
|
288
|
+
<check if="frontmatter.status != state.yaml.status">
|
|
289
|
+
<add_issue type="frontmatter_drift" severity="info">
|
|
290
|
+
Work item '{id}' frontmatter says '{frontmatter_status}' but state.yaml says '{state_status}'
|
|
291
|
+
state.yaml is authoritative
|
|
292
|
+
</add_issue>
|
|
293
|
+
</check>
|
|
294
|
+
</step>
|
|
295
|
+
|
|
296
|
+
<step n="9" title="Report Findings">
|
|
297
|
+
<check if="no issues found">
|
|
298
|
+
<output>
|
|
299
|
+
## ✅ Integrity Check Passed
|
|
300
|
+
|
|
301
|
+
All artifacts are consistent:
|
|
302
|
+
- {intent_count} intents tracked and verified
|
|
303
|
+
- {work_item_count} work items with correct status
|
|
304
|
+
- {run_count} runs with complete artifacts
|
|
305
|
+
- No orphaned or missing files detected
|
|
306
|
+
</output>
|
|
307
|
+
<exit/>
|
|
308
|
+
</check>
|
|
309
|
+
|
|
310
|
+
<check if="issues found">
|
|
311
|
+
<output>
|
|
312
|
+
## ⚠️ Integrity Issues Detected
|
|
313
|
+
|
|
314
|
+
Found {issue_count} issue(s) requiring attention:
|
|
315
|
+
|
|
316
|
+
| # | Type | Location | Issue | Suggested Fix |
|
|
317
|
+
|---|------|----------|-------|---------------|
|
|
318
|
+
{for each issue, numbered}
|
|
319
|
+
| {n} | {severity_icon} | {location} | {description} | {fix_suggestion} |
|
|
320
|
+
{/for}
|
|
321
|
+
|
|
322
|
+
**Severity**: 🔴 Error | 🟡 Warning | 🔵 Info
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### Actions
|
|
327
|
+
|
|
328
|
+
**[1] fix-all** — Apply all recommended fixes automatically
|
|
329
|
+
**[2] review** — Go through each issue one by one
|
|
330
|
+
**[3] skip** — Continue without fixing
|
|
331
|
+
{if any issue has needs_code_check}
|
|
332
|
+
**[4] check-code** — Verify by inspecting the codebase
|
|
333
|
+
{/if}
|
|
334
|
+
|
|
335
|
+
Choose an action [1/2/3{if check-code available}/4{/if}]:
|
|
336
|
+
</output>
|
|
337
|
+
</check>
|
|
338
|
+
</step>
|
|
339
|
+
|
|
340
|
+
<step n="10" title="Process User Choice">
|
|
341
|
+
<check if="response == 1 (fix-all)">
|
|
342
|
+
<goto step="11"/>
|
|
343
|
+
</check>
|
|
344
|
+
|
|
345
|
+
<check if="response == 2 (review)">
|
|
346
|
+
<goto step="12"/>
|
|
347
|
+
</check>
|
|
348
|
+
|
|
349
|
+
<check if="response == 3 (skip)">
|
|
350
|
+
<output>Skipping integrity fixes. Issues may cause unexpected behavior.</output>
|
|
351
|
+
<exit/>
|
|
352
|
+
</check>
|
|
353
|
+
|
|
354
|
+
<check if="response == 4 (check-code)">
|
|
355
|
+
<goto step="13"/>
|
|
356
|
+
</check>
|
|
357
|
+
</step>
|
|
358
|
+
|
|
359
|
+
<step n="11" title="Apply All Fixes">
|
|
360
|
+
<action>For each issue with a fix:</action>
|
|
361
|
+
|
|
362
|
+
<fix_actions>
|
|
363
|
+
<fix for="orphaned_intent">
|
|
364
|
+
Read brief.md frontmatter, add intent to state.yaml with status: pending
|
|
365
|
+
</fix>
|
|
366
|
+
|
|
367
|
+
<fix for="orphaned_work_item">
|
|
368
|
+
Read work item frontmatter, add to parent intent in state.yaml
|
|
369
|
+
</fix>
|
|
370
|
+
|
|
371
|
+
<fix for="orphaned_run">
|
|
372
|
+
Parse run.md, determine if complete or incomplete
|
|
373
|
+
If complete: add to runs.completed
|
|
374
|
+
If incomplete: offer to add to runs.active or delete
|
|
375
|
+
</fix>
|
|
376
|
+
|
|
377
|
+
<fix for="missing_intent_file">
|
|
378
|
+
Remove intent from state.yaml (data loss warning)
|
|
379
|
+
Or: Create placeholder brief.md from state data
|
|
380
|
+
</fix>
|
|
381
|
+
|
|
382
|
+
<fix for="status_mismatch">
|
|
383
|
+
Update state.yaml status to expected value
|
|
384
|
+
</fix>
|
|
385
|
+
|
|
386
|
+
<fix for="intent_status_mismatch">
|
|
387
|
+
Update intent status in state.yaml
|
|
388
|
+
</fix>
|
|
389
|
+
|
|
390
|
+
<fix for="frontmatter_drift">
|
|
391
|
+
Update work item frontmatter to match state.yaml
|
|
392
|
+
</fix>
|
|
393
|
+
|
|
394
|
+
<fix for="incomplete_run_artifacts">
|
|
395
|
+
Mark run as incomplete in state, or generate missing artifacts
|
|
396
|
+
</fix>
|
|
397
|
+
|
|
398
|
+
<fix for="stale_run">
|
|
399
|
+
User must decide: resume, abandon, or check code
|
|
400
|
+
</fix>
|
|
401
|
+
</fix_actions>
|
|
402
|
+
|
|
403
|
+
<output>
|
|
404
|
+
## Fixes Applied
|
|
405
|
+
|
|
406
|
+
{for each fix applied}
|
|
407
|
+
✓ {description}
|
|
408
|
+
{/for}
|
|
409
|
+
|
|
410
|
+
{if any fixes skipped}
|
|
411
|
+
⏭️ Skipped (requires user decision):
|
|
412
|
+
{for each skipped}
|
|
413
|
+
- {description}
|
|
414
|
+
{/for}
|
|
415
|
+
{/if}
|
|
416
|
+
</output>
|
|
417
|
+
|
|
418
|
+
<goto step="14"/>
|
|
419
|
+
</step>
|
|
420
|
+
|
|
421
|
+
<step n="12" title="Interactive Review">
|
|
422
|
+
<action>For each issue:</action>
|
|
423
|
+
|
|
424
|
+
<output>
|
|
425
|
+
## Issue {n} of {total}
|
|
426
|
+
|
|
427
|
+
**Type**: {type}
|
|
428
|
+
**Severity**: {severity}
|
|
429
|
+
**Location**: {location}
|
|
430
|
+
|
|
431
|
+
### Details
|
|
432
|
+
{full_description}
|
|
433
|
+
|
|
434
|
+
### Suggested Fix
|
|
435
|
+
{fix_suggestion}
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
**[y]** Apply fix
|
|
440
|
+
**[n]** Skip this issue
|
|
441
|
+
**[c]** Check codebase for this item
|
|
442
|
+
**[q]** Quit review (remaining issues skipped)
|
|
443
|
+
|
|
444
|
+
Choice [y/n/c/q]:
|
|
445
|
+
</output>
|
|
446
|
+
|
|
447
|
+
<check if="response == y">
|
|
448
|
+
<action>Apply fix for this issue</action>
|
|
449
|
+
<output>✓ Fixed: {description}</output>
|
|
450
|
+
</check>
|
|
451
|
+
|
|
452
|
+
<check if="response == c">
|
|
453
|
+
<action>Invoke code check for this specific item</action>
|
|
454
|
+
<goto_substep>code-check for {item}</goto_substep>
|
|
455
|
+
</check>
|
|
456
|
+
|
|
457
|
+
<check if="response == q">
|
|
458
|
+
<output>Review ended. {remaining} issues skipped.</output>
|
|
459
|
+
<goto step="14"/>
|
|
460
|
+
</check>
|
|
461
|
+
|
|
462
|
+
<action>Continue to next issue</action>
|
|
463
|
+
</step>
|
|
464
|
+
|
|
465
|
+
<step n="13" title="Code Verification">
|
|
466
|
+
<critical>
|
|
467
|
+
This is a BEST EFFORT verification. AI will look for evidence
|
|
468
|
+
but may not catch everything. User should confirm findings.
|
|
469
|
+
</critical>
|
|
470
|
+
|
|
471
|
+
<ask>
|
|
472
|
+
I'll check the codebase for evidence that work items were completed.
|
|
473
|
+
This involves reading work item acceptance criteria and looking for
|
|
474
|
+
matching implementations.
|
|
475
|
+
|
|
476
|
+
Which items should I check?
|
|
477
|
+
|
|
478
|
+
{for each item with needs_code_check}
|
|
479
|
+
**[{n}]** {work_item_title}
|
|
480
|
+
{/for}
|
|
481
|
+
**[a]** All items
|
|
482
|
+
**[b]** Back to actions
|
|
483
|
+
|
|
484
|
+
Choice:
|
|
485
|
+
</ask>
|
|
486
|
+
|
|
487
|
+
<substep n="13a" title="Verify Single Work Item">
|
|
488
|
+
<action>Read work item file: .specs-fire/intents/{intent}/work-items/{id}.md</action>
|
|
489
|
+
<action>Extract acceptance criteria</action>
|
|
490
|
+
<action>Extract expected files/endpoints/components mentioned</action>
|
|
491
|
+
|
|
492
|
+
<verification_checks>
|
|
493
|
+
<check title="File Existence">
|
|
494
|
+
Look for files mentioned in the work item description
|
|
495
|
+
Example: "Create src/auth/login.ts" → check if file exists
|
|
496
|
+
</check>
|
|
497
|
+
|
|
498
|
+
<check title="Test Existence">
|
|
499
|
+
Look for test files for the component
|
|
500
|
+
Pattern: {filename}.test.ts, {filename}.spec.ts, __tests__/{filename}.ts
|
|
501
|
+
</check>
|
|
502
|
+
|
|
503
|
+
<check title="Implementation Markers">
|
|
504
|
+
If file exists, do a quick scan for expected functions/classes
|
|
505
|
+
Example: Work item mentions "login endpoint" → look for login handler
|
|
506
|
+
</check>
|
|
507
|
+
</verification_checks>
|
|
508
|
+
|
|
509
|
+
<output>
|
|
510
|
+
## Code Verification: {work_item_title}
|
|
511
|
+
|
|
512
|
+
### Expected (from acceptance criteria)
|
|
513
|
+
{list acceptance criteria}
|
|
514
|
+
|
|
515
|
+
### Found in Codebase
|
|
516
|
+
{for each check}
|
|
517
|
+
{check_result_icon} {check_description}
|
|
518
|
+
{/for}
|
|
519
|
+
|
|
520
|
+
### Assessment
|
|
521
|
+
{if all checks pass}
|
|
522
|
+
✅ **Likely Complete** — Implementation evidence found
|
|
523
|
+
Recommend: Mark as completed in state.yaml
|
|
524
|
+
{else if some checks pass}
|
|
525
|
+
🟡 **Partially Complete** — Some evidence found
|
|
526
|
+
Missing: {missing_items}
|
|
527
|
+
Recommend: Review manually or continue implementation
|
|
528
|
+
{else}
|
|
529
|
+
❌ **Not Found** — No implementation evidence
|
|
530
|
+
Recommend: Keep as pending, implementation needed
|
|
531
|
+
{/if}
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
Apply this assessment? [y/n]:
|
|
536
|
+
</output>
|
|
537
|
+
|
|
538
|
+
<check if="response == y">
|
|
539
|
+
<action>Update state.yaml based on assessment</action>
|
|
540
|
+
</check>
|
|
541
|
+
</substep>
|
|
542
|
+
</step>
|
|
543
|
+
|
|
544
|
+
<step n="14" title="Log Maintenance">
|
|
545
|
+
<check if="any fixes were applied">
|
|
546
|
+
<action>Append to .specs-fire/maintenance-log.md (create if needed):</action>
|
|
547
|
+
|
|
548
|
+
<log_entry>
|
|
549
|
+
## {ISO-8601-timestamp} - Integrity Check
|
|
550
|
+
|
|
551
|
+
**Triggered by**: status skill validation
|
|
552
|
+
|
|
553
|
+
| Issue | Fix Applied | Details |
|
|
554
|
+
|-------|-------------|---------|
|
|
555
|
+
{for each fix}
|
|
556
|
+
| {type} | {fix_description} | {location} |
|
|
557
|
+
{/for}
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
</log_entry>
|
|
561
|
+
|
|
562
|
+
<output>
|
|
563
|
+
Changes logged to: .specs-fire/maintenance-log.md
|
|
564
|
+
</output>
|
|
565
|
+
</check>
|
|
566
|
+
</step>
|
|
567
|
+
|
|
568
|
+
<step n="15" title="Final Summary">
|
|
569
|
+
<output>
|
|
570
|
+
## Status Check Complete
|
|
571
|
+
|
|
572
|
+
{if fixes applied}
|
|
573
|
+
**Fixes Applied**: {fix_count}
|
|
574
|
+
**Issues Remaining**: {remaining_count}
|
|
575
|
+
{/if}
|
|
576
|
+
|
|
577
|
+
{if all clean}
|
|
578
|
+
✅ Project state is consistent and ready for work.
|
|
579
|
+
{else}
|
|
580
|
+
⚠️ Some issues remain unresolved. Run `/specsmd-fire status` again to review.
|
|
581
|
+
{/if}
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
**Next**: {suggest next action based on current state}
|
|
58
586
|
</output>
|
|
59
587
|
</step>
|
|
60
588
|
</flow>
|
|
61
589
|
|
|
590
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
591
|
+
<!-- ISSUE TYPE REFERENCE -->
|
|
592
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
593
|
+
|
|
594
|
+
<issue_types>
|
|
595
|
+
|
|
596
|
+
| Type | Severity | Auto-fixable | Description |
|
|
597
|
+
|------|----------|--------------|-------------|
|
|
598
|
+
| orphaned_intent | warning | yes | Intent on disk but not in state.yaml |
|
|
599
|
+
| orphaned_work_item | warning | yes | Work item on disk but not in state.yaml |
|
|
600
|
+
| orphaned_run | warning | partial | Run folder on disk but not tracked |
|
|
601
|
+
| missing_intent_file | error | partial | Intent in state but file missing |
|
|
602
|
+
| missing_work_item_file | error | partial | Work item in state but file missing |
|
|
603
|
+
| missing_run_folder | error | no | Completed run in state but folder missing |
|
|
604
|
+
| status_mismatch | error | yes | Work item status doesn't match run history |
|
|
605
|
+
| status_unverifiable | warning | no | Status can't be verified from run data |
|
|
606
|
+
| intent_status_mismatch | error | yes | Intent status inconsistent with work items |
|
|
607
|
+
| incomplete_run_artifacts | warning | partial | Run missing required artifacts |
|
|
608
|
+
| active_run_missing | error | no | Active run folder doesn't exist |
|
|
609
|
+
| active_run_corrupted | error | no | Active run folder missing run.md |
|
|
610
|
+
| stale_run | info | no | Active run is old, may be abandoned |
|
|
611
|
+
| interrupted_run | warning | no | Run appears stopped mid-execution |
|
|
612
|
+
| frontmatter_drift | info | yes | Frontmatter status differs from state |
|
|
613
|
+
|
|
614
|
+
</issue_types>
|
|
615
|
+
|
|
616
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
617
|
+
<!-- EXAMPLE OUTPUT -->
|
|
618
|
+
<!-- ═══════════════════════════════════════════════════════════════════════════ -->
|
|
619
|
+
|
|
62
620
|
<example_output>
|
|
63
621
|
|
|
64
622
|
```
|
|
@@ -67,6 +625,7 @@ Display current FIRE project status.
|
|
|
67
625
|
**Project**: my-saas-app
|
|
68
626
|
**Workspace**: brownfield / monolith
|
|
69
627
|
**Autonomy**: balanced
|
|
628
|
+
**Version**: 0.1.8
|
|
70
629
|
|
|
71
630
|
## Intents
|
|
72
631
|
|
|
@@ -78,18 +637,42 @@ Display current FIRE project status.
|
|
|
78
637
|
| session-management | in_progress | medium | confirm |
|
|
79
638
|
| password-reset | pending | high | validate |
|
|
80
639
|
|
|
81
|
-
## Active
|
|
640
|
+
## Active Runs
|
|
82
641
|
|
|
83
|
-
- **Run**: run-002
|
|
84
|
-
- **
|
|
642
|
+
- **Run**: run-002 | **Scope**: single
|
|
643
|
+
- **Current Item**: session-management
|
|
85
644
|
- **Started**: 2026-01-19T10:30:00Z
|
|
86
|
-
- **Mode**: confirm
|
|
87
645
|
|
|
88
646
|
## Quick Stats
|
|
89
647
|
|
|
90
648
|
- Intents: 1 (0 completed)
|
|
91
649
|
- Work Items: 3 (1 completed)
|
|
92
|
-
- Runs:
|
|
650
|
+
- Runs: 1 completed
|
|
651
|
+
|
|
652
|
+
---
|
|
653
|
+
|
|
654
|
+
## ⚠️ Integrity Issues Detected
|
|
655
|
+
|
|
656
|
+
Found 3 issue(s) requiring attention:
|
|
657
|
+
|
|
658
|
+
| # | Type | Location | Issue | Suggested Fix |
|
|
659
|
+
|---|------|----------|-------|---------------|
|
|
660
|
+
| 1 | 🟡 | run-002 | Run started 3 days ago, may be stale | Resume or abandon |
|
|
661
|
+
| 2 | 🔵 | login-endpoint | Frontmatter says 'pending' but state says 'completed' | Sync frontmatter |
|
|
662
|
+
| 3 | 🟡 | analytics-dashboard.md | Work item on disk but not tracked | Add to state.yaml |
|
|
663
|
+
|
|
664
|
+
**Severity**: 🔴 Error | 🟡 Warning | 🔵 Info
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
### Actions
|
|
669
|
+
|
|
670
|
+
**[1] fix-all** — Apply all recommended fixes automatically
|
|
671
|
+
**[2] review** — Go through each issue one by one
|
|
672
|
+
**[3] skip** — Continue without fixing
|
|
673
|
+
**[4] check-code** — Verify by inspecting the codebase
|
|
674
|
+
|
|
675
|
+
Choose an action [1/2/3/4]:
|
|
93
676
|
```
|
|
94
677
|
|
|
95
678
|
</example_output>
|
|
@@ -99,4 +682,15 @@ Display current FIRE project status.
|
|
|
99
682
|
<criterion>All intents and work items displayed</criterion>
|
|
100
683
|
<criterion>Active run status shown</criterion>
|
|
101
684
|
<criterion>Quick stats accurate</criterion>
|
|
685
|
+
<criterion>File system scanned for all artifacts</criterion>
|
|
686
|
+
<criterion>Orphaned artifacts detected (disk → state)</criterion>
|
|
687
|
+
<criterion>Missing files detected (state → disk)</criterion>
|
|
688
|
+
<criterion>Status cascade validated (work items → intents)</criterion>
|
|
689
|
+
<criterion>Run artifact completeness checked</criterion>
|
|
690
|
+
<criterion>Stale/interrupted runs detected</criterion>
|
|
691
|
+
<criterion>Frontmatter sync checked</criterion>
|
|
692
|
+
<criterion>Issues reported in clear table format</criterion>
|
|
693
|
+
<criterion>User given choice: fix-all, review, skip, check-code</criterion>
|
|
694
|
+
<criterion>Fixes logged to maintenance-log.md</criterion>
|
|
695
|
+
<criterion>Code verification available for ambiguous cases</criterion>
|
|
102
696
|
</success_criteria>
|
|
@@ -19,7 +19,7 @@ You are now the **FIRE Builder Agent** for specsmd.
|
|
|
19
19
|
|
|
20
20
|
## Critical First Steps
|
|
21
21
|
|
|
22
|
-
1. **Read Config**: `.specsmd/fire/
|
|
22
|
+
1. **Read Config**: `.specsmd/fire/memory-bank.yaml`
|
|
23
23
|
2. **Read State**: `.specs-fire/state.yaml`
|
|
24
24
|
3. **Determine Mode**:
|
|
25
25
|
- Active run exists → Resume execution
|
|
@@ -19,7 +19,7 @@ You are now the **FIRE Planner Agent** for specsmd.
|
|
|
19
19
|
|
|
20
20
|
## Critical First Steps
|
|
21
21
|
|
|
22
|
-
1. **Read Config**: `.specsmd/fire/
|
|
22
|
+
1. **Read Config**: `.specsmd/fire/memory-bank.yaml`
|
|
23
23
|
2. **Read State**: `.specs-fire/state.yaml`
|
|
24
24
|
3. **Determine Mode**:
|
|
25
25
|
- No active intent → `intent-capture` skill
|
|
@@ -19,7 +19,7 @@ You are now the **FIRE Orchestrator** for specsmd.
|
|
|
19
19
|
|
|
20
20
|
## Critical First Steps
|
|
21
21
|
|
|
22
|
-
1. **Read Config**: `.specsmd/fire/
|
|
22
|
+
1. **Read Config**: `.specsmd/fire/memory-bank.yaml`
|
|
23
23
|
2. **Check Initialization**: Verify `.specs-fire/state.yaml` exists
|
|
24
24
|
3. **If NOT initialized** → Execute `project-init` skill
|
|
25
25
|
4. **If initialized** → Execute `route` skill to determine next action
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# FIRE Flow Configuration
|
|
2
2
|
# Fast Intent-Run Engineering - Simplified AI-native development
|
|
3
3
|
|
|
4
|
-
# FIRE Flow Version
|
|
4
|
+
# FIRE Flow Version
|
|
5
5
|
version: "0.1.8"
|
|
6
6
|
|
|
7
7
|
# Artifact folder (created at project initialization)
|
|
@@ -55,14 +55,23 @@ state:
|
|
|
55
55
|
- title: "Intent title"
|
|
56
56
|
- status: "pending | in_progress | completed"
|
|
57
57
|
- work_items: "List of work items"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
# Each work item in intents[] has:
|
|
59
|
+
# - id: "Work item identifier"
|
|
60
|
+
# - title: "Work item title"
|
|
61
|
+
# - status: "pending | in_progress | completed | blocked"
|
|
62
|
+
# - complexity: "low | medium | high"
|
|
63
|
+
# - mode: "autopilot | confirm | validate (derived from complexity + autonomy_bias)"
|
|
64
|
+
# - depends_on: "List of work item IDs this depends on (optional)"
|
|
64
65
|
runs:
|
|
66
|
+
- active: "List of currently active runs (supports multiple parallel runs)"
|
|
65
67
|
- completed: "List of completed runs with id, work_item, intent, completed timestamp"
|
|
68
|
+
# Each run (active or completed) has:
|
|
69
|
+
# - id: "Run ID (e.g., run-001)"
|
|
70
|
+
# - scope: "single | batch | wide"
|
|
71
|
+
# - work_items: "List of work items in this run"
|
|
72
|
+
# - current_item: "Work item currently being executed (active runs only)"
|
|
73
|
+
# - started: "ISO 8601 timestamp"
|
|
74
|
+
# - completed: "ISO 8601 timestamp (completed runs only)"
|
|
66
75
|
|
|
67
76
|
# Data Conventions
|
|
68
77
|
conventions:
|
|
@@ -88,23 +97,31 @@ naming:
|
|
|
88
97
|
example: "run-001/"
|
|
89
98
|
note: "Sequential 3-digit number, folder per run"
|
|
90
99
|
contents:
|
|
91
|
-
- "
|
|
92
|
-
- "
|
|
93
|
-
- "test-report.md"
|
|
94
|
-
- "
|
|
100
|
+
- "run.md" # Run log (created by init-run.js)
|
|
101
|
+
- "plan.md" # Implementation plan (ALL modes, created BEFORE implementation)
|
|
102
|
+
- "test-report.md" # Test results and coverage (created AFTER tests pass)
|
|
103
|
+
- "review-report.md" # Code review findings (created by code-review skill)
|
|
104
|
+
- "walkthrough.md" # Implementation walkthrough (created at run completion)
|
|
95
105
|
|
|
96
106
|
# Schema Definition (Source of Truth for Agents)
|
|
97
107
|
schema:
|
|
98
108
|
state: ".specs-fire/state.yaml"
|
|
109
|
+
maintenance-log: ".specs-fire/maintenance-log.md"
|
|
110
|
+
|
|
111
|
+
# Intent Artifacts
|
|
99
112
|
intents: ".specs-fire/intents/{intent-id}/"
|
|
100
113
|
intent-brief: ".specs-fire/intents/{intent-id}/brief.md"
|
|
101
114
|
work-items: ".specs-fire/intents/{intent-id}/work-items/"
|
|
102
115
|
work-item: ".specs-fire/intents/{intent-id}/work-items/{work-item-id}.md"
|
|
116
|
+
design-doc: ".specs-fire/intents/{intent-id}/work-items/{work-item-id}-design.md"
|
|
117
|
+
|
|
118
|
+
# Run Artifacts
|
|
103
119
|
runs: ".specs-fire/runs/"
|
|
104
120
|
run-folder: ".specs-fire/runs/{run-id}/"
|
|
105
|
-
plan: ".specs-fire/runs/{run-id}/plan.md"
|
|
106
121
|
run-log: ".specs-fire/runs/{run-id}/run.md"
|
|
122
|
+
plan: ".specs-fire/runs/{run-id}/plan.md"
|
|
107
123
|
test-report: ".specs-fire/runs/{run-id}/test-report.md"
|
|
124
|
+
review-report: ".specs-fire/runs/{run-id}/review-report.md"
|
|
108
125
|
walkthrough: ".specs-fire/runs/{run-id}/walkthrough.md"
|
|
109
126
|
|
|
110
127
|
# Root Standards
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specsmd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Multi-agent orchestration system for AI-native software development. Delivers AI-DLC, Agile, and custom SDLC flows as markdown-based agent systems.",
|
|
5
5
|
"main": "lib/installer.js",
|
|
6
6
|
"bin": {
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: project-migrate
|
|
3
|
-
description: Migrate existing FIRE project to latest version. Adds constitution.md, updates schema, and optionally detects monorepo modules.
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
<objective>
|
|
8
|
-
Upgrade an existing FIRE project to the latest version, adding new features
|
|
9
|
-
(constitution.md, hierarchical standards) while preserving all existing work.
|
|
10
|
-
</objective>
|
|
11
|
-
|
|
12
|
-
<triggers>
|
|
13
|
-
- User runs `/fire-migrate`
|
|
14
|
-
- Orchestrator detects outdated project version
|
|
15
|
-
</triggers>
|
|
16
|
-
|
|
17
|
-
<principles critical="true">
|
|
18
|
-
<principle>NEVER delete or modify existing intents/work-items/runs</principle>
|
|
19
|
-
<principle>Create backup before any changes</principle>
|
|
20
|
-
<principle>Migration is idempotent — safe to run multiple times</principle>
|
|
21
|
-
<principle>Show changes before applying</principle>
|
|
22
|
-
</principles>
|
|
23
|
-
|
|
24
|
-
<flow>
|
|
25
|
-
<step n="1" title="Detect Current Version">
|
|
26
|
-
<action>Check if .specs-fire/ exists</action>
|
|
27
|
-
<check if="no .specs-fire/">
|
|
28
|
-
<output>Not a FIRE project. Use /fire to initialize.</output>
|
|
29
|
-
<exit/>
|
|
30
|
-
</check>
|
|
31
|
-
|
|
32
|
-
<action>Read .specs-fire/state.yaml</action>
|
|
33
|
-
<action>Check project.fire_version field</action>
|
|
34
|
-
<action>Read FIRE flow version from memory-bank.yaml</action>
|
|
35
|
-
|
|
36
|
-
<version_detection>
|
|
37
|
-
| Check | Meaning |
|
|
38
|
-
|-------|---------|
|
|
39
|
-
| project.fire_version missing | Pre-0.1.8 project |
|
|
40
|
-
| project.fire_version < current | Needs migration |
|
|
41
|
-
| project.fire_version == current | Up to date |
|
|
42
|
-
|
|
43
|
-
Also check for feature indicators:
|
|
44
|
-
| Missing Feature | Added In |
|
|
45
|
-
|-----------------|----------|
|
|
46
|
-
| constitution.md | 0.1.8 |
|
|
47
|
-
| workspace.structure | 0.1.8 |
|
|
48
|
-
</version_detection>
|
|
49
|
-
|
|
50
|
-
<check if="already up to date">
|
|
51
|
-
<output>Project is already at the latest version ({current_version}). No migration needed.</output>
|
|
52
|
-
<exit/>
|
|
53
|
-
</check>
|
|
54
|
-
|
|
55
|
-
<output>
|
|
56
|
-
Current version: {project_fire_version or "pre-0.1.8"}
|
|
57
|
-
Latest version: {fire_flow_version}
|
|
58
|
-
Migration required.
|
|
59
|
-
</output>
|
|
60
|
-
</step>
|
|
61
|
-
|
|
62
|
-
<step n="2" title="Analyze Migration Scope">
|
|
63
|
-
<action>Determine what needs to be migrated:</action>
|
|
64
|
-
|
|
65
|
-
<check_constitution>
|
|
66
|
-
Does .specs-fire/standards/constitution.md exist?
|
|
67
|
-
If no → needs_constitution = true
|
|
68
|
-
</check_constitution>
|
|
69
|
-
|
|
70
|
-
<check_schema>
|
|
71
|
-
Does state.yaml have workspace.structure field?
|
|
72
|
-
If no → needs_schema_update = true
|
|
73
|
-
</check_schema>
|
|
74
|
-
|
|
75
|
-
<check_monorepo>
|
|
76
|
-
Is this actually a monorepo? Check for:
|
|
77
|
-
- nx.json, turbo.json, pnpm-workspace.yaml, lerna.json
|
|
78
|
-
- package.json with "workspaces"
|
|
79
|
-
- Multiple package/dependency manifests
|
|
80
|
-
If detected → is_monorepo = true
|
|
81
|
-
</check_monorepo>
|
|
82
|
-
|
|
83
|
-
<output>
|
|
84
|
-
Migration Plan:
|
|
85
|
-
┌─────────────────────────────────────────────────────┐
|
|
86
|
-
│ Changes to be made: │
|
|
87
|
-
{{#if needs_constitution}}
|
|
88
|
-
│ ✓ Create constitution.md (universal policies) │
|
|
89
|
-
{{/if}}
|
|
90
|
-
{{#if needs_schema_update}}
|
|
91
|
-
│ ✓ Update state.yaml schema │
|
|
92
|
-
{{/if}}
|
|
93
|
-
{{#if is_monorepo}}
|
|
94
|
-
│ ? Monorepo detected — offer module standards │
|
|
95
|
-
{{/if}}
|
|
96
|
-
│ │
|
|
97
|
-
│ Will NOT change: │
|
|
98
|
-
│ • Existing intents and work items │
|
|
99
|
-
│ • Existing runs and logs │
|
|
100
|
-
│ • Existing standards (only add new ones) │
|
|
101
|
-
└─────────────────────────────────────────────────────┘
|
|
102
|
-
</output>
|
|
103
|
-
</step>
|
|
104
|
-
|
|
105
|
-
<step n="3" title="Create Backup">
|
|
106
|
-
<action>Create backup: cp -r .specs-fire .specs-fire-backup-{timestamp}</action>
|
|
107
|
-
<output>Backup created: .specs-fire-backup-{timestamp}</output>
|
|
108
|
-
</step>
|
|
109
|
-
|
|
110
|
-
<step n="4" title="Confirm Migration">
|
|
111
|
-
<ask>
|
|
112
|
-
Ready to migrate. Backup saved.
|
|
113
|
-
|
|
114
|
-
Proceed with migration? [Y/n]
|
|
115
|
-
</ask>
|
|
116
|
-
</step>
|
|
117
|
-
|
|
118
|
-
<step n="5" title="Add Constitution" if="needs_constitution">
|
|
119
|
-
<ask>
|
|
120
|
-
How should I create constitution.md?
|
|
121
|
-
|
|
122
|
-
[a] Auto-generate — analyze project (git, CI, existing patterns)
|
|
123
|
-
[d] Default — use standard template
|
|
124
|
-
[c] Custom — I'll provide the content
|
|
125
|
-
</ask>
|
|
126
|
-
|
|
127
|
-
<check if="response == a">
|
|
128
|
-
<action>Analyze project for constitution content:</action>
|
|
129
|
-
<substep>Check .gitignore, CI config for workflow hints</substep>
|
|
130
|
-
<substep>Check existing PR templates, CONTRIBUTING.md</substep>
|
|
131
|
-
<substep>Infer commit style from git log</substep>
|
|
132
|
-
<action>Generate constitution.md from findings</action>
|
|
133
|
-
</check>
|
|
134
|
-
|
|
135
|
-
<check if="response == d">
|
|
136
|
-
<action>Create constitution.md from default template</action>
|
|
137
|
-
</check>
|
|
138
|
-
|
|
139
|
-
<check if="response == c">
|
|
140
|
-
<ask>Please describe your key policies (git workflow, PR process, security).</ask>
|
|
141
|
-
<action>Generate constitution.md from input</action>
|
|
142
|
-
</check>
|
|
143
|
-
|
|
144
|
-
<action>Write to .specs-fire/standards/constitution.md</action>
|
|
145
|
-
<output>Created: .specs-fire/standards/constitution.md</output>
|
|
146
|
-
</step>
|
|
147
|
-
|
|
148
|
-
<step n="6" title="Update State Schema" if="needs_schema_update">
|
|
149
|
-
<action>Read current state.yaml</action>
|
|
150
|
-
<action>Add missing fields with defaults:</action>
|
|
151
|
-
<substep>project.fire_version: "{current_fire_flow_version}"</substep>
|
|
152
|
-
<substep>workspace.structure: "monolith" (or "monorepo" if detected)</substep>
|
|
153
|
-
<action>Write updated state.yaml (preserve all existing data)</action>
|
|
154
|
-
<output>Updated: .specs-fire/state.yaml</output>
|
|
155
|
-
</step>
|
|
156
|
-
|
|
157
|
-
<step n="7" title="Monorepo Module Setup" if="is_monorepo" optional="true">
|
|
158
|
-
<action>Discover modules (same as project-init):</action>
|
|
159
|
-
<substep>Check workspace config for project list</substep>
|
|
160
|
-
<substep>Scan packages/*, apps/*, services/*, libs/*</substep>
|
|
161
|
-
<substep>Analyze each module's tech stack</substep>
|
|
162
|
-
|
|
163
|
-
<ask>
|
|
164
|
-
This appears to be a monorepo. Found {{module_count}} modules:
|
|
165
|
-
|
|
166
|
-
{{#each modules}}
|
|
167
|
-
• {{path}} ({{language}})
|
|
168
|
-
{{/each}}
|
|
169
|
-
|
|
170
|
-
Create module-specific standards?
|
|
171
|
-
[y] Yes — create for all modules
|
|
172
|
-
[s] Select — choose which modules
|
|
173
|
-
[n] No — skip for now
|
|
174
|
-
</ask>
|
|
175
|
-
|
|
176
|
-
<check if="response == y or response == s">
|
|
177
|
-
<action>For each selected module:</action>
|
|
178
|
-
<substep>Create {module}/.specs-fire/standards/</substep>
|
|
179
|
-
<substep>Generate tech-stack.md with detected settings</substep>
|
|
180
|
-
</check>
|
|
181
|
-
</step>
|
|
182
|
-
|
|
183
|
-
<step n="8" title="Verify Migration">
|
|
184
|
-
<action>Verify migration completed:</action>
|
|
185
|
-
<substep>Read state.yaml — valid YAML?</substep>
|
|
186
|
-
<substep>Check new files exist</substep>
|
|
187
|
-
<substep>Ensure no existing files corrupted</substep>
|
|
188
|
-
|
|
189
|
-
<check if="verification fails">
|
|
190
|
-
<output>Migration failed. Restoring from backup...</output>
|
|
191
|
-
<action>rm -rf .specs-fire && mv .specs-fire-backup-{timestamp} .specs-fire</action>
|
|
192
|
-
<output>Restored. Please report this issue.</output>
|
|
193
|
-
<exit status="error"/>
|
|
194
|
-
</check>
|
|
195
|
-
</step>
|
|
196
|
-
|
|
197
|
-
<step n="9" title="Report">
|
|
198
|
-
<output>
|
|
199
|
-
Migration complete!
|
|
200
|
-
|
|
201
|
-
Changes made:
|
|
202
|
-
{{#each changes_made}}
|
|
203
|
-
✓ {{description}}
|
|
204
|
-
{{/each}}
|
|
205
|
-
|
|
206
|
-
Backup preserved at: .specs-fire-backup-{timestamp}
|
|
207
|
-
(Delete once you've verified everything works)
|
|
208
|
-
|
|
209
|
-
New features available:
|
|
210
|
-
• Constitution: Universal policies in constitution.md
|
|
211
|
-
{{#if is_monorepo}}
|
|
212
|
-
• Monorepo: Module-specific standards supported
|
|
213
|
-
{{/if}}
|
|
214
|
-
</output>
|
|
215
|
-
</step>
|
|
216
|
-
</flow>
|
|
217
|
-
|
|
218
|
-
<safety_guarantees>
|
|
219
|
-
<guarantee>Backup created before any changes</guarantee>
|
|
220
|
-
<guarantee>Idempotent — running twice is safe</guarantee>
|
|
221
|
-
<guarantee>Verify after — validates migration succeeded</guarantee>
|
|
222
|
-
<guarantee>Restore on failure — automatic rollback</guarantee>
|
|
223
|
-
<guarantee>Never deletes — only adds, never removes</guarantee>
|
|
224
|
-
</safety_guarantees>
|
|
225
|
-
|
|
226
|
-
<success_criteria>
|
|
227
|
-
<criterion>Current version detected correctly</criterion>
|
|
228
|
-
<criterion>Backup created before changes</criterion>
|
|
229
|
-
<criterion>constitution.md added if missing</criterion>
|
|
230
|
-
<criterion>state.yaml schema updated if needed</criterion>
|
|
231
|
-
<criterion>Monorepo modules detected and offered (if applicable)</criterion>
|
|
232
|
-
<criterion>Migration verified successfully</criterion>
|
|
233
|
-
<criterion>No existing data lost or corrupted</criterion>
|
|
234
|
-
</success_criteria>
|