deepflow 0.1.97 → 0.1.99

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepflow",
3
- "version": "0.1.97",
3
+ "version": "0.1.99",
4
4
  "description": "Doing reveals what thinking can't predict — spec-driven iterative development for Claude Code",
5
5
  "keywords": [
6
6
  "claude",
@@ -10,7 +10,7 @@ description: Execute tasks from PLAN.md with agent spawning, ratchet health chec
10
10
  You are a coordinator. Spawn agents, run ratchet checks, update PLAN.md. Never implement code yourself.
11
11
 
12
12
  **NEVER:** Read source files, edit code, use TaskOutput, use EnterPlanMode, use ExitPlanMode
13
- **ONLY:** Read PLAN.md, read specs/doing-*.md, spawn background agents, run ratchet health checks, update PLAN.md, write `.deepflow/decisions.md`
13
+ **ONLY:** Read PLAN.md, read specs/doing-*.md, read `.deepflow/plans/doing-*.md` for task detail, spawn background agents, run ratchet health checks, update PLAN.md, write `.deepflow/decisions.md`
14
14
 
15
15
  ## Core Loop (Notification-Driven)
16
16
 
@@ -79,6 +79,12 @@ If `SNAPSHOT_COUNT` is `0` (zero test files found), MUST spawn bootstrap agent b
79
79
 
80
80
  Load PLAN.md (required), specs/doing-*.md, .deepflow/config.yaml. Missing → "No PLAN.md found. Run /df:plan first."
81
81
 
82
+ **Per-task detail files** (shell injection — load once after PLAN.md):
83
+ ```
84
+ PLAN_TASK_FILES=!`ls .deepflow/plans/doing-*.md 2>/dev/null | tr '\n' ' ' || echo 'NOT_FOUND'`
85
+ ```
86
+ When `PLAN_TASK_FILES` is not `NOT_FOUND`, each file `.deepflow/plans/doing-{task_id}.md` contains the full task detail block (Steps, ACs, Impact) for that task. Load a task's detail file on demand when building its agent prompt (§6), falling back to the PLAN.md inline block if the file is absent.
87
+
82
88
  ### 2.5. REGISTER NATIVE TASKS
83
89
 
84
90
  For each `[ ]` task: `TaskCreate(subject: "{task_id}: {description}", activeForm: "{gerund}", description: full block)`. Store task_id → native ID. Set deps via `TaskUpdate(addBlockedBy: [...])`. `--continue` → only remaining `[ ]` items.
@@ -89,17 +95,34 @@ Warn if unplanned `specs/*.md` (excluding doing-/done-) exist (non-blocking).
89
95
 
90
96
  **Wave computation (shell injection — do NOT compute manually):**
91
97
  ```
98
+ WAVE_JSON=!`node bin/wave-runner.js --json --plan PLAN.md 2>/dev/null || echo 'WAVE_ERROR'`
99
+ ```
100
+ `WAVE_JSON` is structured JSON (produced by T1's `--json` flag). Parse it to determine the current wave and scheduling decisions:
101
+ ```json
102
+ {
103
+ "waves": [
104
+ {"wave": 1, "tasks": [{"id": "T1", "description": "...", "files": ["..."], "isolation": "worktree"}, ...]},
105
+ {"wave": 2, "tasks": [...]}
106
+ ],
107
+ "blocked": [{"id": "T3", "blockedBy": ["T2"]}],
108
+ "done": ["T0"]
109
+ }
110
+ ```
111
+ Use `waves[0].tasks` as the ready set for the current wave. Use `isolation` field from each task entry (if present) to determine `isolation:` mode when spawning agents. Use `blocked` to identify tasks not yet ready.
112
+
113
+ **Fallback (text mode):** If `WAVE_JSON` is `WAVE_ERROR` or cannot be parsed as JSON, fall back to text mode:
114
+ ```
92
115
  WAVE_PLAN=!`node bin/wave-runner.js --plan PLAN.md 2>/dev/null || echo 'WAVE_ERROR'`
93
116
  ```
94
- Parse the output to determine the current wave. Output format:
117
+ Text output format:
95
118
  ```
96
119
  Wave 1: T1 — description, T4 — description
97
120
  Wave 2: T2 — description
98
121
  ...
99
122
  ```
100
- If output is `WAVE_ERROR` or `(no pending tasks)`, fall back to TaskList where status: "pending" AND blockedBy: empty for wave 1.
123
+ In text fallback: if output is `WAVE_ERROR` or `(no pending tasks)`, fall back to TaskList where status: "pending" AND blockedBy: empty for wave 1.
101
124
 
102
- Ready = tasks listed in Wave 1 of the wave-runner output (cross-referenced with TaskList status: "pending").
125
+ Ready = tasks listed in Wave 1 (cross-referenced with TaskList status: "pending").
103
126
 
104
127
  ### 5. SPAWN AGENTS
105
128
 
@@ -167,10 +190,11 @@ The script handles all health checks internally and outputs structured JSON:
167
190
  - **Exit 0 (PASS):** Commit stands. Proceed to §5.6 wave test agent.
168
191
  - **Exit 1 (FAIL):** Script already reverted. Set `TaskUpdate(status: "pending")`. Recompute remaining waves:
169
192
  ```
170
- WAVE_PLAN=!`node bin/wave-runner.js --plan PLAN.md --recalc --failed T{N} 2>/dev/null || echo 'WAVE_ERROR'`
193
+ WAVE_JSON=!`node bin/wave-runner.js --json --plan PLAN.md --recalc --failed T{N} 2>/dev/null || echo 'WAVE_ERROR'`
171
194
  ```
195
+ (Fall back to text mode if `--json` is unavailable: `node bin/wave-runner.js --plan PLAN.md --recalc --failed T{N}`)
172
196
  Report: `"✗ T{n}: reverted"`.
173
- - **Exit 2 (SALVAGEABLE):** Spawn `Agent(model="haiku")` to fix lint/typecheck issues. Re-run `node bin/ratchet.js`. If still non-zero → revert both commits, set status pending.
197
+ - **Exit 2 (SALVAGEABLE):** Spawn `Agent(model="sonnet")` to fix lint/typecheck issues. Re-run `node bin/ratchet.js`. If still non-zero → revert both commits, set status pending.
174
198
 
175
199
  **Edit scope validation:** `git diff HEAD~1 --name-only` vs allowed globs. Violation → revert, report.
176
200
  **Impact completeness:** diff vs Impact callers/duplicates. Gap → advisory warning (no revert).
@@ -329,6 +353,12 @@ REPEAT:
329
353
 
330
354
  **Common preamble (all):** `Working directory: {worktree_absolute_path}. All file ops use this path. Commit format: {type}({spec}): {desc}`
331
355
 
356
+ **Task detail loading (before building agent prompt):** Check for `.deepflow/plans/doing-{task_id}.md` (shell injection):
357
+ ```
358
+ TASK_DETAIL=!`cat .deepflow/plans/doing-{task_id}.md 2>/dev/null || echo 'NOT_FOUND'`
359
+ ```
360
+ If `TASK_DETAIL` is not `NOT_FOUND`, use it as the full Middle section (Steps, ACs, Impact) in the agent prompt, overriding the inline PLAN.md block. If `NOT_FOUND`, fall back to the inline PLAN.md task block.
361
+
332
362
  **Standard Task** (`Agent(model="{Model}", ...)`):
333
363
  ```
334
364
  --- START ---
@@ -343,6 +373,7 @@ spike_results:
343
373
  }
344
374
  Success criteria: {ACs from spec relevant to this task}
345
375
  --- MIDDLE (omit for low effort; omit deps for medium) ---
376
+ {TASK_DETAIL if available, else inline block:}
346
377
  Impact: Callers: {file} ({why}) | Duplicates: [active→consolidate] [dead→DELETE] | Data flow: {consumers}
347
378
  Prior tasks: {dep_id}: {summary}
348
379
  Steps: 1. chub search/get for APIs 2. LSP findReferences, add unlisted callers 3. Read all Impact files 4. Implement 5. Commit
@@ -501,7 +532,7 @@ Skills: `atomic-commits`, `browse-fetch`. Agents: Implementation (`general-purpo
501
532
 
502
533
  | Fields | Agent | Preamble |
503
534
  |--------|-------|----------|
504
- | haiku/low | `Agent(model="haiku")` | `Maximally efficient: skip explanations, minimize tool calls, straight to implementation.` |
535
+ | sonnet/low | `Agent(model="sonnet")` | `Maximally efficient: skip explanations, minimize tool calls, straight to implementation.` |
505
536
  | sonnet/medium | `Agent(model="sonnet")` | `Direct and efficient. Explain only non-obvious logic.` |
506
537
  | opus/high | `Agent(model="opus")` | _(none)_ |
507
538
 
@@ -127,51 +127,69 @@ Count plannable specs (no `doing-`/`done-` prefix, passed `validateSpec`).
127
127
  Re-run /df:plan to process remaining specs.
128
128
  ```
129
129
 
130
- #### 4.7.2. Spawn Sub-Agents
130
+ #### 4.7.2. Spawn Sub-Agents (Thin Dispatcher)
131
131
 
132
132
  For each plannable spec (up to 5), spawn a **parallel non-background** `Task(subagent_type="default", model="sonnet")` call. All calls are independent — spawn them simultaneously.
133
133
 
134
- Each sub-agent prompt MUST include:
135
-
136
- 1. **Layer-gating rules** (from §1.5): The spec's computed layer and which task types are allowed
137
- 2. **Experiment check results** (from §2): Past experiments for this spec's topic — `--passed.md`, `--failed.md`, `--active.md` status and extracted next-hypothesis
138
- 3. **Project context** (from §3): Code style, patterns, integration points detected for this project
139
- 4. **Impact analysis instructions** (from §4, L3 specs only): LSP-first blast radius search for each file in the task's `Files:` list
140
- 5. **Targeted exploration instructions** (from §4.5): Follow `templates/explore-agent.md` spawn rules
141
- 6. **The spec content**: Full text of that spec file
142
- 7. **Format enforcement clause**:
143
- ```
144
- OUTPUT FORMAT — MANDATORY (no deviations):
145
- Return ONLY a markdown task list. Use local T-numbering starting at T1.
146
- Each task MUST follow this exact format:
147
-
148
- ### {spec-name}
149
-
150
- - [ ] **T{N}**: {Task description}
151
- - Files: {comma-separated file paths}
152
- - Blocked by: none | T{N}[, T{M}...]
153
-
154
- Optional fields (add when applicable):
155
- - Model: haiku | sonnet | opus
156
- - Effort: low | medium | high
157
- - Impact: {blast radius details, L3 only}
158
- - Optimize: {metric block, for metric ACs only}
159
-
160
- Rules:
161
- - "Blocked by: none" is required (not "N/A", not empty)
162
- - T-numbers are local to this spec (T1, T2, T3...)
163
- - One task = one atomic commit
164
- - Spike tasks use: **T{N}** [SPIKE]: {description}
165
- - L0-L1 specs: ONLY spike tasks allowed
166
- - L2+ specs: spikes + implementation tasks allowed
167
- - L3 specs: include Impact: blocks from impact analysis
168
- ```
169
-
170
- #### 4.7.3. Collect Mini-Plans
134
+ **The master orchestrator is a thin dispatcher.** Each sub-agent receives ONLY the spec file path — no pre-computed context, no spec content, no impact analysis, no experiment results.
135
+
136
+ Each sub-agent prompt:
137
+
138
+ ```
139
+ You are a spec planner. Your job is to independently analyze a spec and produce a mini-plan.
140
+
141
+ ## Spec file
142
+ {spec_file_path}
143
+
144
+ ## Instructions
145
+
146
+ 1. **Read the spec** use Read tool on the spec file path above
147
+ 2. **Compute spec layer** — determine L0–L3 based on sections present (see layer rules below)
148
+ 3. **Check experiments** — glob `.deepflow/experiments/{topic}--*` for past spikes
149
+ 4. **Explore the codebase** — detect code style, patterns, integration points relevant to this spec
150
+ 5. **Impact analysis** (L3 only) — LSP-first blast radius for files in scope
151
+ 6. **Targeted exploration** — follow `templates/explore-agent.md` spawn rules for post-LSP gaps
152
+ 7. **Generate tasks** — produce a mini-plan following the output format below
153
+
154
+ ## Layer-gating rules
155
+ | Layer | Sections present | Allowed task types |
156
+ |-------|------------------|--------------------|
157
+ | L0 | Objective | Spikes only |
158
+ | L1 | + Requirements | Spikes only (better targeted) |
159
+ | L2 | + Acceptance Criteria | Spikes + Implementation |
160
+ | L3 | + Constraints, Out of Scope, Technical Notes | Spikes + Implementation + Impact analysis + Optimize |
161
+
162
+ ## OUTPUT FORMAT MANDATORY (no deviations)
163
+ Return ONLY a markdown task list. Use local T-numbering starting at T1.
164
+ Each task MUST follow this exact format:
165
+
166
+ ### {spec-name}
167
+
168
+ - [ ] **T{N}**: {Task description}
169
+ - Files: {comma-separated file paths}
170
+ - Blocked by: none | T{N}[, T{M}...]
171
+
172
+ Optional fields (add when applicable):
173
+ - Model: haiku | sonnet | opus
174
+ - Effort: low | medium | high
175
+ - Impact: {blast radius details, L3 only}
176
+ - Optimize: {metric block, for metric ACs only}
177
+
178
+ Rules:
179
+ - "Blocked by: none" is required (not "N/A", not empty)
180
+ - T-numbers are local to this spec (T1, T2, T3...)
181
+ - One task = one atomic commit
182
+ - Spike tasks use: **T{N}** [SPIKE]: {description}
183
+ - L0-L1 specs: ONLY spike tasks allowed
184
+ - L2+ specs: spikes + implementation tasks allowed
185
+ - L3 specs: include Impact: blocks from impact analysis
186
+ ```
187
+
188
+ #### 4.7.3. Collect & Persist Mini-Plans
171
189
 
172
190
  Each sub-agent returns a mini-plan string (markdown). Collect all return values.
173
191
 
174
- **Graceful degradation (AC-11):** For each sub-agent result, check for failure conditions:
192
+ **Graceful degradation (AC-10):** For each sub-agent result, check for failure conditions:
175
193
  - Sub-agent threw an error or returned a non-string value → log warning, skip spec
176
194
  - Output is empty (whitespace only) → log warning, skip spec
177
195
  - Output contains no task items (no `- [ ] **T` pattern) → log warning (unparseable), skip spec
@@ -183,11 +201,12 @@ Warning format:
183
201
 
184
202
  Continue processing remaining specs regardless of individual failures. Only successfully parsed mini-plans are stored.
185
203
 
186
- - Store results as an array of `{ specName, miniPlan }` objects (successfully parsed only) for consolidation by §5.
204
+ **Persist to disk (REQ-3):** For each successful mini-plan, write to `.deepflow/plans/doing-{specName}.md`. Create `.deepflow/plans/` directory if it doesn't exist.
205
+
187
206
  - If ALL sub-agents fail: report error, abort plan generation.
188
- - If at least 1 succeeds: continue to §5 with successful mini-plans only.
207
+ - If at least 1 succeeds: continue to §5 with successful mini-plans on disk.
189
208
 
190
- **Flow after fan-out:** The collected mini-plans are passed to §5 for consolidation (global renumbering, cross-spec conflict detection, prioritization). §5 handles both the single-spec monolithic path and the multi-spec consolidation path.
209
+ **Flow after fan-out:** The consolidator (§5B) reads mini-plans from `.deepflow/plans/` for consolidation (global renumbering, cross-spec conflict detection, prioritization). §5 handles both the single-spec monolithic path and the multi-spec consolidation path.
191
210
 
192
211
  ### 5. COMPARE & PRIORITIZE
193
212
 
@@ -213,54 +232,55 @@ Then apply §5.5 routing matrix. Continue to §6.
213
232
 
214
233
  #### 5B. MULTI-SPEC CONSOLIDATOR (FAN-OUT PATH)
215
234
 
216
- **When:** >1 plannable spec (§4.7 produced mini-plans).
235
+ **When:** >1 plannable spec (§4.7 produced mini-plans in `.deepflow/plans/`).
217
236
 
218
237
  **This is the ONLY Opus invocation in the fan-out path** (REQ-12). Sub-agents in §4.7 use Sonnet.
219
238
 
220
- Spawn a single `Task(subagent_type="reasoner", model="opus")` with the following prompt:
239
+ **Input:** Mini-plan files in `.deepflow/plans/doing-*.md`. The consolidator must NOT modify these files (REQ-5).
240
+
241
+ **Architecture:** Mechanical work (T-id renumbering, file-conflict detection) is delegated to `bin/plan-consolidator.js`. Opus handles ONLY cross-spec prioritization and summary narrative.
242
+
243
+ ##### Step 1: Run plan-consolidator (mechanical — no LLM)
244
+
245
+ Shell-inject the consolidator output:
246
+
247
+ `` !`node bin/plan-consolidator.js --plans-dir .deepflow/plans/ 2>/dev/null` ``
248
+
249
+ This produces the `## Tasks` section with:
250
+ - Globally sequential T-ids (no gaps, no duplicates) — AC-4
251
+ - Remapped `Blocked by` references (local → global)
252
+ - `[file-conflict: {filename}]` annotations on cross-spec file overlaps
253
+ - Mini-plan files left byte-identical (read-only) — AC-5
254
+
255
+ If the consolidator output is empty or contains `(no mini-plan files found` → abort, report error.
256
+
257
+ ##### Step 2: Opus prioritization & summary (single invocation)
258
+
259
+ Spawn a single `Task(subagent_type="reasoner", model="opus")` with the consolidated tasks from Step 1:
221
260
 
222
261
  ```
223
- You are the plan consolidator. You receive mini-plans from multiple spec-planning agents.
224
- Your job is to merge them into a single globally-numbered PLAN.md.
262
+ You are the plan prioritizer. The mechanical consolidation (global T-numbering, file-conflict detection) is already done. Do NOT renumber tasks or modify T-ids.
225
263
 
226
- ## Input mini-plans
264
+ ## Consolidated tasks (from plan-consolidator)
227
265
 
228
- {for each entry in miniPlans array:}
229
- ### {specName}
230
- {miniPlan content}
231
- {end for}
266
+ {paste consolidator stdout here}
232
267
 
233
- ## Instructions
268
+ ## Spec files
234
269
 
235
- ### Step 1: Spec Priority Ordering
236
- Sort specs for global numbering. Use this priority:
237
- 1. Specs with no cross-spec file overlaps first (independent work)
238
- 2. Specs with overlaps ordered by dependency direction (depended-on first)
239
- 3. Alphabetical as tiebreaker
240
-
241
- ### Step 2: Global T-Number Assignment
242
- Assign sequential global T-numbers (T1, T2, ..., TN) with NO gaps and NO duplicates.
243
- - Process specs in priority order from Step 1
244
- - Within each spec, preserve the local task ordering
245
- - Translate all intra-spec `Blocked by: T{local}` references to global T-IDs
246
-
247
- ### Step 3: Cross-Spec File Conflict Detection
248
- Build a map: `file → [global task IDs]`.
249
- For each file appearing in >1 task across different specs:
250
- - Add `Blocked by` from the later task → the earlier task
251
- - Append `[file-conflict: {filename}]` annotation to the Blocked by line
252
- - Skip if a dependency already exists (direct or transitive)
253
- - Chain only: T5→T3, not T5→T1+T3 (block on nearest earlier task for that file)
254
-
255
- ### Step 4: Requirement Mapping
256
- For each spec, map requirements to DONE/PARTIAL/MISSING/CONFLICT. Flag spec gaps.
270
+ {for each plannable spec: spec filename and its Requirements + Acceptance Criteria sections}
257
271
 
258
- ### Step 5: Metric AC Detection
259
- Scan ACs for pattern `{metric} {operator} {number}[unit]`.
260
- - Match → flag as metric AC (for §6.5 Optimize task generation)
261
- - Ambiguous ("fast", "small") → flag as spec gap
272
+ ## Your job THREE things only
262
273
 
263
- ### Step 6: Model + Effort Classification
274
+ ### 1. Cross-Spec Prioritization
275
+ Review the task ordering across specs. If a different spec ordering would reduce blocked tasks or improve parallelism, suggest reordering. Otherwise confirm the current ordering is optimal.
276
+
277
+ If reordering is needed, output the recommended spec order. The orchestrator will reorder the mini-plan files in `.deepflow/plans/` (alphabetical prefix rename) and re-run the consolidator.
278
+
279
+ ### 2. Requirement Mapping & Spec Gaps
280
+ For each spec, map requirements to DONE/PARTIAL/MISSING/CONFLICT. Flag spec gaps.
281
+ Scan ACs for metric patterns `{metric} {operator} {number}[unit]` — flag matches for §6.5 Optimize tasks, flag ambiguous thresholds ("fast", "small") as spec gaps.
282
+
283
+ ### 3. Model + Effort Classification
264
284
  Apply routing matrix to each task:
265
285
 
266
286
  | Task type | Model | Effort |
@@ -282,8 +302,7 @@ Apply routing matrix to each task:
282
302
 
283
303
  Defaults: sonnet / medium.
284
304
 
285
- ### Step 7: Output
286
- Return the consolidated plan in this exact format:
305
+ ## OUTPUT FORMAT — MANDATORY
287
306
 
288
307
  ## Summary
289
308
 
@@ -300,41 +319,20 @@ Return the consolidated plan in this exact format:
300
319
 
301
320
  ## Tasks
302
321
 
303
- ### doing-{spec-name-1}
304
-
305
- - [ ] **T1**: {Task description}
306
- - Files: {files}
307
- - Model: {model}
308
- - Effort: {effort}
309
- - Blocked by: none
310
-
311
- - [ ] **T2**: {Task description}
312
- - Files: {files}
313
- - Model: {model}
314
- - Effort: {effort}
315
- - Blocked by: T1
316
-
317
- ### doing-{spec-name-2}
318
-
319
- - [ ] **T3**: {Task description}
320
- - Files: {files}
321
- - Model: {model}
322
- - Effort: {effort}
323
- - Blocked by: none
322
+ {Insert the consolidated tasks from plan-consolidator verbatim, adding ONLY `Model:` and `Effort:` lines to each task. Do NOT alter T-ids, descriptions, Files, Blocked by, or conflict annotations.}
324
323
 
325
324
  Rules:
326
- - T-numbers MUST be globally sequential (T1...TN), no gaps, no duplicates
327
- - Group tasks under `### doing-{spec-name}` headers
328
- - Preserve all optional fields from mini-plans (Impact:, Optimize:, etc.)
329
- - [file-conflict: {filename}] annotations are REQUIRED for cross-spec file overlaps
330
- - "Blocked by: none" is required (not "N/A", not empty)
325
+ - Do NOT renumber T-ids they are already globally sequential from plan-consolidator
326
+ - Do NOT modify Blocked by lines or conflict annotations — they are mechanical outputs
327
+ - ONLY add Model: and Effort: lines per the routing matrix
328
+ - Preserve all existing fields (Impact:, Optimize:, tags, etc.)
331
329
  - Spike tasks keep their [SPIKE] or [OPTIMIZE] markers
332
330
  ```
333
331
 
334
332
  **Post-consolidation:**
335
- - The orchestrator receives the consolidator's output as structured PLAN.md content
336
- - Mini-plans are ephemeral they exist only as sub-agent return values, never written to disk (REQ-7)
337
- - §8 cleanup and §9 output/rename run after this step in the orchestrator (REQ-13)
333
+ - The orchestrator receives the Opus output as structured PLAN.md content
334
+ - Mini-plans persist in `.deepflow/plans/doing-{name}.md` for reuse by `/df:execute` (REQ-3, REQ-7)
335
+ - §8 cleanup and §9 output/rename run after this step in the orchestrator
338
336
 
339
337
  ### 5.5. CLASSIFY MODEL + EFFORT PER TASK
340
338
 
@@ -344,12 +342,12 @@ Rules:
344
342
 
345
343
  | Task type | Model | Effort |
346
344
  |-----------|-------|--------|
347
- | Bootstrap (scaffold, config, rename) | `haiku` | `low` |
345
+ | Bootstrap (scaffold, config, rename) | `sonnet` | `low` |
348
346
  | browse-fetch (doc retrieval) | `haiku` | `low` |
349
- | Single-file simple addition | `haiku` | `high` |
347
+ | Single-file simple addition | `sonnet` | `medium` |
350
348
  | Multi-file with clear specs | `sonnet` | `medium` |
351
- | Bug fix (clear repro) | `sonnet` | `medium` |
352
- | Bug fix (unclear cause) | `sonnet` | `high` |
349
+ | Bug fix (clear repro) | `opus` | `medium` |
350
+ | Bug fix (unclear cause) | `opus` | `high` |
353
351
  | Spike / validation | `sonnet` | `high` |
354
352
  | Optimize (metric AC) | `opus` | `high` |
355
353
  | Feature work (well-specced) | `sonnet` | `medium` |
@@ -196,4 +196,4 @@ Objective: ... | Approach: ... | Why it worked: ... | Files: ...
196
196
  5. **Extract decisions:** Read done spec, extract `[APPROACH]`/`[ASSUMPTION]`/`[PROVISIONAL]` decisions, append to `.deepflow/decisions.md` as `### {date} — {spec}\n- [TAG] decision — rationale`. Delete done spec after successful write; preserve on failure.
197
197
  6. **Clean PLAN.md:** Find the `### {spec-name}` section (match on name stem, strip `doing-`/`done-` prefix). Delete from header through the line before the next `### ` header (or EOF). Recalculate Summary table (recount `### ` headers for spec count, `- [ ]`/`- [x]` for task counts). If no spec sections remain, delete PLAN.md entirely. Skip silently if PLAN.md missing or section already gone.
198
198
 
199
- Output: `✓ Merged → main | ✓ Cleaned worktree | ✓ Spec complete | ✓ Cleaned PLAN.md | Workflow complete! Ready: /df:spec <name>`
199
+ Output: `✓ Merged → main | ✓ Cleaned worktree | ✓ Spec done | ✓ Decisions extracted | ✓ Cleaned PLAN.md | Workflow complete! Ready: /df:spec <name>`