maestro-flow 0.3.27 → 0.3.29

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.
@@ -0,0 +1,519 @@
1
+ ---
2
+ name: maestro-ralph
3
+ description: Closed-loop lifecycle decision engine — read state, infer position, build adaptive chain, execute via CSV waves, STOP at decision nodes for re-evaluation
4
+ argument-hint: "\"intent\" | status | continue | execute"
5
+ allowed-tools: spawn_agents_on_csv, Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
6
+ ---
7
+
8
+ <purpose>
9
+ Closed-loop decision engine for the maestro workflow lifecycle.
10
+ Two entry points with distinct roles:
11
+
12
+ - **`$maestro-ralph "intent"`** — Decision mode: read state → infer position → build/expand chain → write status.json → execute first wave(s) until a decision node → STOP
13
+ - **`$maestro-ralph execute`** — Execute mode: resume from status.json → run next wave(s) until a decision node → STOP
14
+ - **`$maestro-ralph status`** — Display session progress
15
+ - **`$maestro-ralph continue`** — Alias for `execute` (resume after decision)
16
+
17
+ Key difference from maestro coordinator:
18
+ - maestro: static chain → run all waves to completion
19
+ - ralph: living chain → decision nodes pause execution → ralph re-evaluates → chain grows/shrinks dynamically
20
+
21
+ Three node types in the chain:
22
+ - **decision**: Barrier that STOPS execution. Ralph re-reads result files, decides whether to expand chain.
23
+ - **skill**: Executed via `spawn_agents_on_csv`. Barrier skills (analyze, plan, execute, brainstorm) run solo. Non-barriers can parallel.
24
+ - **cli**: Executed via `spawn_agents_on_csv` with delegate wrapper.
25
+
26
+ Session at `.workflow/.ralph/ralph-{YYYYMMDD-HHmmss}/status.json`.
27
+ </purpose>
28
+
29
+ <context>
30
+ $ARGUMENTS — intent text, or keywords.
31
+
32
+ **Routing:**
33
+ ```
34
+ "status" → handleStatus(). End.
35
+ "execute" | "continue"→ handleExecute(). Jump to Phase 2.
36
+ otherwise → handleNew(). Start from Phase 1.
37
+ ```
38
+
39
+ **Decision-node detection (for execute mode):**
40
+ If status.json has a pending decision node as next step → Phase 2b (evaluate), not Phase 2a (spawn).
41
+ </context>
42
+
43
+ <invariants>
44
+ 1. **ALL skills via spawn_agents_on_csv**: Coordinator NEVER executes skills directly.
45
+ 2. **Decision nodes STOP execution**: After processing a decision node, coordinator writes status.json and STOPS. User must call `$maestro-ralph execute` to resume.
46
+ 3. **Barrier = solo wave**: barrier skills (analyze, plan, execute, brainstorm, roadmap) always run alone.
47
+ 4. **Non-barriers can parallel**: consecutive non-barrier + non-decision steps grouped into one wave.
48
+ 5. **Decision = barrier + stop**: decision node is always solo AND halts the loop.
49
+ 6. **Wave-by-wave**: never start wave N+1 before wave N results are read.
50
+ 7. **Coordinator owns context**: sub-agents never read prior results.
51
+ 8. **Abort on failure**: failed step → mark remaining skipped → pause session.
52
+ </invariants>
53
+
54
+ <execution>
55
+
56
+ ## Phase 1: Resolve Intent and Build Chain (handleNew)
57
+
58
+ ### 1a: Read project state
59
+
60
+ Read `.workflow/state.json`. Actual schema:
61
+
62
+ ```json
63
+ {
64
+ "current_milestone": "MVP",
65
+ "milestones": [{ "id": "M1", "name": "MVP", "status": "active", "phases": [1, 2] }],
66
+ "artifacts": [
67
+ {
68
+ "id": "ANL-001",
69
+ "type": "analyze", // analyze | plan | execute | verify
70
+ "milestone": "MVP",
71
+ "phase": 1,
72
+ "scope": "phase", // phase | milestone | adhoc | standalone
73
+ "path": "phases/01-auth-multi-tenant", // relative to .workflow/scratch/
74
+ "status": "completed",
75
+ "depends_on": "PLN-001",
76
+ "harvested": true
77
+ }
78
+ ],
79
+ "accumulated_context": {
80
+ "key_decisions": [...],
81
+ "deferred": [...]
82
+ }
83
+ }
84
+ ```
85
+
86
+ **Bootstrap state detection:**
87
+
88
+ ```
89
+ Case A — No .workflow/ at all:
90
+ A1: No source files (empty project, 0→1)
91
+ → position = "brainstorm", chain starts: brainstorm → init → roadmap → analyze → ...
92
+ A2: Has source files (existing code, first time using maestro)
93
+ → position = "init", chain starts: init → roadmap → analyze → ...
94
+
95
+ Case B — Has .workflow/, no state.json or empty milestones:
96
+ → position = "init" or "roadmap"
97
+
98
+ Case C — Has state.json with artifacts:
99
+ → artifact-based inference (see below)
100
+ ```
101
+
102
+ ### 1b: Artifact-based position inference (Case C)
103
+
104
+ Filter artifacts by `milestone == current_milestone`. Group by phase. For the target phase, find the **latest completed artifact type**:
105
+
106
+ ```
107
+ state.json exists, no milestones[] → "roadmap"
108
+ Has milestones, no roadmap.md → "roadmap"
109
+ Has roadmap, no artifacts for target phase → "analyze"
110
+ Latest artifact type == "analyze" → "plan"
111
+ Latest artifact type == "plan" → "execute"
112
+ Latest artifact type == "execute" → "verify"
113
+ Latest artifact type == "verify" → check result files (see below)
114
+
115
+ When latest is "verify", read result files to refine position:
116
+ resolve_artifact_dir(latest_verify_artifact)
117
+ Read verification.json from that dir:
118
+ gaps[] non-empty or passed == false → "verify-failed" (needs fix loop)
119
+ passed == true, no review.json → "business-test"
120
+ has review.json with verdict == "BLOCK" → "review-failed"
121
+ has review.json with verdict != "BLOCK" → "test"
122
+ has uat.md with status == "complete", all passed → "milestone-audit"
123
+ has uat.md with failures → "test-failed"
124
+ ```
125
+
126
+ **resolve_artifact_dir(artifact):**
127
+ ```
128
+ artifact.path is relative path (e.g. "phases/01-auth-multi-tenant")
129
+ Full path = .workflow/scratch/{artifact.path}/
130
+ If path starts with "phases/": also try .workflow/scratch/{YYYYMMDD}-*-P{phase}-*/
131
+ Fallback: glob .workflow/scratch/*-P{phase}-*/ sorted by date DESC, take first
132
+ ```
133
+
134
+ ### 1c: Build command sequence
135
+
136
+ **Lifecycle stages** (full pipeline):
137
+ ```
138
+ Stage Skill Barrier Decision After
139
+ ──────────────────────────────────────────────────────────────────────────
140
+ brainstorm maestro-brainstorm "{intent}" yes — (0→1 only)
141
+ init maestro-init no —
142
+ roadmap maestro-roadmap "{intent}" yes —
143
+ analyze maestro-analyze {phase} yes —
144
+ plan maestro-plan {phase} yes —
145
+ execute maestro-execute {phase} yes —
146
+ verify maestro-verify {phase} no decision:post-verify
147
+ business-test quality-business-test {phase} no decision:post-business-test
148
+ review quality-review {phase} no decision:post-review
149
+ test-gen quality-test-gen {phase} no —
150
+ test quality-test {phase} no decision:post-test
151
+ milestone-audit maestro-milestone-audit no —
152
+ milestone-complete maestro-milestone-complete no decision:post-milestone
153
+ ```
154
+
155
+ Generate `steps[]` from current position to target. Decision nodes use:
156
+ ```json
157
+ { "type": "decision", "skill": "maestro-ralph", "args": "{\"decision\":\"post-verify\",\"retry_count\":0,\"max_retries\":2}" }
158
+ ```
159
+
160
+ ### 1d: Create session
161
+
162
+ Write `.workflow/.ralph/ralph-{YYYYMMDD-HHmmss}/status.json`:
163
+ ```json
164
+ {
165
+ "id": "ralph-{YYYYMMDD-HHmmss}",
166
+ "created_at": "ISO",
167
+ "intent": "{user_intent}",
168
+ "status": "running",
169
+ "lifecycle_position": "{position}",
170
+ "target": "milestone-complete",
171
+ "phase": null,
172
+ "milestone": null,
173
+ "auto_mode": false,
174
+ "context": { "plan_dir": null, "analysis_dir": null, "brainstorm_dir": null },
175
+ "steps": [...],
176
+ "waves": [],
177
+ "current_step": 0,
178
+ "updated_at": "ISO"
179
+ }
180
+ ```
181
+
182
+ ### 1e: Display plan + confirm
183
+
184
+ ```
185
+ ============================================================
186
+ RALPH DECISION ENGINE
187
+ ============================================================
188
+ Position: {position} (Phase {N}, {milestone})
189
+ Target: milestone-complete
190
+ Steps: {total} ({decision_count} decision points)
191
+
192
+ [ ] 0. maestro-plan {phase} [skill/barrier]
193
+ [ ] 1. maestro-execute {phase} [skill/barrier]
194
+ [ ] 2. maestro-verify {phase} [skill]
195
+ [ ] 3. ◆ post-verify [decision] ← STOP
196
+ [ ] 4. quality-business-test {phase} [skill]
197
+ ...
198
+ ============================================================
199
+ ```
200
+
201
+ If not auto_mode: AskUserQuestion → Proceed / Cancel
202
+
203
+ ### 1f: Fall through to Phase 2
204
+
205
+ ---
206
+
207
+ ## Phase 2: Wave Execution Loop (handleExecute)
208
+
209
+ ### 2a: Load session
210
+
211
+ Read status.json. Find first pending step.
212
+
213
+ If first pending step is a decision node → go to Phase 2b.
214
+ Otherwise → go to Phase 2c.
215
+
216
+ ### 2b: Decision Evaluation (when next pending is decision)
217
+
218
+ Read decision metadata from step.args: `{ decision, retry_count, max_retries }`
219
+
220
+ **Locate result files** — find the artifact dir for current phase:
221
+ ```
222
+ Read .workflow/state.json
223
+ Filter artifacts: milestone == session.milestone, phase == session.phase
224
+ Sort by created_at DESC
225
+
226
+ For the decision type, find the relevant artifact:
227
+ post-verify → latest type=="verify" artifact
228
+ post-business-test → same dir as verify (business-test writes to same artifact dir)
229
+ post-review → latest artifact dir → review.json
230
+ post-test → latest artifact dir → uat.md + .tests/test-results.json
231
+
232
+ artifact_dir = resolve_artifact_dir(artifact)
233
+ ```
234
+
235
+ **Evaluate by decision type:**
236
+
237
+ **post-verify:**
238
+ ```
239
+ Read {artifact_dir}/verification.json
240
+ Check: gaps[] array and passed field
241
+
242
+ If gaps found (passed == false or gaps[].length > 0):
243
+ If meta.retry_count >= meta.max_retries:
244
+ → Insert: [quality-debug "{gap_summary}", decision:post-debug-escalate]
245
+ → Display: ◆ post-verify: max retries reached, escalating to debug
246
+ Else:
247
+ → Insert: [quality-debug "{gap_summary}", maestro-plan --gaps {phase},
248
+ maestro-execute {phase}, maestro-verify {phase},
249
+ decision:post-verify(retry+1)]
250
+ → Display: ◆ post-verify: gaps detected, inserting debug+fix loop (retry {N}/{max})
251
+
252
+ If no gaps (passed == true):
253
+ → No insertion, proceed
254
+ ```
255
+
256
+ **post-business-test:**
257
+ ```
258
+ Read {artifact_dir}/business-test-results.json or scan for business test output
259
+ Check: failures[] or passed field
260
+
261
+ If failures found:
262
+ If meta.retry_count >= meta.max_retries:
263
+ → Insert: [quality-debug --from-business-test {phase}, decision:post-debug-escalate]
264
+ Else:
265
+ → Insert: [quality-debug --from-business-test {phase},
266
+ maestro-plan --gaps {phase}, maestro-execute {phase},
267
+ maestro-verify {phase}, decision:post-verify(retry:0),
268
+ quality-business-test {phase}, decision:post-business-test(retry+1)]
269
+
270
+ If all pass:
271
+ → No insertion, proceed
272
+ ```
273
+
274
+ **post-review:**
275
+ ```
276
+ Read {artifact_dir}/review.json
277
+ Check: verdict field and issues[].severity
278
+
279
+ If verdict == "BLOCK" or any issue.severity == "critical":
280
+ If meta.retry_count >= meta.max_retries:
281
+ → Insert: [quality-debug "{block_summary}", decision:post-debug-escalate]
282
+ Else:
283
+ → Insert: [quality-debug "{block_issues}",
284
+ maestro-plan --gaps {phase}, maestro-execute {phase},
285
+ quality-review {phase}, decision:post-review(retry+1)]
286
+
287
+ If verdict == "PASS" or "WARN":
288
+ → No insertion, proceed
289
+ ```
290
+
291
+ **post-test:**
292
+ ```
293
+ Read {artifact_dir}/uat.md (parse frontmatter + gap sections)
294
+ Read {artifact_dir}/.tests/test-results.json if exists
295
+
296
+ If failures found (any test result != pass, or gaps with severity >= high):
297
+ If meta.retry_count >= meta.max_retries:
298
+ → Insert: [quality-debug --from-uat {phase}, decision:post-debug-escalate]
299
+ Else:
300
+ → Insert: [quality-debug --from-uat {phase},
301
+ maestro-plan --gaps {phase}, maestro-execute {phase},
302
+ maestro-verify {phase}, decision:post-verify(retry:0),
303
+ quality-business-test {phase}, decision:post-business-test(retry:0),
304
+ quality-review {phase}, decision:post-review(retry:0),
305
+ quality-test-gen {phase}, quality-test {phase},
306
+ decision:post-test(retry+1)]
307
+
308
+ If all pass:
309
+ → No insertion, proceed
310
+ ```
311
+
312
+ **post-milestone:**
313
+ ```
314
+ Re-read .workflow/state.json (milestone-complete will have updated it).
315
+ Check: state.milestones[] for next milestone with status == "pending" or "active"
316
+
317
+ If next milestone found:
318
+ next_m = next milestone
319
+ first_phase = next_m.phases[0]
320
+ Update ralph session: milestone = next_m.name, phase = first_phase
321
+
322
+ → Insert full lifecycle for next milestone:
323
+ [maestro-analyze {first_phase} [barrier],
324
+ maestro-plan {first_phase} [barrier],
325
+ maestro-execute {first_phase} [barrier],
326
+ maestro-verify {first_phase},
327
+ decision:post-verify(retry:0),
328
+ quality-business-test {first_phase},
329
+ decision:post-business-test(retry:0),
330
+ quality-review {first_phase},
331
+ decision:post-review(retry:0),
332
+ quality-test-gen {first_phase},
333
+ quality-test {first_phase},
334
+ decision:post-test(retry:0),
335
+ maestro-milestone-audit,
336
+ maestro-milestone-complete,
337
+ decision:post-milestone]
338
+
339
+ → Display: ◆ post-milestone: {completed_m.name} done → advancing to {next_m.name} Phase {first_phase}
340
+
341
+ If no next milestone:
342
+ → No insertion — session will complete naturally
343
+ → Display: ◆ post-milestone: all milestones complete!
344
+ ```
345
+
346
+ **post-debug-escalate:**
347
+ ```
348
+ This is a terminal escalation — debug was run but we exceeded max retries.
349
+ → Set session status = "paused"
350
+ → Display: ◆ 已达最大重试次数,debug 已执行。请人工介入检查结果。
351
+ → Display: 使用 $maestro-ralph execute 在处理后恢复
352
+ → STOP
353
+ ```
354
+
355
+ After evaluation:
356
+ 1. Mark decision step as "completed"
357
+ 2. Reindex steps if inserted
358
+ 3. Write status.json
359
+ 4. Display: `◆ Decision: {type} → {outcome}`
360
+ 5. Fall through to Phase 2c (continue executing next steps)
361
+
362
+ ### 2c: Build and Execute Next Wave
363
+
364
+ **While pending non-decision steps remain:**
365
+
366
+ 1. **buildNextWave**: Take first pending step.
367
+ - If barrier → solo wave
368
+ - If non-barrier → collect consecutive non-barrier, non-decision steps
369
+ - Stop at first decision node (it will be processed in next `execute` call)
370
+
371
+ 2. **Assemble args** (placeholder resolution):
372
+ ```
373
+ {phase} → status.phase
374
+ {intent} → status.intent
375
+ {scratch_dir} → from latest artifact path
376
+ {plan_dir} → status.context.plan_dir
377
+ {analysis_dir}→ status.context.analysis_dir
378
+ ```
379
+
380
+ 3. **Write wave CSV**: `{sessionDir}/wave-{N}.csv`
381
+ Each row spawns a `$maestro-ralph-execute` agent with the target skill_call as argument:
382
+ ```csv
383
+ id,skill_call,topic
384
+ "3","$maestro-ralph-execute \"$maestro-verify 1\"","Ralph step 3/14: verify phase 1"
385
+ ```
386
+ The inner `$maestro-verify 1` is the actual skill; `$maestro-ralph-execute` is the worker wrapper.
387
+
388
+ 4. **Spawn**:
389
+ ```
390
+ spawn_agents_on_csv({
391
+ csv_path: "{sessionDir}/wave-{N}.csv",
392
+ id_column: "id",
393
+ instruction: WAVE_INSTRUCTION,
394
+ max_workers: <wave_size>,
395
+ max_runtime_seconds: 3600,
396
+ output_csv_path: "{sessionDir}/wave-{N}-results.csv",
397
+ output_schema: RESULT_SCHEMA
398
+ })
399
+ ```
400
+
401
+ 5. **Read results**: Update step status from results CSV
402
+
403
+ 6. **Barrier check**: If wave was a barrier skill, read artifacts, update context:
404
+ | Barrier | Read | Update |
405
+ |---------|------|--------|
406
+ | maestro-analyze | context.md, state.json | context.analysis_dir, context.gaps |
407
+ | maestro-plan | plan.json | context.plan_dir, context.task_count |
408
+ | maestro-execute | results.csv | context.exec_status |
409
+ | maestro-brainstorm | .brainstorming/ | context.brainstorm_dir |
410
+ | maestro-roadmap | specs/ | context.spec_session_id |
411
+
412
+ 7. **Persist**: Write status.json with updated steps, waves, context
413
+
414
+ 8. **Failure check**: Any step failed → mark remaining skipped, pause session, STOP
415
+
416
+ 9. **Decision check**: If next pending step is a decision node → STOP.
417
+ Display: `⏸ 到达决策节点: {decision_type}。使用 $maestro-ralph execute 继续。`
418
+
419
+ 10. **Continue**: If next pending is not decision, loop back to step 1
420
+
421
+ ### Sub-Agent Instruction Template
422
+
423
+ ```
424
+ 你是 Ralph 执行器子 agent。
425
+
426
+ skill_call 列包含 $maestro-ralph-execute 调用,它会解析内部的目标 skill 并执行。
427
+ 直接运行 skill_call 中的命令即可。
428
+
429
+ 限制:
430
+ - 不要修改 .workflow/.ralph/ 下的文件
431
+ - ralph-execute 内部处理 skill 路由和执行
432
+
433
+ 完成后调用 report_agent_job_result,返回:
434
+ {"status":"completed|failed","skill_call":"{skill_call}","summary":"一句话结果","artifacts":"产物路径或空","error":"失败原因或空"}
435
+ ```
436
+
437
+ ### Result Schema
438
+
439
+ `{ status, skill_call, summary, artifacts, error }` — all string, status = "completed"|"failed"
440
+
441
+ ---
442
+
443
+ ## Phase 3: Completion (when no pending steps remain)
444
+
445
+ ```
446
+ status.status = "completed"
447
+ status.updated_at = now
448
+ Write status.json
449
+
450
+ ============================================================
451
+ RALPH COMPLETE
452
+ ============================================================
453
+ Session: {id}
454
+ Phase: {phase} → {milestone}
455
+ Waves: {wave_count} executed
456
+ Steps: {completed}/{total}
457
+
458
+ [✓] 0. maestro-plan 1 [W1]
459
+ [✓] 1. maestro-execute 1 [W2]
460
+ [✓] 2. maestro-verify 1 [W3]
461
+ [✓] 3. ◆ post-verify [decision: no gaps]
462
+ [✓] 4. quality-business-test 1 [W4]
463
+ ...
464
+
465
+ Resume: $maestro-ralph execute
466
+ ============================================================
467
+ ```
468
+
469
+ </execution>
470
+
471
+ <csv_schema>
472
+ ### wave-{N}.csv
473
+
474
+ All skill execution goes through `$maestro-ralph-execute` as the worker wrapper:
475
+
476
+ ```csv
477
+ id,skill_call,topic
478
+ "3","$maestro-ralph-execute \"$maestro-verify 1\"","Ralph step 3/14: verify phase 1"
479
+ "4","$maestro-ralph-execute \"$quality-business-test 1\"","Ralph step 4/14: business test phase 1"
480
+ ```
481
+
482
+ - `skill_call` column: always `$maestro-ralph-execute "<inner_skill_call>"`
483
+ - `topic` column: human-readable step description
484
+ - Non-barrier + non-decision steps can be grouped in one wave CSV with multiple rows
485
+ - Barrier steps always solo (one row per CSV)
486
+ - Decision steps are NEVER in CSV — processed by ralph directly
487
+ </csv_schema>
488
+
489
+ <error_codes>
490
+ | Code | Severity | Description | Recovery |
491
+ |------|----------|-------------|----------|
492
+ | E001 | error | No intent and no running session | Prompt for intent |
493
+ | E002 | error | Cannot infer lifecycle position | Show raw state, ask user |
494
+ | E003 | error | Artifact dir not found for decision evaluation | Show glob results, ask user |
495
+ | E004 | error | Result file (verification.json etc) missing in artifact dir | Warn, treat as failure |
496
+ | E005 | error | Wave timeout (max_runtime_seconds) | Mark step failed, pause session |
497
+ | E006 | error | No session found for execute/continue | Suggest $maestro-ralph "intent" |
498
+ | W001 | warning | Decision node expanded chain (gap/failure detected) | Auto-handled, log expansion |
499
+ | W002 | warning | Max retries reached, escalating to debug | Auto-handled |
500
+ | W003 | warning | Multiple running sessions found | Use latest, warn user |
501
+ </error_codes>
502
+
503
+ <success_criteria>
504
+ - [ ] state.json artifacts correctly read with actual schema (type, path, scope, milestone, depends_on)
505
+ - [ ] Lifecycle position inferred from artifacts + result files (verification.json, review.json, uat.md)
506
+ - [ ] Artifact dir resolved via resolve_artifact_dir() with fallback globs
507
+ - [ ] Full quality pipeline: verify → business-test → review → test-gen → test
508
+ - [ ] Decision nodes at: post-verify, post-business-test, post-review, post-test, post-milestone
509
+ - [ ] Every decision failure path starts with quality-debug before plan --gaps
510
+ - [ ] retry_count tracked per decision node, max_retries enforced
511
+ - [ ] Max retries → post-debug-escalate → session paused for human intervention
512
+ - [ ] All skills via spawn_agents_on_csv (through ralph-execute) — coordinator never executes directly
513
+ - [ ] Decision nodes STOP execution — user must call `execute` to resume
514
+ - [ ] Barrier skills run solo, non-barriers grouped in parallel waves
515
+ - [ ] Placeholder args resolved before CSV assembly ({phase}, {intent}, {scratch_dir})
516
+ - [ ] post-milestone inserts next milestone lifecycle with recursive post-milestone
517
+ - [ ] status.json persisted after every wave
518
+ - [ ] Command insertion + reindex works correctly after decision expansion
519
+ </success_criteria>