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 +25 -0
- package/README.md +7 -0
- package/agents/impl-reviewer.md +8 -0
- package/agents/sf-spec-executor-orchestrator.md +8 -0
- package/agents/spec-auditor.md +8 -0
- package/agents/spec-creator.md +10 -0
- package/agents/spec-executor-orchestrator.md +21 -0
- package/agents/spec-executor.md +8 -0
- package/agents/spec-reviser.md +8 -0
- package/agents/spec-splitter.md +10 -0
- package/commands/sf/audit.md +11 -69
- package/commands/sf/autopilot.md +601 -0
- package/commands/sf/done.md +11 -69
- package/commands/sf/help.md +14 -0
- package/commands/sf/review.md +11 -69
- package/commands/sf/revise.md +4 -7
- package/commands/sf/run.md +11 -69
- package/package.json +1 -1
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
|
---
|
package/agents/impl-reviewer.md
CHANGED
|
@@ -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
|
package/agents/spec-auditor.md
CHANGED
|
@@ -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>
|
package/agents/spec-creator.md
CHANGED
|
@@ -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
|
package/agents/spec-executor.md
CHANGED
|
@@ -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
|
package/agents/spec-reviser.md
CHANGED
|
@@ -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>
|
package/agents/spec-splitter.md
CHANGED
|
@@ -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>
|
package/commands/sf/audit.md
CHANGED
|
@@ -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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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>
|
package/commands/sf/done.md
CHANGED
|
@@ -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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
|
package/commands/sf/help.md
CHANGED
|
@@ -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>`
|
package/commands/sf/review.md
CHANGED
|
@@ -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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
|
package/commands/sf/revise.md
CHANGED
|
@@ -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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
package/commands/sf/run.md
CHANGED
|
@@ -251,75 +251,17 @@ The agent will:
|
|
|
251
251
|
|
|
252
252
|
After updating STATE.md, check if rotation is needed:
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
|