maestro-flow 0.5.38 → 0.5.39
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/.agents/skills/odyssey-debug/SKILL.md +90 -269
- package/.agents/skills/odyssey-improve/SKILL.md +39 -240
- package/.agents/skills/odyssey-planex/SKILL.md +21 -105
- package/.agents/skills/odyssey-review-test-fix/SKILL.md +98 -318
- package/.agents/skills/odyssey-ui/SKILL.md +82 -265
- package/.agy/skills/odyssey-debug/SKILL.md +90 -269
- package/.agy/skills/odyssey-improve/SKILL.md +39 -240
- package/.agy/skills/odyssey-planex/SKILL.md +21 -105
- package/.agy/skills/odyssey-review-test-fix/SKILL.md +98 -318
- package/.agy/skills/odyssey-ui/SKILL.md +82 -265
- package/.claude/commands/odyssey-debug.md +90 -269
- package/.claude/commands/odyssey-improve.md +39 -240
- package/.claude/commands/odyssey-planex.md +21 -105
- package/.claude/commands/odyssey-review-test-fix.md +98 -318
- package/.claude/commands/odyssey-ui.md +82 -265
- package/.codex/skills/odyssey-debug/SKILL.md +167 -338
- package/.codex/skills/odyssey-improve/SKILL.md +226 -395
- package/.codex/skills/odyssey-planex/SKILL.md +317 -159
- package/.codex/skills/odyssey-review-test-fix/SKILL.md +137 -255
- package/.codex/skills/odyssey-ui/SKILL.md +197 -338
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.d.ts +23 -2
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js +242 -26
- package/dashboard/dist-server/dashboard/src/server/wiki/embedding.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +92 -29
- package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
- package/dashboard/dist-server/src/commands/hooks.d.ts +2 -1
- package/dashboard/dist-server/src/commands/hooks.js +16 -9
- package/dashboard/dist-server/src/commands/hooks.js.map +1 -1
- package/dashboard/dist-server/src/hooks/kg-sync-hook.js +5 -0
- package/dashboard/dist-server/src/hooks/kg-sync-hook.js.map +1 -1
- package/dashboard/dist-server/src/hooks/session-context.js +276 -3
- package/dashboard/dist-server/src/hooks/session-context.js.map +1 -1
- package/dashboard/dist-server/src/search/daemon-client.d.ts +8 -3
- package/dashboard/dist-server/src/search/daemon-client.js +20 -0
- package/dashboard/dist-server/src/search/daemon-client.js.map +1 -1
- package/dist/src/commands/domain.d.ts.map +1 -1
- package/dist/src/commands/domain.js +12 -3
- package/dist/src/commands/domain.js.map +1 -1
- package/dist/src/commands/hooks.d.ts +2 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +16 -9
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/install.js +33 -2
- package/dist/src/commands/install.js.map +1 -1
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +59 -6
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/commands/spec.d.ts.map +1 -1
- package/dist/src/commands/spec.js +15 -0
- package/dist/src/commands/spec.js.map +1 -1
- package/dist/src/hooks/kg-sync-hook.d.ts.map +1 -1
- package/dist/src/hooks/kg-sync-hook.js +5 -0
- package/dist/src/hooks/kg-sync-hook.js.map +1 -1
- package/dist/src/hooks/session-context.d.ts.map +1 -1
- package/dist/src/hooks/session-context.js +276 -3
- package/dist/src/hooks/session-context.js.map +1 -1
- package/dist/src/search/daemon-client.d.ts +8 -3
- package/dist/src/search/daemon-client.d.ts.map +1 -1
- package/dist/src/search/daemon-client.js +20 -0
- package/dist/src/search/daemon-client.js.map +1 -1
- package/dist/src/search/daemon.d.ts +3 -3
- package/dist/src/search/daemon.d.ts.map +1 -1
- package/dist/src/search/daemon.js +9 -3
- package/dist/src/search/daemon.js.map +1 -1
- package/package.json +1 -1
- package/workflows/odyssey-base.md +258 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: odyssey-debug
|
|
3
3
|
description: "Long-running debug cycle — archaeology, diagnosis, fix, confirmation, generalization, discovery, and knowledge persistence"
|
|
4
|
-
argument-hint: "<issue> [--skip-fix] [--skip-generalize] [--auto] [-y] [-c]"
|
|
4
|
+
argument-hint: "<issue> [--skip-fix] [--skip-generalize] [--auto] [-y] [-c] [--heartbeat]"
|
|
5
5
|
allowed-tools: spawn_agents_on_csv, Read, Write, Edit, Bash, Glob, Grep, request_user_input
|
|
6
6
|
---
|
|
7
|
+
<base>@~/.maestro/workflows/odyssey-base.md</base>
|
|
7
8
|
|
|
8
9
|
<purpose>
|
|
9
|
-
Closed-loop deep debugging: archaeology
|
|
10
|
+
Closed-loop deep debugging: archaeology → explore → diagnose → fix & confirm → generalize → discover siblings → persist.
|
|
11
|
+
Treats every bug as a learning signal with exhaustive iteration until root cause confirmed or INCONCLUSIVE.
|
|
10
12
|
|
|
11
13
|
Core philosophy:
|
|
12
14
|
- **Archaeology before hypothesis** — look at what changed before guessing why
|
|
@@ -21,359 +23,197 @@ Core philosophy:
|
|
|
21
23
|
</purpose>
|
|
22
24
|
|
|
23
25
|
<boundary>
|
|
24
|
-
**范围内:** 单一 bug/issue 的完整闭环 — 考古 → 探索 → 诊断 → 修复 → 确认 →
|
|
25
|
-
**范围外:**
|
|
26
|
-
**探索自由度:**
|
|
27
|
-
**Zero-residual principle:** Every finding MUST have a concrete action (fix / issue / decision). "
|
|
28
|
-
|
|
26
|
+
**范围内:** 单一 bug/issue 的完整闭环 — 考古 → 探索 → 诊断 → 修复 → 确认 → 泛化同类 → 沉淀
|
|
27
|
+
**范围外:** 新功能开发 → `$odyssey-planex` | 代码质量审查 → `$odyssey-review-test-fix` | UI 视觉优化 → `$odyssey-ui` | 架构重设计 → `/maestro-plan`
|
|
28
|
+
**探索自由度:** 边界内自由探索 — 可追踪任意调用链、分析任意历史、测试任意假设。泛化阶段可扫描全项目寻找同类问题。
|
|
29
|
+
**Zero-residual principle:** Every finding MUST have a concrete action (fix / issue / decision). "Pre-existing issue" is not a valid skip reason.
|
|
30
|
+
**模板支持:** `--template <name>` 从预定义调查策略启动:
|
|
31
|
+
|
|
32
|
+
| Template | 调查策略 | 适用场景 |
|
|
33
|
+
|----------|---------|---------|
|
|
34
|
+
| `performance` | profiling → hot path → allocation → cache | 性能劣化 |
|
|
35
|
+
| `memory-leak` | heap snapshot → retention chain → lifecycle | 内存泄漏 |
|
|
36
|
+
| `race-condition` | timeline → concurrent access → lock analysis | 竞态条件 |
|
|
37
|
+
| `regression` | git bisect → diff analysis → boundary check | 回归问题 |
|
|
38
|
+
| `crash` | stack trace → null chain → error propagation | 崩溃/异常 |
|
|
29
39
|
</boundary>
|
|
30
40
|
|
|
31
|
-
<execution_discipline>
|
|
32
|
-
**三条铁律(所有阶段适用):**
|
|
33
|
-
1. **Phase auto-commit** — 阶段完成后**自动** `git commit`,无需用户确认(session.json/evidence.ndjson 不纳入)
|
|
34
|
-
2. **Confident edits only, but must attempt** — only modify what you're confident about; record decisions only when genuinely requiring human judgment
|
|
35
|
-
- Confident → edit code directly, commit
|
|
36
|
-
- Needs decision → record `evidence.ndjson {"phase":"decision","status":"pending"}`, don't touch code
|
|
37
|
-
- No speculative changes
|
|
38
|
-
- ⚠️ **Decision gate** — ONLY these qualify as decisions (not fixes):
|
|
39
|
-
- Cross-module architectural tradeoffs requiring human direction
|
|
40
|
-
- Ambiguous business semantics where the fix could alter intended behavior
|
|
41
|
-
- Requires new dependency or breaking API change
|
|
42
|
-
- ❌ "Unsure how to fix", "Large scope", "Pre-existing issue" are NOT valid decision reasons — either fix it, or explain specifically why it's unfixable
|
|
43
|
-
3. **多 CLI 辅助** — `maestro delegate` 多 `--role`(analyze/review/explore)交叉验证关键判断
|
|
44
|
-
</execution_discipline>
|
|
45
|
-
|
|
46
41
|
<context>
|
|
47
42
|
$ARGUMENTS — issue description and optional flags.
|
|
48
43
|
|
|
49
|
-
**Flags:** `--skip-fix` analysis-only | `--skip-generalize` quick fix | `--template <name>` 预定义策略 | `--auto` no delegate confirmation | `-y` auto-confirm all decisions | `-c` resume last session
|
|
44
|
+
**Flags:** `--skip-fix` analysis-only | `--skip-generalize` quick fix | `--template <name>` 预定义策略 | `--auto` no delegate confirmation | `-y` auto-confirm all decisions | `-c` resume last session | `--heartbeat` enable /loop heartbeat
|
|
50
45
|
|
|
51
46
|
**Session**: `SESSION_DIR = .workflow/scratch/{YYYYMMDD}-debug-odyssey-{slug}/`
|
|
47
|
+
**Output**: `session.json` | `evidence.ndjson` | `explore.json` | `understanding.md`
|
|
52
48
|
|
|
53
|
-
**
|
|
54
|
-
```
|
|
55
|
-
SESSION_DIR/
|
|
56
|
-
├── session.json # state + confirmation + patterns + phase_goals
|
|
57
|
-
├── evidence.ndjson # append-only evidence trail (phase field distinguishes origin)
|
|
58
|
-
├── explore.json # structured CLI exploration snapshot
|
|
59
|
-
└── understanding.md # evolving narrative — 9 sections
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**evidence.ndjson — unified trail:**
|
|
49
|
+
**session.json unique fields:**
|
|
63
50
|
```json
|
|
64
|
-
{"
|
|
51
|
+
{ "issue": "", "diagnosis_retries": 0, "root_cause": null, "confirmation": null,
|
|
52
|
+
"patterns": [], "generalization_stats": null, "cross_phase_loops": 0, "max_loops": 5 }
|
|
65
53
|
```
|
|
66
|
-
|
|
67
|
-
|
|
54
|
+
共有字段(`progress_metrics`, `directions_tried` 等)见 base。
|
|
55
|
+
|
|
56
|
+
**evidence.ndjson phases:** `archaeology|explore|diagnosis|discovery|decision|self-iteration`
|
|
57
|
+
- `archaeology`: `sha`, `author`, `date`, `message`, `relevance`
|
|
68
58
|
- `explore`: `category` (call_chain|recent_change|error_gap|similar_pattern), `detail`
|
|
69
59
|
- `diagnosis`: `hypothesis`, `result` (confirmed|disproved|inconclusive)
|
|
70
|
-
- `discovery`: `file`, `line`, `classification` (safe|risk|bug), `action`
|
|
71
|
-
- `decision`: `question`, `options`, `context`, `status
|
|
60
|
+
- `discovery`: `file`, `line`, `classification` (safe|risk|bug), `action` (fix|issue|decision|skip)
|
|
61
|
+
- `decision`: `question`, `options`, `context`, `status`, `resolution`
|
|
62
|
+
- `self-iteration`: `stage`, `round`, `assessment`, `expansion`
|
|
72
63
|
|
|
73
|
-
**explore.json
|
|
74
|
-
```json
|
|
75
|
-
{
|
|
76
|
-
"call_chains": [{"entry":"","chain":["file:line"]}],
|
|
77
|
-
"recent_changes": [{"file":"","commits":[{"sha":"","message":"","date":""}]}],
|
|
78
|
-
"error_gaps": [{"file":"","line":0,"description":""}],
|
|
79
|
-
"similar_patterns": [{"file":"","line":0,"description":""}],
|
|
80
|
-
"cli_tool": "", "timestamp": ""
|
|
81
|
-
}
|
|
82
|
-
```
|
|
64
|
+
**explore.json**: `{call_chains, recent_changes, error_gaps, similar_patterns, cli_tool, timestamp}`
|
|
83
65
|
|
|
84
|
-
**
|
|
85
|
-
```json
|
|
86
|
-
{
|
|
87
|
-
"session_id": "debug-odyssey-{YYYYMMDD-HHmmss}", "issue": "",
|
|
88
|
-
"flags": { "skip_fix": false, "skip_generalize": false, "auto": false, "auto_confirm": false },
|
|
89
|
-
"current_state": "S_INTAKE", "diagnosis_retries": 0,
|
|
90
|
-
"root_cause": null, "patterns": [], "confirmation": null,
|
|
91
|
-
"phase_goals": [], "phase_goals_all_done": false, "self_iteration_log": [],
|
|
92
|
-
"cross_phase_loops": 0, "max_loops": 5,
|
|
93
|
-
"generalization_stats": null,
|
|
94
|
-
"created_at": "", "updated_at": ""
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**phase_goals[] — auto-derived from flags:**
|
|
66
|
+
**phase_goals[]:**
|
|
99
67
|
|
|
100
68
|
| ID | Goal | done_when | phase | skip_when |
|
|
101
69
|
|----|------|-----------|-------|-----------|
|
|
102
|
-
| G1 | Root cause identified |
|
|
103
|
-
| G2 | Explore context gathered | explore.json ≥1 category
|
|
70
|
+
| G1 | Root cause identified | phase=diagnosis result=confirmed | S_DIAGNOSE | — |
|
|
71
|
+
| G2 | Explore context gathered | explore.json ≥1 category | S_EXPLORE | — |
|
|
104
72
|
| G3 | Fix applied and confirmed | confirmation.overall == confirmed | S_CONFIRM | skip_fix |
|
|
105
73
|
| G4 | Pattern generalized | patterns[] ≥1 entry | S_GENERALIZE | skip_generalize |
|
|
106
74
|
| G5 | Discoveries triaged | all scan hits classified | S_DISCOVER | skip_generalize |
|
|
107
|
-
| G6 | Learnings persisted | spec entries created OR
|
|
108
|
-
|
|
109
|
-
When `flags[skip_when] == true` → auto set `status: "skipped"`, `completion_confirmed: true`.
|
|
75
|
+
| G6 | Learnings persisted | spec entries created OR none actionable | S_RECORD | — |
|
|
110
76
|
|
|
111
|
-
**understanding.md — 9 sections
|
|
77
|
+
**understanding.md — 9 sections:**
|
|
112
78
|
1. Issue & Scope ← S_INTAKE | 2. Archaeology ← S_ARCHAEOLOGY | 3. Exploration ← S_EXPLORE
|
|
113
79
|
4. Hypotheses ← S_DIAGNOSE | 5. Root Cause ← S_DIAGNOSE | 6. Fix & Confirmation ← S_FIX+S_CONFIRM
|
|
114
80
|
7. Generalization ← S_GENERALIZE | 8. Discoveries ← S_DISCOVER | 9. Learnings ← S_RECORD
|
|
115
81
|
|
|
116
82
|
### Pre-load(可选,缺失不阻塞)
|
|
117
83
|
|
|
118
|
-
|
|
|
119
|
-
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
|
131
|
-
|
|
132
|
-
|
|
|
133
|
-
| 非显而易见 workaround | 问题场景 + 解决方案 + 适用范围 | `$spec-add learning "..."` |
|
|
134
|
-
| 架构边界违反 | 违反描述 + 正确边界 + 检查方法 | `$spec-add arch "..."` |
|
|
135
|
-
| 可复用泛化 pattern | pattern 签名 + 风险说明 + fix 模板 | `$spec-add coding "..."` |
|
|
136
|
-
|
|
137
|
-
**两步模式:** 执行中写入产出文件(临时记录)→ 任务完成后用户沉淀为永久知识。执行过程中不调用外部 skill。
|
|
84
|
+
| 命令 | 作用 |
|
|
85
|
+
|------|------|
|
|
86
|
+
| Read `.workflow/codebase/ARCHITECTURE.md` | 模块边界 |
|
|
87
|
+
| `maestro search "<issue keywords>" --json` | 先前调查(top 5) |
|
|
88
|
+
| `maestro load --type spec --category debug --keyword "<symptom>"` | 已知 issue/workaround |
|
|
89
|
+
| `Glob(".workflow/scratch/*-debug-odyssey-*")` | 相关 odyssey 会话 |
|
|
90
|
+
|
|
91
|
+
### Knowledge Persistence(S_RECORD → understanding.md §9)
|
|
92
|
+
|
|
93
|
+
| 分类 | 后续建议命令 |
|
|
94
|
+
|------|-------------|
|
|
95
|
+
| 反复根因模式 | `/spec-add debug "..."` |
|
|
96
|
+
| 非显而易见 workaround | `/spec-add learning "..."` |
|
|
97
|
+
| 架构边界违反 | `/spec-add arch "..."` |
|
|
98
|
+
| 可复用泛化 pattern | `/spec-add coding "..."` |
|
|
138
99
|
</context>
|
|
139
100
|
|
|
140
101
|
<self_iteration>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
| 维度 | sufficient | insufficient |
|
|
144
|
-
|------|-----------|-------------|
|
|
145
|
-
| Coverage | 已知相关文件/模块均已分析 | 遗漏 grep/git log 可发现的目标 |
|
|
146
|
-
| Depth | ≥80% 发现有 file:line 级证据 | 多数仅泛泛描述 |
|
|
147
|
-
| Actionability | 每条结论有具体后续动作 | 仅"建议关注"类无操作性结论 |
|
|
148
|
-
|
|
149
|
-
**Rules:** Phase complete → evaluate 3 dimensions → any insufficient → re-enter (max **3 rounds** per phase).
|
|
150
|
-
- Round 1: Broaden scope — add directories, git log depth ×2, add delegate angles
|
|
151
|
-
- Round 2: Switch perspective — different CLI tool, reverse tracing, manual code reading
|
|
152
|
-
- Round 3: Combine both + targeted deep-dive on remaining gaps
|
|
153
|
-
|
|
154
|
-
**Exit:** All sufficient → advance | 3-round limit → record gaps and continue. Log to `evidence.ndjson` + `session.json.self_iteration_log[]`.
|
|
102
|
+
适用阶段: S_ARCHAEOLOGY, S_EXPLORE, S_DIAGNOSE, S_GENERALIZE
|
|
155
103
|
</self_iteration>
|
|
156
104
|
|
|
157
|
-
<
|
|
158
|
-
### Shared Output Schema (all waves)
|
|
159
|
-
```json
|
|
160
|
-
{
|
|
161
|
-
"type": "object",
|
|
162
|
-
"properties": {
|
|
163
|
-
"id": {"type":"string"}, "result_status": {"type":"string","enum":["completed","failed"]},
|
|
164
|
-
"findings": {"type":"string","maxLength":500}, "evidence": {"type":"string"}, "error": {"type":"string"}
|
|
165
|
-
},
|
|
166
|
-
"required": ["id","result_status","findings"]
|
|
167
|
-
}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
**Termination Contract** (embed in every instruction):
|
|
171
|
-
```
|
|
172
|
-
You MUST call report_agent_job_result EXACTLY ONCE before exiting.
|
|
173
|
-
Success → result_status=completed | Failure → result_status=failed with error | Timeout → completed with partial.
|
|
174
|
-
NEVER continue indefinitely. NEVER exit silently. Read-only — do NOT modify source files.
|
|
175
|
-
Do NOT write to tasks.csv, wave-*.csv, results.csv. Do NOT call spawn_agents_on_csv.
|
|
176
|
-
```
|
|
105
|
+
<state_machine>
|
|
177
106
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```
|
|
182
|
-
- Wave 1: Archaeology (git-timeline, git-blame) — parallel
|
|
183
|
-
- Wave 2: Generalization (syntax-grep, semantic-scan, structural-match, historical-grep) — parallel, depends on root cause
|
|
184
|
-
- Single-agent stages (explore, diagnose, fix, confirm) remain inline
|
|
185
|
-
</csv_schema>
|
|
186
|
-
|
|
187
|
-
<invariants>
|
|
188
|
-
1. **Iron Law**: NO FIX without root cause evidence
|
|
189
|
-
2. **Archaeology first**: git history MUST precede any hypothesis
|
|
190
|
-
3. **Evidence append-only**: never modify/delete evidence.ndjson entries
|
|
191
|
-
4. **Session is source of truth**: session.json holds all state
|
|
192
|
-
5. **Phase goal tracking**: each phase MUST mark its goal on completion
|
|
193
|
-
6. **Decision journal integrity**: all human-judgment items recorded phase=decision
|
|
194
|
-
7. **`-y` defers, never drops**: auto-confirm records "deferred", never silently skips
|
|
195
|
-
8. **CLI delegate is background**: all `maestro delegate` → `run_in_background: true`, wait for callback (do NOT halt the Odyssey flow)
|
|
196
|
-
9. **Resumable state**: current_state saved at every transition
|
|
197
|
-
10. **Goal is outcome-oriented**: `/goal` user-bound; odyssey outputs prompt then continues
|
|
198
|
-
11. **Violation = BLOCK**: violating any invariant blocks the operation
|
|
199
|
-
</invariants>
|
|
200
|
-
|
|
201
|
-
<execution>
|
|
202
|
-
|
|
203
|
-
### Stage 1: Intake (S_INTAKE)
|
|
204
|
-
1. Parse arguments: issue description, flags
|
|
205
|
-
2. Generate slug, create `SESSION_DIR`
|
|
206
|
-
3. Search: `maestro search "<keywords>"` + Glob prior sessions + ARCHITECTURE.md + Grep keywords
|
|
207
|
-
4. Derive `phase_goals[]` from flags (apply `skip_when`)
|
|
208
|
-
5. Write `session.json` + `understanding.md` §1
|
|
209
|
-
6. Display Goal Prompt (Appendix), continue without blocking
|
|
210
|
-
|
|
211
|
-
**Resume (`-c`):** Glob latest session → read `session.json` → restore `current_state` → jump.
|
|
212
|
-
|
|
213
|
-
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): S_INTAKE — 目标解析"`
|
|
214
|
-
|
|
215
|
-
### Stage 2: Archaeology (S_ARCHAEOLOGY)
|
|
216
|
-
**Step 1 — Git archaeology (spawn_agents_on_csv, Wave 1):**
|
|
217
|
-
|
|
218
|
-
Write `tasks.csv` with Wave 1 rows:
|
|
219
|
-
```csv
|
|
220
|
-
id,title,description,task_type,deps,wave,status,findings,evidence,error
|
|
221
|
-
"arch-timeline","Git Timeline","Run git log --oneline -20 -- {files}. Return [{sha,date,author,message,files_changed}] as JSON.","archaeology","","1","pending","","",""
|
|
222
|
-
"arch-blame","Git Blame","Top 3 suspicious files: git blame -L {region}. Return [{file,line_range,sha,author,date,content}] as JSON.","archaeology","","1","pending","","",""
|
|
223
|
-
```
|
|
107
|
+
<states>
|
|
108
|
+
S_INTAKE → S_ARCHAEOLOGY → S_EXPLORE → S_DIAGNOSE → S_FIX → S_CONFIRM → S_GENERALIZE → S_DISCOVER → S_RECORD → END
|
|
109
|
+
</states>
|
|
224
110
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
output_csv_path:"wave-1-results.csv", output_schema: SHARED_OUTPUT_SCHEMA })
|
|
230
|
-
```
|
|
111
|
+
<transitions>
|
|
112
|
+
S_INTAKE → S_INTAKE : -c + session found → A_RESUME_SESSION
|
|
113
|
+
S_INTAKE → S_ARCHAEOLOGY : issue parsed → A_INTAKE
|
|
114
|
+
S_INTAKE → S_INTAKE : no issue, no session → request_user_input
|
|
231
115
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
**Step 2 — CLI change review:**
|
|
235
|
-
```bash
|
|
236
|
-
maestro delegate "PURPOSE: Review recent modifications related to: {issue}
|
|
237
|
-
TASK: Analyze intent | Identify risky modifications | Flag potential bug sources
|
|
238
|
-
MODE: analysis
|
|
239
|
-
CONTEXT: @{relevant_files} | Git log: {top_10_commits}
|
|
240
|
-
EXPECTED: JSON [{commit_sha, risk_level, analysis, could_cause_issue, explanation}]
|
|
241
|
-
CONSTRAINTS: Focus on behavioral changes, not formatting
|
|
242
|
-
" --role analyze --mode analysis
|
|
243
|
-
```
|
|
244
|
-
Execute with `run_in_background: true`, then wait for callback (do NOT halt the Odyssey flow). Append results.
|
|
116
|
+
S_ARCHAEOLOGY → S_EXPLORE : A_ARCHAEOLOGY complete
|
|
117
|
+
S_EXPLORE → S_DIAGNOSE : A_EXPLORE complete
|
|
245
118
|
|
|
246
|
-
|
|
119
|
+
S_DIAGNOSE → S_FIX : root cause confirmed, !skip_fix
|
|
120
|
+
S_DIAGNOSE → S_GENERALIZE : root cause confirmed, skip_fix, !skip_generalize
|
|
121
|
+
S_DIAGNOSE → S_RECORD : root cause confirmed, skip_fix, skip_generalize
|
|
122
|
+
S_DIAGNOSE → S_DIAGNOSE : all hypotheses failed, retries < 3 → A_ESCALATE_DIAGNOSIS
|
|
123
|
+
S_DIAGNOSE → S_RECORD : retries >= 3 → mark INCONCLUSIVE
|
|
247
124
|
|
|
248
|
-
|
|
125
|
+
S_FIX → S_CONFIRM : fix implemented
|
|
126
|
+
S_CONFIRM → S_GENERALIZE : confirmed, !skip_generalize
|
|
127
|
+
S_CONFIRM → S_RECORD : confirmed, skip_generalize
|
|
128
|
+
S_CONFIRM → S_FIX : needs_rework
|
|
249
129
|
|
|
250
|
-
|
|
251
|
-
|
|
130
|
+
S_GENERALIZE → S_DISCOVER : similar code found
|
|
131
|
+
S_GENERALIZE → S_RECORD : no similar code
|
|
252
132
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
CONTEXT: @**/*
|
|
258
|
-
EXPECTED: JSON {call_chains, recent_changes, error_gaps, similar_patterns}
|
|
259
|
-
CONSTRAINTS: Max 20 entries/category | Symptom-related code paths
|
|
260
|
-
Symptoms: {issue} Archaeology hints: {suspicious_commits}
|
|
261
|
-
" --role explore --mode analysis
|
|
262
|
-
```
|
|
263
|
-
Execute with `run_in_background: true`, then wait for callback (do NOT halt the Odyssey flow).
|
|
133
|
+
S_DISCOVER → S_DIAGNOSE : new bug worth investigating → cross_phase_loops++
|
|
134
|
+
S_DISCOVER → S_FIX : same-pattern bug, fix template applies, !skip_fix → cross_phase_loops++
|
|
135
|
+
S_DISCOVER → S_RECORD : triage complete, remaining_actionable == 0
|
|
136
|
+
S_DISCOVER → S_RECORD : loops >= max_loops → log each unfixed item with specific reason
|
|
264
137
|
|
|
265
|
-
|
|
138
|
+
S_RECORD → END : A_RECORD complete
|
|
139
|
+
</transitions>
|
|
266
140
|
|
|
267
|
-
|
|
141
|
+
<actions>
|
|
268
142
|
|
|
269
|
-
###
|
|
270
|
-
1.
|
|
271
|
-
2.
|
|
272
|
-
3.
|
|
273
|
-
4.
|
|
143
|
+
### A_INTAKE
|
|
144
|
+
1. Parse arguments, generate slug, create `SESSION_DIR`
|
|
145
|
+
2. Search: `maestro search "<keywords>"` + Glob prior sessions + ARCHITECTURE.md + Grep keywords
|
|
146
|
+
3. Derive `phase_goals[]` from flags (apply `skip_when`)
|
|
147
|
+
4. Write `session.json` + `understanding.md` §1, emit Goal Prompt
|
|
274
148
|
|
|
275
|
-
**
|
|
276
|
-
All hypotheses fail → increment `diagnosis_retries`.
|
|
277
|
-
- < 3: broaden scope via `maestro delegate --role analyze`, form new hypotheses.
|
|
278
|
-
- >= 3: Normal → request_user_input (broaden/new/INCONCLUSIVE) | `-y` → auto INCONCLUSIVE, proceed to S_RECORD.
|
|
149
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): INTAKE — 目标解析与上下文加载"`
|
|
279
150
|
|
|
280
|
-
|
|
151
|
+
### A_RESUME_SESSION
|
|
152
|
+
Find latest session via Glob → read `session.json` → display summary → jump to `current_state`.
|
|
281
153
|
|
|
282
|
-
###
|
|
283
|
-
|
|
154
|
+
### A_ARCHAEOLOGY
|
|
155
|
+
**2 parallel agents (spawn_agents_on_csv):** Timeline (`git log --oneline -20 -- {files}`) + Blame (top 3 suspicious files `git blame -L {region}`). Append evidence (phase: "archaeology").
|
|
284
156
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
📌 **Auto-commit**: `git add -A && git commit -m "odyssey-debug({slug}): S_FIX — 修复"`
|
|
290
|
-
|
|
291
|
-
### Stage 6: Confirmation (S_CONFIRM)
|
|
292
|
-
Skip if `--skip-fix`.
|
|
293
|
-
|
|
294
|
-
1. **Tests**: auto-detect framework, run covering tests
|
|
295
|
-
2. **CLI fix review**:
|
|
296
|
-
```bash
|
|
297
|
-
maestro delegate "PURPOSE: Review fix for: {issue}
|
|
298
|
-
TASK: Verify correctness | Check regressions | Assess completeness
|
|
299
|
-
MODE: analysis
|
|
300
|
-
CONTEXT: @{modified_files} | Root cause: {summary} | Diff: {git_diff}
|
|
301
|
-
EXPECTED: JSON {verdict, findings [{severity, description, suggestion}], regression_risk}
|
|
302
|
-
CONSTRAINTS: Focus on correctness, not style
|
|
303
|
-
" --role review --mode analysis
|
|
304
|
-
```
|
|
305
|
-
Execute with `run_in_background: true`, then wait for callback (do NOT halt the Odyssey flow).
|
|
157
|
+
**CLI change review** via `maestro delegate --role analyze --mode analysis` (`run_in_background: true`):
|
|
158
|
+
- PURPOSE: Review recent modifications related to {issue}
|
|
159
|
+
- EXPECTED: JSON [{commit_sha, risk_level, analysis, could_cause_issue, explanation}]
|
|
306
160
|
|
|
307
|
-
|
|
308
|
-
4. Update §6. `needs_rework` → Stage 5. `confirmed` → mark G3 done, advance.
|
|
161
|
+
Update §2.
|
|
309
162
|
|
|
310
|
-
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}):
|
|
163
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): ARCHAEOLOGY — git 考古分析"`
|
|
311
164
|
|
|
312
|
-
###
|
|
313
|
-
Skip if
|
|
165
|
+
### A_EXPLORE
|
|
166
|
+
Skip if no enabled CLI tools (W006).
|
|
314
167
|
|
|
315
|
-
|
|
168
|
+
`maestro delegate --role explore --mode analysis` (`run_in_background: true`):
|
|
169
|
+
- PURPOSE: Gather codebase evidence — call chains, recent changes, error gaps, similar patterns
|
|
170
|
+
- EXPECTED: JSON {call_chains, recent_changes, error_gaps, similar_patterns}
|
|
316
171
|
|
|
317
|
-
|
|
318
|
-
|-------|--------|---------|
|
|
319
|
-
| Syntax | Regex patterns (direct Grep) | `eval(`, missing `await`, unclosed resource |
|
|
320
|
-
| Semantic | Anti-pattern description (Agent scan) | Unhandled async errors, unvalidated input |
|
|
321
|
-
| Structural | Architecture-level similarity | Same import structure, missing override |
|
|
172
|
+
Parse → write `explore.json` + evidence (phase: "explore"). Update §3. Mark G2 done.
|
|
322
173
|
|
|
323
|
-
|
|
174
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): EXPLORE — 代码探索完成"`
|
|
324
175
|
|
|
325
|
-
|
|
176
|
+
### A_DIAGNOSE
|
|
177
|
+
1. Form hypotheses from evidence, ranked [HIGH]/[MEDIUM]/[LOW] → §4
|
|
178
|
+
2. Test each: design test → execute → evidence (phase: "diagnosis")
|
|
179
|
+
3. Decision journal: ambiguity → evidence (phase: "decision"); Normal: request_user_input | `-y`: defer
|
|
180
|
+
4. Root cause confirmed → `session.json.root_cause` + §5. Mark G1 done.
|
|
326
181
|
|
|
327
|
-
|
|
328
|
-
```csv
|
|
329
|
-
"gen-syntax","Syntax Grep","Grep syntax-layer signatures '${signature}' across project. Return [{file,line,context,risk_level,layer:'syntax',confidence}].","generalization","","2","pending","","",""
|
|
330
|
-
"gen-semantic","Semantic Scan","Check related modules for anti-pattern: ${description}. Return [{file,line,context,risk_level,layer:'semantic',confidence}].","generalization","","2","pending","","",""
|
|
331
|
-
"gen-structural","Structural Match","Find structurally similar files to ${buggy_files}, check for anti-pattern. Return [{file,line,description,risk,layer:'structural',confidence}].","generalization","","2","pending","","",""
|
|
332
|
-
"gen-historical","Historical Grep","Run git log -S '${signature}' --oneline. Return [{sha,file,date,type:'introduced|fixed',context}].","generalization","","2","pending","","",""
|
|
333
|
-
```
|
|
182
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): DIAGNOSE — 根因确认"`
|
|
334
183
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
instruction: GENERALIZATION_INSTRUCTION + TERMINATION_CONTRACT,
|
|
338
|
-
max_concurrency:4, max_runtime_seconds:300,
|
|
339
|
-
output_csv_path:"wave-2-results.csv", output_schema: SHARED_OUTPUT_SCHEMA })
|
|
340
|
-
```
|
|
184
|
+
### A_ESCALATE_DIAGNOSIS
|
|
185
|
+
Increment `diagnosis_retries`. < 3: broaden via `maestro delegate --role analyze`, new hypotheses, return S_DIAGNOSE. >= 3: Normal → request_user_input | `-y` → auto INCONCLUSIVE → S_RECORD.
|
|
341
186
|
|
|
342
|
-
|
|
187
|
+
### A_FIX
|
|
188
|
+
1. Present root cause + proposed fix. Normal: request_user_input | `-y`: auto proceed
|
|
189
|
+
2. Implement fix, record evidence (phase: "decision")
|
|
343
190
|
|
|
344
|
-
**
|
|
191
|
+
📌 **Auto-commit**: `git add -A && git commit -m "odyssey-debug({slug}): FIX — {修复摘要}"`
|
|
345
192
|
|
|
346
|
-
|
|
193
|
+
### A_CONFIRM
|
|
194
|
+
1. Run covering tests (auto-detect framework)
|
|
195
|
+
2. CLI fix review via `maestro delegate --role review --mode analysis` (`run_in_background: true`):
|
|
196
|
+
- EXPECTED: JSON {verdict, findings [{severity, description, suggestion}], regression_risk}
|
|
197
|
+
3. Write `session.json.confirmation`: `{test_result, cli_review, overall: "confirmed|needs_rework"}`
|
|
198
|
+
4. Update §6. `needs_rework` → S_FIX. `confirmed` → mark G3 done.
|
|
347
199
|
|
|
348
|
-
**
|
|
200
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): CONFIRM — 修复验证"`
|
|
349
201
|
|
|
350
|
-
|
|
202
|
+
### A_GENERALIZE
|
|
203
|
+
按 base A_GENERALIZE 执行。Pattern 来源: root cause + fix。统计写入 `session.json.generalization_stats`。Mark G4 done.
|
|
351
204
|
|
|
352
|
-
|
|
353
|
-
Skip if no generalization hits.
|
|
205
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): GENERALIZE — 泛化扫描完成"`
|
|
354
206
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
- `bug` + directly fixable → **fix immediately** (not just log an issue) → back to S_FIX
|
|
358
|
-
- `bug` + requires cross-module/architectural decision → create issue (with fix suggestion + impact analysis)
|
|
359
|
-
- `risk` → evaluate if guard/validation can mitigate directly; if yes, fix it
|
|
360
|
-
- `safe` → mark skip
|
|
361
|
-
See Appendix `-y` behavior. Append evidence (phase: "discovery" + "decision")
|
|
362
|
-
3. **Cross-phase loop**:
|
|
363
|
-
- discovery finds new bug → S_DIAGNOSE (cross_phase_loops++)
|
|
364
|
-
- same-pattern bug + fix template → S_FIX
|
|
365
|
-
- S_DISCOVER → S_RECORD: triage complete AND remaining_actionable == 0
|
|
366
|
-
- S_DISCOVER → S_RECORD: loops >= max_loops → MUST log each unfixed item with specific reason (blanket "pre-existing" is forbidden)
|
|
367
|
-
4. Update §8. Mark G5 done.
|
|
207
|
+
### A_DISCOVER
|
|
208
|
+
按 base A_DISCOVER 执行。Mark G5 done.
|
|
368
209
|
|
|
369
|
-
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}):
|
|
210
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): DISCOVER — 发现分类完成"`
|
|
370
211
|
|
|
371
|
-
###
|
|
372
|
-
1. Finalize `understanding.md` §9
|
|
373
|
-
2.
|
|
374
|
-
3.
|
|
375
|
-
4. **
|
|
376
|
-
5. **Completion**: `current_state = "COMPLETED"`, emit summary:
|
|
212
|
+
### A_RECORD
|
|
213
|
+
1. Finalize `understanding.md` §9,按 Knowledge Persistence 表分类记录
|
|
214
|
+
2. Mark G6 done. Pending decisions: Normal → request_user_input | `-y` → skip (show deferred count)
|
|
215
|
+
3. 其余按 base A_RECORD 执行
|
|
216
|
+
4. **Completion summary**:
|
|
377
217
|
```
|
|
378
218
|
--- DEBUG ODYSSEY COMPLETE ---
|
|
379
219
|
Issue: {issue}
|
|
@@ -389,86 +229,75 @@ Goals: {done}/{total} confirmed ({skipped} skipped)
|
|
|
389
229
|
---
|
|
390
230
|
```
|
|
391
231
|
|
|
392
|
-
|
|
393
|
-
`$quality-review`, `$learn-second-opinion <understanding.md>`, `$learn-investigate "<question>"`
|
|
232
|
+
📌 **Auto-commit**: `git add understanding.md && git commit -m "odyssey-debug({slug}): RECORD — 会话总结与知识沉淀"`
|
|
394
233
|
|
|
395
|
-
|
|
396
|
-
</execution>
|
|
234
|
+
</actions>
|
|
397
235
|
|
|
398
236
|
<appendix>
|
|
399
237
|
|
|
400
238
|
### Goal Prompt Template
|
|
401
239
|
|
|
402
|
-
**时机守卫:仅在
|
|
240
|
+
**时机守卫:仅在 A_INTAKE 完成后显示一次。** 机制见 base。
|
|
403
241
|
|
|
404
242
|
```
|
|
405
243
|
📋 Debug Odyssey 会话已创建。可随时复制以下 /goal 设定终止条件:
|
|
406
244
|
|
|
407
|
-
/goal
|
|
245
|
+
/goal 完成以下目标:
|
|
246
|
+
{for each G in phase_goals where status != "skipped":}
|
|
247
|
+
- {G.id}: {G.goal} — 完成条件: {G.done_when}
|
|
248
|
+
{end for}
|
|
249
|
+
穷尽迭代:直到根因确认(或明确 INCONCLUSIVE)且修复验证通过
|
|
408
250
|
且泛化扫描穷尽且 phase_goals_all_done=true 才停。
|
|
409
|
-
假设失败时扩范围→换视角→升级工具,不轻易放弃。
|
|
410
251
|
泛化发现的同类 bug 全部修复或创建 issue,不允许遗留。
|
|
411
252
|
遇到 phase=decision 的 pending 必须 request_user_input,不得自行 resolve。
|
|
412
253
|
```
|
|
413
254
|
|
|
414
|
-
Odyssey 输出提示词后继续执行不阻塞。`/goal` 由用户任意时刻输入。
|
|
415
|
-
|
|
416
255
|
### `-y` Auto-Confirm Behavior
|
|
417
256
|
|
|
418
257
|
| Decision Point | Normal | `-y` mode |
|
|
419
258
|
|---------------|--------|-----------|
|
|
420
|
-
|
|
|
421
|
-
|
|
|
422
|
-
|
|
|
423
|
-
|
|
|
424
|
-
|
|
|
425
|
-
|
|
|
426
|
-
|
|
|
427
|
-
|
|
428
|
-
`deferred` items shown as "待决策" in summary; recoverable via `-c`.
|
|
429
|
-
|
|
430
|
-
### Phase Goal Lifecycle
|
|
431
|
-
|
|
432
|
-
`pending → done (confirmed=true)` normal | `pending → skipped (confirmed=true)` flags/manual | `pending → failed (confirmed=false)` INCONCLUSIVE
|
|
433
|
-
|
|
434
|
-
`phase_goals_all_done = true` only when ALL goals have `completion_confirmed == true`.
|
|
259
|
+
| A_DIAGNOSE ambiguity | request_user_input | `deferred`, best-effort continue |
|
|
260
|
+
| A_ESCALATE 3-strike | request_user_input 3-way | auto INCONCLUSIVE |
|
|
261
|
+
| A_FIX direction | request_user_input | auto proceed with suggested fix |
|
|
262
|
+
| A_DISCOVER bug triage | request_user_input | auto create issue |
|
|
263
|
+
| A_DISCOVER ambiguous | request_user_input batch | all `deferred` |
|
|
264
|
+
| A_RECORD decisions | request_user_input per-item | skip, show deferred count |
|
|
265
|
+
| A_RECORD goal audit | request_user_input 3-way | auto accept current state |
|
|
435
266
|
|
|
436
267
|
</appendix>
|
|
437
268
|
|
|
269
|
+
</state_machine>
|
|
270
|
+
|
|
438
271
|
<error_codes>
|
|
439
272
|
| Code | Severity | Condition | Recovery |
|
|
440
273
|
|------|----------|-----------|----------|
|
|
441
274
|
| E001 | error | No issue and no session to resume | Provide issue or use -c |
|
|
442
|
-
| E003 | error | Resume but no session found | Start new session |
|
|
443
|
-
| E004 | error | Delegate execution failed | Retry or proceed without CLI |
|
|
444
275
|
| W001 | warning | No relevant git history | Proceed with limited context |
|
|
445
276
|
| W002 | warning | All hypotheses inconclusive after 3 retries | INCONCLUSIVE |
|
|
446
|
-
| W003 | warning | Generalization scan 0 hits | Skip discovery |
|
|
447
|
-
| W004 | warning | Delegate parse failed | Use raw output |
|
|
448
277
|
| W005 | warning | Pending decisions unresolved | Filter evidence.ndjson phase=decision |
|
|
449
278
|
| W006 | warning | CLI exploration skipped (no tools) | Proceed without explore.json |
|
|
450
279
|
</error_codes>
|
|
451
280
|
|
|
452
281
|
<success_criteria>
|
|
453
|
-
- [ ] Session
|
|
454
|
-
- [ ]
|
|
455
|
-
- [ ]
|
|
456
|
-
- [ ]
|
|
457
|
-
- [ ] Hypotheses formed from archaeology + explore, tested and logged phase=diagnosis
|
|
458
|
-
- [ ] Root cause declared with evidence refs
|
|
282
|
+
- [ ] Session created with 4 output files, prior knowledge searched
|
|
283
|
+
- [ ] Git archaeology + CLI change review → evidence phase=archaeology
|
|
284
|
+
- [ ] CLI exploration → explore.json + evidence phase=explore
|
|
285
|
+
- [ ] Hypotheses tested, root cause declared with evidence refs
|
|
459
286
|
- [ ] understanding.md tracks all 9 sections progressively
|
|
460
|
-
- [ ] Fix implemented + confirmed
|
|
461
|
-
- [ ] Multi-layer
|
|
462
|
-
- [ ]
|
|
463
|
-
- [ ]
|
|
464
|
-
- [ ] Decision journal: all human-judgment items in evidence.ndjson phase=decision
|
|
465
|
-
- [ ] phase_goals derived from flags, skip_when applied, each phase marks its goal
|
|
466
|
-
- [ ] Goal audit in Stage 9 — unmet goals surfaced, phase_goals_all_done set correctly
|
|
467
|
-
- [ ] Goal Prompt displayed once after session creation
|
|
468
|
-
- [ ] `-y`: all decisions auto-resolve/defer, deferred count in summary
|
|
469
|
-
- [ ] State saved at each transition (resumable via -c)
|
|
470
|
-
- [ ] Quality Gate self-iteration when insufficient, logged in self_iteration_log
|
|
471
|
-
- [ ] Spec entries persisted for reusable learnings
|
|
287
|
+
- [ ] Fix implemented + confirmed (unless --skip-fix)
|
|
288
|
+
- [ ] Multi-layer generalization + scan (unless --skip-generalize)
|
|
289
|
+
- [ ] Discoveries classified and routed; every unfixed finding individually justified
|
|
290
|
+
- [ ] phase_goals derived, goal audit in A_RECORD, state resumable via -c
|
|
472
291
|
- [ ] Completion summary with all stats
|
|
473
|
-
- [ ] **Every unfixed finding has individual classification and reason** — blanket "pre-existing" labels are forbidden
|
|
474
292
|
</success_criteria>
|
|
293
|
+
|
|
294
|
+
<next_step_routing>
|
|
295
|
+
| Condition | Next step |
|
|
296
|
+
|-----------|-----------|
|
|
297
|
+
| Issues from discoveries | `/manage-issue list --source debug-odyssey` |
|
|
298
|
+
| Pattern worth documenting | `/learn-decompose <module>` |
|
|
299
|
+
| Fix needs formal review | `/quality-review <phase>` |
|
|
300
|
+
| Second opinion on root cause | `/learn-second-opinion <understanding.md>` |
|
|
301
|
+
| Related question | `/learn-investigate "<question>"` |
|
|
302
|
+
| Decisions still pending | Filter evidence.ndjson phase=decision status=pending |
|
|
303
|
+
</next_step_routing>
|