specflow-cc 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to SpecFlow will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.13.0] - 2026-02-11
9
+
10
+ ### Added
11
+
12
+ - **Autopilot mode** (`/sf:autopilot`) — run the full spec lifecycle autonomously
13
+ - Single spec: `/sf:autopilot` or `/sf:autopilot SPEC-XXX`
14
+ - Batch mode: `/sf:autopilot --all` processes entire queue sequentially
15
+ - Cycle detection: configurable limits for audit (default: 3) and fix (default: 3) cycles
16
+ - Graceful halt on `needs_decomposition` or `paused` specs
17
+ - Summary report with per-spec outcomes and cycle counts
18
+ - Agent failure handling: continues batch on single-spec failure
19
+ - Configurable via `.specflow/config.json` under `"autopilot"` key
20
+
21
+ ### Changed
22
+
23
+ - **Replaced all Bash/awk/sed markdown mutations** with Read+Write tool instructions across 13 agent and command files
24
+ - Eliminates fragile shell-based file editing that could corrupt markdown structure
25
+ - All STATE.md, spec, and archive updates now use explicit Read→Write pattern
26
+ - Affected: spec-creator, spec-auditor, spec-reviser, spec-splitter, spec-executor, spec-executor-orchestrator, impl-reviewer, and 6 command files
27
+
28
+ - `/sf:help` — added Autonomous Execution section with autopilot commands
29
+ - README — added autopilot to workflow diagram, commands table, and typical session
30
+
31
+ ---
32
+
8
33
  ## [1.12.0] - 2026-02-10
9
34
 
10
35
  ### Added
package/README.md CHANGED
@@ -241,6 +241,8 @@ Your spec becomes documentation: why the code exists, what decisions were made,
241
241
  ↓ ↓ ↓
242
242
  /sf:revise /sf:fix (optional UAT)
243
243
  (if needed) (if needed)
244
+
245
+ /sf:autopilot — runs the entire flow above automatically
244
246
  ```
245
247
 
246
248
  **Key principle:** Audits and reviews run in fresh context — no bias from creation.
@@ -312,6 +314,7 @@ Six months later, you can read the spec and understand not just *what* was built
312
314
  | `/sf:fix` | Fix based on review feedback |
313
315
  | `/sf:verify` | Interactive user acceptance testing |
314
316
  | `/sf:done` | Complete and archive |
317
+ | `/sf:autopilot` | Run full lifecycle autonomously |
315
318
 
316
319
  **Quick mode:**
317
320
 
@@ -455,6 +458,10 @@ Use `max` for maximum quality everywhere, `quality` for critical features, `budg
455
458
  /sf:review # Fresh context review
456
459
  /sf:verify # Manual verification
457
460
  /sf:done # Archive
461
+
462
+ # Or skip manual steps — run everything autonomously
463
+ /sf:autopilot # Process active spec end-to-end
464
+ /sf:autopilot --all # Process entire queue
458
465
  ```
459
466
 
460
467
  ---
@@ -288,6 +288,14 @@ Append to specification's Review History:
288
288
  - If APPROVED: Status → "done", Next Step → "/sf:done"
289
289
  - If CHANGES_REQUESTED: Status → "review", Next Step → "/sf:fix"
290
290
 
291
+ Update STATE.md by reading the current file content, then writing the updated file with:
292
+ - "**Status:**" line changed to the new status
293
+ - "**Next Step:**" line changed to the new next step
294
+ - No other content modified
295
+
296
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
297
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
298
+
291
299
  </process>
292
300
 
293
301
  <output>
@@ -389,6 +389,14 @@ Update ONLY the Current Position section:
389
389
  - Status → "review"
390
390
  - Next Step → "/sf:review"
391
391
 
392
+ Update STATE.md by reading the current file content, then writing the updated file with:
393
+ - "**Status:**" line changed to the new status
394
+ - "**Next Step:**" line changed to the new next step
395
+ - No other content modified
396
+
397
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
398
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
399
+
392
400
  **CRITICAL — DO NOT go beyond this:**
393
401
  - Do NOT move the spec to Completed Specifications table
394
402
  - Do NOT remove the spec from Queue table
@@ -685,6 +685,14 @@ Update status:
685
685
  - If NEEDS_DECOMPOSITION: Status → "needs_decomposition", Next Step → "/sf:split or /sf:run --parallel"
686
686
  - If NEEDS_REVISION: Status → "revision_requested", Next Step → "/sf:revise"
687
687
 
688
+ Update STATE.md by reading the current file content, then writing the updated file with:
689
+ - "**Status:**" line changed to the new status
690
+ - "**Next Step:**" line changed to the new next step
691
+ - No other content modified
692
+
693
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
694
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
695
+
688
696
  </process>
689
697
 
690
698
  <output>
@@ -241,6 +241,16 @@ Update `.specflow/STATE.md`:
241
241
  - Set Next Step to "/sf:audit"
242
242
  - Add spec to Queue
243
243
 
244
+ Update STATE.md by reading the current file content, then writing the updated file with:
245
+ - "**Active Specification:**" line changed to the new spec
246
+ - "**Status:**" line changed to "drafting"
247
+ - "**Next Step:**" line changed to "/sf:audit"
248
+ - Queue table updated with new spec entry
249
+ - No other content modified
250
+
251
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
252
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
253
+
244
254
  **If `<prior_discussion>` provided:**
245
255
  Update the discussion file (PRE-XXX.md or DISC-XXX.md):
246
256
  - Set `used_by: SPEC-XXX` in frontmatter
@@ -330,6 +330,10 @@ Write `.specflow/execution/SPEC-XXX-state.json`:
330
330
  | SPEC-XXX | orchestrated | Wave 0/{total} (0%) | {timestamp} |
331
331
  ```
332
332
 
333
+ Update STATE.md by reading the current file content, then writing the updated file with the Execution Status table row added/updated.
334
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
335
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
336
+
333
337
  ## Step 3: Execute Waves
334
338
 
335
339
  For each wave:
@@ -597,6 +601,10 @@ After wave completes (all groups done):
597
601
  | SPEC-XXX | orchestrated | Wave 2/{total} (67%) | {timestamp} |
598
602
  ```
599
603
 
604
+ Update STATE.md by reading the current file content, then writing the updated file with the Execution Status table row updated for this wave.
605
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
606
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
607
+
600
608
  ## Step 4: Aggregate Results
601
609
 
602
610
  Combine all worker results:
@@ -683,6 +691,10 @@ rm .specflow/execution/SPEC-XXX-state.json
683
691
  - Change row to show "Complete" or remove row entirely
684
692
  - Or archive: `mv .specflow/execution/SPEC-XXX-state.json .specflow/execution/archive/`
685
693
 
694
+ Update STATE.md by reading the current file content, then writing the updated file with the Execution Status table row removed or updated to "Complete".
695
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
696
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
697
+
686
698
  **Note:** Only delete on FULL success. If any groups failed or are partial, keep state file for potential retry.
687
699
 
688
700
  ## Step 7: Update STATE.md
@@ -692,6 +704,15 @@ Update ONLY the Current Position section:
692
704
  - Next Step → "/sf:review"
693
705
  - Remove or update Execution Status row
694
706
 
707
+ Update STATE.md by reading the current file content, then writing the updated file with:
708
+ - "**Status:**" line changed to the new status
709
+ - "**Next Step:**" line changed to the new next step
710
+ - Execution Status row removed or updated
711
+ - No other content modified
712
+
713
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
714
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
715
+
695
716
  **CRITICAL — DO NOT go beyond this:**
696
717
  - Do NOT move the spec to Completed Specifications table
697
718
  - Do NOT remove the spec from Queue table
@@ -268,6 +268,14 @@ Update ONLY the Current Position section:
268
268
  - Status → "review"
269
269
  - Next Step → "/sf:review"
270
270
 
271
+ Update STATE.md by reading the current file content, then writing the updated file with:
272
+ - "**Status:**" line changed to the new status
273
+ - "**Next Step:**" line changed to the new next step
274
+ - No other content modified
275
+
276
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
277
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
278
+
271
279
  **CRITICAL — DO NOT go beyond this:**
272
280
  - Do NOT move the spec to Completed Specifications table
273
281
  - Do NOT remove the spec from Queue table
@@ -139,6 +139,14 @@ Set status to "auditing" (ready for re-audit).
139
139
  - Status → "auditing"
140
140
  - Next Step → "/sf:audit"
141
141
 
142
+ Update STATE.md by reading the current file content, then writing the updated file with:
143
+ - "**Status:**" line changed to the new status
144
+ - "**Next Step:**" line changed to the new next step
145
+ - No other content modified
146
+
147
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
148
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
149
+
142
150
  </process>
143
151
 
144
152
  <output>
@@ -188,6 +188,16 @@ Update `.specflow/STATE.md`:
188
188
  - Set first child (no dependencies) as Active Specification
189
189
  - Add note to Decisions: "Split SPEC-XXX into N parts"
190
190
 
191
+ Update STATE.md by reading the current file content, then writing the updated file with:
192
+ - Parent spec removed from Queue table
193
+ - All child specs added to Queue table in dependency order
194
+ - First child (no dependencies) set as Active Specification
195
+ - Decisions section updated with split note
196
+ - No other content modified
197
+
198
+ Use the Read tool to read `.specflow/STATE.md`, then use the Write tool to write the updated content.
199
+ Do NOT use Bash (awk, sed, or echo) to modify `.specflow/STATE.md`.
200
+
191
201
  </process>
192
202
 
193
203
  <output>
@@ -242,75 +242,17 @@ The agent will:
242
242
 
243
243
  After the agent updates STATE.md, check if rotation is needed:
244
244
 
245
- ```bash
246
- LINE_COUNT=$(wc -l < .specflow/STATE.md)
247
- if [ $LINE_COUNT -gt 100 ]; then
248
- echo "STATE.md exceeds 100 lines ($LINE_COUNT), rotating old decisions..."
249
-
250
- # Parse decisions table and extract all decisions
251
- DECISIONS=$(awk '/^## Decisions$/ { found=1; next } /^## / && found { exit } found { print }' .specflow/STATE.md | grep -E '^\| [0-9]{4}-' || true)
252
- DECISION_COUNT=$(echo "$DECISIONS" | grep -c '^|' || echo 0)
253
-
254
- if [ "$DECISION_COUNT" -gt 7 ]; then
255
- # Keep only 5 most recent decisions
256
- RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
257
- OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
258
- OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
259
-
260
- # Create or append to archive
261
- if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
262
- cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
263
- # SpecFlow Decisions Archive
264
-
265
- Historical decisions rotated from STATE.md to maintain compactness.
266
-
267
- ## Archived Decisions
268
-
269
- | Date | Decision |
270
- |------|----------|
271
- EOF
272
- fi
273
-
274
- # Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
275
- TEMP_OLD=$(mktemp)
276
- echo "$OLD_DECISIONS" > "$TEMP_OLD"
277
-
278
- # Append old decisions to archive (insert after table header)
279
- TEMP_ARCHIVE=$(mktemp)
280
- awk -v oldfile="$TEMP_OLD" '
281
- /^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
282
- {print}
283
- ' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
284
- mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
285
- rm -f "$TEMP_OLD"
286
-
287
- # Write recent decisions to temp file for awk to read
288
- TEMP_RECENT=$(mktemp)
289
- echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
290
-
291
- # Update STATE.md with only recent decisions
292
- TEMP_STATE=$(mktemp)
293
- awk -v recentfile="$TEMP_RECENT" '
294
- /^## Decisions$/ {
295
- print
296
- print ""
297
- print "| Date | Decision |"
298
- print "|------|----------|"
299
- while ((getline line < recentfile) > 0) print line
300
- close(recentfile)
301
- in_decisions=1
302
- next
303
- }
304
- /^## / && in_decisions { in_decisions=0 }
305
- !in_decisions || !/^\|/ { print }
306
- ' .specflow/STATE.md > "$TEMP_STATE"
307
- mv "$TEMP_STATE" .specflow/STATE.md
308
- rm -f "$TEMP_RECENT"
309
-
310
- echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
311
- fi
312
- fi
313
- ```
245
+ 1. Use the Read tool to read `.specflow/STATE.md` and count total lines
246
+ 2. If total lines <= 100, no action needed
247
+ 3. If total lines > 100:
248
+ a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
249
+ b. Count decision rows. If <= 7, no rotation needed
250
+ c. If > 7 decisions:
251
+ - Identify the 5 most recent decisions (last 5 rows) -- these STAY
252
+ - Identify older decisions (all rows except last 5) -- these MOVE to archive
253
+ - Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
254
+ - Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
255
+ - Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
314
256
 
315
257
  ## Step 7: Display Result
316
258
 
@@ -0,0 +1,601 @@
1
+ ---
2
+ name: sf:autopilot
3
+ description: Run full spec lifecycle autonomously (audit -> run -> review -> done)
4
+ argument-hint: "[SPEC-XXX] [--all]"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Glob
10
+ - Grep
11
+ - Task
12
+ ---
13
+
14
+ <purpose>
15
+ Run the full specification lifecycle autonomously. Reads STATE.md to determine current phase, spawns appropriate agents, advances through audit -> revise -> run -> review -> fix -> done cycle without manual intervention. Includes cycle-detection safeguards to prevent infinite loops.
16
+ </purpose>
17
+
18
+ <context>
19
+ @.specflow/STATE.md
20
+ @.specflow/specs/SPEC-*.md
21
+ @.specflow/config.json
22
+ </context>
23
+
24
+ <workflow>
25
+
26
+ ## Step 1: Verify Initialization
27
+
28
+ ```bash
29
+ [ -d .specflow ] && echo "OK" || echo "NOT_INITIALIZED"
30
+ ```
31
+
32
+ **If NOT_INITIALIZED:**
33
+ ```
34
+ SpecFlow not initialized.
35
+
36
+ Run `/sf:init` first.
37
+ ```
38
+ Exit.
39
+
40
+ ## Step 2: Parse Arguments and Determine Mode
41
+
42
+ Parse the command argument to determine execution mode:
43
+
44
+ | Argument | Mode | Behavior |
45
+ |----------|------|----------|
46
+ | (none) | single | Process the active spec in STATE.md |
47
+ | `SPEC-XXX` | single | Set SPEC-XXX as active, then process it |
48
+ | `--all` | batch | Process all actionable specs in Queue order |
49
+
50
+ **If single mode:**
51
+ - If SPEC-XXX argument provided: update STATE.md to set it as active spec
52
+ - If no argument and no active spec exists: display error and exit
53
+
54
+ **If batch mode (--all):**
55
+ - Identify all actionable specs from Queue (any spec with status: draft, auditing, revision_requested, audited, running, review)
56
+
57
+ **Error case (single mode, no active, no argument):**
58
+ ```
59
+ No active specification to process.
60
+
61
+ Provide a spec ID: `/sf:autopilot SPEC-XXX`
62
+ Or run on all specs: `/sf:autopilot --all`
63
+ ```
64
+ Exit.
65
+
66
+ ## Step 3: Set Configuration Constants
67
+
68
+ Read `.specflow/config.json` for autopilot configuration:
69
+
70
+ ```bash
71
+ [ -f .specflow/config.json ] && cat .specflow/config.json
72
+ ```
73
+
74
+ Parse the `"autopilot"` section if it exists:
75
+
76
+ ```json
77
+ {
78
+ "autopilot": {
79
+ "max_audit_cycles": 3,
80
+ "max_fix_cycles": 3
81
+ }
82
+ }
83
+ ```
84
+
85
+ **Configuration constants:**
86
+
87
+ | Constant | Default | Description |
88
+ |----------|---------|-------------|
89
+ | MAX_AUDIT_CYCLES | 3 | Max audit->revise iterations before halt |
90
+ | MAX_FIX_CYCLES | 3 | Max review->fix iterations before halt |
91
+
92
+ If config file doesn't exist or autopilot section is missing, use defaults.
93
+
94
+ ## Step 4: Initialize Tracking State
95
+
96
+ Initialize per-spec tracking variables (maintained in command memory, not persisted to files):
97
+
98
+ ```
99
+ audit_cycles = 0
100
+ fix_cycles = 0
101
+ specs_processed = [] (batch mode)
102
+ specs_failed = [] (batch mode)
103
+ current_spec = null
104
+ ```
105
+
106
+ ## Step 5: Main Loop (per spec)
107
+
108
+ ### 5.1 Load Current Spec State
109
+
110
+ Read `.specflow/STATE.md` to get active specification.
111
+ Read `.specflow/specs/SPEC-XXX.md` to get frontmatter status.
112
+
113
+ ### 5.2 Determine Current Phase
114
+
115
+ Based on spec status, determine the phase and action:
116
+
117
+ | Spec Status | Phase | Action |
118
+ |-------------|-------|--------|
119
+ | `draft` | audit | Spawn spec-auditor agent |
120
+ | `auditing` | audit | Spawn spec-auditor agent |
121
+ | `revision_requested` | revise | Spawn spec-reviser agent with scope "all" |
122
+ | `audited` | run | Spawn spec-executor or spec-executor-orchestrator agent |
123
+ | `running` | run | Spawn spec-executor or spec-executor-orchestrator agent |
124
+ | `review` | review-or-fix | Check for latest review result (see 5.3) |
125
+ | `needs_decomposition` | halt | Halt with decomposition message |
126
+ | `paused` | halt | Halt with paused message |
127
+ | `done` | done | Run done logic (archive, update STATE.md) |
128
+
129
+ **Halt messages:**
130
+
131
+ **If `needs_decomposition`:**
132
+ ```
133
+ Spec SPEC-XXX requires decomposition.
134
+
135
+ Run `/sf:split` manually, then restart autopilot.
136
+ ```
137
+ Record as failed in batch mode. Exit in single mode.
138
+
139
+ **If `paused`:**
140
+ ```
141
+ Spec SPEC-XXX is paused.
142
+
143
+ Resume with `/sf:resume` first.
144
+ ```
145
+ Record as failed in batch mode. Exit in single mode.
146
+
147
+ ### 5.3 Review Phase Logic
148
+
149
+ When spec status is `review`, inspect the Review History section:
150
+
151
+ **If no review exists yet OR last review entry is a Fix Response:**
152
+ - Spawn impl-reviewer agent
153
+
154
+ **If last review entry is APPROVED:**
155
+ - Proceed to done phase (5.5)
156
+
157
+ **If last review entry is CHANGES_REQUESTED:**
158
+ - Spawn spec-executor in fix mode with scope "all"
159
+
160
+ ### 5.4 Spawn Agent for Phase
161
+
162
+ Spawn the appropriate agent based on phase (see Step 6 for details).
163
+
164
+ Include `<autopilot>true</autopilot>` context tag in all Task prompts.
165
+
166
+ **Agent spawning example:**
167
+
168
+ ```
169
+ Task(prompt="
170
+ <specification>
171
+ @.specflow/specs/SPEC-XXX.md
172
+ </specification>
173
+
174
+ <project_context>
175
+ @.specflow/PROJECT.md
176
+ </project_context>
177
+
178
+ <autopilot>true</autopilot>
179
+
180
+ Execute this specification following the spec-executor agent instructions.
181
+ Implement all requirements with atomic commits.
182
+ ", subagent_type="sf-spec-executor", model="{profile_model}", description="Execute specification (autopilot mode)")
183
+ ```
184
+
185
+ ### 5.5 After Agent Completes
186
+
187
+ 1. **Re-read STATE.md and spec file** to get updated status
188
+ 2. **Check STATE.md size and rotate if needed:**
189
+ - Use Read tool to read `.specflow/STATE.md` and count total lines
190
+ - If total lines <= 100, no action needed
191
+ - If total lines > 100:
192
+ a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
193
+ b. Count decision rows. If <= 7, no rotation needed
194
+ c. If > 7 decisions:
195
+ - Identify the 5 most recent decisions (last 5 rows) -- these STAY
196
+ - Identify older decisions (all rows except last 5) -- these MOVE to archive
197
+ - Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
198
+ - Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
199
+ - Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
200
+
201
+ 3. **Increment cycle counters:**
202
+ - If just completed revise phase: `audit_cycles++`
203
+ - If just completed fix phase: `fix_cycles++`
204
+
205
+ 4. **Check cycle limits:**
206
+ - If `audit_cycles >= MAX_AUDIT_CYCLES`: HALT with "Audit cycle limit reached (3/3)"
207
+ - If `fix_cycles >= MAX_FIX_CYCLES`: HALT with "Fix cycle limit reached (3/3)"
208
+
209
+ 5. **Reset cycle counters when transitioning between major phases:**
210
+ - If spec transitions from audit/revise phase to run phase (status becomes "audited"): `audit_cycles = 0`
211
+ - If spec enters review/fix phase (status becomes "review"): `fix_cycles = 0`
212
+
213
+ 6. **Loop back to 5.2** with the updated status
214
+
215
+ **Halt behavior when cycle limit reached:**
216
+ 1. Leave the spec in its current state in STATE.md (do not archive, do not clear active)
217
+ 2. Record as failed in specs_failed list with reason "Audit cycle limit (3/3)" or "Fix cycle limit (3/3)"
218
+ 3. In batch mode: attempt next spec in queue (do not abort the entire batch)
219
+ 4. In single mode: proceed directly to summary report (Step 9)
220
+
221
+ ### 5.6 Done Phase (inline)
222
+
223
+ When spec reaches done status OR last review is APPROVED, execute the done logic inline:
224
+
225
+ 1. **Create archive directory:**
226
+ ```bash
227
+ mkdir -p .specflow/archive
228
+ ```
229
+
230
+ 2. **Update spec frontmatter:**
231
+ - status → "done"
232
+ - Add Completion section with timestamp and commit/review counts
233
+
234
+ ```markdown
235
+ ---
236
+
237
+ ## Completion
238
+
239
+ **Completed:** {date} {time}
240
+ **Total Commits:** {count from Execution Summary}
241
+ **Review Cycles:** {count of Review v[N] entries}
242
+ ```
243
+
244
+ 3. **Extract decisions:**
245
+ - Scan specification for technology choices mentioned in Context or Assumptions
246
+ - Scan for patterns established during implementation
247
+ - If significant decisions found, add to STATE.md Decisions table:
248
+ ```markdown
249
+ | {date} | SPEC-XXX | {decision description} |
250
+ ```
251
+
252
+ 4. **Archive specification:**
253
+ ```bash
254
+ mv .specflow/specs/SPEC-XXX.md .specflow/archive/
255
+ ```
256
+
257
+ 5. **Update STATE.md:**
258
+ - Active Specification → "none"
259
+ - Status → "idle"
260
+ - Next Step → "/sf:new or /sf:next"
261
+ - Remove SPEC-XXX row from Queue table
262
+
263
+ 6. **Check STATE.md size and rotate** (same logic as 5.5 step 2)
264
+
265
+ 7. **Create final commit:**
266
+ ```bash
267
+ git add .specflow/
268
+ git commit -m "docs(sf): complete SPEC-XXX"
269
+ ```
270
+
271
+ 8. **Record completion:**
272
+ - In batch mode: add to specs_processed list with outcome "COMPLETED"
273
+
274
+ ## Step 6: Agent Spawning Details
275
+
276
+ For each phase, determine the agent type and model profile:
277
+
278
+ | Phase | Agent | Subagent Type | Auto-Resolution |
279
+ |-------|-------|---------------|-----------------|
280
+ | audit | spec-auditor | sf-spec-auditor | N/A (no interactive prompts) |
281
+ | revise | spec-reviser | sf-spec-reviser | scope = "all" |
282
+ | run | spec-executor or spec-executor-orchestrator | sf-spec-executor / sf-spec-executor-orchestrator | Skip audit-status warning (proceed anyway) |
283
+ | review | impl-reviewer | sf-impl-reviewer | N/A (no interactive prompts) |
284
+ | fix | spec-executor (fix mode) | sf-spec-executor | scope = "all" |
285
+ | done | (inline logic) | N/A | Skip review/verify warnings (proceed anyway) |
286
+
287
+ ### 6.1 Determine Model Profile
288
+
289
+ Check `.specflow/config.json` for model profile setting:
290
+
291
+ ```bash
292
+ [ -f .specflow/config.json ] && cat .specflow/config.json | grep -o '"model_profile"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "balanced"
293
+ ```
294
+
295
+ **Profile Table:**
296
+
297
+ | Profile | spec-auditor | spec-reviser | spec-executor | spec-executor-orchestrator | spec-executor-worker | impl-reviewer |
298
+ |---------|--------------|--------------|---------------|---------------------------|---------------------|---------------|
299
+ | max | opus | opus | opus | opus | opus | opus |
300
+ | quality | opus | sonnet | opus | opus | opus | sonnet |
301
+ | balanced | opus | sonnet | sonnet | sonnet | sonnet | sonnet |
302
+ | budget | sonnet | sonnet | sonnet | sonnet | sonnet | haiku |
303
+
304
+ ### 6.2 Determine Execution Mode (run phase)
305
+
306
+ When spawning execution agent, check specification complexity:
307
+
308
+ **If `## Implementation Tasks` section exists in spec:**
309
+ - Count task groups (G1, G2, G3, etc.)
310
+ - Check for parallel opportunities (groups with no dependencies on each other)
311
+ - If groups > 1 AND parallelism exists → use `spec-executor-orchestrator`
312
+ - Otherwise → use `spec-executor`
313
+
314
+ **If no Implementation Tasks section:**
315
+ - Use `spec-executor`
316
+
317
+ ### 6.3 Agent Prompts
318
+
319
+ **Audit phase (spec-auditor):**
320
+ ```
321
+ Task(prompt="
322
+ <specification>
323
+ @.specflow/specs/SPEC-XXX.md
324
+ </specification>
325
+
326
+ <project_context>
327
+ @.specflow/PROJECT.md
328
+ </project_context>
329
+
330
+ <autopilot>true</autopilot>
331
+
332
+ Audit this specification following the spec-auditor agent instructions.
333
+ Check for completeness, clarity, feasibility, and alignment with project patterns.
334
+ ", subagent_type="sf-spec-auditor", model="{profile_model}", description="Audit specification (autopilot mode)")
335
+ ```
336
+
337
+ **Revise phase (spec-reviser):**
338
+ ```
339
+ Task(prompt="
340
+ <specification>
341
+ @.specflow/specs/SPEC-XXX.md
342
+ </specification>
343
+
344
+ <project_context>
345
+ @.specflow/PROJECT.md
346
+ </project_context>
347
+
348
+ <autopilot>true</autopilot>
349
+ <scope>all</scope>
350
+
351
+ Revise this specification to address ALL audit findings.
352
+ Follow the spec-reviser agent instructions.
353
+ ", subagent_type="sf-spec-reviser", model="{profile_model}", description="Revise specification (autopilot mode)")
354
+ ```
355
+
356
+ **Run phase (spec-executor):**
357
+ ```
358
+ Task(prompt="
359
+ <specification>
360
+ @.specflow/specs/SPEC-XXX.md
361
+ </specification>
362
+
363
+ <project_context>
364
+ @.specflow/PROJECT.md
365
+ </project_context>
366
+
367
+ <autopilot>true</autopilot>
368
+
369
+ Execute this specification following the spec-executor agent instructions.
370
+ Implement all requirements with atomic commits.
371
+ Proceed even if audit status is not 'audited'.
372
+ ", subagent_type="sf-spec-executor", model="{profile_model}", description="Execute specification (autopilot mode)")
373
+ ```
374
+
375
+ **Run phase (spec-executor-orchestrator):**
376
+ ```
377
+ Task(prompt="
378
+ <specification>
379
+ @.specflow/specs/SPEC-XXX.md
380
+ </specification>
381
+
382
+ <project_context>
383
+ @.specflow/PROJECT.md
384
+ </project_context>
385
+
386
+ <autopilot>true</autopilot>
387
+
388
+ Orchestrate execution of this large specification.
389
+ Parse task groups from Implementation Tasks section.
390
+ Determine execution waves based on dependencies.
391
+ Spawn worker subagents in parallel where possible.
392
+ Proceed even if audit status is not 'audited'.
393
+ ", subagent_type="sf-spec-executor-orchestrator", model="{profile_model}", description="Orchestrate specification execution (autopilot mode)")
394
+ ```
395
+
396
+ **Review phase (impl-reviewer):**
397
+ ```
398
+ Task(prompt="
399
+ <specification>
400
+ @.specflow/specs/SPEC-XXX.md
401
+ </specification>
402
+
403
+ <project_context>
404
+ @.specflow/PROJECT.md
405
+ </project_context>
406
+
407
+ <autopilot>true</autopilot>
408
+
409
+ Review the implementation against the specification.
410
+ Follow the impl-reviewer agent instructions.
411
+ ", subagent_type="sf-impl-reviewer", model="{profile_model}", description="Review implementation (autopilot mode)")
412
+ ```
413
+
414
+ **Fix phase (spec-executor):**
415
+ ```
416
+ Task(prompt="
417
+ <specification>
418
+ @.specflow/specs/SPEC-XXX.md
419
+ </specification>
420
+
421
+ <project_context>
422
+ @.specflow/PROJECT.md
423
+ </project_context>
424
+
425
+ <autopilot>true</autopilot>
426
+ <mode>fix</mode>
427
+ <scope>all</scope>
428
+
429
+ Fix ALL issues identified in the latest review.
430
+ Follow the spec-executor agent instructions in fix mode.
431
+ ", subagent_type="sf-spec-executor", model="{profile_model}", description="Fix implementation issues (autopilot mode)")
432
+ ```
433
+
434
+ ## Step 7: Batch Mode — Advance to Next Spec
435
+
436
+ If `--all` mode (batch execution):
437
+
438
+ 1. **Record completed spec** in specs_processed list:
439
+ - Spec ID
440
+ - Title
441
+ - Outcome (COMPLETED or reason for failure)
442
+ - Audit cycles used
443
+ - Fix cycles used
444
+
445
+ 2. **Read STATE.md Queue** for next actionable spec:
446
+ - First spec in Queue by Priority that has an actionable status
447
+ - Actionable statuses: draft, auditing, revision_requested, audited, running, review
448
+
449
+ 3. **If next spec found:**
450
+ - Update STATE.md active spec to the next spec
451
+ - Reset cycle counters: `audit_cycles = 0`, `fix_cycles = 0`
452
+ - Loop to Step 5
453
+
454
+ 4. **If no more actionable specs:**
455
+ - Proceed to Step 9 (summary report)
456
+
457
+ ## Step 8: Handle Agent Failures
458
+
459
+ If a Task agent fails to spawn or encounters an unrecoverable error:
460
+
461
+ 1. **Log the error** with full details:
462
+ - Phase where failure occurred
463
+ - Spec ID
464
+ - Error message from Task agent
465
+
466
+ 2. **Record as failed:**
467
+ - Add to specs_failed list with reason: "Agent failure: [phase] - {error message}"
468
+
469
+ 3. **Continue execution:**
470
+ - In batch mode: continue to next spec in queue (do not abort the entire batch)
471
+ - In single mode: proceed directly to summary report (Step 9)
472
+
473
+ 4. **Leave spec in current state:**
474
+ - Do not archive
475
+ - Do not modify status
476
+ - Leave in `.specflow/specs/` directory
477
+
478
+ ## Step 9: Display Summary Report
479
+
480
+ **IMPORTANT:** Output the following directly as formatted text, NOT wrapped in a markdown code block:
481
+
482
+ **Single mode:**
483
+
484
+ ```
485
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
486
+ AUTOPILOT COMPLETE
487
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
488
+
489
+ **Mode:** single
490
+ **Spec:** SPEC-XXX
491
+
492
+ ### Result
493
+
494
+ **Outcome:** {COMPLETED | HALTED}
495
+ **Audit Cycles:** {count}/{MAX_AUDIT_CYCLES}
496
+ **Fix Cycles:** {count}/{MAX_FIX_CYCLES}
497
+
498
+ {If COMPLETED:}
499
+ ✓ Specification processed from {start_status} to done
500
+ - Files created: {count}
501
+ - Files modified: {count}
502
+ - Total commits: {count}
503
+ - Total review cycles: {count}
504
+
505
+ {If HALTED:}
506
+ ✗ Halted at phase: {phase}
507
+ Reason: {reason}
508
+
509
+ ---
510
+
511
+ ## Next Steps
512
+
513
+ {If COMPLETED and queue has more specs:}
514
+ `/sf:autopilot --all` — process remaining queue
515
+
516
+ {If COMPLETED and queue is empty:}
517
+ All specs completed. Queue is empty.
518
+
519
+ {If HALTED:}
520
+ Review spec status with `/sf:status` and `/sf:show SPEC-XXX`.
521
+ Address the issue manually, then resume autopilot.
522
+ ```
523
+
524
+ **Batch mode:**
525
+
526
+ ```
527
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
528
+ AUTOPILOT COMPLETE
529
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
530
+
531
+ **Mode:** batch
532
+ **Specs Processed:** {count}
533
+ **Specs Completed:** {completed_count}
534
+ **Specs Failed:** {failed_count}
535
+
536
+ ### Results
537
+
538
+ | Spec | Title | Outcome | Audit Cycles | Fix Cycles |
539
+ |------|-------|---------|--------------|------------|
540
+ {For each spec in specs_processed:}
541
+ | SPEC-XXX | {title} | COMPLETED | 2 | 1 |
542
+
543
+ {If any failures:}
544
+ ### Failures
545
+
546
+ | Spec | Title | Halted At | Reason |
547
+ |------|-------|-----------|--------|
548
+ {For each spec in specs_failed:}
549
+ | SPEC-ZZZ | {title} | {phase} | Fix cycle limit (3/3) |
550
+
551
+ ---
552
+
553
+ ## Next Steps
554
+
555
+ {If all succeeded and queue empty:}
556
+ All specs processed successfully. Queue is empty.
557
+
558
+ {If all succeeded and queue has more:}
559
+ Queue has {count} remaining specs.
560
+ `/sf:autopilot --all` — process remaining queue
561
+
562
+ {If failures occurred:}
563
+ Failed specs remain in `.specflow/specs/` with their current status.
564
+ Review manually with `/sf:status` and `/sf:show SPEC-ZZZ`.
565
+ Fix issues, then resume with `/sf:autopilot --all`.
566
+ ```
567
+
568
+ </workflow>
569
+
570
+ <fallback>
571
+
572
+ If Task agent spawning fails for any phase, the command handles it via Step 8 (Handle Agent Failures).
573
+
574
+ The autopilot does NOT have an inline fallback for agent logic itself — it relies on the specialized agents to execute their phases correctly.
575
+
576
+ **Agent failure handling:**
577
+ 1. Log error details (phase, spec ID, error message)
578
+ 2. Record spec as failed with reason "Agent failure: [phase]"
579
+ 3. In batch mode: continue to next spec
580
+ 4. In single mode: proceed to summary report
581
+ 5. Leave spec in current state (do not archive or modify status)
582
+
583
+ This ensures one agent failure does not crash the entire autopilot run.
584
+
585
+ </fallback>
586
+
587
+ <success_criteria>
588
+ - [ ] Mode determined correctly (single vs batch)
589
+ - [ ] Configuration constants loaded from config.json
590
+ - [ ] Spec processed from current status through to "done" (single mode)
591
+ - [ ] All actionable specs processed (batch mode)
592
+ - [ ] Audit cycle limit enforced (MAX_AUDIT_CYCLES)
593
+ - [ ] Fix cycle limit enforced (MAX_FIX_CYCLES)
594
+ - [ ] Cycle counters reset when transitioning between major phases
595
+ - [ ] STATE.md decision rotation performed when needed
596
+ - [ ] Summary report displayed with accurate metrics
597
+ - [ ] AskUserQuestion never called by autopilot command itself
598
+ - [ ] STATE.md accurate at every point
599
+ - [ ] No infinite loops possible
600
+ - [ ] Agent failures handled gracefully (do not crash entire run)
601
+ </success_criteria>
@@ -228,75 +228,17 @@ If implementation established new patterns, add to Project Patterns section.
228
228
 
229
229
  After updating STATE.md, check if rotation is needed:
230
230
 
231
- ```bash
232
- LINE_COUNT=$(wc -l < .specflow/STATE.md)
233
- if [ $LINE_COUNT -gt 100 ]; then
234
- echo "STATE.md exceeds 100 lines ($LINE_COUNT), rotating old decisions..."
235
-
236
- # Parse decisions table and extract all decisions
237
- DECISIONS=$(awk '/^## Decisions$/ { found=1; next } /^## / && found { exit } found { print }' .specflow/STATE.md | grep -E '^\| [0-9]{4}-' || true)
238
- DECISION_COUNT=$(echo "$DECISIONS" | grep -c '^|' || echo 0)
239
-
240
- if [ "$DECISION_COUNT" -gt 7 ]; then
241
- # Keep only 5 most recent decisions
242
- RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
243
- OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
244
- OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
245
-
246
- # Create or append to archive
247
- if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
248
- cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
249
- # SpecFlow Decisions Archive
250
-
251
- Historical decisions rotated from STATE.md to maintain compactness.
252
-
253
- ## Archived Decisions
254
-
255
- | Date | Decision |
256
- |------|----------|
257
- EOF
258
- fi
259
-
260
- # Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
261
- TEMP_OLD=$(mktemp)
262
- echo "$OLD_DECISIONS" > "$TEMP_OLD"
263
-
264
- # Append old decisions to archive (insert after table header)
265
- TEMP_ARCHIVE=$(mktemp)
266
- awk -v oldfile="$TEMP_OLD" '
267
- /^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
268
- {print}
269
- ' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
270
- mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
271
- rm -f "$TEMP_OLD"
272
-
273
- # Write recent decisions to temp file for awk to read
274
- TEMP_RECENT=$(mktemp)
275
- echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
276
-
277
- # Update STATE.md with only recent decisions
278
- TEMP_STATE=$(mktemp)
279
- awk -v recentfile="$TEMP_RECENT" '
280
- /^## Decisions$/ {
281
- print
282
- print ""
283
- print "| Date | Decision |"
284
- print "|------|----------|"
285
- while ((getline line < recentfile) > 0) print line
286
- close(recentfile)
287
- in_decisions=1
288
- next
289
- }
290
- /^## / && in_decisions { in_decisions=0 }
291
- !in_decisions || !/^\|/ { print }
292
- ' .specflow/STATE.md > "$TEMP_STATE"
293
- mv "$TEMP_STATE" .specflow/STATE.md
294
- rm -f "$TEMP_RECENT"
295
-
296
- echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
297
- fi
298
- fi
299
- ```
231
+ 1. Use the Read tool to read `.specflow/STATE.md` and count total lines
232
+ 2. If total lines <= 100, no action needed
233
+ 3. If total lines > 100:
234
+ a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
235
+ b. Count decision rows. If <= 7, no rotation needed
236
+ c. If > 7 decisions:
237
+ - Identify the 5 most recent decisions (last 5 rows) -- these STAY
238
+ - Identify older decisions (all rows except last 5) -- these MOVE to archive
239
+ - Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
240
+ - Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
241
+ - Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
300
242
 
301
243
  ## Step 10: Create Final Commit (if needed)
302
244
 
@@ -236,6 +236,12 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
236
236
  |--------------|-----------------------------------------|
237
237
  | /sf:quick | Execute minor tasks (1-3 files) fast |
238
238
 
239
+ ## Autonomous Execution
240
+
241
+ | Command | Description |
242
+ |--------------|-----------------------------------------|
243
+ | /sf:autopilot | Run full lifecycle autonomously |
244
+
239
245
  ## Navigation
240
246
 
241
247
  | Command | Description |
@@ -296,6 +302,7 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
296
302
  5. `/sf:run` — Implement
297
303
  6. `/sf:review` — Review implementation
298
304
  7. `/sf:done` — Complete and archive
305
+ 8. Or skip steps 4-7: `/sf:autopilot` -- run everything autonomously
299
306
 
300
307
  ## Typical Session
301
308
 
@@ -309,6 +316,13 @@ Workflow: Spec → Audit → Revise → Run → Review → Fix → Done
309
316
  /sf:done # Complete
310
317
  ```
311
318
 
319
+ ## Autonomous Alternative
320
+
321
+ ```
322
+ /sf:autopilot # Process active spec end-to-end
323
+ /sf:autopilot --all # Process entire queue
324
+ ```
325
+
312
326
  ---
313
327
 
314
328
  **Detailed help:** `/sf:help <command>`
@@ -129,75 +129,17 @@ The agent will:
129
129
 
130
130
  After the agent updates STATE.md, check if rotation is needed:
131
131
 
132
- ```bash
133
- LINE_COUNT=$(wc -l < .specflow/STATE.md)
134
- if [ $LINE_COUNT -gt 100 ]; then
135
- echo "STATE.md exceeds 100 lines ($LINE_COUNT), rotating old decisions..."
136
-
137
- # Parse decisions table and extract all decisions
138
- DECISIONS=$(awk '/^## Decisions$/ { found=1; next } /^## / && found { exit } found { print }' .specflow/STATE.md | grep -E '^\| [0-9]{4}-' || true)
139
- DECISION_COUNT=$(echo "$DECISIONS" | grep -c '^|' || echo 0)
140
-
141
- if [ "$DECISION_COUNT" -gt 7 ]; then
142
- # Keep only 5 most recent decisions
143
- RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
144
- OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
145
- OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
146
-
147
- # Create or append to archive
148
- if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
149
- cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
150
- # SpecFlow Decisions Archive
151
-
152
- Historical decisions rotated from STATE.md to maintain compactness.
153
-
154
- ## Archived Decisions
155
-
156
- | Date | Decision |
157
- |------|----------|
158
- EOF
159
- fi
160
-
161
- # Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
162
- TEMP_OLD=$(mktemp)
163
- echo "$OLD_DECISIONS" > "$TEMP_OLD"
164
-
165
- # Append old decisions to archive (insert after table header)
166
- TEMP_ARCHIVE=$(mktemp)
167
- awk -v oldfile="$TEMP_OLD" '
168
- /^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
169
- {print}
170
- ' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
171
- mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
172
- rm -f "$TEMP_OLD"
173
-
174
- # Write recent decisions to temp file for awk to read
175
- TEMP_RECENT=$(mktemp)
176
- echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
177
-
178
- # Update STATE.md with only recent decisions
179
- TEMP_STATE=$(mktemp)
180
- awk -v recentfile="$TEMP_RECENT" '
181
- /^## Decisions$/ {
182
- print
183
- print ""
184
- print "| Date | Decision |"
185
- print "|------|----------|"
186
- while ((getline line < recentfile) > 0) print line
187
- close(recentfile)
188
- in_decisions=1
189
- next
190
- }
191
- /^## / && in_decisions { in_decisions=0 }
192
- !in_decisions || !/^\|/ { print }
193
- ' .specflow/STATE.md > "$TEMP_STATE"
194
- mv "$TEMP_STATE" .specflow/STATE.md
195
- rm -f "$TEMP_RECENT"
196
-
197
- echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
198
- fi
199
- fi
200
- ```
132
+ 1. Use the Read tool to read `.specflow/STATE.md` and count total lines
133
+ 2. If total lines <= 100, no action needed
134
+ 3. If total lines > 100:
135
+ a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
136
+ b. Count decision rows. If <= 7, no rotation needed
137
+ c. If > 7 decisions:
138
+ - Identify the 5 most recent decisions (last 5 rows) -- these STAY
139
+ - Identify older decisions (all rows except last 5) -- these MOVE to archive
140
+ - Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
141
+ - Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
142
+ - Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
201
143
 
202
144
  ## Step 8: Display Result
203
145
 
@@ -156,13 +156,10 @@ Continue to Step 5 with analysis context available.
156
156
  | "..." | Treat as custom revision instructions |
157
157
 
158
158
  **Check for `--no-analysis` flag:**
159
- ```bash
160
- if echo "$ARGS" | grep -q "\-\-no-analysis"; then
161
- SKIP_ANALYSIS=true
162
- # Remove flag from args for further processing
163
- ARGS=$(echo "$ARGS" | sed 's/--no-analysis//g' | xargs)
164
- fi
165
- ```
159
+
160
+ If the arguments string contains `--no-analysis`:
161
+ - Set SKIP_ANALYSIS to true
162
+ - Remove the `--no-analysis` flag from the arguments string for further processing
166
163
 
167
164
  ### If Interactive Mode (no arguments):
168
165
 
@@ -251,75 +251,17 @@ The agent will:
251
251
 
252
252
  After updating STATE.md, check if rotation is needed:
253
253
 
254
- ```bash
255
- LINE_COUNT=$(wc -l < .specflow/STATE.md)
256
- if [ $LINE_COUNT -gt 100 ]; then
257
- echo "STATE.md exceeds 100 lines ($LINE_COUNT), rotating old decisions..."
258
-
259
- # Parse decisions table and extract all decisions
260
- DECISIONS=$(awk '/^## Decisions$/ { found=1; next } /^## / && found { exit } found { print }' .specflow/STATE.md | grep -E '^\| [0-9]{4}-' || true)
261
- DECISION_COUNT=$(echo "$DECISIONS" | grep -c '^|' || echo 0)
262
-
263
- if [ "$DECISION_COUNT" -gt 7 ]; then
264
- # Keep only 5 most recent decisions
265
- RECENT_DECISIONS=$(echo "$DECISIONS" | tail -5)
266
- OLD_DECISION_COUNT=$((DECISION_COUNT - 5))
267
- OLD_DECISIONS=$(echo "$DECISIONS" | head -n $OLD_DECISION_COUNT)
268
-
269
- # Create or append to archive
270
- if [ ! -f .specflow/DECISIONS_ARCHIVE.md ]; then
271
- cat > .specflow/DECISIONS_ARCHIVE.md << 'EOF'
272
- # SpecFlow Decisions Archive
273
-
274
- Historical decisions rotated from STATE.md to maintain compactness.
275
-
276
- ## Archived Decisions
277
-
278
- | Date | Decision |
279
- |------|----------|
280
- EOF
281
- fi
282
-
283
- # Write old decisions to temp file for awk to read (awk -v cannot handle multiline strings)
284
- TEMP_OLD=$(mktemp)
285
- echo "$OLD_DECISIONS" > "$TEMP_OLD"
286
-
287
- # Append old decisions to archive (insert after table header)
288
- TEMP_ARCHIVE=$(mktemp)
289
- awk -v oldfile="$TEMP_OLD" '
290
- /^\| Date \| Decision \|$/ { print; getline; print; while ((getline line < oldfile) > 0) print line; close(oldfile); next }
291
- {print}
292
- ' .specflow/DECISIONS_ARCHIVE.md > "$TEMP_ARCHIVE"
293
- mv "$TEMP_ARCHIVE" .specflow/DECISIONS_ARCHIVE.md
294
- rm -f "$TEMP_OLD"
295
-
296
- # Write recent decisions to temp file for awk to read
297
- TEMP_RECENT=$(mktemp)
298
- echo "$RECENT_DECISIONS" > "$TEMP_RECENT"
299
-
300
- # Update STATE.md with only recent decisions
301
- TEMP_STATE=$(mktemp)
302
- awk -v recentfile="$TEMP_RECENT" '
303
- /^## Decisions$/ {
304
- print
305
- print ""
306
- print "| Date | Decision |"
307
- print "|------|----------|"
308
- while ((getline line < recentfile) > 0) print line
309
- close(recentfile)
310
- in_decisions=1
311
- next
312
- }
313
- /^## / && in_decisions { in_decisions=0 }
314
- !in_decisions || !/^\|/ { print }
315
- ' .specflow/STATE.md > "$TEMP_STATE"
316
- mv "$TEMP_STATE" .specflow/STATE.md
317
- rm -f "$TEMP_RECENT"
318
-
319
- echo "Rotated $(echo "$OLD_DECISIONS" | grep -c '^|') old decisions to DECISIONS_ARCHIVE.md"
320
- fi
321
- fi
322
- ```
254
+ 1. Use the Read tool to read `.specflow/STATE.md` and count total lines
255
+ 2. If total lines <= 100, no action needed
256
+ 3. If total lines > 100:
257
+ a. Read the `## Decisions` section and extract all decision rows (lines matching `| YYYY-`)
258
+ b. Count decision rows. If <= 7, no rotation needed
259
+ c. If > 7 decisions:
260
+ - Identify the 5 most recent decisions (last 5 rows) -- these STAY
261
+ - Identify older decisions (all rows except last 5) -- these MOVE to archive
262
+ - Read `.specflow/DECISIONS_ARCHIVE.md` (create with template if missing)
263
+ - Write updated DECISIONS_ARCHIVE.md: insert old decisions after the table header row
264
+ - Write updated STATE.md: replace Decisions section content with only the 5 most recent decisions
323
265
 
324
266
  ## Step 10: Display Result
325
267
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specflow-cc",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Spec-driven development system for Claude Code — quality-first workflow with explicit audit cycles",
5
5
  "bin": {
6
6
  "specflow-cc": "bin/install.js"