@thierrynakoa/fire-flow 10.0.0 → 12.2.1
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/.claude-plugin/plugin.json +8 -8
- package/ARCHITECTURE-DIAGRAM.md +7 -4
- package/COMMAND-REFERENCE.md +33 -13
- package/DOMINION-FLOW-OVERVIEW.md +581 -421
- package/QUICK-START.md +3 -3
- package/README.md +101 -44
- package/TROUBLESHOOTING.md +264 -264
- package/agents/fire-executor.md +200 -116
- package/agents/fire-fact-checker.md +276 -276
- package/agents/fire-phoenix-analyst.md +394 -0
- package/agents/fire-planner.md +145 -53
- package/agents/fire-project-researcher.md +155 -155
- package/agents/fire-research-synthesizer.md +166 -166
- package/agents/fire-researcher.md +144 -59
- package/agents/fire-roadmapper.md +215 -203
- package/agents/fire-verifier.md +247 -65
- package/agents/fire-vision-architect.md +381 -0
- package/commands/fire-0-orient.md +476 -476
- package/commands/fire-1a-new.md +216 -0
- package/commands/fire-1b-research.md +210 -0
- package/commands/fire-1c-setup.md +254 -0
- package/commands/{fire-1a-discuss.md → fire-1d-discuss.md} +35 -7
- package/commands/fire-3-execute.md +55 -2
- package/commands/fire-4-verify.md +61 -0
- package/commands/fire-5-handoff.md +2 -2
- package/commands/fire-6-resume.md +37 -2
- package/commands/fire-add-new-skill.md +2 -2
- package/commands/fire-autonomous.md +20 -3
- package/commands/fire-brainstorm.md +1 -1
- package/commands/fire-complete-milestone.md +2 -2
- package/commands/fire-cost.md +183 -0
- package/commands/fire-dashboard.md +2 -2
- package/commands/fire-debug.md +663 -663
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +1168 -1168
- package/commands/fire-map-codebase.md +3 -3
- package/commands/fire-new-milestone.md +356 -356
- package/commands/fire-phoenix.md +603 -0
- package/commands/fire-reflect.md +235 -235
- package/commands/fire-research.md +246 -246
- package/commands/fire-search.md +1 -1
- package/commands/fire-skills-diff.md +3 -3
- package/commands/fire-skills-history.md +3 -3
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +5 -5
- package/commands/fire-test.md +9 -9
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/hooks/hooks.json +16 -16
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -2
- package/plugin.json +7 -7
- package/references/metrics-and-trends.md +1 -1
- package/skills-library/SKILLS-INDEX.md +588 -588
- package/skills-library/_general/methodology/AUTONOMOUS_ORCHESTRATION.md +182 -0
- package/skills-library/_general/methodology/BACKWARD_PLANNING_INTERVIEW.md +307 -0
- package/skills-library/_general/methodology/CIRCUIT_BREAKER_INTELLIGENCE.md +163 -0
- package/skills-library/_general/methodology/CONTEXT_ROTATION.md +151 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +188 -0
- package/skills-library/_general/methodology/DESIGN_PHILOSOPHY_ENFORCEMENT.md +152 -0
- package/skills-library/_general/methodology/INTERNAL_CONSISTENCY_AUDIT.md +212 -0
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +242 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +251 -0
- package/skills-library/_general/methodology/QUALITY_GATES_AND_VERIFICATION.md +157 -0
- package/skills-library/_general/methodology/RELIABILITY_PREDICTION.md +104 -0
- package/skills-library/_general/methodology/REQUIREMENTS_DECOMPOSITION.md +155 -0
- package/skills-library/_general/methodology/SELF_TESTING_FEEDBACK_LOOP.md +143 -0
- package/skills-library/_general/methodology/STACK_COMPATIBILITY_MATRIX.md +178 -0
- package/skills-library/_general/methodology/TIERED_CONTEXT_ARCHITECTURE.md +118 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +312 -0
- package/skills-library/_general/methodology/autonomous-multi-phase-build.md +133 -0
- package/skills-library/_general/methodology/claude-md-archival.md +280 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/git-worktrees-parallel.md +232 -0
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +241 -0
- package/skills-library/_general/methodology/multi-project-autonomous-build.md +360 -0
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +238 -238
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +358 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +1 -1
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +1 -1
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/BLOCKERS.md +1 -1
- package/templates/DECISION_LOG.md +1 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +80 -0
- package/version.json +2 -2
- package/workflows/handoff-session.md +1 -1
- package/workflows/new-project.md +2 -2
- package/commands/fire-1-new.md +0 -281
|
@@ -1,238 +1,238 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: shell-autonomous-loop-fixplan
|
|
3
|
-
category: methodology
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
contributed: 2026-03-04
|
|
6
|
-
contributor: dominion-flow-v2
|
|
7
|
-
last_updated: 2026-03-04
|
|
8
|
-
tags: [autonomous, shell-loop, fix_plan, circuit-breaker, session-management, context-limits, ralph-pattern]
|
|
9
|
-
difficulty: hard
|
|
10
|
-
usage_count: 0
|
|
11
|
-
success_rate: 100
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# Shell-Level Autonomous Loop with @fix_plan.md
|
|
15
|
-
|
|
16
|
-
## Problem
|
|
17
|
-
|
|
18
|
-
Conversation-level autonomous loops (`/fire-loop`, while-loops inside a single Claude session)
|
|
19
|
-
degrade over time: context fills up, the model loses track of early decisions, and performance
|
|
20
|
-
drops. For long-running tasks (10+ iterations, multi-phase builds, complex debugging), the loop
|
|
21
|
-
**must** run at the shell level — spawning fresh Claude CLI sessions per iteration while
|
|
22
|
-
preserving task continuity through a persistent task file.
|
|
23
|
-
|
|
24
|
-
**Symptoms of the conversation-loop problem:**
|
|
25
|
-
- AI starts repeating work it already did
|
|
26
|
-
- Circuit breaker fires due to output decline (context is full, responses get shorter)
|
|
27
|
-
- Task list lives only in conversation — lost on restart
|
|
28
|
-
- No rate limiting — hits API limits unexpectedly
|
|
29
|
-
- Can't reattach to a running loop after terminal disconnect
|
|
30
|
-
|
|
31
|
-
## Solution Pattern
|
|
32
|
-
|
|
33
|
-
Implement a **bash loop** that spawns `claude --resume <session_id>` on each iteration.
|
|
34
|
-
The AI reads `@fix_plan.md` (a persistent markdown checklist on disk) at the start of
|
|
35
|
-
every fresh session, does one task, checks it off, and writes `EXIT_SIGNAL=true` when done.
|
|
36
|
-
The shell script detects this signal and exits cleanly.
|
|
37
|
-
|
|
38
|
-
**Key insight from bmalph/Ralph:** The shell owns the loop. Claude owns the task.
|
|
39
|
-
The `@fix_plan.md` file is the shared state between them — it survives context resets,
|
|
40
|
-
restarts, disconnects, and rate limit cooldowns.
|
|
41
|
-
|
|
42
|
-
### The Three-Layer Architecture
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
SHELL LAYER (bash script)
|
|
46
|
-
├── Rate limiting (MAX_CALLS_PER_HOUR)
|
|
47
|
-
├── Session management (--resume <id>, expiry after 24h)
|
|
48
|
-
├── Circuit breaker (stagnation / error / output-decline)
|
|
49
|
-
└── EXIT_SIGNAL + BLOCKED_TASK detection
|
|
50
|
-
|
|
51
|
-
TASK LAYER (@fix_plan.md on disk)
|
|
52
|
-
├── [ ] TASK-001: ... AC: ...
|
|
53
|
-
├── [x] TASK-002: ... (completed)
|
|
54
|
-
└── EXIT_SIGNAL=false → EXIT_SIGNAL=true when done
|
|
55
|
-
|
|
56
|
-
CLAUDE LAYER (fresh session each iteration)
|
|
57
|
-
├── Reads @fix_plan.md + PROJECT_CONTEXT.md
|
|
58
|
-
├── Works on next unchecked task
|
|
59
|
-
├── Checks it off [x]
|
|
60
|
-
└── Writes EXIT_SIGNAL=true when all done
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Code Example
|
|
64
|
-
|
|
65
|
-
### @fix_plan.md format
|
|
66
|
-
|
|
67
|
-
```markdown
|
|
68
|
-
# @fix_plan — My Project
|
|
69
|
-
|
|
70
|
-
> AI: Read this at the start of every iteration. Check off completed tasks [x].
|
|
71
|
-
> When ALL tasks are checked, write EXIT_SIGNAL=true.
|
|
72
|
-
|
|
73
|
-
## Phase 1 — Schema
|
|
74
|
-
|
|
75
|
-
- [ ] TASK-001: Create user table migration
|
|
76
|
-
- AC: `npm run db:migrate` runs without errors
|
|
77
|
-
- Files: prisma/schema.prisma, migrations/
|
|
78
|
-
|
|
79
|
-
- [ ] TASK-002: Add email + created_at indexes
|
|
80
|
-
- AC: `EXPLAIN` shows index usage on user queries
|
|
81
|
-
- Files: prisma/schema.prisma
|
|
82
|
-
|
|
83
|
-
## Phase 2 — API
|
|
84
|
-
|
|
85
|
-
- [ ] TASK-003: Build POST /api/users endpoint
|
|
86
|
-
- AC: Returns 201 + user object, Playwright smoke passes
|
|
87
|
-
- Files: src/routes/users.ts, src/controllers/users.ts
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
EXIT_SIGNAL=false
|
|
92
|
-
|
|
93
|
-
<!--
|
|
94
|
-
AI: Check boxes [ ] → [x] as you complete tasks.
|
|
95
|
-
If BLOCKED: write BLOCKED_TASK=TASK-NNN on its own line, then
|
|
96
|
-
Reason: [what you tried and why you're stuck]
|
|
97
|
-
When all [x]: change EXIT_SIGNAL=false → EXIT_SIGNAL=true
|
|
98
|
-
-->
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### dominion_loop.sh (core loop)
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
#!/usr/bin/env bash
|
|
105
|
-
set -euo pipefail
|
|
106
|
-
|
|
107
|
-
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
|
|
108
|
-
MAX_CALLS_PER_HOUR="${MAX_CALLS_PER_HOUR:-50}"
|
|
109
|
-
MAX_ITERATIONS="${MAX_ITERATIONS:-100}"
|
|
110
|
-
CIRCUIT_STAGNATION_LIMIT="${CIRCUIT_STAGNATION_LIMIT:-3}"
|
|
111
|
-
CIRCUIT_ERROR_LIMIT="${CIRCUIT_ERROR_LIMIT:-5}"
|
|
112
|
-
SESSION_EXPIRY_SECS="${SESSION_EXPIRY_SECS:-86400}"
|
|
113
|
-
|
|
114
|
-
FIX_PLAN="$PROJECT_DIR/.planning/@fix_plan.md"
|
|
115
|
-
SESSION_FILE="$PROJECT_DIR/.planning/.loop-session"
|
|
116
|
-
|
|
117
|
-
# Load per-project config override
|
|
118
|
-
[ -f "$PROJECT_DIR/.planning/dominion.rc" ] && source "$PROJECT_DIR/.planning/dominion.rc"
|
|
119
|
-
|
|
120
|
-
count_checked() { grep -c '^\- \[x\]' "$FIX_PLAN" 2>/dev/null || echo 0; }
|
|
121
|
-
|
|
122
|
-
SESSION_ID=""
|
|
123
|
-
if [ -f "$SESSION_FILE" ]; then
|
|
124
|
-
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_FILE" 2>/dev/null || echo "")
|
|
125
|
-
SESSION_AGE=$(( $(date +%s) - $(jq -r '.createdAt // 0' "$SESSION_FILE" 2>/dev/null) ))
|
|
126
|
-
[ "$SESSION_AGE" -gt "$SESSION_EXPIRY_SECS" ] && SESSION_ID="" && rm -f "$SESSION_FILE"
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
CALL_WINDOW_START=$(date +%s)
|
|
130
|
-
CALLS_THIS_WINDOW=0
|
|
131
|
-
CB_STAGNATION=0
|
|
132
|
-
CB_ERRORS=0
|
|
133
|
-
CB_LAST_CHECKED=0
|
|
134
|
-
ITERATION=0
|
|
135
|
-
|
|
136
|
-
PROMPT="Read .planning/@fix_plan.md and .planning/PROJECT_CONTEXT.md.
|
|
137
|
-
Work on the next unchecked task [ ]. Update it to [x] when done.
|
|
138
|
-
If BLOCKED after genuine attempts: write BLOCKED_TASK=TASK-NNN then Reason: [why].
|
|
139
|
-
When ALL tasks are [x]: write EXIT_SIGNAL=true in @fix_plan.md."
|
|
140
|
-
|
|
141
|
-
while [ "$ITERATION" -lt "$MAX_ITERATIONS" ]; do
|
|
142
|
-
ITERATION=$(( ITERATION + 1 ))
|
|
143
|
-
CHECKED=$(count_checked)
|
|
144
|
-
|
|
145
|
-
# Rate limiting
|
|
146
|
-
NOW=$(date +%s); ELAPSED=$(( NOW - CALL_WINDOW_START ))
|
|
147
|
-
[ "$ELAPSED" -ge 3600 ] && { CALL_WINDOW_START=$NOW; CALLS_THIS_WINDOW=0; }
|
|
148
|
-
[ "$CALLS_THIS_WINDOW" -ge "$MAX_CALLS_PER_HOUR" ] && { sleep $(( 3600 - ELAPSED )); CALL_WINDOW_START=$(date +%s); CALLS_THIS_WINDOW=0; }
|
|
149
|
-
CALLS_THIS_WINDOW=$(( CALLS_THIS_WINDOW + 1 ))
|
|
150
|
-
|
|
151
|
-
# Build and run claude command
|
|
152
|
-
RESUME_FLAG=""; [ -n "$SESSION_ID" ] && RESUME_FLAG="--resume $SESSION_ID"
|
|
153
|
-
TMPOUT=$(mktemp)
|
|
154
|
-
HAD_ERROR="false"
|
|
155
|
-
|
|
156
|
-
# shellcheck disable=SC2086
|
|
157
|
-
claude --output-format json \
|
|
158
|
-
--allowedTools 'Write,Read,Edit,Glob,Grep,Bash,Task,TodoWrite,WebSearch,WebFetch' \
|
|
159
|
-
$RESUME_FLAG -p "$PROMPT" > "$TMPOUT" 2>&1 || HAD_ERROR="true"
|
|
160
|
-
|
|
161
|
-
# Capture session ID on first run
|
|
162
|
-
if [ -z "$SESSION_ID" ]; then
|
|
163
|
-
SID=$(jq -r '.sessionId // empty' "$TMPOUT" 2>/dev/null || echo "")
|
|
164
|
-
[ -n "$SID" ] && SESSION_ID="$SID" && printf '{"sessionId":"%s","createdAt":%s}' "$SID" "$(date +%s)" > "$SESSION_FILE"
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
# Check exit conditions
|
|
168
|
-
grep -q 'EXIT_SIGNAL=true' "$FIX_PLAN" 2>/dev/null && { echo "✓ Done."; rm -f "$TMPOUT"; exit 0; }
|
|
169
|
-
|
|
170
|
-
if grep -q 'BLOCKED_TASK=' "$TMPOUT" 2>/dev/null; then
|
|
171
|
-
BLOCKED=$(grep 'BLOCKED_TASK=' "$TMPOUT" | head -1)
|
|
172
|
-
printf '{"blocked":true,"task":"%s","iteration":%s}' "$BLOCKED" "$ITERATION" > "$PROJECT_DIR/.planning/loop-blocked.json"
|
|
173
|
-
echo "⚠ BLOCKED: $BLOCKED"; rm -f "$TMPOUT"; exit 2
|
|
174
|
-
fi
|
|
175
|
-
|
|
176
|
-
# Circuit breaker
|
|
177
|
-
NEW_CHECKED=$(count_checked)
|
|
178
|
-
[ "$NEW_CHECKED" -le "$CB_LAST_CHECKED" ] && CB_STAGNATION=$(( CB_STAGNATION + 1 )) || { CB_STAGNATION=0; CB_LAST_CHECKED=$NEW_CHECKED; }
|
|
179
|
-
[ "$HAD_ERROR" = "true" ] && CB_ERRORS=$(( CB_ERRORS + 1 )) || CB_ERRORS=0
|
|
180
|
-
[ "$CB_STAGNATION" -ge "$CIRCUIT_STAGNATION_LIMIT" ] && { echo "⚡ Stagnation. Cooling down 30m."; sleep 1800; CB_STAGNATION=0; }
|
|
181
|
-
[ "$CB_ERRORS" -ge "$CIRCUIT_ERROR_LIMIT" ] && { echo "⚡ Error limit. Halting."; exit 1; }
|
|
182
|
-
|
|
183
|
-
rm -f "$TMPOUT"; sleep 2
|
|
184
|
-
done
|
|
185
|
-
exit 1
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Implementation Steps
|
|
189
|
-
|
|
190
|
-
1. **Generate @fix_plan.md** — run `/fire-implement` (or manually write tasks with `- [ ] TASK-NNN:` format + `AC:` acceptance criteria)
|
|
191
|
-
2. **Generate PROJECT_CONTEXT.md** — consolidated planning docs in one file the AI reads per iteration
|
|
192
|
-
3. **Copy dominion.rc** — set `MAX_CALLS_PER_HOUR`, `MAX_ITERATIONS`, circuit breaker thresholds
|
|
193
|
-
4. **Run the loop** — `bash dominion_loop.sh --project-dir $(pwd)` or via `/fire-loop`
|
|
194
|
-
5. **Monitor** — `cat .planning/loop-status.json` or `/fire-dashboard`
|
|
195
|
-
6. **Handle BLOCKED** — loop exits code 2, read `.planning/loop-blocked.json`, invoke researcher
|
|
196
|
-
|
|
197
|
-
## When to Use
|
|
198
|
-
|
|
199
|
-
- Task requires >10 AI iterations to complete
|
|
200
|
-
- Multi-phase feature build (schema → API → UI → tests)
|
|
201
|
-
- Long-running autonomous execution where context bloat is a real risk
|
|
202
|
-
- You want rate limiting and circuit breaking enforced at the OS level
|
|
203
|
-
- Task must survive terminal disconnects or restarts
|
|
204
|
-
- You need a reattachable, resumable execution that persists across sessions
|
|
205
|
-
|
|
206
|
-
## When NOT to Use
|
|
207
|
-
|
|
208
|
-
- Simple 1-3 iteration tasks (conversation loop is fine)
|
|
209
|
-
- No `claude` CLI available in PATH
|
|
210
|
-
- Task requires continuous human judgment at each step (use manual `/fire-3-execute`)
|
|
211
|
-
- Project has no `.planning/` structure yet (run `/fire-
|
|
212
|
-
|
|
213
|
-
## Common Mistakes
|
|
214
|
-
|
|
215
|
-
- **Vague acceptance criteria** — if AC is unclear, AI marks tasks done prematurely. Write AC as a testable command: `npm test passes`, `Playwright smoke green`, `tsc --noEmit returns 0`
|
|
216
|
-
- **Too many tasks per @fix_plan.md** — keep tasks 15-30 min each. Huge tasks cause stagnation (CB fires before completion)
|
|
217
|
-
- **Missing PROJECT_CONTEXT.md** — without it, each fresh session lacks planning context and the AI reinvents decisions. Always run `/fire-implement` to generate it
|
|
218
|
-
- **Forgetting exit code 2** — if your orchestrator calls the loop, check exit code 2 = BLOCKED (needs researcher), not just 0 = done and 1 = error
|
|
219
|
-
|
|
220
|
-
## Exit Codes
|
|
221
|
-
|
|
222
|
-
| Code | Meaning | Action |
|
|
223
|
-
|------|---------|--------|
|
|
224
|
-
| 0 | `EXIT_SIGNAL=true` — all tasks complete | Proceed to verification |
|
|
225
|
-
| 1 | Circuit breaker halt or max iterations | Investigate `.planning/loop-status.json` |
|
|
226
|
-
| 2 | `BLOCKED_TASK` detected | Read `.planning/loop-blocked.json`, invoke researcher |
|
|
227
|
-
|
|
228
|
-
## Related Skills
|
|
229
|
-
|
|
230
|
-
- [autonomous-multi-phase-build](autonomous-multi-phase-build.md) — phase-level orchestration within conversation
|
|
231
|
-
- [multi-project-autonomous-build](multi-project-autonomous-build.md) — running multiple projects autonomously
|
|
232
|
-
|
|
233
|
-
## References
|
|
234
|
-
|
|
235
|
-
- Inspired by: [bmalph](https://github.com/LarsCowe/bmalph) — Ralph autonomous loop pattern
|
|
236
|
-
- Ralph loop architecture: `ralph_loop.sh` in bmalph v2.7.0
|
|
237
|
-
- Gap analysis session: 2026-03-04
|
|
238
|
-
- Contributed from: dominion-flow-v2 build session
|
|
1
|
+
---
|
|
2
|
+
name: shell-autonomous-loop-fixplan
|
|
3
|
+
category: methodology
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-03-04
|
|
6
|
+
contributor: dominion-flow-v2
|
|
7
|
+
last_updated: 2026-03-04
|
|
8
|
+
tags: [autonomous, shell-loop, fix_plan, circuit-breaker, session-management, context-limits, ralph-pattern]
|
|
9
|
+
difficulty: hard
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Shell-Level Autonomous Loop with @fix_plan.md
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
Conversation-level autonomous loops (`/fire-loop`, while-loops inside a single Claude session)
|
|
19
|
+
degrade over time: context fills up, the model loses track of early decisions, and performance
|
|
20
|
+
drops. For long-running tasks (10+ iterations, multi-phase builds, complex debugging), the loop
|
|
21
|
+
**must** run at the shell level — spawning fresh Claude CLI sessions per iteration while
|
|
22
|
+
preserving task continuity through a persistent task file.
|
|
23
|
+
|
|
24
|
+
**Symptoms of the conversation-loop problem:**
|
|
25
|
+
- AI starts repeating work it already did
|
|
26
|
+
- Circuit breaker fires due to output decline (context is full, responses get shorter)
|
|
27
|
+
- Task list lives only in conversation — lost on restart
|
|
28
|
+
- No rate limiting — hits API limits unexpectedly
|
|
29
|
+
- Can't reattach to a running loop after terminal disconnect
|
|
30
|
+
|
|
31
|
+
## Solution Pattern
|
|
32
|
+
|
|
33
|
+
Implement a **bash loop** that spawns `claude --resume <session_id>` on each iteration.
|
|
34
|
+
The AI reads `@fix_plan.md` (a persistent markdown checklist on disk) at the start of
|
|
35
|
+
every fresh session, does one task, checks it off, and writes `EXIT_SIGNAL=true` when done.
|
|
36
|
+
The shell script detects this signal and exits cleanly.
|
|
37
|
+
|
|
38
|
+
**Key insight from bmalph/Ralph:** The shell owns the loop. Claude owns the task.
|
|
39
|
+
The `@fix_plan.md` file is the shared state between them — it survives context resets,
|
|
40
|
+
restarts, disconnects, and rate limit cooldowns.
|
|
41
|
+
|
|
42
|
+
### The Three-Layer Architecture
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
SHELL LAYER (bash script)
|
|
46
|
+
├── Rate limiting (MAX_CALLS_PER_HOUR)
|
|
47
|
+
├── Session management (--resume <id>, expiry after 24h)
|
|
48
|
+
├── Circuit breaker (stagnation / error / output-decline)
|
|
49
|
+
└── EXIT_SIGNAL + BLOCKED_TASK detection
|
|
50
|
+
|
|
51
|
+
TASK LAYER (@fix_plan.md on disk)
|
|
52
|
+
├── [ ] TASK-001: ... AC: ...
|
|
53
|
+
├── [x] TASK-002: ... (completed)
|
|
54
|
+
└── EXIT_SIGNAL=false → EXIT_SIGNAL=true when done
|
|
55
|
+
|
|
56
|
+
CLAUDE LAYER (fresh session each iteration)
|
|
57
|
+
├── Reads @fix_plan.md + PROJECT_CONTEXT.md
|
|
58
|
+
├── Works on next unchecked task
|
|
59
|
+
├── Checks it off [x]
|
|
60
|
+
└── Writes EXIT_SIGNAL=true when all done
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Code Example
|
|
64
|
+
|
|
65
|
+
### @fix_plan.md format
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
# @fix_plan — My Project
|
|
69
|
+
|
|
70
|
+
> AI: Read this at the start of every iteration. Check off completed tasks [x].
|
|
71
|
+
> When ALL tasks are checked, write EXIT_SIGNAL=true.
|
|
72
|
+
|
|
73
|
+
## Phase 1 — Schema
|
|
74
|
+
|
|
75
|
+
- [ ] TASK-001: Create user table migration
|
|
76
|
+
- AC: `npm run db:migrate` runs without errors
|
|
77
|
+
- Files: prisma/schema.prisma, migrations/
|
|
78
|
+
|
|
79
|
+
- [ ] TASK-002: Add email + created_at indexes
|
|
80
|
+
- AC: `EXPLAIN` shows index usage on user queries
|
|
81
|
+
- Files: prisma/schema.prisma
|
|
82
|
+
|
|
83
|
+
## Phase 2 — API
|
|
84
|
+
|
|
85
|
+
- [ ] TASK-003: Build POST /api/users endpoint
|
|
86
|
+
- AC: Returns 201 + user object, Playwright smoke passes
|
|
87
|
+
- Files: src/routes/users.ts, src/controllers/users.ts
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
EXIT_SIGNAL=false
|
|
92
|
+
|
|
93
|
+
<!--
|
|
94
|
+
AI: Check boxes [ ] → [x] as you complete tasks.
|
|
95
|
+
If BLOCKED: write BLOCKED_TASK=TASK-NNN on its own line, then
|
|
96
|
+
Reason: [what you tried and why you're stuck]
|
|
97
|
+
When all [x]: change EXIT_SIGNAL=false → EXIT_SIGNAL=true
|
|
98
|
+
-->
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### dominion_loop.sh (core loop)
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
#!/usr/bin/env bash
|
|
105
|
+
set -euo pipefail
|
|
106
|
+
|
|
107
|
+
PROJECT_DIR="${PROJECT_DIR:-$(pwd)}"
|
|
108
|
+
MAX_CALLS_PER_HOUR="${MAX_CALLS_PER_HOUR:-50}"
|
|
109
|
+
MAX_ITERATIONS="${MAX_ITERATIONS:-100}"
|
|
110
|
+
CIRCUIT_STAGNATION_LIMIT="${CIRCUIT_STAGNATION_LIMIT:-3}"
|
|
111
|
+
CIRCUIT_ERROR_LIMIT="${CIRCUIT_ERROR_LIMIT:-5}"
|
|
112
|
+
SESSION_EXPIRY_SECS="${SESSION_EXPIRY_SECS:-86400}"
|
|
113
|
+
|
|
114
|
+
FIX_PLAN="$PROJECT_DIR/.planning/@fix_plan.md"
|
|
115
|
+
SESSION_FILE="$PROJECT_DIR/.planning/.loop-session"
|
|
116
|
+
|
|
117
|
+
# Load per-project config override
|
|
118
|
+
[ -f "$PROJECT_DIR/.planning/dominion.rc" ] && source "$PROJECT_DIR/.planning/dominion.rc"
|
|
119
|
+
|
|
120
|
+
count_checked() { grep -c '^\- \[x\]' "$FIX_PLAN" 2>/dev/null || echo 0; }
|
|
121
|
+
|
|
122
|
+
SESSION_ID=""
|
|
123
|
+
if [ -f "$SESSION_FILE" ]; then
|
|
124
|
+
SESSION_ID=$(jq -r '.sessionId // empty' "$SESSION_FILE" 2>/dev/null || echo "")
|
|
125
|
+
SESSION_AGE=$(( $(date +%s) - $(jq -r '.createdAt // 0' "$SESSION_FILE" 2>/dev/null) ))
|
|
126
|
+
[ "$SESSION_AGE" -gt "$SESSION_EXPIRY_SECS" ] && SESSION_ID="" && rm -f "$SESSION_FILE"
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
CALL_WINDOW_START=$(date +%s)
|
|
130
|
+
CALLS_THIS_WINDOW=0
|
|
131
|
+
CB_STAGNATION=0
|
|
132
|
+
CB_ERRORS=0
|
|
133
|
+
CB_LAST_CHECKED=0
|
|
134
|
+
ITERATION=0
|
|
135
|
+
|
|
136
|
+
PROMPT="Read .planning/@fix_plan.md and .planning/PROJECT_CONTEXT.md.
|
|
137
|
+
Work on the next unchecked task [ ]. Update it to [x] when done.
|
|
138
|
+
If BLOCKED after genuine attempts: write BLOCKED_TASK=TASK-NNN then Reason: [why].
|
|
139
|
+
When ALL tasks are [x]: write EXIT_SIGNAL=true in @fix_plan.md."
|
|
140
|
+
|
|
141
|
+
while [ "$ITERATION" -lt "$MAX_ITERATIONS" ]; do
|
|
142
|
+
ITERATION=$(( ITERATION + 1 ))
|
|
143
|
+
CHECKED=$(count_checked)
|
|
144
|
+
|
|
145
|
+
# Rate limiting
|
|
146
|
+
NOW=$(date +%s); ELAPSED=$(( NOW - CALL_WINDOW_START ))
|
|
147
|
+
[ "$ELAPSED" -ge 3600 ] && { CALL_WINDOW_START=$NOW; CALLS_THIS_WINDOW=0; }
|
|
148
|
+
[ "$CALLS_THIS_WINDOW" -ge "$MAX_CALLS_PER_HOUR" ] && { sleep $(( 3600 - ELAPSED )); CALL_WINDOW_START=$(date +%s); CALLS_THIS_WINDOW=0; }
|
|
149
|
+
CALLS_THIS_WINDOW=$(( CALLS_THIS_WINDOW + 1 ))
|
|
150
|
+
|
|
151
|
+
# Build and run claude command
|
|
152
|
+
RESUME_FLAG=""; [ -n "$SESSION_ID" ] && RESUME_FLAG="--resume $SESSION_ID"
|
|
153
|
+
TMPOUT=$(mktemp)
|
|
154
|
+
HAD_ERROR="false"
|
|
155
|
+
|
|
156
|
+
# shellcheck disable=SC2086
|
|
157
|
+
claude --output-format json \
|
|
158
|
+
--allowedTools 'Write,Read,Edit,Glob,Grep,Bash,Task,TodoWrite,WebSearch,WebFetch' \
|
|
159
|
+
$RESUME_FLAG -p "$PROMPT" > "$TMPOUT" 2>&1 || HAD_ERROR="true"
|
|
160
|
+
|
|
161
|
+
# Capture session ID on first run
|
|
162
|
+
if [ -z "$SESSION_ID" ]; then
|
|
163
|
+
SID=$(jq -r '.sessionId // empty' "$TMPOUT" 2>/dev/null || echo "")
|
|
164
|
+
[ -n "$SID" ] && SESSION_ID="$SID" && printf '{"sessionId":"%s","createdAt":%s}' "$SID" "$(date +%s)" > "$SESSION_FILE"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# Check exit conditions
|
|
168
|
+
grep -q 'EXIT_SIGNAL=true' "$FIX_PLAN" 2>/dev/null && { echo "✓ Done."; rm -f "$TMPOUT"; exit 0; }
|
|
169
|
+
|
|
170
|
+
if grep -q 'BLOCKED_TASK=' "$TMPOUT" 2>/dev/null; then
|
|
171
|
+
BLOCKED=$(grep 'BLOCKED_TASK=' "$TMPOUT" | head -1)
|
|
172
|
+
printf '{"blocked":true,"task":"%s","iteration":%s}' "$BLOCKED" "$ITERATION" > "$PROJECT_DIR/.planning/loop-blocked.json"
|
|
173
|
+
echo "⚠ BLOCKED: $BLOCKED"; rm -f "$TMPOUT"; exit 2
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
# Circuit breaker
|
|
177
|
+
NEW_CHECKED=$(count_checked)
|
|
178
|
+
[ "$NEW_CHECKED" -le "$CB_LAST_CHECKED" ] && CB_STAGNATION=$(( CB_STAGNATION + 1 )) || { CB_STAGNATION=0; CB_LAST_CHECKED=$NEW_CHECKED; }
|
|
179
|
+
[ "$HAD_ERROR" = "true" ] && CB_ERRORS=$(( CB_ERRORS + 1 )) || CB_ERRORS=0
|
|
180
|
+
[ "$CB_STAGNATION" -ge "$CIRCUIT_STAGNATION_LIMIT" ] && { echo "⚡ Stagnation. Cooling down 30m."; sleep 1800; CB_STAGNATION=0; }
|
|
181
|
+
[ "$CB_ERRORS" -ge "$CIRCUIT_ERROR_LIMIT" ] && { echo "⚡ Error limit. Halting."; exit 1; }
|
|
182
|
+
|
|
183
|
+
rm -f "$TMPOUT"; sleep 2
|
|
184
|
+
done
|
|
185
|
+
exit 1
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Implementation Steps
|
|
189
|
+
|
|
190
|
+
1. **Generate @fix_plan.md** — run `/fire-implement` (or manually write tasks with `- [ ] TASK-NNN:` format + `AC:` acceptance criteria)
|
|
191
|
+
2. **Generate PROJECT_CONTEXT.md** — consolidated planning docs in one file the AI reads per iteration
|
|
192
|
+
3. **Copy dominion.rc** — set `MAX_CALLS_PER_HOUR`, `MAX_ITERATIONS`, circuit breaker thresholds
|
|
193
|
+
4. **Run the loop** — `bash dominion_loop.sh --project-dir $(pwd)` or via `/fire-loop`
|
|
194
|
+
5. **Monitor** — `cat .planning/loop-status.json` or `/fire-dashboard`
|
|
195
|
+
6. **Handle BLOCKED** — loop exits code 2, read `.planning/loop-blocked.json`, invoke researcher
|
|
196
|
+
|
|
197
|
+
## When to Use
|
|
198
|
+
|
|
199
|
+
- Task requires >10 AI iterations to complete
|
|
200
|
+
- Multi-phase feature build (schema → API → UI → tests)
|
|
201
|
+
- Long-running autonomous execution where context bloat is a real risk
|
|
202
|
+
- You want rate limiting and circuit breaking enforced at the OS level
|
|
203
|
+
- Task must survive terminal disconnects or restarts
|
|
204
|
+
- You need a reattachable, resumable execution that persists across sessions
|
|
205
|
+
|
|
206
|
+
## When NOT to Use
|
|
207
|
+
|
|
208
|
+
- Simple 1-3 iteration tasks (conversation loop is fine)
|
|
209
|
+
- No `claude` CLI available in PATH
|
|
210
|
+
- Task requires continuous human judgment at each step (use manual `/fire-3-execute`)
|
|
211
|
+
- Project has no `.planning/` structure yet (run `/fire-1a-new` first)
|
|
212
|
+
|
|
213
|
+
## Common Mistakes
|
|
214
|
+
|
|
215
|
+
- **Vague acceptance criteria** — if AC is unclear, AI marks tasks done prematurely. Write AC as a testable command: `npm test passes`, `Playwright smoke green`, `tsc --noEmit returns 0`
|
|
216
|
+
- **Too many tasks per @fix_plan.md** — keep tasks 15-30 min each. Huge tasks cause stagnation (CB fires before completion)
|
|
217
|
+
- **Missing PROJECT_CONTEXT.md** — without it, each fresh session lacks planning context and the AI reinvents decisions. Always run `/fire-implement` to generate it
|
|
218
|
+
- **Forgetting exit code 2** — if your orchestrator calls the loop, check exit code 2 = BLOCKED (needs researcher), not just 0 = done and 1 = error
|
|
219
|
+
|
|
220
|
+
## Exit Codes
|
|
221
|
+
|
|
222
|
+
| Code | Meaning | Action |
|
|
223
|
+
|------|---------|--------|
|
|
224
|
+
| 0 | `EXIT_SIGNAL=true` — all tasks complete | Proceed to verification |
|
|
225
|
+
| 1 | Circuit breaker halt or max iterations | Investigate `.planning/loop-status.json` |
|
|
226
|
+
| 2 | `BLOCKED_TASK` detected | Read `.planning/loop-blocked.json`, invoke researcher |
|
|
227
|
+
|
|
228
|
+
## Related Skills
|
|
229
|
+
|
|
230
|
+
- [autonomous-multi-phase-build](autonomous-multi-phase-build.md) — phase-level orchestration within conversation
|
|
231
|
+
- [multi-project-autonomous-build](multi-project-autonomous-build.md) — running multiple projects autonomously
|
|
232
|
+
|
|
233
|
+
## References
|
|
234
|
+
|
|
235
|
+
- Inspired by: [bmalph](https://github.com/LarsCowe/bmalph) — Ralph autonomous loop pattern
|
|
236
|
+
- Ralph loop architecture: `ralph_loop.sh` in bmalph v2.7.0
|
|
237
|
+
- Gap analysis session: 2026-03-04 fire-flow-v2 implementation
|
|
238
|
+
- Contributed from: dominion-flow-v2 build session
|