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.
@@ -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
- if (!state.active_run) {
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
- 'No active run found in state.yaml.',
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
- if (state.active_run.id !== runId) {
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 = state.active_run.work_items || [];
269
- const currentItemId = state.active_run.current_item;
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 state
301
- state.active_run.work_items = workItems;
302
- state.active_run.current_item = nextItem ? nextItem.id : null;
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, state.active_run, completionParams, completedTime, false);
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 (!state.active_run) {
339
- throw fireError(
340
- 'No active run found in state.yaml.',
341
- 'COMPLETE_040',
342
- 'The run may have already been completed or was never started.'
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
- if (state.active_run.id !== runId) {
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 ID mismatch. Active run is "${state.active_run.id}" but trying to complete "${runId}".`,
349
- 'COMPLETE_041',
350
- `Complete the active run "${state.active_run.id}" first.`
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 = state.active_run.work_items || [];
356
- const scope = state.active_run.scope || 'single';
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
- state.active_run.work_items = workItems;
367
- state.active_run.current_item = null;
371
+ activeRun.work_items = workItems;
372
+ activeRun.current_item = null;
368
373
 
369
374
  // Update run log
370
- updateRunLog(runLogPath, state.active_run, completionParams, completedTime, true);
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 = existingCompleted.some(r => r.id === runId);
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
- // Update state
409
- state.active_run = null;
410
- state.runs = {
411
- completed: alreadyRecorded ? existingCompleted : [...existingCompleted, completedRun],
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
- // Check for existing active run
321
- if (state.active_run) {
322
- throw fireError(
323
- `A run is already active: "${state.active_run.id}".`,
324
- 'INIT_080',
325
- `Complete or cancel run "${state.active_run.id}" before starting a new one.`
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
- // Update state with active run
349
- state.active_run = {
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/fire-config.yaml` for schema</action>
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
- framework: fire-v1
82
+ fire_version: "0.1.8"
83
83
 
84
84
  workspace:
85
85
  type: brownfield
86
86
  structure: monolith
87
- default_mode: confirm
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
- active_run: null # or { id: run-001, work_item: session-management }
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
 
@@ -9,7 +9,7 @@ Analyze project state and route user to the appropriate agent.
9
9
  </objective>
10
10
 
11
11
  <triggers>
12
- - User runs `/fire` on initialized project
12
+ - User runs `/specsmd-fire` on initialized project
13
13
  - After any agent completes its task
14
14
  </triggers>
15
15
 
@@ -1,21 +1,38 @@
1
1
  ---
2
2
  name: status
3
- description: Display current FIRE project status including intents, work items, and active runs.
4
- version: 1.0.0
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 Run
60
+ ## Active Runs
43
61
 
44
- {if active_run}
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 Run
640
+ ## Active Runs
82
641
 
83
- - **Run**: run-002
84
- - **Work Item**: session-management
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: 2
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/fire-config.yaml`
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/fire-config.yaml`
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/fire-config.yaml`
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 (used by migrate skill to detect outdated projects)
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
- active_run:
59
- - id: "Current run ID"
60
- - scope: "single | batch | wide"
61
- - work_items: "List of work items in this run"
62
- - current_item: "Work item currently being executed"
63
- - started: "ISO 8601 timestamp"
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
- - "plan.md" # Approved implementation plan (confirm/validate modes)
92
- - "run.md" # Run log
93
- - "test-report.md" # Test results and coverage
94
- - "walkthrough.md" # Implementation walkthrough
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.9",
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>