deepflow 0.1.49 → 0.1.51

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/README.md CHANGED
@@ -27,6 +27,7 @@
27
27
  - **Spike-first planning** — Validate risky hypotheses before full implementation
28
28
  - **Worktree isolation** — Main branch stays clean during execution
29
29
  - **Parallel execution** with context-aware checkpointing
30
+ - **Automatic decision capture** on spec completion, periodic consolidation
30
31
  - **Atomic commits** for clean rollback
31
32
 
32
33
  ## Quick Start
@@ -41,29 +42,38 @@ npx deepflow --uninstall
41
42
  # In your project
42
43
  claude
43
44
 
44
- # 1. Discuss what you want to build
45
- # 2. Generate spec when ready
45
+ # 1. Explore the problem space
46
+ /df:discover image-upload
47
+
48
+ # 2. Debate tradeoffs (optional)
49
+ /df:debate upload-strategy
50
+
51
+ # 3. Generate spec from conversation
46
52
  /df:spec image-upload
47
53
 
48
- # 3. Compare specs to code, generate tasks
54
+ # 4. Compare specs to code, generate tasks
49
55
  /df:plan
50
56
 
51
- # 4. Execute tasks with parallel agents
57
+ # 5. Execute tasks with parallel agents
52
58
  /df:execute
53
59
 
54
- # 5. Verify specs are satisfied
60
+ # 6. Verify specs are satisfied
55
61
  /df:verify
56
62
  ```
57
63
 
58
64
  ## The Flow
59
65
 
60
66
  ```
61
- CONVERSATION
62
- Describe what you want
63
- │ LLM asks gap questions
67
+ /df:discover <name>
68
+ Socratic questioning (motivation, scope, constraints...)
69
+
70
+ /df:debate <topic> ← optional
71
+ │ 4 perspectives: User Advocate, Tech Skeptic,
72
+ │ Systems Thinker, LLM Efficiency
73
+ │ Creates specs/.debate-{topic}.md
64
74
 
65
75
  /df:spec <name>
66
- │ Creates specs/{name}.md
76
+ │ Creates specs/{name}.md from conversation
67
77
 
68
78
  /df:plan
69
79
  │ Checks past experiments (learn from failures)
@@ -80,7 +90,8 @@ CONVERSATION
80
90
  /df:verify
81
91
  │ Checks requirements met
82
92
  │ Merges worktree to main, cleans up
83
- Renames: doing-feature.mddone-feature.md
93
+ Extracts decisions → .deepflow/decisions.md
94
+ │ Deletes done-* spec after extraction
84
95
  ```
85
96
 
86
97
  ## Spec Lifecycle
@@ -89,7 +100,7 @@ CONVERSATION
89
100
  specs/
90
101
  feature.md → new, needs /df:plan
91
102
  doing-feature.md → in progress, has tasks in PLAN.md
92
- done-feature.md → completed, history embedded
103
+ done-feature.md → transient (decisions extracted, then deleted)
93
104
  ```
94
105
 
95
106
  ## Works With Any Project
@@ -130,10 +141,15 @@ Statusline shows context usage. At ≥50%:
130
141
 
131
142
  | Command | Purpose |
132
143
  |---------|---------|
144
+ | `/df:discover <name>` | Explore problem space with Socratic questioning |
145
+ | `/df:debate <topic>` | Multi-perspective analysis (4 agents) |
133
146
  | `/df:spec <name>` | Generate spec from conversation |
134
147
  | `/df:plan` | Compare specs to code, create tasks |
135
148
  | `/df:execute` | Run tasks with parallel agents |
136
- | `/df:verify` | Check specs satisfied |
149
+ | `/df:verify` | Check specs satisfied, merge to main |
150
+ | `/df:note` | Capture decisions ad-hoc from conversation |
151
+ | `/df:consolidate` | Deduplicate and clean up decisions.md |
152
+ | `/df:resume` | Session continuity briefing |
137
153
  | `/df:update` | Update deepflow to latest |
138
154
 
139
155
  ## File Structure
@@ -142,15 +158,16 @@ Statusline shows context usage. At ≥50%:
142
158
  your-project/
143
159
  ├── specs/
144
160
  │ ├── auth.md # new spec
145
- ├── doing-upload.md # in progress
146
- │ └── done-payments.md # completed
161
+ └── doing-upload.md # in progress
147
162
  ├── PLAN.md # active tasks
148
163
  └── .deepflow/
149
- ├── config.yaml # project settings
150
- ├── context.json # context % tracking
151
- ├── experiments/ # spike results (pass/fail)
152
- └── worktrees/ # isolated execution
153
- └── upload/ # one worktree per spec
164
+ ├── config.yaml # project settings
165
+ ├── decisions.md # auto-extracted + ad-hoc decisions
166
+ ├── last-consolidated.json # consolidation timestamp
167
+ ├── context.json # context % tracking
168
+ ├── experiments/ # spike results (pass/fail)
169
+ └── worktrees/ # isolated execution
170
+ └── upload/ # one worktree per spec
154
171
  ```
155
172
 
156
173
  ## Configuration
package/bin/install.js CHANGED
@@ -146,7 +146,7 @@ async function main() {
146
146
  console.log(`${c.green}Installation complete!${c.reset}`);
147
147
  console.log('');
148
148
  console.log(`Installed to ${c.cyan}${CLAUDE_DIR}${c.reset}:`);
149
- console.log(' commands/df/ — /df:discover, /df:debate, /df:spec, /df:plan, /df:execute, /df:verify');
149
+ console.log(' commands/df/ — /df:discover, /df:debate, /df:spec, /df:plan, /df:execute, /df:verify, /df:note, /df:resume, /df:update');
150
150
  console.log(' skills/ — gap-discovery, atomic-commits, code-completeness');
151
151
  console.log(' agents/ — reasoner');
152
152
  if (level === 'global') {
@@ -196,6 +196,7 @@ async function configureHooks(claudeDir) {
196
196
  const settingsPath = path.join(claudeDir, 'settings.json');
197
197
  const statuslineCmd = `node "${path.join(claudeDir, 'hooks', 'df-statusline.js')}"`;
198
198
  const updateCheckCmd = `node "${path.join(claudeDir, 'hooks', 'df-check-update.js')}"`;
199
+ const consolidationCheckCmd = `node "${path.join(claudeDir, 'hooks', 'df-consolidation-check.js')}"`;
199
200
 
200
201
  let settings = {};
201
202
 
@@ -234,7 +235,7 @@ async function configureHooks(claudeDir) {
234
235
  // Remove any existing deepflow update check hooks
235
236
  settings.hooks.SessionStart = settings.hooks.SessionStart.filter(hook => {
236
237
  const cmd = hook.hooks?.[0]?.command || '';
237
- return !cmd.includes('df-check-update');
238
+ return !cmd.includes('df-check-update') && !cmd.includes('df-consolidation-check');
238
239
  });
239
240
 
240
241
  // Add update check hook
@@ -244,6 +245,14 @@ async function configureHooks(claudeDir) {
244
245
  command: updateCheckCmd
245
246
  }]
246
247
  });
248
+
249
+ // Add consolidation check hook
250
+ settings.hooks.SessionStart.push({
251
+ hooks: [{
252
+ type: 'command',
253
+ command: consolidationCheckCmd
254
+ }]
255
+ });
247
256
  log('SessionStart hook configured');
248
257
 
249
258
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
@@ -330,7 +339,7 @@ async function uninstall() {
330
339
  ];
331
340
 
332
341
  if (level === 'global') {
333
- toRemove.push('hooks/df-statusline.js', 'hooks/df-check-update.js');
342
+ toRemove.push('hooks/df-statusline.js', 'hooks/df-check-update.js', 'hooks/df-consolidation-check.js');
334
343
  }
335
344
 
336
345
  for (const item of toRemove) {
@@ -359,7 +368,7 @@ async function uninstall() {
359
368
  if (settings.hooks?.SessionStart) {
360
369
  settings.hooks.SessionStart = settings.hooks.SessionStart.filter(hook => {
361
370
  const cmd = hook.hooks?.[0]?.command || '';
362
- return !cmd.includes('df-check-update');
371
+ return !cmd.includes('df-check-update') && !cmd.includes('df-consolidation-check');
363
372
  });
364
373
  if (settings.hooks.SessionStart.length === 0) {
365
374
  delete settings.hooks.SessionStart;
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * deepflow consolidation checker
4
+ * Checks if decisions.md needs consolidation, outputs suggestion if overdue
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ const DAYS_THRESHOLD = 7;
11
+ const LINES_THRESHOLD = 20;
12
+ const DEEPFLOW_DIR = path.join(process.cwd(), '.deepflow');
13
+ const DECISIONS_FILE = path.join(DEEPFLOW_DIR, 'decisions.md');
14
+ const LAST_CONSOLIDATED_FILE = path.join(DEEPFLOW_DIR, 'last-consolidated.json');
15
+
16
+ function checkConsolidation() {
17
+ try {
18
+ // Check if decisions.md exists
19
+ if (!fs.existsSync(DECISIONS_FILE)) {
20
+ process.exit(0);
21
+ }
22
+
23
+ // Check if decisions.md has more than LINES_THRESHOLD lines
24
+ const decisionsContent = fs.readFileSync(DECISIONS_FILE, 'utf8');
25
+ const lineCount = decisionsContent.split('\n').length;
26
+ if (lineCount <= LINES_THRESHOLD) {
27
+ process.exit(0);
28
+ }
29
+
30
+ // Get last consolidated timestamp
31
+ let lastConsolidated;
32
+ if (fs.existsSync(LAST_CONSOLIDATED_FILE)) {
33
+ try {
34
+ const data = JSON.parse(fs.readFileSync(LAST_CONSOLIDATED_FILE, 'utf8'));
35
+ if (data.last_consolidated) {
36
+ lastConsolidated = new Date(data.last_consolidated);
37
+ }
38
+ } catch (e) {
39
+ // Fall through to use mtime
40
+ }
41
+ }
42
+
43
+ // Fallback: use mtime of decisions.md
44
+ if (!lastConsolidated || isNaN(lastConsolidated.getTime())) {
45
+ const stat = fs.statSync(DECISIONS_FILE);
46
+ lastConsolidated = stat.mtime;
47
+ }
48
+
49
+ // Calculate days since last consolidation
50
+ const now = new Date();
51
+ const diffMs = now - lastConsolidated;
52
+ const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
53
+
54
+ if (diffDays >= DAYS_THRESHOLD) {
55
+ process.stderr.write(
56
+ `\u{1F4A1} decisions.md hasn't been consolidated in ${diffDays} days. Run /df:consolidate to clean up.\n`
57
+ );
58
+ }
59
+
60
+ } catch (e) {
61
+ // Fail silently
62
+ }
63
+
64
+ process.exit(0);
65
+ }
66
+
67
+ checkConsolidation();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepflow",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "description": "Stay in flow state - lightweight spec-driven task orchestration for Claude Code",
5
5
  "keywords": [
6
6
  "claude",
@@ -0,0 +1,58 @@
1
+ # /df:consolidate — Consolidate Decisions
2
+
3
+ ## Purpose
4
+ Remove duplicates, superseded entries, and promote stale provisionals. Keep decisions.md dense and useful.
5
+
6
+ **NEVER:** use EnterPlanMode, use ExitPlanMode
7
+
8
+ ## Usage
9
+ ```
10
+ /df:consolidate # Consolidate decisions.md
11
+ ```
12
+
13
+ ## Behavior
14
+
15
+ ### 1. LOAD
16
+ Read `.deepflow/decisions.md`. If missing or empty, report and exit.
17
+
18
+ ### 2. ANALYZE
19
+ Model-driven analysis (not regex):
20
+ - Identify duplicate decisions (same meaning, different wording)
21
+ - Identify superseded decisions (later entry contradicts earlier)
22
+ - Identify stale `[PROVISIONAL]` entries (>30 days old, no resolution)
23
+
24
+ ### 3. CONSOLIDATE
25
+ - Remove duplicates (keep the more precise wording)
26
+ - Silently remove superseded entries (the later decision wins)
27
+ - Promote stale `[PROVISIONAL]` to `[DEBT]` (needs revisiting)
28
+ - Preserve all `[APPROACH]` entries unless superseded
29
+ - Preserve all `[ASSUMPTION]` entries unless invalidated
30
+ - Target: 200-500 lines (if currently longer)
31
+ - When in doubt, keep both entries (conservative)
32
+
33
+ ### 4. WRITE
34
+ - Rewrite `.deepflow/decisions.md` with consolidated content
35
+ - Write timestamp to `.deepflow/last-consolidated.json`:
36
+ ```json
37
+ { "last_consolidated": "{ISO-8601 timestamp}" }
38
+ ```
39
+
40
+ ### 5. REPORT
41
+ ```
42
+ ✓ Consolidated: {before} → {after} lines, {n} removed, {n} promoted to [DEBT]
43
+ ```
44
+
45
+ ## Tags
46
+ | Tag | Meaning | Source |
47
+ |-----|---------|--------|
48
+ | `[APPROACH]` | Firm decision | Auto-extraction, /df:note |
49
+ | `[PROVISIONAL]` | Revisit later | Auto-extraction, /df:note |
50
+ | `[ASSUMPTION]` | Unverified | Auto-extraction, /df:note |
51
+ | `[DEBT]` | Needs revisiting | Consolidation only |
52
+
53
+ ## Rules
54
+ - Conservative: when in doubt, keep both entries
55
+ - Never add new decisions — only remove, merge, or re-tag
56
+ - [DEBT] is never manually assigned — only produced by consolidation
57
+ - Preserve chronological ordering within sections
58
+ - decisions.md stays a single flat file, human-readable
@@ -35,136 +35,83 @@ Generate a multi-perspective analysis of a problem before formalizing into a spe
35
35
 
36
36
  ### 1. SUMMARIZE
37
37
 
38
- Summarize the conversation context (from prior discover/conversation) in ~200 words. This summary will be passed to each perspective agent.
39
-
40
- The summary should capture:
41
- - The core problem being solved
42
- - Key requirements mentioned
43
- - Constraints and boundaries
44
- - User's stated preferences and priorities
38
+ Summarize conversation context in ~200 words: core problem, key requirements, constraints, user priorities. Passed to each perspective agent.
45
39
 
46
40
  ### 2. GATHER CODEBASE CONTEXT
47
41
 
48
- Before spawning perspectives, ground the debate in what actually exists. Use Glob, Grep, and Read to understand the current implementation relevant to the debate topic.
49
-
50
- **Steps:**
51
- 1. **Glob** for files related to the topic (e.g., `**/*{topic}*`, `src/**/*.{ts,js,py}`)
52
- 2. **Grep** for key terms, patterns, or interfaces mentioned in the conversation
53
- 3. **Read** the most relevant files (up to 5-6 files — focus on core logic, not boilerplate)
54
-
55
- **Produce a ~300 word codebase summary covering:**
56
- - What already exists (implemented features, patterns, architecture)
57
- - Key interfaces, types, or contracts in play
58
- - Current limitations or technical debt visible in the code
59
- - Dependencies and integration points
42
+ Ground the debate in what actually exists. Glob/Grep/Read relevant files (up to 5-6, focus on core logic).
60
43
 
61
- This codebase summary is appended to the context passed to every perspective agent, so they argue from facts rather than assumptions.
44
+ Produce a ~300 word codebase summary: what exists, key interfaces/contracts, current limitations, dependencies. Passed to every perspective agent so they argue from facts, not assumptions.
62
45
 
63
46
  ### 3. SPAWN PERSPECTIVES
64
47
 
65
48
  **Spawn ALL 4 perspective agents in ONE message (non-background, parallel):**
66
49
 
67
- Each agent receives the same context summary + codebase context but a different role. Each must:
68
- - Argue from their perspective, grounded in what the codebase actually does
69
- - Identify risks the other perspectives might miss
70
- - Propose concrete alternatives where they disagree with the likely approach
71
-
72
- ```python
73
- # All 4 in a single message — parallel, non-background:
74
- Task(subagent_type="reasoner", model="opus", prompt="""
75
- You are the USER ADVOCATE in a design debate.
50
+ Each agent receives the same preamble + codebase context but a different role lens.
76
51
 
52
+ **Shared preamble for all perspectives:**
53
+ ```
77
54
  ## Context
78
55
  {summary}
79
56
 
80
57
  ## Current Codebase
81
58
  {codebase_summary}
82
59
 
83
- ## Your Role
84
- Argue from the perspective of the end user. Focus on:
85
- - Simplicity and ease of use
86
- - Real user needs vs assumed needs
87
- - Friction points and cognitive load
88
- - Whether the solution matches how users actually think
89
-
90
60
  Provide:
91
61
  1. Your key arguments (3-5 points)
92
- 2. Risks you see from a user perspective
62
+ 2. Risks your perspective surfaces
93
63
  3. Concrete alternatives if you disagree with the current direction
94
64
 
95
65
  Keep response under 400 words.
96
- """)
66
+ ```
67
+
68
+ **Perspective-specific role lenses (append to preamble):**
69
+
70
+ ```python
71
+ # All 4 in a single message — parallel, non-background:
97
72
 
98
73
  Task(subagent_type="reasoner", model="opus", prompt="""
99
- You are the TECH SKEPTIC in a design debate.
74
+ {shared_preamble}
100
75
 
101
- ## Context
102
- {summary}
76
+ ## Your Role: USER ADVOCATE
77
+ Argue from the perspective of the end user. Focus on:
78
+ - Simplicity and ease of use
79
+ - Real user needs vs assumed needs
80
+ - Friction points and cognitive load
81
+ - Whether the solution matches how users actually think
82
+ """)
103
83
 
104
- ## Current Codebase
105
- {codebase_summary}
84
+ Task(subagent_type="reasoner", model="opus", prompt="""
85
+ {shared_preamble}
106
86
 
107
- ## Your Role
87
+ ## Your Role: TECH SKEPTIC
108
88
  Challenge technical assumptions and surface hidden complexity. Focus on:
109
89
  - What could go wrong technically
110
90
  - Hidden dependencies or coupling
111
91
  - Complexity that seems simple but isn't
112
92
  - Maintenance burden over time
113
-
114
- Provide:
115
- 1. Your key arguments (3-5 points)
116
- 2. Technical risks others might overlook
117
- 3. Simpler alternatives worth considering
118
-
119
- Keep response under 400 words.
120
93
  """)
121
94
 
122
95
  Task(subagent_type="reasoner", model="opus", prompt="""
123
- You are the SYSTEMS THINKER in a design debate.
124
-
125
- ## Context
126
- {summary}
96
+ {shared_preamble}
127
97
 
128
- ## Current Codebase
129
- {codebase_summary}
130
-
131
- ## Your Role
98
+ ## Your Role: SYSTEMS THINKER
132
99
  Analyze how this fits into the broader system. Focus on:
133
100
  - Integration with existing components
134
101
  - Scalability implications
135
102
  - Second-order effects and unintended consequences
136
103
  - Long-term evolution and extensibility
137
-
138
- Provide:
139
- 1. Your key arguments (3-5 points)
140
- 2. Systemic risks and ripple effects
141
- 3. Architectural alternatives worth considering
142
-
143
- Keep response under 400 words.
144
104
  """)
145
105
 
146
106
  Task(subagent_type="reasoner", model="opus", prompt="""
147
- You are the LLM EFFICIENCY expert in a design debate.
107
+ {shared_preamble}
148
108
 
149
- ## Context
150
- {summary}
151
-
152
- ## Current Codebase
153
- {codebase_summary}
154
-
155
- ## Your Role
109
+ ## Your Role: LLM EFFICIENCY
156
110
  Evaluate from the perspective of LLM consumption and interaction. Focus on:
157
111
  - Token density: can the output be consumed efficiently by LLMs?
158
112
  - Minimal scaffolding: avoid ceremony that adds tokens without information
159
113
  - Navigable structure: can an LLM quickly find what it needs?
160
114
  - Attention budget: does the design respect limited context windows?
161
-
162
- Provide:
163
- 1. Your key arguments (3-5 points)
164
- 2. Efficiency risks others might not consider
165
- 3. Alternatives that optimize for LLM consumption
166
-
167
- Keep response under 400 words.
168
115
  """)
169
116
  ```
170
117
 
@@ -207,83 +154,17 @@ Keep response under 500 words.
207
154
 
208
155
  ### 5. WRITE DEBATE FILE
209
156
 
210
- Create `specs/.debate-{name}.md`:
211
-
212
- ```markdown
213
- # Debate: {Name}
214
-
215
- ## Context
216
- [~200 word summary from step 1]
217
-
218
- ## Codebase Context
219
- [~300 word summary from step 2 — what exists, key patterns, limitations]
220
-
221
- ## Perspectives
222
-
223
- ### User Advocate
224
- [arguments from agent]
225
-
226
- ### Tech Skeptic
227
- [arguments from agent]
228
-
229
- ### Systems Thinker
230
- [arguments from agent]
231
-
232
- ### LLM Efficiency
233
- [arguments from agent]
234
-
235
- ## Synthesis
236
-
237
- ### Consensus
238
- [from synthesizer]
239
-
240
- ### Tensions
241
- [from synthesizer]
242
-
243
- ### Open Decisions
244
- [from synthesizer]
245
-
246
- ### Recommendation
247
- [from synthesizer]
248
- ```
157
+ Create `specs/.debate-{name}.md` with sections: Context · Codebase Context · Perspectives (User Advocate / Tech Skeptic / Systems Thinker / LLM Efficiency) · Synthesis (Consensus / Tensions / Open Decisions / Recommendation).
249
158
 
250
159
  ### 6. CONFIRM
251
160
 
252
- After writing the file, present a brief summary to the user:
253
-
254
- ```
255
- ✓ Created specs/.debate-{name}.md
256
-
257
- Key tensions:
258
- - [tension 1]
259
- - [tension 2]
260
-
261
- Open decisions:
262
- - [decision 1]
263
- - [decision 2]
264
-
265
- Next: Run /df:spec {name} to formalize into a specification
266
- ```
267
-
268
- ### 7. CAPTURE DECISIONS
269
-
270
- Extract up to 4 candidates from consensus/resolved tensions. Ask user via `AskUserQuestion(multiSelect=True)` with options like `{ label: "[APPROACH] {decision}", description: "{rationale}" }`.
271
-
272
- For confirmed decisions, append to `.deepflow/decisions.md` (create if absent) using format:
273
- ```
274
- ### {YYYY-MM-DD} — debate
275
- - [{TAG}] {decision text} — {rationale}
276
- ```
277
- Tags: [APPROACH] directional choices · [PROVISIONAL] tentative · [ASSUMPTION] unverified premises. If a new decision contradicts an existing one, note the conflict inline.
161
+ Present key tensions and open decisions, then: `Next: Run /df:spec {name} to formalize into a specification`
278
162
 
279
163
  ---
280
164
 
281
165
  ## Rules
282
166
 
283
167
  - **All 4 perspective agents MUST be spawned in ONE message** (parallel, non-background)
284
- - **NEVER use `run_in_background`** — causes late notifications that pollute output
285
- - **NEVER use TaskOutput** — returns full transcripts that explode context
286
- - **NEVER use Explore agents** — the orchestrator gathers context directly
287
168
  - **Codebase context is gathered by the orchestrator** (step 2) and passed to agents via prompt
288
169
  - Reasoner agents receive context through their prompt, not by reading files themselves
289
170
  - The debate file goes in `specs/` so `/df:spec` can reference it
@@ -81,31 +81,10 @@ Example questions:
81
81
  - Mix structured questions (AskUserQuestion) with conversational follow-ups
82
82
  - Ask follow-up questions based on answers — don't just march through phases mechanically
83
83
  - Go deeper on surprising or unclear answers
84
-
85
84
  ### Behavioral Rules
86
- - **NEVER assume** — if something is ambiguous, ask
87
- - **NEVER suggest ending** — the user decides when they're done
88
- - **NEVER take action** — no code reading, no file creation, no agents
89
- - **NEVER skip phases** — but adapt depth based on the problem
90
85
  - Keep your responses short between questions — don't lecture
91
86
  - Acknowledge answers briefly before asking the next question
92
87
 
93
- ### Decision Capture
94
- When the user signals they are ready to move on, before presenting next-step options, extract up to 4 candidate decisions from the session (meaningful choices about approach, scope, or constraints). Present via `AskUserQuestion` with `multiSelect: true`, e.g.:
95
-
96
- ```json
97
- {"questions": [{"question": "Which decisions should be recorded?", "header": "Decisions", "multiSelect": true,
98
- "options": [{"label": "[APPROACH] Use event sourcing", "description": "Matches audit requirements"}]}]}
99
- ```
100
-
101
- For each confirmed decision, append to `.deepflow/decisions.md` (create if missing):
102
- ```
103
- ### {YYYY-MM-DD} — discover
104
- - [APPROACH] Decision text — rationale
105
- ```
106
-
107
- Tags: `[APPROACH]` firm choice · `[PROVISIONAL]` revisit later · `[ASSUMPTION]` unverified belief.
108
-
109
88
  ### When the User Wants to Move On
110
89
  When the user signals they want to advance (e.g., "I think that's enough", "let's move on", "ready for next step"):
111
90