maestro-flow 0.3.34 → 0.3.36

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.
Files changed (34) hide show
  1. package/.claude/commands/maestro-ralph-execute.md +136 -177
  2. package/.claude/commands/maestro-ralph.md +292 -326
  3. package/.codex/skills/maestro-ralph/SKILL.md +358 -454
  4. package/README.md +83 -221
  5. package/README.zh-CN.md +94 -241
  6. package/dashboard/dist-server/dashboard/src/server/routes/csv-waves.d.ts +2 -0
  7. package/dashboard/dist-server/dashboard/src/server/routes/csv-waves.js +244 -0
  8. package/dashboard/dist-server/dashboard/src/server/routes/csv-waves.js.map +1 -0
  9. package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
  10. package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
  11. package/dashboard/dist-server/dashboard/src/server/state/fs-watcher.js +7 -0
  12. package/dashboard/dist-server/dashboard/src/server/state/fs-watcher.js.map +1 -1
  13. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +84 -12
  14. package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
  15. package/dashboard/dist-server/dashboard/src/server/state/state-manager.test.js +2 -1
  16. package/dashboard/dist-server/dashboard/src/server/state/state-manager.test.js.map +1 -1
  17. package/dashboard/dist-server/dashboard/src/shared/csv-wave-types.d.ts +48 -0
  18. package/dashboard/dist-server/dashboard/src/shared/csv-wave-types.js +5 -0
  19. package/dashboard/dist-server/dashboard/src/shared/csv-wave-types.js.map +1 -0
  20. package/dashboard/dist-server/src/config/cli-tools-config.d.ts +6 -0
  21. package/dashboard/dist-server/src/config/cli-tools-config.js +21 -0
  22. package/dashboard/dist-server/src/config/cli-tools-config.js.map +1 -1
  23. package/dist/src/config/cli-tools-config.d.ts +6 -0
  24. package/dist/src/config/cli-tools-config.d.ts.map +1 -1
  25. package/dist/src/config/cli-tools-config.js +21 -0
  26. package/dist/src/config/cli-tools-config.js.map +1 -1
  27. package/dist/src/tui/tools-ui/ToolsDashboard.d.ts +1 -1
  28. package/dist/src/tui/tools-ui/ToolsDashboard.d.ts.map +1 -1
  29. package/dist/src/tui/tools-ui/ToolsDashboard.js +17 -2
  30. package/dist/src/tui/tools-ui/ToolsDashboard.js.map +1 -1
  31. package/dist/src/tui/tools-ui/ToolsOverview.d.ts.map +1 -1
  32. package/dist/src/tui/tools-ui/ToolsOverview.js +30 -1
  33. package/dist/src/tui/tools-ui/ToolsOverview.js.map +1 -1
  34. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: maestro-ralph
3
3
  description: Closed-loop lifecycle decision engine — read project state, infer position, build adaptive command chain with decision/skill/cli nodes
4
- argument-hint: "\"intent\" | status | continue"
4
+ argument-hint: "[-y] \"intent\" | status | continue"
5
5
  allowed-tools:
6
6
  - Read
7
7
  - Write
@@ -14,35 +14,27 @@ allowed-tools:
14
14
  ---
15
15
  <purpose>
16
16
  Closed-loop decision engine for the maestro workflow lifecycle.
17
- Reads project state → infers lifecycle position → builds command chain with three node types:
18
- - **decision**: Hand back to ralph for re-evaluation (adaptive branching)
19
- - **skill**: In-session Skill() call (synchronous, lightweight)
20
- - **cli**: CLI delegate call via `maestro delegate` (context-isolated, heavy)
21
17
 
22
- Decision nodes at key checkpoints enable dynamic chain expansion
23
- ralph re-reads actual execution result files, then decides whether to append debug+fix loops or proceed.
18
+ Reads project state infers lifecycle position → builds adaptive command chain delegates execution.
19
+
20
+ Three node types:
21
+ - **skill**: In-session `Skill()` call (synchronous, lightweight)
22
+ - **cli**: `maestro delegate` (context-isolated, heavy computation)
23
+ - **decision**: Hand back to ralph for re-evaluation (adaptive branching)
24
24
 
25
25
  Key difference from maestro coordinator:
26
- - maestro: static chainMap → one-time selection → chain-execute runs all steps
27
- - ralph: living chain → decision nodes re-evaluate after each critical step → chain grows/shrinks dynamically
26
+ - maestro: static chain → one-time selection → runs all steps sequentially
27
+ - ralph: living chain → decision nodes re-evaluate after critical steps → chain grows/shrinks dynamically
28
28
 
29
- Produces session at `.workflow/.maestro/ralph-{YYYYMMDD-HHmmss}/status.json` using unified JSON schema (source: "ralph").
30
- Mutual invocation with `/maestro-ralph-execute` forms a persistent self-perpetuating work loop.
29
+ Session path: `.workflow/.maestro/ralph-{YYYYMMDD-HHmmss}/status.json`
30
+ Mutual invocation with `/maestro-ralph-execute` forms a self-perpetuating work loop.
31
31
  </purpose>
32
32
 
33
33
  <context>
34
- $ARGUMENTS — user intent text, or keywords.
35
-
36
- **Keywords:**
37
- - `status` — Display current ralph session progress. **End.**
38
- - `continue` — Find latest running session → `Skill({ skill: "maestro-ralph-execute" })`. **End.**
34
+ $ARGUMENTS — user intent text, flags, or keywords.
39
35
 
40
- **Decision-node trigger detection:**
41
- If a running ralph session exists AND `steps[current_step].type == "decision"` AND `steps[current_step].status == "running"`:
42
- → Enter **Decision Evaluation Mode** (Step 2b) instead of New Session Mode.
43
-
44
- **State files read:**
45
- - `.workflow/state.json` — artifact registry, milestone, phase status
36
+ **State files:**
37
+ - `.workflow/state.json` artifact registry, milestones, phases
46
38
  - `.workflow/roadmap.md` — milestone/phase structure
47
39
  - `.workflow/.maestro/ralph-*/status.json` — ralph session state
48
40
  </context>
@@ -53,194 +45,154 @@ If a running ralph session exists AND `steps[current_step].type == "decision"` A
53
45
 
54
46
  ```
55
47
  Parse $ARGUMENTS:
56
- "status" handleStatus(). End.
57
- "continue"handleContinue(). End.
48
+ -y flag auto_confirm = true (skip confirmation, NOT ambiguity resolution)
49
+ .md/.txt path input_doc (supplementary context for downstream commands)
50
+ Remaining → intent
51
+
52
+ Route:
53
+ intent == "status" → handleStatus()
54
+ intent == "continue" → handleContinue()
58
55
 
59
- Check running ralph session:
60
- Scan .workflow/.maestro/ralph-*/status.json for status == "running"
61
- If found AND steps[current_step].type == "decision" AND steps[current_step].status == "running":
62
- Step 2b (Decision Evaluation Mode)
63
- Else if $ARGUMENTS is non-empty:
64
- → Step 2a (New Session Mode)
65
- Else:
66
- → AskUserQuestion: "请描述目标,或输入 status/continue"
56
+ Check running ralph session (.workflow/.maestro/ralph-*/status.json, session status=="running"):
57
+ If found AND steps[current_step].type == "decision" AND steps[current_step].status == "running":
58
+ Step 3: Decision Evaluation Mode
59
+ Else if intent is non-empty:
60
+ Step 2: New Session Mode
61
+ Else:
62
+ → AskUserQuestion: "请描述目标,或输入 status/continue"
67
63
  ```
68
64
 
69
65
  ### handleStatus()
70
66
  ```
71
- Scan .workflow/.maestro/ralph-*/status.json (latest by created_at)
67
+ Find latest ralph session (by created_at).
72
68
  Display:
73
69
  Session: {id}
74
70
  Status: {status}
75
71
  Position: {lifecycle_position}
76
72
  Progress: {completed}/{total} commands
77
- Current: [{current}] {steps[current_step].skill} [{steps[current_step].type}]
73
+ Current: [{current_step}] {steps[current_step].skill} [{type}]
78
74
 
79
75
  Commands:
80
76
  [✓] 0. maestro-analyze 1 [skill]
81
77
  [▸] 1. maestro-plan 1 [skill]
82
78
  [ ] 2. maestro-execute 1 [cli]
83
79
  ...
80
+ End.
84
81
  ```
85
82
 
86
83
  ### handleContinue()
87
84
  ```
88
- Find latest running ralph session
89
- If not found → "无运行中的 ralph 会话"
90
- Skill({ skill: "maestro-ralph-execute" })
85
+ Find latest running ralph session.
86
+ If not found → "无运行中的 ralph 会话". End.
87
+ Skill({ skill: "maestro-ralph-execute" }). End.
91
88
  ```
92
89
 
93
90
  ---
94
91
 
95
- ## Step 2a: New Session Mode
92
+ ## Step 2: New Session Mode
96
93
 
97
- ### 2a.1: Read project state
94
+ ### 2.1: Read project state
98
95
 
99
- Read `.workflow/state.json`. Extract:
100
-
101
- ```
102
- state.json actual schema:
96
+ Read `.workflow/state.json` schema:
97
+ ```json
103
98
  {
104
99
  "current_milestone": "MVP",
105
100
  "milestones": [{ "id": "M1", "name": "MVP", "status": "active", "phases": [1, 2] }],
106
- "artifacts": [
107
- {
108
- "id": "ANL-001",
109
- "type": "analyze", // analyze | plan | execute | verify
110
- "milestone": "MVP",
111
- "phase": 1,
112
- "scope": "phase", // phase | milestone | adhoc | standalone
113
- "path": "phases/01-auth-multi-tenant", // relative to .workflow/scratch/
114
- "status": "completed",
115
- "depends_on": "PLN-001",
116
- "harvested": true
117
- }
118
- ],
119
- "accumulated_context": {
120
- "key_decisions": [...],
121
- "deferred": [...]
122
- }
101
+ "artifacts": [{
102
+ "id": "ANL-001", "type": "analyze|plan|execute|verify",
103
+ "milestone": "MVP", "phase": 1, "scope": "phase|milestone|adhoc|standalone",
104
+ "path": "phases/01-auth-multi-tenant", // relative to .workflow/scratch/
105
+ "status": "completed", "depends_on": "PLN-001", "harvested": true
106
+ }],
107
+ "accumulated_context": { "key_decisions": [], "deferred": [] }
123
108
  }
124
109
  ```
125
110
 
126
- Also check:
127
- - `.workflow/roadmap.md` existence
128
- - `.workflow/scratch/` for recent result files
111
+ Also check: `.workflow/roadmap.md` existence, `.workflow/scratch/` for result files.
129
112
 
130
- ### 2a.2: Infer lifecycle position
113
+ ### 2.2: Infer lifecycle position
131
114
 
132
- **First: determine project bootstrap state:**
115
+ **Phase 1 Bootstrap detection:**
133
116
 
134
- ```
135
- Check .workflow/ existence:
117
+ | Condition | Position | Chain starts at |
118
+ |-----------|----------|-----------------|
119
+ | No `.workflow/` + no source files (empty project) | `brainstorm` | brainstorm → init → roadmap → ... |
120
+ | No `.workflow/` + has source files (existing code) | `init` | init → roadmap → ... |
121
+ | Has `.workflow/` but no `state.json` | `init` | init → roadmap → ... |
122
+ | Has `state.json` | → Phase 2 below | — |
136
123
 
137
- Case A No .workflow/ at all (0→1 or existing code without workflow):
138
- Check project root for source files (src/, package.json, go.mod, etc.)
139
-
140
- A1: No source files (empty project, 0→1)
141
- → position = "brainstorm"
142
- → chain starts: brainstorm → init → roadmap → analyze → ...
143
- → brainstorm args = "{intent}" (user describes what to build)
124
+ HARD RULE: `input_doc` is supplementary context only. It NEVER substitutes for lifecycle stages.
144
125
 
145
- A2: Has source files (existing code, first time using maestro)
146
- → position = "init"
147
- → chain starts: init → roadmap → analyze → ...
148
- → init auto-detects existing code and bootstraps state.json
126
+ **Phase 2 Artifact-based inference (when state.json exists):**
149
127
 
150
- Case B Has .workflow/ but no state.json:
151
- → position = "init" (corrupted or partial setup)
152
- → chain starts: init → roadmap → analyze → ...
128
+ Filter artifacts by `milestone == current_milestone`, group by target phase. Find latest completed artifact type:
153
129
 
154
- Case C Has state.json:
155
- → proceed to artifact-based position inference below
156
- ```
130
+ | State | Position |
131
+ |-------|----------|
132
+ | No milestones[] or no roadmap.md | `roadmap` |
133
+ | No artifacts for target phase | `analyze` |
134
+ | Latest type == "analyze" | `plan` |
135
+ | Latest type == "plan" | `execute` |
136
+ | Latest type == "execute" | `verify` |
137
+ | Latest type == "verify" | → Refine by result files below |
157
138
 
158
- **Artifact-based position inference (Case C):**
139
+ **Refine from verify results** (read `{artifact_dir}/` files):
159
140
 
160
- Filter artifacts by `milestone == current_milestone`. Group by phase. For the target phase, find the **latest completed artifact type**:
141
+ | Condition | Position |
142
+ |-----------|----------|
143
+ | verification.json: `passed==false` or `gaps[]` non-empty | `verify-failed` |
144
+ | verification.json: `passed==true`, no review.json | `business-test` |
145
+ | review.json: `verdict=="BLOCK"` | `review-failed` |
146
+ | review.json: `verdict!="BLOCK"` | `test` |
147
+ | uat.md: all passed | `milestone-audit` |
148
+ | uat.md: has failures | `test-failed` |
161
149
 
162
- ```
163
- state.json exists, no milestones[] → "roadmap" (init done, needs roadmap)
164
- Has milestones, no roadmap.md → "roadmap"
165
- Has roadmap, no artifacts for target phase → "analyze"
166
- Latest artifact type == "analyze" → "plan"
167
- Latest artifact type == "plan" → "execute"
168
- Latest artifact type == "execute" → "verify"
169
- Latest artifact type == "verify" → check result files (see below)
170
-
171
- When latest is "verify", read result files to refine position:
172
- resolve_artifact_dir(latest_verify_artifact)
173
- Read verification.json from that dir:
174
- gaps[] non-empty or passed == false → "verify-failed" (needs fix loop)
175
- passed == true, no review.json → "business-test"
176
- has review.json with verdict == "BLOCK" → "review-failed"
177
- has review.json with verdict != "BLOCK" → "test"
178
- has uat.md with status == "complete", all passed → "milestone-audit"
179
- has uat.md with failures → "test-failed"
180
- ```
181
-
182
- **resolve_artifact_dir(artifact):**
183
- ```
184
- artifact.path is relative path (e.g. "phases/01-auth-multi-tenant")
185
- Full path = .workflow/scratch/{artifact.path}/
186
- If path starts with "phases/": also try .workflow/scratch/{YYYYMMDD}-*-P{phase}-*/
187
- Fallback: glob .workflow/scratch/*-P{phase}-*/ sorted by date DESC, take first
188
- ```
150
+ ### 2.3: Resolve phase number
189
151
 
190
- ### 2a.3: Resolve phase number
191
-
192
- Priority:
193
- 1. User intent text (regex `phase\s*(\d+)` or bare number)
152
+ Priority order:
153
+ 1. Regex from intent: `phase\s*(\d+)` or bare number
194
154
  2. Latest in-progress artifact's phase field
195
- 3. First phase in current milestone's `phases[]` that lacks complete artifact chain
196
- 4. AskUserQuestion if ambiguous
197
-
198
- ### 2a.4: Build command sequence
199
-
200
- Generate commands from `lifecycle_position` to target (default: `milestone-complete`).
201
-
202
- **Lifecycle stages** (full pipeline with decision nodes):
203
-
204
- ```
205
- Stage Command Type Decision After
206
- ─────────────────────────────────────────────────────────────────────────
207
- brainstorm maestro-brainstorm "{intent}" cli — (0→1 only)
208
- init maestro-init skill
209
- roadmap maestro-roadmap "{intent}" skill
210
- analyze maestro-analyze {phase} cli
211
- plan maestro-plan {phase} skill
212
- execute maestro-execute {phase} cli
213
- verify maestro-verify {phase} skill decision:post-verify
214
- business-test quality-auto-test {phase} skill decision:post-business-test
215
- review quality-review {phase} skill decision:post-review
216
- test-gen quality-auto-test {phase} skill
217
- test quality-test {phase} skill decision:post-test
218
- milestone-audit maestro-milestone-audit skill
219
- milestone-complete maestro-milestone-complete skill decision:post-milestone
220
- ```
221
-
222
- **Command type (cli vs skill):**
223
- | Command | Type | Why |
224
- |---------|------|-----|
225
- | maestro-analyze | `cli` | Heavy multi-source exploration |
226
- | maestro-execute | `cli` | Heavy code generation |
227
- | maestro-brainstorm | `cli` | Heavy multi-role generation |
228
- | maestro-plan | `skill` | Needs user interaction for clarification |
229
- | All quality-* | `skill` | In-session, user-visible results |
230
- | All milestone-* | `skill` | Lightweight lifecycle ops |
155
+ 3. First incomplete phase in current milestone's `phases[]`
156
+ 4. `null` if position is brainstorm/init/roadmap (deferred to post-roadmap)
157
+ 5. AskUserQuestion if ambiguous (auto_confirm does NOT skip this)
158
+
159
+ ### 2.4: Build command sequence
160
+
161
+ Generate steps from `lifecycle_position` to target (default: `milestone-complete`).
162
+
163
+ **Lifecycle stages reference:**
164
+
165
+ | Stage | Skill command | Type | Decision after |
166
+ |-------|--------------|------|----------------|
167
+ | brainstorm | `maestro-brainstorm "{intent}"` | cli | — (0→1 only) |
168
+ | init | `maestro-init` | skill | |
169
+ | roadmap | `maestro-roadmap "{intent}"` | skill | |
170
+ | analyze | `maestro-analyze {phase}` | cli | |
171
+ | plan | `maestro-plan {phase}` | skill | |
172
+ | execute | `maestro-execute {phase}` | cli | |
173
+ | verify | `maestro-verify {phase}` | skill | `post-verify` |
174
+ | business-test | `quality-auto-test {phase}` | skill | `post-business-test` |
175
+ | review | `quality-review {phase}` | skill | `post-review` |
176
+ | test-gen | `quality-auto-test {phase}` | skill | |
177
+ | test | `quality-test {phase}` | skill | `post-test` |
178
+ | milestone-audit | `maestro-milestone-audit` | skill | |
179
+ | milestone-complete | `maestro-milestone-complete` | skill | `post-milestone` |
180
+
181
+ **Type rationale:**
182
+ - `cli` = heavy computation needing isolated context (analyze, execute, brainstorm)
183
+ - `skill` = needs user interaction or is lightweight (plan, verify, quality-*, milestone-*)
231
184
 
232
185
  **Build rules:**
233
- 1. Start from current lifecycle_position (skip completed stages)
234
- 2. After each decision-triggering stage, insert a decision node
235
- 3. Each decision node carries: `{ decision, retry_count: 0, max_retries: 2 }` in args
236
- 4. Args use placeholders — resolved at execution time by ralph-execute (Step 2.5):
186
+ 1. Start from inferred position, skip completed stages
187
+ 2. After each decision-triggering stage, insert a decision node with `{ decision, retry_count: 0, max_retries: 2 }`
188
+ 3. Args use placeholders resolved at execution time by ralph-execute:
237
189
  - `{phase}` → session.phase
238
- - `{intent}` → session.intent (user's original text)
239
- - `{scratch_dir}` → resolved from latest artifact path at execution time
240
- 5. Commands that need user intent text (brainstorm, roadmap, init) use `"{intent}"` as args
241
- 6. Commands that need prior output (plan→execute, analyzeplan) have args resolved via artifact lookup at execution time
190
+ - `{intent}` → session.intent
191
+ - `{scratch_dir}` → latest artifact path
192
+ 4. Phase-independent commands (brainstorm, roadmap, init) use `"{intent}"` as args
193
+ 5. Commands needing prior output (analyze→plan, planexecute) have args resolved via artifact lookup at execution time by ralph-execute
242
194
 
243
- **Example — from "plan" position (M1 with phases [1,2]):**
195
+ **Example — from "plan" position:**
244
196
  ```json
245
197
  [
246
198
  { "index": 0, "type": "skill", "skill": "maestro-plan", "args": "{phase}" },
@@ -260,38 +212,28 @@ milestone-complete maestro-milestone-complete skill decision:post-milestone
260
212
  ]
261
213
  ```
262
214
 
263
- ### 2a.5: Create session
264
-
265
- ```
266
- session_id = "ralph-{YYYYMMDD-HHmmss}"
267
- session_dir = ".workflow/.maestro/{session_id}/"
215
+ ### 2.5: Create session
268
216
 
269
- Write status.json:
217
+ ```json
270
218
  {
271
- "session_id": "{session_id}",
219
+ "session_id": "ralph-{YYYYMMDD-HHmmss}",
272
220
  "source": "ralph",
273
- "created_at": "{ISO}",
274
- "updated_at": "{ISO}",
221
+ "created_at": "{ISO}", "updated_at": "{ISO}",
275
222
  "intent": "{user_intent}",
276
223
  "status": "running",
277
224
  "chain_name": "ralph-lifecycle",
278
225
  "task_type": "lifecycle",
279
226
  "lifecycle_position": "{position}",
280
227
  "target": "milestone-complete",
281
- "phase": {N},
228
+ "phase": null | N,
282
229
  "milestone": "{M}",
283
230
  "auto_mode": false,
284
- "cli_tool": "gemini",
231
+ "cli_tool": "claude",
285
232
  "quality_mode": "standard",
286
233
  "passed_gates": [],
287
234
  "context": {
288
- "issue_id": null,
289
- "milestone_num": null,
290
- "spec_session_id": null,
291
- "scratch_dir": null,
292
- "plan_dir": null,
293
- "analysis_dir": null,
294
- "brainstorm_dir": null
235
+ "issue_id": null, "milestone_num": null, "spec_session_id": null,
236
+ "scratch_dir": null, "plan_dir": null, "analysis_dir": null, "brainstorm_dir": null
295
237
  },
296
238
  "steps": [...],
297
239
  "waves": [],
@@ -299,7 +241,9 @@ Write status.json:
299
241
  }
300
242
  ```
301
243
 
302
- ### 2a.6: Display plan + confirm
244
+ Write to `.workflow/.maestro/{session_id}/status.json`.
245
+
246
+ ### 2.6: Display plan + confirm
303
247
 
304
248
  ```
305
249
  ============================================================
@@ -313,206 +257,219 @@ Write status.json:
313
257
  [ ] 1. maestro-execute 1 [cli]
314
258
  [ ] 2. maestro-verify 1 [skill]
315
259
  [ ] 3. ◆ post-verify [decision]
316
- [ ] 4. quality-auto-test 1 [skill]
317
- [ ] 5. ◆ post-business-test [decision]
318
- [ ] 6. quality-review 1 [skill]
319
- [ ] 7. ◆ post-review [decision]
320
- [ ] 8. quality-auto-test 1 [skill]
321
- [ ] 9. quality-test 1 [skill]
322
- [ ] 10. ◆ post-test [decision]
323
- [ ] 11. maestro-milestone-audit [skill]
324
- [ ] 12. maestro-milestone-complete [skill]
260
+ ...
325
261
  ============================================================
326
262
  ```
327
263
 
328
- AskUserQuestion: Proceed / Edit / Cancel
264
+ - If auto_confirm (`-y`): proceed directly
265
+ - Else: AskUserQuestion → Proceed / Edit / Cancel
266
+
267
+ ### 2.7: Launch execution
329
268
 
330
- ### 2a.7: Launch execution
269
+ HARD RULE: Ralph's job ends at session creation. Do NOT execute steps, read project files for execution, or update step statuses directly.
331
270
 
332
271
  ```
333
272
  Skill({ skill: "maestro-ralph-execute" })
273
+ End.
334
274
  ```
335
275
 
336
276
  ---
337
277
 
338
- ## Step 2b: Decision Evaluation Mode
278
+ ## Step 3: Decision Evaluation Mode
339
279
 
340
280
  Triggered when ralph-execute encounters a decision node and hands back to ralph.
341
281
 
342
- ### 2b.1: Load session + locate results
282
+ ### 3.1: Load session + resolve artifact dir
343
283
 
344
- Read ralph session status.json. Identify the decision node at `steps[current_step]`.
284
+ Read session status.json. Identify decision node at `steps[current_step]`.
345
285
 
346
- **Locate result files** — find the artifact dir for current phase:
286
+ **Artifact dir resolution:**
347
287
  ```
348
288
  Read .workflow/state.json
349
- Filter artifacts: milestone == session.milestone, phase == session.phase
350
- Sort by created_at DESC
351
-
352
- For the decision type, find the relevant artifact:
353
- post-verify → latest type=="verify" artifact → {.workflow/scratch/{artifact.path}/}
354
- post-business-test → same dir as verify (business-test writes to same artifact dir)
355
- post-review → latest artifact dir → review.json
356
- post-test → latest artifact dir → uat.md + .tests/test-results.json
289
+ Filter: milestone == session.milestone, phase == session.phase
290
+ Sort: created_at DESC
357
291
 
358
292
  artifact_dir = .workflow/scratch/{artifact.path}/
293
+
294
+ Fallback if path not found:
295
+ glob .workflow/scratch/*-P{phase}-*/ sorted by date DESC, take first
359
296
  ```
360
297
 
361
- ### 2b.2: Parse decision metadata
298
+ ### 3.2: Parse decision metadata
362
299
 
363
300
  ```
364
301
  meta = JSON.parse(decision_node.args)
365
302
  // { decision: "post-verify", retry_count: 0, max_retries: 2 }
366
- // or { decision: "post-milestone" }
367
- decision_type = meta.decision
368
303
  ```
369
304
 
370
- ### 2b.3: Evaluate by decision type (meta.decision)
305
+ ### 3.3: Delegate evaluation
371
306
 
372
- **post-verify:**
373
- ```
374
- Read {artifact_dir}/verification.json
375
- Check: gaps[] array and passed field
307
+ For quality-gate decisions (post-verify, post-business-test, post-review, post-test), delegate analysis to external CLI. For structural decisions (post-milestone, post-debug-escalate), evaluate directly.
376
308
 
377
- If gaps found (passed == false or gaps[].length > 0):
378
- If meta.retry_count >= meta.max_retries:
379
- → Insert: [quality-debug "{gap_summary}", decision:post-debug-escalate]
380
- → Display: ◆ post-verify: max retries ({max_retries}) reached, escalating to debug
381
- Else:
382
- → Insert: [quality-debug "{gap_summary}", maestro-plan --gaps {phase},
383
- maestro-execute {phase} [cli], maestro-verify {phase},
384
- decision:post-verify {retry_count+1}]
385
- → Display: ◆ post-verify: gaps detected, inserting debug+fix loop (retry {N}/{max})
309
+ **Structural decisions Step 3.5 (direct evaluation)**
310
+ **Quality-gate decisions delegate below:**
386
311
 
387
- If no gaps (passed == true):
388
- → No insertion, proceed
389
- ```
312
+ **Result file mapping** (for delegate CONTEXT):
313
+
314
+ | Decision type | Files to include |
315
+ |---------------|-----------------|
316
+ | post-verify | `{artifact_dir}/verification.json` |
317
+ | post-business-test | `{artifact_dir}/business-test-results.json` |
318
+ | post-review | `{artifact_dir}/review.json` |
319
+ | post-test | `{artifact_dir}/uat.md`, `{artifact_dir}/.tests/test-results.json` |
390
320
 
391
- **post-business-test:**
392
321
  ```
393
- Read {artifact_dir}/business-test-results.json or scan for business test output
394
- Check: failures[] or passed field
322
+ Bash({
323
+ command: `maestro delegate "PURPOSE: 评估 ${meta.decision} 质量门结果,判断是否通过
324
+ TASK: 读取结果文件 | 分析通过/失败状态 | 评估问题严重性 | 给出下一步建议
325
+ MODE: analysis
326
+ CONTEXT: @${result_files}
327
+ EXPECTED: 严格按以下格式输出:
328
+ ---VERDICT---
329
+ STATUS: proceed | fix | escalate
330
+ REASON: 一句话解释
331
+ GAP_SUMMARY: 具体问题描述(仅 fix/escalate 时填写,用于传递给 quality-debug)
332
+ CONFIDENCE: high | medium | low
333
+ ---END---
334
+ CONSTRAINTS: 只评估不修改 | STATUS 三选一 | 如果 retry ${meta.retry_count}/${meta.max_retries} 已达上限且仍有问题则必须 escalate" --role analyze --mode analysis`,
335
+ run_in_background: true
336
+ })
337
+ STOP — wait for callback.
338
+ ```
395
339
 
396
- If failures found:
397
- If meta.retry_count >= meta.max_retries:
398
- → Insert: [quality-debug --from-business-test {phase}, decision:post-debug-escalate]
399
- Else:
400
- → Insert: [quality-debug --from-business-test {phase},
401
- maestro-plan --gaps {phase}, maestro-execute {phase} [cli],
402
- maestro-verify {phase}, decision:post-verify {retry:0},
403
- quality-auto-test {phase}, decision:post-business-test {retry+1}]
340
+ ### 3.4: Parse verdict + apply
404
341
 
405
- If all pass:
406
- → No insertion, proceed
342
+ **On callback:** retrieve output via `maestro delegate output <exec_id>`.
343
+
344
+ Parse structured response:
407
345
  ```
346
+ Extract between ---VERDICT--- and ---END---:
347
+ verdict.status = "proceed" | "fix" | "escalate"
348
+ verdict.reason = string
349
+ verdict.gap_summary = string (context for quality-debug)
350
+ verdict.confidence = "high" | "medium" | "low"
408
351
 
409
- **post-review:**
352
+ If parse fails → fallback: treat as "fix" with generic gap_summary
410
353
  ```
411
- Read {artifact_dir}/review.json
412
- Check: verdict field and issues[].severity
413
354
 
414
- If verdict == "BLOCK" or any issue.severity == "critical":
415
- If meta.retry_count >= meta.max_retries:
416
- Insert: [quality-debug "{block_summary}", decision:post-debug-escalate]
417
- Else:
418
- Insert: [quality-debug "{block_issues}",
419
- maestro-plan --gaps {phase}, maestro-execute {phase} [cli],
420
- quality-review {phase}, decision:post-review {retry+1}]
355
+ **Apply verdict:**
356
+
357
+ | Mode | Behavior |
358
+ |------|----------|
359
+ | `-y` (auto_confirm) | Follow verdict directly — no user confirmation |
360
+ | Interactive + confidence == "high" | Display recommendation, AskUserQuestion: "按建议执行 / 覆盖 / 取消" |
361
+ | Interactive + confidence != "high" | Display recommendation with warning, AskUserQuestion: "按建议执行 / 覆盖 / 取消" |
362
+
363
+ User override options (interactive only):
364
+ - **按建议执行** → apply verdict as-is
365
+ - **覆盖 proceed** → force proceed regardless of verdict
366
+ - **覆盖 fix** → force fix loop
367
+ - **取消** → pause session, End.
368
+
369
+ **Verdict → action mapping:**
370
+
371
+ | Verdict | Action |
372
+ |---------|--------|
373
+ | `proceed` | No insertion, continue to next step |
374
+ | `fix` | Insert fix-loop commands (see 3.4a) |
375
+ | `escalate` | Insert `[quality-debug "{gap_summary}", decision:post-debug-escalate]` |
376
+
377
+ ### 3.4a: Fix-loop templates (by decision type)
421
378
 
422
- If verdict == "PASS" or "WARN":
423
- No insertion, proceed
379
+ When verdict == "fix", insert pre-defined fix-loop based on decision type.
380
+ The delegate's `gap_summary` is passed as context to `quality-debug`.
381
+
382
+ #### post-verify fix-loop
383
+ ```
384
+ quality-debug "{gap_summary}"
385
+ maestro-plan --gaps {phase}
386
+ maestro-execute {phase} [cli]
387
+ maestro-verify {phase}
388
+ decision:post-verify {retry_count + 1}
424
389
  ```
425
390
 
426
- **post-test:**
391
+ #### post-business-test fix-loop
392
+ ```
393
+ quality-debug --from-business-test "{gap_summary}"
394
+ maestro-plan --gaps {phase}
395
+ maestro-execute {phase} [cli]
396
+ maestro-verify {phase}
397
+ decision:post-verify {retry: 0}
398
+ quality-auto-test {phase}
399
+ decision:post-business-test {retry_count + 1}
427
400
  ```
428
- Read {artifact_dir}/uat.md (parse frontmatter + gap sections)
429
- Read {artifact_dir}/.tests/test-results.json if exists
430
401
 
431
- If failures found (any test result != pass, or gaps with severity >= high):
432
- If meta.retry_count >= meta.max_retries:
433
- → Insert: [quality-debug --from-uat {phase}, decision:post-debug-escalate]
434
- Else:
435
- → Insert: [quality-debug --from-uat {phase},
436
- maestro-plan --gaps {phase}, maestro-execute {phase} [cli],
437
- maestro-verify {phase}, decision:post-verify {retry:0},
438
- quality-auto-test {phase}, decision:post-business-test {retry:0},
439
- quality-review {phase}, decision:post-review {retry:0},
440
- quality-auto-test {phase}, quality-test {phase},
441
- decision:post-test {retry+1}]
402
+ #### post-review fix-loop
403
+ ```
404
+ quality-debug "{gap_summary}"
405
+ maestro-plan --gaps {phase}
406
+ maestro-execute {phase} [cli]
407
+ quality-review {phase}
408
+ decision:post-review {retry_count + 1}
409
+ ```
442
410
 
443
- If all pass:
444
- → No insertion, proceed
411
+ #### post-test fix-loop
412
+ ```
413
+ quality-debug --from-uat "{gap_summary}"
414
+ maestro-plan --gaps {phase}
415
+ maestro-execute {phase} [cli]
416
+ maestro-verify {phase}
417
+ decision:post-verify {retry: 0}
418
+ quality-auto-test {phase}
419
+ decision:post-business-test {retry: 0}
420
+ quality-review {phase}
421
+ decision:post-review {retry: 0}
422
+ quality-auto-test {phase}
423
+ quality-test {phase}
424
+ decision:post-test {retry_count + 1}
445
425
  ```
446
426
 
447
- **post-milestone:**
427
+ ### 3.5: Structural decisions (direct evaluation)
428
+
429
+ These don't need delegate analysis — evaluated directly by ralph.
430
+
431
+ #### post-milestone
432
+
448
433
  ```
449
- Re-read .workflow/state.json (milestone-complete will have updated it).
450
- Check: state.milestones[] for next milestone with status == "pending" or "active"
434
+ Read .workflow/state.json — check for next milestone (status "pending" or "active")
451
435
 
452
436
  If next milestone found:
453
- next_m = next milestone
454
- next_phases = next_m.phases[]
455
- first_phase = next_phases[0]
456
-
457
- Update ralph session: milestone = next_m.name, phase = first_phase
458
-
459
- → Insert full lifecycle for next milestone:
460
- [maestro-analyze {first_phase} [cli],
461
- maestro-plan {first_phase} [skill],
462
- maestro-execute {first_phase} [cli],
463
- maestro-verify {first_phase} [skill],
464
- decision:post-verify {retry:0},
465
- quality-auto-test {first_phase} [skill],
466
- decision:post-business-test {retry:0},
467
- quality-review {first_phase} [skill],
468
- decision:post-review {retry:0},
469
- quality-auto-test {first_phase} [skill],
470
- quality-test {first_phase} [skill],
471
- decision:post-test {retry:0},
472
- maestro-milestone-audit [skill],
473
- maestro-milestone-complete [skill],
474
- decision:post-milestone {}]
475
-
476
- → Display: ◆ post-milestone: {completed_m.name} done → advancing to {next_m.name} Phase {first_phase} (+14 commands)
437
+ Update session: milestone = next_m.name, phase = first_phase
438
+ Insert full lifecycle for next milestone (analyze through milestone-complete + decision nodes)
439
+ Display: post-milestone: {completed} done → advancing to {next_m.name} Phase {first_phase}
477
440
 
478
441
  If no next milestone:
479
- No insertion — session will complete naturally
480
- Display: ◆ post-milestone: all milestones complete! 🎉
481
- ```
482
-
483
- **post-debug-escalate:**
484
- ```
485
- This is a terminal escalation — debug was run but we exceeded max retries.
486
- → Set session status = "paused"
487
- → Display: ◆ 已达最大重试次数,debug 已执行。请人工介入检查结果。
488
- → Display: 使用 /maestro-ralph continue 在处理后恢复
489
- → End.
442
+ Proceed — session completes naturally
443
+ Display: ◆ post-milestone: all milestones complete!
490
444
  ```
491
445
 
492
- ### 2b.4: Insert commands + reindex
446
+ #### post-debug-escalate
493
447
 
494
- When inserting new commands after current position:
448
+ Terminal escalation max retries exceeded after debug.
495
449
 
496
450
  ```
497
- new_commands = buildInsertionCommands(...) // each with appropriate type/skill/args
498
- splice steps[] at position (current_step + 1), insert new_commands
499
- Reindex: commands.forEach((cmd, i) => cmd.index = i)
451
+ Set session status = "paused"
452
+ Display: 已达最大重试次数,debug 已执行。请人工介入检查结果。
453
+ Display: 使用 /maestro-ralph continue 在处理后恢复
454
+ End.
500
455
  ```
501
456
 
502
- ### 2b.5: Update session
457
+ ### 3.6: Insert commands + update session
503
458
 
504
459
  ```
505
- Mark current decision node status = "completed", completed_at = now
506
- Update status.json: steps[], current_step, updated_at
460
+ Insert new_commands at position (current_step + 1)
461
+ Reindex all steps: step.index = array position
462
+ Mark current decision node: status = "completed", completed_at = now
463
+ Write status.json
507
464
 
508
- If commands were inserted:
509
- Display: ◆ Decision: {type} → {outcome}, +{N} commands inserted
465
+ Display: ◆ Decision: {type} → {verdict.status} ({verdict.reason}), +{N} commands inserted
510
466
  ```
511
467
 
512
- ### 2b.6: Resume execution
468
+ ### 3.7: Resume execution
513
469
 
514
470
  ```
515
471
  Skill({ skill: "maestro-ralph-execute" })
472
+ End.
516
473
  ```
517
474
 
518
475
  </execution>
@@ -523,21 +480,30 @@ Skill({ skill: "maestro-ralph-execute" })
523
480
  | E001 | error | No intent and no running session | Prompt for intent |
524
481
  | E002 | error | Cannot infer lifecycle position | Show raw state, ask user |
525
482
  | E003 | error | Artifact dir not found for decision evaluation | Show glob results, ask user |
526
- | E004 | error | Result file (verification.json etc) missing in artifact dir | Warn, treat as failure |
483
+ | E004 | error | Delegate verdict parse failed | Fallback: treat as "fix" |
484
+ | E005 | error | Delegate execution failed | Fallback: treat as "fix" with generic summary |
527
485
  | W001 | warning | Decision node expanded chain | Auto-handled, log expansion |
528
- | W002 | warning | Max retries reached, escalating to debug | Auto-handled |
486
+ | W002 | warning | Max retries reached, escalating | Auto-handled |
529
487
  | W003 | warning | Multiple running sessions found | Use latest, warn user |
488
+ | W004 | warning | Delegate confidence == "low" | Show warning in interactive mode |
530
489
  </error_codes>
531
490
 
532
491
  <success_criteria>
533
- - [ ] state.json artifacts correctly read with actual schema (type, path, scope, milestone)
534
- - [ ] Lifecycle position inferred from artifacts + result files (verification.json, review.json, uat.md)
535
- - [ ] Artifact dir resolved via artifact.path → .workflow/scratch/{path}/
536
- - [ ] Full quality pipeline: verify → business-test → review → test-gen → test
537
- - [ ] Decision nodes at: post-verify, post-business-test, post-review, post-test
538
- - [ ] Every decision failure path starts with quality-debug before plan --gaps
539
- - [ ] retry_count tracked per decision node, max_retries enforced
540
- - [ ] Max retries → post-debug-escalate session paused for human intervention
541
- - [ ] Command insertion + reindex works correctly
542
- - [ ] Handoff to maestro-ralph-execute via Skill()
492
+ - [ ] state.json parsed with correct schema (type, path, scope, milestone, artifacts[])
493
+ - [ ] Lifecycle position inferred from bootstrap state + artifact chain + result files
494
+ - [ ] Artifact dir resolved: `.workflow/scratch/{artifact.path}/` with fallback glob
495
+ - [ ] Full quality pipeline generated: verify → business-test → review → test-gen → test
496
+ - [ ] Decision nodes inserted after: post-verify, post-business-test, post-review, post-test, post-milestone
497
+ - [ ] Quality-gate decisions delegated via `maestro delegate --role analyze --mode analysis`
498
+ - [ ] Delegate verdict parsed: STATUS / REASON / GAP_SUMMARY / CONFIDENCE
499
+ - [ ] `-y` mode: auto-follow delegate verdict without user confirmation
500
+ - [ ] Interactive mode: display recommendation + AskUserQuestion with override options
501
+ - [ ] Delegate failure fallback: treat as "fix" verdict
502
+ - [ ] gap_summary from delegate passed to quality-debug as context
503
+ - [ ] Fix-loop templates applied per decision type with retry_count increment
504
+ - [ ] retry_count tracked per decision, max_retries enforced, escalation to post-debug-escalate
505
+ - [ ] Structural decisions (post-milestone, post-debug-escalate) evaluated directly without delegate
506
+ - [ ] Command insertion + reindex preserves step integrity
507
+ - [ ] Ralph never executes steps — only creates sessions and evaluates decisions
508
+ - [ ] Handoff to maestro-ralph-execute via Skill() at session creation and after decision evaluation
543
509
  </success_criteria>