@engineereddev/fractal-planner 0.1.1
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/.claude-plugin/marketplace.json +22 -0
- package/.claude-plugin/plugin.json +19 -0
- package/LICENSE +21 -0
- package/README.md +257 -0
- package/agents/fp-analyst.md +96 -0
- package/agents/fp-context-builder.md +87 -0
- package/agents/fp-critic.md +140 -0
- package/agents/fp-decomposer.md +261 -0
- package/agents/fp-interviewer.md +263 -0
- package/agents/fp-linear-sync.md +128 -0
- package/agents/fp-researcher.md +82 -0
- package/agents/fp-task-tracker.md +134 -0
- package/dist/cli/classify-intent.js +118 -0
- package/dist/cli/compute-signals.js +495 -0
- package/dist/cli/generate-plan.js +14209 -0
- package/dist/cli/load-config.js +13661 -0
- package/dist/cli/validate-tasks.js +467 -0
- package/dist/index.js +24598 -0
- package/dist/src/cli/classify-intent.d.ts +3 -0
- package/dist/src/cli/compute-signals.d.ts +14 -0
- package/dist/src/cli/generate-plan.d.ts +3 -0
- package/dist/src/cli/load-config.d.ts +3 -0
- package/dist/src/cli/validate-tasks.d.ts +3 -0
- package/dist/src/config.d.ts +182 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/phases/clearance.d.ts +12 -0
- package/dist/src/phases/decomposition.d.ts +41 -0
- package/dist/src/phases/interview.d.ts +17 -0
- package/dist/src/phases/planning.d.ts +21 -0
- package/dist/src/phases/research.d.ts +9 -0
- package/dist/src/types/index.d.ts +116 -0
- package/dist/src/utils/draft.d.ts +21 -0
- package/dist/src/utils/question-strategies.d.ts +24 -0
- package/dist/src/utils/task-parser.d.ts +3 -0
- package/hooks/hooks.json +27 -0
- package/hooks/nudge-teammate.sh +216 -0
- package/hooks/run-comment-checker.sh +91 -0
- package/package.json +65 -0
- package/skills/commit/SKILL.md +157 -0
- package/skills/fp/SKILL.md +857 -0
- package/skills/fp/scripts/resolve-env.sh +66 -0
- package/skills/handoff/SKILL.md +195 -0
- package/skills/implement/SKILL.md +783 -0
- package/skills/implement/reference.md +935 -0
- package/skills/retry/SKILL.md +333 -0
- package/skills/status/SKILL.md +182 -0
|
@@ -0,0 +1,857 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fp:plan
|
|
3
|
+
description: Iterative planning framework with requirements interview, research, decomposition, and optional Linear sync.
|
|
4
|
+
context: fork
|
|
5
|
+
agent: Plan
|
|
6
|
+
allowed-tools: AskUserQuestion, Read, Write, Bash, Task, Glob, TeamCreate, TeamDelete, SendMessage
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Fractal Planner — Orchestrator
|
|
10
|
+
|
|
11
|
+
You are orchestrating the fractal planning framework. This framework breaks down complex features into progressively smaller tasks through iterative clarification, research, and decomposition.
|
|
12
|
+
|
|
13
|
+
Each phase is handled by a specialized subagent — except the interview phase, which uses an **agent team** with a lead-relay pattern so the interviewer can ask the user questions via you (the lead). Your job is to coordinate data flow between phases.
|
|
14
|
+
|
|
15
|
+
## Your Task
|
|
16
|
+
|
|
17
|
+
**Goal**: $ARGUMENTS
|
|
18
|
+
|
|
19
|
+
## Step 1: Goal
|
|
20
|
+
|
|
21
|
+
**Goal**: `$ARGUMENTS`
|
|
22
|
+
|
|
23
|
+
This is the user's request. All configuration values (maxComplexity, maxIterations, researchOnly, planOnly, noCommit, etc.) are loaded from config files in Step 3.
|
|
24
|
+
|
|
25
|
+
## Step 2: Setup
|
|
26
|
+
|
|
27
|
+
Generate a descriptive `planId` slug from the user's goal.
|
|
28
|
+
|
|
29
|
+
1. Extract 2-4 descriptive words from the goal (`$ARGUMENTS`), ignoring filler words (a, the, to, for, add, create, implement, build, make, update, fix, want, need, please, etc.).
|
|
30
|
+
2. Lowercase, join with hyphens, keep only `[a-z0-9-]`, truncate to 30 characters.
|
|
31
|
+
3. If no descriptive words remain, fall back to a timestamp: `$(date +%Y%m%d-%H%M%S)`.
|
|
32
|
+
|
|
33
|
+
Examples: "Add JWT authentication to API" → `jwt-authentication-api`, "fix dark mode toggle" → `dark-mode-toggle`
|
|
34
|
+
|
|
35
|
+
Run this to check for collisions and create the directory:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
planId="<your-slug>"
|
|
39
|
+
base="$planId"
|
|
40
|
+
i=2
|
|
41
|
+
while [ -d ".fractal-planner/plans/${planId}" ]; do
|
|
42
|
+
planId="${base}-${i}"
|
|
43
|
+
i=$((i + 1))
|
|
44
|
+
if [ "$i" -gt 9 ]; then
|
|
45
|
+
planId="$(date +%Y%m%d-%H%M%S)"
|
|
46
|
+
break
|
|
47
|
+
fi
|
|
48
|
+
done
|
|
49
|
+
echo "planId=$planId"
|
|
50
|
+
mkdir -p ".fractal-planner/plans/${planId}"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Capture the echoed `planId`. **Do not proceed until it is a non-empty string and the directory exists.**
|
|
54
|
+
|
|
55
|
+
After confirming the directory, scan for interrupted implementation sessions:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
grep -rl "IN_PROGRESS" .fractal-planner/plans/*/progress.md 2>/dev/null
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For each matching file path, extract the planId from the path (the segment between `plans/` and `/progress.md`) and show a non-blocking notice to the user:
|
|
62
|
+
|
|
63
|
+
> Notice: Plan `{planId}` has an interrupted implementation session. Run `/fp:implement {planId}` to resume it.
|
|
64
|
+
|
|
65
|
+
This is informational only — continue to Step 3 regardless.
|
|
66
|
+
|
|
67
|
+
## Step 3: Resolve Plugin Root & Environment
|
|
68
|
+
|
|
69
|
+
This SKILL.md is located at `skills/fp/SKILL.md` relative to the plugin root. From the skill/plugin metadata in your context, determine the **absolute path** to the plugin root directory (the ancestor containing `.claude-plugin/`). Store it as `PLUGIN_ROOT`.
|
|
70
|
+
|
|
71
|
+
Run the environment resolver (single bash call — returns plugin root, CLI runner, CLI dir, and full merged config):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
CLAUDE_PLUGIN_ROOT="<PLUGIN_ROOT>" bash "<PLUGIN_ROOT>/skills/fp/scripts/resolve-env.sh"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
This outputs four key-value lines. Parse them:
|
|
78
|
+
- **PLUGIN_ROOT** — absolute path to the plugin repository root
|
|
79
|
+
- **CLI_RUNNER** — `bun` or `node`
|
|
80
|
+
- **CLI_DIR** — absolute path to CLI helper directory (source TS or compiled JS)
|
|
81
|
+
- **CONFIG_JSON** — full merged configuration as a JSON object
|
|
82
|
+
|
|
83
|
+
From CONFIG_JSON, extract and remember these for all subsequent steps:
|
|
84
|
+
- `maxComplexity` (default: 3) — used in Step 7, Step 7.5
|
|
85
|
+
- `maxIterations` (default: 3) — used in Step 7
|
|
86
|
+
- `maxParallelTasks` (default: 1) — passed to implement (controls parallel wave execution)
|
|
87
|
+
- `researchOnly` (default: false) — if true, stop after Step 6
|
|
88
|
+
- `planOnly` (default: false) — if true, stop after Step 8
|
|
89
|
+
- `skipPlanReview` (default: false) — if true, skip Step 9 plan review gate
|
|
90
|
+
- `skipApproachReview` (default: false) — if true, skip Step 6.5 approach review gate
|
|
91
|
+
- `preAnalysis` (default: true) — if true, run fp-analyst for complex intents (Step 4.7)
|
|
92
|
+
- `noCommit` (default: false) — passed to implement
|
|
93
|
+
- `linear.enabled` (default: false) — controls Step 9/10
|
|
94
|
+
- `linear.teamId`, `linear.projectId`, `linear.userId` — used in Step 10
|
|
95
|
+
|
|
96
|
+
If CONFIG_JSON contains `"_error"`, use defaults: maxComplexity=3, maxIterations=3, maxParallelTasks=1, all booleans false (skipPlanReview=false, skipApproachReview=false, etc.), linear disabled.
|
|
97
|
+
|
|
98
|
+
## Step 4: Classify Intent
|
|
99
|
+
|
|
100
|
+
Run the deterministic intent classifier using CLI_RUNNER and CLI_DIR from Step 3:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
${CLI_RUNNER} ${CLI_DIR}/classify-intent.* "<goal text>"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
This outputs JSON: `{ "intent": "...", "strategy": { "researchFirst": ..., "focusAreas": [...], "initialQuestions": [...], "researchPrompts": [...] } }`
|
|
107
|
+
|
|
108
|
+
Capture the output for the next step.
|
|
109
|
+
|
|
110
|
+
## Step 4.5: Quick Project Structure Scan
|
|
111
|
+
|
|
112
|
+
Get a snapshot of the project structure to seed the interviewer with directory awareness:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
ls -1 src/ 2>/dev/null | head -20
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Capture this output as `PROJECT_STRUCTURE` for the next step.
|
|
119
|
+
|
|
120
|
+
## Step 4.7: Pre-Interview Analysis (conditional)
|
|
121
|
+
|
|
122
|
+
If **both** of the following are true, spawn the pre-interview analyst:
|
|
123
|
+
- `preAnalysis` (from Step 3) is `true`
|
|
124
|
+
- The intent from Step 4 is one of: `mid-sized`, `build-from-scratch`, `architecture`
|
|
125
|
+
|
|
126
|
+
Otherwise, skip this step and set `preAnalysisFindings` to `null`.
|
|
127
|
+
|
|
128
|
+
If running the analyst:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
Task(
|
|
132
|
+
subagent_type: "fp-analyst",
|
|
133
|
+
description: "Pre-interview codebase analysis",
|
|
134
|
+
mode: "acceptEdits",
|
|
135
|
+
prompt: "Analyze the codebase for hidden complexity and risk factors before the requirements interview.
|
|
136
|
+
|
|
137
|
+
Goal: <goal text>
|
|
138
|
+
Intent: <intent from Step 4>
|
|
139
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
140
|
+
|
|
141
|
+
Write pre-analysis.md to the plan directory."
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
After the analyst completes, read `.fractal-planner/plans/{planId}/pre-analysis.md` and extract:
|
|
146
|
+
- `hiddenComplexityFlags` — key complexity findings
|
|
147
|
+
- `riskItems` — high-risk areas
|
|
148
|
+
- `ambiguityCandidates` — terms/choices needing clarification
|
|
149
|
+
- `suggestedFocusAreas` — recommended interview topics
|
|
150
|
+
|
|
151
|
+
Store all of this as `preAnalysisFindings` for use in Step 5b (injected into the interviewer prompt).
|
|
152
|
+
|
|
153
|
+
## Step 5: Requirements Interview (Phase 0)
|
|
154
|
+
|
|
155
|
+
The interview phase uses an **agent team** so the interviewer can ask the user questions via you (the lead). You relay questions to the user with `AskUserQuestion` and forward answers back.
|
|
156
|
+
|
|
157
|
+
### Step 5a: Create Interview Team
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
TeamCreate(team_name: "fp-interview-<planId>")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
You are now the team lead with agent name **`team-lead`**.
|
|
164
|
+
|
|
165
|
+
### Step 5b: Spawn Interviewer Teammate
|
|
166
|
+
|
|
167
|
+
Spawn the interviewer as a teammate (NOT a subagent):
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
Task(
|
|
171
|
+
subagent_type: "general-purpose",
|
|
172
|
+
name: "interviewer",
|
|
173
|
+
team_name: "fp-interview-<planId>",
|
|
174
|
+
description: "Requirements interview",
|
|
175
|
+
mode: "acceptEdits",
|
|
176
|
+
prompt: "You are the requirements interviewer on the fp-interview-<planId> team.
|
|
177
|
+
|
|
178
|
+
Your job is to conduct a research-grounded, iterative requirements interview. You CANNOT talk to the user directly — send all questions to the team lead via SendMessage, and the lead will relay user answers back to you.
|
|
179
|
+
|
|
180
|
+
## Inputs
|
|
181
|
+
|
|
182
|
+
- Goal: <goal text>
|
|
183
|
+
- Intent: <intent from step 4>
|
|
184
|
+
- Question Strategy:
|
|
185
|
+
- Focus areas: <focusAreas from step 4>
|
|
186
|
+
- Initial questions: <initialQuestions from step 4>
|
|
187
|
+
- Research Prompts: <researchPrompts from step 4, one per line — if empty, skip the scan>
|
|
188
|
+
- Project Structure: <PROJECT_STRUCTURE from step 4.5>
|
|
189
|
+
- Pre-Analysis Findings: <if preAnalysisFindings is not null, paste pre-analysis.md contents; otherwise write 'none'>
|
|
190
|
+
- Plan directory: .fractal-planner/plans/<planId>
|
|
191
|
+
|
|
192
|
+
## Process
|
|
193
|
+
|
|
194
|
+
### 1. Quick Context Scan (before asking any questions)
|
|
195
|
+
|
|
196
|
+
For non-trivial intents, do a quick codebase scan before your first question. This grounds your questions in concrete findings instead of generic prompts.
|
|
197
|
+
|
|
198
|
+
If Pre-Analysis Findings are provided (not 'none'), use them to sharpen your focus — the analyst has already identified complexity flags and ambiguity candidates. Use those as your starting point and supplement with targeted additional scans rather than rediscovering them from scratch.
|
|
199
|
+
|
|
200
|
+
- Use Glob to find files matching goal keywords (e.g., **/*auth* for an auth feature)
|
|
201
|
+
- Use Grep for 2-3 targeted pattern searches guided by the research prompts
|
|
202
|
+
- Cap at ~5 tool calls — this is a quick scan, not deep research
|
|
203
|
+
- Record findings as working context for grounding questions
|
|
204
|
+
|
|
205
|
+
For trivial intent: skip the scan entirely, go straight to questions.
|
|
206
|
+
|
|
207
|
+
### 2. Ask Research-Grounded Questions
|
|
208
|
+
|
|
209
|
+
Send questions to the team lead via SendMessage using this structured format:
|
|
210
|
+
|
|
211
|
+
SendMessage(
|
|
212
|
+
type: 'message',
|
|
213
|
+
recipient: 'team-lead',
|
|
214
|
+
summary: '<5-10 word summary>',
|
|
215
|
+
content: 'QUESTIONS:
|
|
216
|
+
|
|
217
|
+
Q1:
|
|
218
|
+
<Your first research-grounded question>
|
|
219
|
+
OPTIONS:
|
|
220
|
+
- <option 1 label> | <option 1 description>
|
|
221
|
+
- <option 2 label> | <option 2 description>
|
|
222
|
+
- <option 3 label> | <option 3 description>
|
|
223
|
+
HEADER: <short label, max 12 chars>
|
|
224
|
+
MULTI_SELECT: <true/false>
|
|
225
|
+
|
|
226
|
+
Q2:
|
|
227
|
+
<Your second research-grounded question>
|
|
228
|
+
OPTIONS:
|
|
229
|
+
- <option 1 label> | <option 1 description>
|
|
230
|
+
- <option 2 label> | <option 2 description>
|
|
231
|
+
HEADER: <short label, max 12 chars>
|
|
232
|
+
MULTI_SELECT: <true/false>'
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
Up to Q4 max per message. Can still send just Q1 if only 1 question is needed.
|
|
236
|
+
|
|
237
|
+
Follow these rules:
|
|
238
|
+
- Batch up to 4 questions per message — this is the maximum AskUserQuestion supports. Collect all relevant questions for this round and send them together in a single QUESTIONS: message. Fewer is fine when fewer are needed.
|
|
239
|
+
- Start with the provided initial questions from the strategy, but rephrase them using your scan findings
|
|
240
|
+
- Provide meaningful options that guide thinking
|
|
241
|
+
- Adapt follow-up questions based on answers
|
|
242
|
+
|
|
243
|
+
Research-grounded question examples:
|
|
244
|
+
|
|
245
|
+
Instead of: 'Should this follow existing patterns in the codebase?'
|
|
246
|
+
Ask: 'I found your codebase uses the repository pattern in src/repos/. Should we follow that for the new data layer?'
|
|
247
|
+
|
|
248
|
+
Instead of: 'Are there similar features I can learn from?'
|
|
249
|
+
Ask: 'I found src/auth/oauth-handler.ts and src/auth/session.ts — should the new authentication extend these, or is this a separate auth system?'
|
|
250
|
+
|
|
251
|
+
Instead of: 'What libraries/frameworks should be used?'
|
|
252
|
+
Ask: 'Your package.json already includes zod for validation and express for routing. Should we use these for the new feature, or do you prefer alternatives?'
|
|
253
|
+
|
|
254
|
+
Instead of: 'Are there tests covering this code?'
|
|
255
|
+
Ask: 'I found test files in src/__tests__/ using bun:test. The module you want to refactor (src/utils/parser.ts) has no existing tests. Should we add tests first as a safety net?'
|
|
256
|
+
|
|
257
|
+
### 3. Receiving Answers
|
|
258
|
+
|
|
259
|
+
When the lead sends you a message starting with 'USER RESPONSE:', process **all** answers (Q1, Q2, etc.):
|
|
260
|
+
- Extract each numbered answer's selection and additional context
|
|
261
|
+
- Update the interview draft with all new information at once (see section 6)
|
|
262
|
+
- Continue to next question batch or achieve clearance
|
|
263
|
+
|
|
264
|
+
### 4. Gather Requirements in 7 Areas
|
|
265
|
+
|
|
266
|
+
- Core objective: What exactly needs to be accomplished?
|
|
267
|
+
- Scope inclusions: What's explicitly IN scope?
|
|
268
|
+
- Scope exclusions: What's explicitly OUT of scope?
|
|
269
|
+
- Technical decisions: Specific technologies, patterns, or approaches required?
|
|
270
|
+
- Constraints: Limitations, requirements, or boundaries?
|
|
271
|
+
- Success criteria: How do we know when it's done?
|
|
272
|
+
- Test strategy: How should this be tested?
|
|
273
|
+
|
|
274
|
+
### 5. Turn Protocol (strict termination rules)
|
|
275
|
+
|
|
276
|
+
Every turn MUST end with exactly one of:
|
|
277
|
+
1. A SendMessage to 'team-lead' with a QUESTIONS: batch (1-4 questions) (normal case — gathering more requirements)
|
|
278
|
+
2. Writing final artifacts + SendMessage 'CLEARANCE ACHIEVED' to 'team-lead' (all 6 checklist items pass)
|
|
279
|
+
|
|
280
|
+
Forbidden endings:
|
|
281
|
+
- Summaries without a question
|
|
282
|
+
- Passive statements like 'Let me know if you have questions'
|
|
283
|
+
- Analysis or commentary without an action (question or artifact write)
|
|
284
|
+
|
|
285
|
+
### 6. Initial Draft (before first question)
|
|
286
|
+
|
|
287
|
+
After the quick context scan and before asking your first question, write an initial draft to {plan directory}/interview.json with:
|
|
288
|
+
- intent and userGoal from the inputs
|
|
289
|
+
- codebaseContext populated from your scan findings (but testStrategy left empty — this requires user confirmation)
|
|
290
|
+
- All other fields empty (confirmedRequirements: [], scopeInclusions: [], etc.)
|
|
291
|
+
|
|
292
|
+
This establishes a baseline. Track your round number starting at 1 (incremented after each user response).
|
|
293
|
+
|
|
294
|
+
### 7. Mandatory Draft Update Loop
|
|
295
|
+
|
|
296
|
+
After EVERY user response (USER RESPONSE message from lead), follow this exact sequence:
|
|
297
|
+
|
|
298
|
+
1. Increment round number
|
|
299
|
+
2. Read the current draft from {plan directory}/interview.json
|
|
300
|
+
3. Update the draft with new information from the user's response
|
|
301
|
+
4. Write the updated draft back to {plan directory}/interview.json
|
|
302
|
+
5. Send a draft status message to the lead:
|
|
303
|
+
SendMessage(type: 'message', recipient: 'team-lead', summary: 'Draft updated round N', content: 'DRAFT UPDATED (Round N)\nClearance: M/6 passed\nGaps: <list remaining gaps>')
|
|
304
|
+
6. Evaluate clearance — you MUST explicitly enumerate each item (see section 8). Output the evaluation in your thinking before deciding next action.
|
|
305
|
+
7. If clearance NOT achieved: identify which items still fail, then send a QUESTIONS: batch targeting the most critical gaps
|
|
306
|
+
8. If clearance achieved: write final artifacts (interview.json + interview.md) and send:
|
|
307
|
+
SendMessage(type: 'message', recipient: 'team-lead', summary: 'Clearance achieved', content: 'CLEARANCE ACHIEVED\nArtifacts written to .fractal-planner/plans/<planId>/')
|
|
308
|
+
|
|
309
|
+
### 8. Evaluate Clearance (6-item checklist)
|
|
310
|
+
|
|
311
|
+
After each draft update, you MUST explicitly evaluate each item and output the result in this format before deciding your next action:
|
|
312
|
+
|
|
313
|
+
Clearance Evaluation (Round N):
|
|
314
|
+
1. Core objective defined: [PASS/FAIL] — <reason>
|
|
315
|
+
2. Scope boundaries established: [PASS/FAIL] — <reason>
|
|
316
|
+
3. No ambiguities: [PASS/FAIL] — <reason>
|
|
317
|
+
4. Technical approach decided: [PASS/FAIL] — <reason>
|
|
318
|
+
5. No blocking questions: [PASS/FAIL] — <reason>
|
|
319
|
+
6. Test strategy identified: [PASS/FAIL] — <reason>
|
|
320
|
+
Result: [N/6 passed — CLEARANCE NOT MET / CLEARANCE ACHIEVED]
|
|
321
|
+
|
|
322
|
+
The 6 conditions:
|
|
323
|
+
1. Core objective defined: User has explicitly confirmed at least 1 requirement (goal text alone is NOT sufficient — the user must have validated something)
|
|
324
|
+
2. Scope boundaries established: At least 1 scope inclusion AND at least 1 scope exclusion
|
|
325
|
+
3. No ambiguities: At least 1 confirmed requirement exists AND no unvalidated assumptions remain
|
|
326
|
+
4. Technical approach decided: At least 1 technical decision made (auto-pass for trivial)
|
|
327
|
+
5. No blocking questions: Zero open questions remaining
|
|
328
|
+
6. Test strategy identified: User has confirmed a test approach (either via explicit answer or a test-related technicalDecisions key). Scan findings alone do NOT satisfy this — the user must have weighed in. (Auto-pass for trivial)
|
|
329
|
+
|
|
330
|
+
Continue asking until ALL 6 conditions are met.
|
|
331
|
+
|
|
332
|
+
### 9. Complexity-Based Behavior
|
|
333
|
+
|
|
334
|
+
- trivial: Quick scan skipped. 1 confirmation question. Items 4, 5, 6 auto-pass if no blockers.
|
|
335
|
+
- mid-sized, refactoring, build-from-scratch: Minimum 2 rounds before clearance can pass.
|
|
336
|
+
- architecture: Minimum 3 rounds before clearance can pass.
|
|
337
|
+
|
|
338
|
+
### 10. Write Output Artifacts
|
|
339
|
+
|
|
340
|
+
Once clearance is achieved, write two files to the plan directory:
|
|
341
|
+
|
|
342
|
+
interview.json (machine-readable):
|
|
343
|
+
{
|
|
344
|
+
'intent': '<intent type>',
|
|
345
|
+
'userGoal': '<original goal>',
|
|
346
|
+
'confirmedRequirements': ['...'],
|
|
347
|
+
'scopeInclusions': ['...'],
|
|
348
|
+
'scopeExclusions': ['...'],
|
|
349
|
+
'technicalDecisions': { 'key': 'value' },
|
|
350
|
+
'constraints': ['...'],
|
|
351
|
+
'assumptions': ['...'],
|
|
352
|
+
'openQuestions': [],
|
|
353
|
+
'codebaseContext': {
|
|
354
|
+
'relevantFiles': ['files found during scan'],
|
|
355
|
+
'existingPatterns': ['patterns observed'],
|
|
356
|
+
'testStrategy': 'how this should be tested'
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
interview.md (human-readable summary):
|
|
361
|
+
# Requirements Interview
|
|
362
|
+
## Goal
|
|
363
|
+
[Original goal]
|
|
364
|
+
## Intent
|
|
365
|
+
[trivial|refactoring|build-from-scratch|mid-sized|architecture]
|
|
366
|
+
## Codebase Context
|
|
367
|
+
- Relevant files: [files found during quick scan]
|
|
368
|
+
- Existing patterns: [patterns observed]
|
|
369
|
+
- Test strategy: [how this will be tested]
|
|
370
|
+
## Confirmed Requirements
|
|
371
|
+
- [List of validated requirements]
|
|
372
|
+
## Scope
|
|
373
|
+
### Inclusions
|
|
374
|
+
- [What's explicitly in scope]
|
|
375
|
+
### Exclusions
|
|
376
|
+
- [What's explicitly out of scope]
|
|
377
|
+
## Technical Decisions
|
|
378
|
+
- [Technology choices, patterns, approaches]
|
|
379
|
+
## Constraints
|
|
380
|
+
- [Limitations, requirements, boundaries]
|
|
381
|
+
## Success Criteria
|
|
382
|
+
- [How we know it's done]
|
|
383
|
+
## Open Questions
|
|
384
|
+
- [Any remaining questions or assumptions]
|
|
385
|
+
|
|
386
|
+
## Important
|
|
387
|
+
|
|
388
|
+
- NEVER skip the interview — even for trivial tasks, confirm scope
|
|
389
|
+
- If the user seems impatient, explain why requirements clarity prevents rework
|
|
390
|
+
- Keep questions focused on the strategy's focus areas
|
|
391
|
+
- Write both interview.json AND interview.md before finishing
|
|
392
|
+
- Ground questions in concrete codebase findings — never ask generic questions when you have scan data"
|
|
393
|
+
)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**IMPORTANT**: After spawning, do NOT call `TaskOutput` on the interviewer — it is a teammate, not a background task. Messages will arrive automatically via the team message system. Simply proceed to the relay loop below and wait.
|
|
397
|
+
|
|
398
|
+
### Step 5c: Relay Loop
|
|
399
|
+
|
|
400
|
+
**CRITICAL — Idle notifications are EXPECTED and MUST be ignored.** The agent team framework automatically sends an idle notification after every teammate turn. These are NOT errors, NOT signs of stalling, and NOT signals that the interviewer is done. The interviewer processes your response (reads draft, updates it, evaluates clearance, composes next questions) and then goes idle while waiting for your next message — this is completely normal.
|
|
401
|
+
|
|
402
|
+
You are now the relay between the interviewer and the user. Follow this protocol:
|
|
403
|
+
|
|
404
|
+
1. **Wait for protocol messages** from the interviewer (QUESTIONS, DRAFT UPDATED, CLEARANCE ACHIEVED, or ERROR) — they are delivered automatically, no polling needed. **Ignore any idle notifications while waiting.**
|
|
405
|
+
|
|
406
|
+
2. **On `QUESTIONS:` message**: Parse all question blocks (Q1 through Q4) from the structured content:
|
|
407
|
+
- For each `QN:` block, extract: question text, options (label | description), header, multi-select flag
|
|
408
|
+
- Call `AskUserQuestion` once with all parsed questions (1-4 questions in a single call)
|
|
409
|
+
- When the user answers, format ALL answers into a single response and forward back:
|
|
410
|
+
```
|
|
411
|
+
SendMessage(
|
|
412
|
+
type: "message",
|
|
413
|
+
recipient: "interviewer",
|
|
414
|
+
summary: "User responses to N questions",
|
|
415
|
+
content: "USER RESPONSE:\n\nQ1: User selected: \"<option>\"\nAdditional context: <text>\n\nQ2: User selected: \"<option>\"\nAdditional context: <text>"
|
|
416
|
+
)
|
|
417
|
+
```
|
|
418
|
+
- After sending, **wait patiently** for the interviewer's next protocol message. You WILL see idle notifications during this time as the interviewer processes the response — this is normal. Do NOT react to them.
|
|
419
|
+
|
|
420
|
+
3. **On `DRAFT UPDATED` message**: Informational only — no action needed. You may briefly note the clearance status if useful. **Continue waiting** for the next QUESTIONS or CLEARANCE ACHIEVED message.
|
|
421
|
+
|
|
422
|
+
4. **On `CLEARANCE ACHIEVED` message**: Exit the relay loop, proceed to Step 5d.
|
|
423
|
+
|
|
424
|
+
5. **On `ERROR:` message**: Report the error to the user and stop.
|
|
425
|
+
|
|
426
|
+
6. **On any other message (including idle notifications)**: Ignore it completely. Do not respond, do not exit the loop. Continue waiting for the next protocol message (QUESTIONS, DRAFT UPDATED, CLEARANCE ACHIEVED, or ERROR).
|
|
427
|
+
|
|
428
|
+
7. **Safety limit**: If you've relayed 30 round trips without clearance, warn the user and proceed to Step 5d anyway.
|
|
429
|
+
|
|
430
|
+
### Step 5d: Interview Cleanup
|
|
431
|
+
|
|
432
|
+
1. Shut down the interviewer:
|
|
433
|
+
```
|
|
434
|
+
SendMessage(type: "shutdown_request", recipient: "interviewer", content: "Interview complete, shutting down.")
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
2. Delete the team:
|
|
438
|
+
```
|
|
439
|
+
TeamDelete()
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
3. Read `.fractal-planner/plans/${planId}/interview.json` to get the structured findings for subsequent phases.
|
|
443
|
+
|
|
444
|
+
## Step 6: Research & Context Building (Phase 1)
|
|
445
|
+
|
|
446
|
+
Read `interview.json` from the plan directory. Extract the **Research Agenda**:
|
|
447
|
+
- `codebaseContext.relevantFiles` — files the interviewer already identified as relevant
|
|
448
|
+
- `technicalDecisions` — decisions that need verification or implementation detail
|
|
449
|
+
- `scopeExclusions` — areas to avoid during research
|
|
450
|
+
|
|
451
|
+
Spawn **both** research agents in parallel using `run_in_background: true`:
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
Task(
|
|
455
|
+
subagent_type: "fp-researcher",
|
|
456
|
+
description: "Codebase research for planned feature",
|
|
457
|
+
run_in_background: true,
|
|
458
|
+
mode: "bypassPermissions",
|
|
459
|
+
prompt: "Research the codebase for the following planned feature.
|
|
460
|
+
|
|
461
|
+
Goal: <goal text>
|
|
462
|
+
|
|
463
|
+
Interview Findings:
|
|
464
|
+
<paste interview.json contents>
|
|
465
|
+
|
|
466
|
+
Research Agenda:
|
|
467
|
+
- Confirmed relevant files (from interviewer scan — verify and explore deeper):
|
|
468
|
+
<codebaseContext.relevantFiles from interview.json, one per line — or 'none identified'>
|
|
469
|
+
- Technical decisions to verify:
|
|
470
|
+
<technicalDecisions from interview.json as key: value pairs — or 'none'>
|
|
471
|
+
- Scope exclusions (do NOT research these areas):
|
|
472
|
+
<scopeExclusions from interview.json, one per line — or 'none'>
|
|
473
|
+
|
|
474
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
475
|
+
|
|
476
|
+
Write research.md to the plan directory. Do NOT write context.md (that is handled by a parallel agent)."
|
|
477
|
+
)
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
```
|
|
481
|
+
Task(
|
|
482
|
+
subagent_type: "fp-context-builder",
|
|
483
|
+
description: "Build codebase context summary",
|
|
484
|
+
run_in_background: true,
|
|
485
|
+
mode: "bypassPermissions",
|
|
486
|
+
prompt: "Build a static codebase context summary.
|
|
487
|
+
|
|
488
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
489
|
+
|
|
490
|
+
Write context.md to the plan directory."
|
|
491
|
+
)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
Both agents run in parallel. **Wait for both** to complete by calling TaskOutput on both task IDs in a single message (parallel blocking calls). Then read `research.md` and `context.md` from the plan directory.
|
|
495
|
+
|
|
496
|
+
**If `researchOnly` (from Step 3) is true**: After both agents complete, read `research.md` and `context.md`, present a summary to the user, and stop.
|
|
497
|
+
|
|
498
|
+
## Step 6.5: Approach Review Gate
|
|
499
|
+
|
|
500
|
+
**Skip condition**: If `skipApproachReview` (from Step 3) is `true`, skip directly to Step 7.
|
|
501
|
+
|
|
502
|
+
This lightweight checkpoint lets the user review the synthesized approach before the expensive decomposition phase begins.
|
|
503
|
+
|
|
504
|
+
### Synthesize Approach Summary
|
|
505
|
+
|
|
506
|
+
Read `interview.json` and `research.md` from the plan directory. Synthesize a high-level approach summary covering:
|
|
507
|
+
|
|
508
|
+
- **Goal**: Restate the core objective from `interview.json` → `userGoal`
|
|
509
|
+
- **Scope**: In-scope items from `scopeInclusions`, out-of-scope from `scopeExclusions`
|
|
510
|
+
- **Technical Approach**: Cross-reference `technicalDecisions` from `interview.json` with findings from `research.md` — note any conflicts or validations
|
|
511
|
+
- **Key Files & Patterns**: Merge `codebaseContext.relevantFiles` and `codebaseContext.existingPatterns` from `interview.json` with file/pattern discoveries from `research.md`
|
|
512
|
+
- **Risk Areas**: Extract risk factors, knowledge gaps, or caveats identified in `research.md`
|
|
513
|
+
- **Test Strategy**: From `codebaseContext.testStrategy` in `interview.json`
|
|
514
|
+
|
|
515
|
+
### Present to User
|
|
516
|
+
|
|
517
|
+
Display the approach summary as formatted markdown text, then call `AskUserQuestion`:
|
|
518
|
+
|
|
519
|
+
- **"Proceed to decomposition"** — continue to Step 7
|
|
520
|
+
- **"Refine the approach"** — enter the refinement loop below
|
|
521
|
+
|
|
522
|
+
### Refinement Loop
|
|
523
|
+
|
|
524
|
+
If the user picks "Refine the approach":
|
|
525
|
+
|
|
526
|
+
1. Ask what they want to change via `AskUserQuestion` (free text — use a single question with descriptive options like "Change scope", "Change technical approach", "Change test strategy", "Something else").
|
|
527
|
+
2. Based on their feedback, read the current `interview.json`, update the relevant fields (e.g., add/remove scope items, modify technical decisions, adjust test strategy), and write the updated `interview.json` back.
|
|
528
|
+
3. Re-synthesize the approach summary from the updated `interview.json` + `research.md`.
|
|
529
|
+
4. Re-present the summary and the same two options ("Proceed to decomposition" / "Refine the approach").
|
|
530
|
+
5. **Safety limit**: After 5 refinement rounds, add a gentle nudge: "You've refined the approach 5 times. Consider proceeding to decomposition — you can still adjust during the plan review (Step 9)." Still allow further refinement if the user insists.
|
|
531
|
+
|
|
532
|
+
### Write Artifact
|
|
533
|
+
|
|
534
|
+
Before proceeding to Step 7, write the final approach summary as `approach-summary.md` to the plan directory for traceability. Use this format:
|
|
535
|
+
|
|
536
|
+
```markdown
|
|
537
|
+
# Approach Summary
|
|
538
|
+
|
|
539
|
+
## Goal
|
|
540
|
+
<restated goal>
|
|
541
|
+
|
|
542
|
+
## Scope
|
|
543
|
+
### In Scope
|
|
544
|
+
- <items>
|
|
545
|
+
### Out of Scope
|
|
546
|
+
- <items>
|
|
547
|
+
|
|
548
|
+
## Technical Approach
|
|
549
|
+
- <decisions, cross-referenced with research>
|
|
550
|
+
|
|
551
|
+
## Key Files & Patterns
|
|
552
|
+
- <files and patterns>
|
|
553
|
+
|
|
554
|
+
## Risk Areas
|
|
555
|
+
- <risks from research>
|
|
556
|
+
|
|
557
|
+
## Test Strategy
|
|
558
|
+
- <test approach>
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
## Step 7: Fractal Decomposition (Phase 2)
|
|
562
|
+
|
|
563
|
+
Read research.md and context.md, then spawn the decomposer agent:
|
|
564
|
+
|
|
565
|
+
```
|
|
566
|
+
Task(
|
|
567
|
+
subagent_type: "fp-decomposer",
|
|
568
|
+
description: "Task decomposition",
|
|
569
|
+
mode: "acceptEdits",
|
|
570
|
+
prompt: "Decompose the following goal into a task tree.
|
|
571
|
+
|
|
572
|
+
Goal: <goal text>
|
|
573
|
+
|
|
574
|
+
Interview Findings:
|
|
575
|
+
<paste interview.json contents>
|
|
576
|
+
|
|
577
|
+
Research Findings:
|
|
578
|
+
<paste research.md contents>
|
|
579
|
+
|
|
580
|
+
Max Complexity: <maxComplexity from Step 3>
|
|
581
|
+
|
|
582
|
+
Scope Exclusions (use as guardrails on relevant tasks):
|
|
583
|
+
<paste scopeExclusions array from interview.json, one per line — if empty, write 'none'>
|
|
584
|
+
|
|
585
|
+
Test Strategy: <paste testStrategy from interview.json codebaseContext, or 'not specified'>
|
|
586
|
+
|
|
587
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
588
|
+
|
|
589
|
+
Write tasks.md to the plan directory."
|
|
590
|
+
)
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
## Step 7.25: Compute Complexity Signals
|
|
594
|
+
|
|
595
|
+
Run the signals computation using CLI_RUNNER and CLI_DIR from Step 3:
|
|
596
|
+
|
|
597
|
+
```bash
|
|
598
|
+
${CLI_RUNNER} ${CLI_DIR}/compute-signals.* "${planId}"
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
This outputs per-task signals. Read `signals.json` from the plan directory.
|
|
602
|
+
|
|
603
|
+
Compare each leaf task's LLM-assigned complexity against the programmatic composite:
|
|
604
|
+
- If `|llm_score - composite| > 2`: flag as "signal-divergence" and store for inclusion in Step 7.5 validation feedback.
|
|
605
|
+
|
|
606
|
+
Store any divergences as `signalDivergences` for use in the retry loop.
|
|
607
|
+
|
|
608
|
+
## Step 7.5: Validate Task Tree
|
|
609
|
+
|
|
610
|
+
Run the deterministic task tree validator using CLI_RUNNER and CLI_DIR from Step 3:
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
${CLI_RUNNER} ${CLI_DIR}/validate-tasks.* "${planId}" ${maxComplexity}
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
This outputs JSON: `{ "valid": true/false, "maxComplexity": N, "totalLeafTasks": N, "violations": [...], "warnings": [...], "stats": {...} }`
|
|
617
|
+
|
|
618
|
+
Parse and store `warnings` from the result. These are non-blocking issues (like `scattered-files`) that should be included as feedback in retry prompts but do NOT make `valid: false`.
|
|
619
|
+
|
|
620
|
+
**If `valid: true`**: Proceed to Step 8.
|
|
621
|
+
|
|
622
|
+
**If `valid: false`**: Re-spawn the decomposer to fix violations. Repeat up to **5 retries** (6 total decomposition passes):
|
|
623
|
+
|
|
624
|
+
1. Read the current `tasks.md` from the plan directory.
|
|
625
|
+
2. Spawn `fp-decomposer` with targeted instructions:
|
|
626
|
+
|
|
627
|
+
```
|
|
628
|
+
Task(
|
|
629
|
+
subagent_type: "fp-decomposer",
|
|
630
|
+
description: "Fix task tree violations",
|
|
631
|
+
mode: "acceptEdits",
|
|
632
|
+
prompt: "The task tree validation found violations. Fix ONLY the flagged tasks — preserve everything else.
|
|
633
|
+
|
|
634
|
+
Goal: <goal text>
|
|
635
|
+
|
|
636
|
+
Max Complexity: <maxComplexity>
|
|
637
|
+
|
|
638
|
+
Violations:
|
|
639
|
+
<for each violation: '- Task {id} [{type}]: {detail}'>
|
|
640
|
+
|
|
641
|
+
Current tasks.md:
|
|
642
|
+
<paste full tasks.md contents>
|
|
643
|
+
|
|
644
|
+
Instructions per violation type:
|
|
645
|
+
- [over-complexity]: Decompose the task into smaller subtasks, each at or below maxComplexity. Do NOT lower complexity scores to game the threshold.
|
|
646
|
+
- [missing-acceptance]: Add concrete, measurable acceptance criteria to the leaf task.
|
|
647
|
+
- [missing-files]: Add a Files: line listing the files this task will modify (use 'none' only if truly no files are touched).
|
|
648
|
+
- [missing-tests-required]: Add a Tests Required: line (yes/no) to the leaf task.
|
|
649
|
+
- [missing-hints]: Add 2-4 implementation steps as a Hints: block. Tell the builder HOW to implement, not just WHAT.
|
|
650
|
+
- [missing-guardrails]: Add a Guardrails: block with at least: "Do NOT modify files outside: {files}" and "Do NOT add new dependencies". Add task-specific constraints from scope exclusions.
|
|
651
|
+
- [subtask-count]: Merge or split children so the parent has 2-5 subtasks.
|
|
652
|
+
|
|
653
|
+
<if signalDivergences is non-empty, include this section:>
|
|
654
|
+
Signal Divergences (programmatic signals disagree with LLM scores):
|
|
655
|
+
<for each divergence: '- Task {id}: LLM says complexity {N}, but signals suggest {M} (fileScope={a}, coupling={b}, gitRisk={c}, testCoverage={d})'>
|
|
656
|
+
Consider adjusting complexity scores or decomposing further if signals indicate higher actual complexity.
|
|
657
|
+
</if>
|
|
658
|
+
|
|
659
|
+
<if validation result has warnings, include this section:>
|
|
660
|
+
Warnings (non-blocking — consider addressing):
|
|
661
|
+
<for each warning: '- Task {id} [{type}]: {detail}'>
|
|
662
|
+
</if>
|
|
663
|
+
|
|
664
|
+
General:
|
|
665
|
+
- Do NOT change tasks that already pass validation
|
|
666
|
+
- Write the updated tasks.md to: .fractal-planner/plans/<planId>/tasks.md"
|
|
667
|
+
)
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
3. After the decomposer completes, re-run `validate-tasks` CLI.
|
|
671
|
+
4. If still invalid and retries remain, repeat from step 1.
|
|
672
|
+
5. If still invalid after 6 total passes, warn: "Task tree still has violations after 6 decomposition passes. Proceeding with current tree." and continue to Step 7.6.
|
|
673
|
+
|
|
674
|
+
## Step 7.6: Plan Quality Critique
|
|
675
|
+
|
|
676
|
+
Spawn the plan critic agent:
|
|
677
|
+
|
|
678
|
+
```
|
|
679
|
+
Task(
|
|
680
|
+
subagent_type: "fp-critic",
|
|
681
|
+
description: "Plan quality critique",
|
|
682
|
+
mode: "acceptEdits",
|
|
683
|
+
prompt: "Evaluate the quality of the task decomposition.
|
|
684
|
+
|
|
685
|
+
Tasks file: .fractal-planner/plans/<planId>/tasks.md
|
|
686
|
+
Interview file: .fractal-planner/plans/<planId>/interview.json
|
|
687
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
688
|
+
|
|
689
|
+
Read both files and write critique.md to the plan directory."
|
|
690
|
+
)
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
After the critic completes, read `.fractal-planner/plans/{planId}/critique.md`. Parse the `Overall Result` line to extract:
|
|
694
|
+
- `critiqueResult`: PASS, WARN, or FAIL
|
|
695
|
+
- `failCount` and `warnCount` from the CRITIQUE COMPLETE output or the critique.md summary
|
|
696
|
+
|
|
697
|
+
**If `critiqueResult` is FAIL** (re-decomposition loop, independent retry counter, max 3 passes):
|
|
698
|
+
|
|
699
|
+
1. Read the current `tasks.md` and the `## Recommendations` section from `critique.md`.
|
|
700
|
+
2. Spawn `fp-decomposer` with targeted critique feedback:
|
|
701
|
+
|
|
702
|
+
```
|
|
703
|
+
Task(
|
|
704
|
+
subagent_type: "fp-decomposer",
|
|
705
|
+
description: "Fix critic-flagged quality issues",
|
|
706
|
+
mode: "acceptEdits",
|
|
707
|
+
prompt: "The plan quality critic found issues. Fix ONLY the flagged tasks — preserve everything else.
|
|
708
|
+
|
|
709
|
+
Goal: <goal text>
|
|
710
|
+
Max Complexity: <maxComplexity>
|
|
711
|
+
|
|
712
|
+
Critic Recommendations:
|
|
713
|
+
<paste Recommendations section from critique.md>
|
|
714
|
+
|
|
715
|
+
Current tasks.md:
|
|
716
|
+
<paste full tasks.md>
|
|
717
|
+
|
|
718
|
+
Write the updated tasks.md to: .fractal-planner/plans/<planId>/tasks.md"
|
|
719
|
+
)
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
3. Re-run `validate-tasks` CLI (Step 7.5) on the updated tree.
|
|
723
|
+
4. Re-spawn the critic (Step 7.6) on the updated tree.
|
|
724
|
+
5. If still FAIL and critic retries remain, repeat from step 1.
|
|
725
|
+
6. If still FAIL after 3 critic-triggered passes, warn: "Plan quality still has FAIL findings after 3 critic passes. Proceeding to Step 8." and continue.
|
|
726
|
+
|
|
727
|
+
**If `critiqueResult` is WARN**: Store `critiqueWarnings` (the list of WARN findings from `critique.md`). They will be surfaced in Step 9.
|
|
728
|
+
|
|
729
|
+
**If `critiqueResult` is PASS**: Proceed to Step 8.
|
|
730
|
+
|
|
731
|
+
## Step 8: Generate Plan (Phase 3)
|
|
732
|
+
|
|
733
|
+
Run the deterministic plan generator using CLI_RUNNER and CLI_DIR from Step 3:
|
|
734
|
+
|
|
735
|
+
```bash
|
|
736
|
+
${CLI_RUNNER} ${CLI_DIR}/generate-plan.* "<planId>"
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
This reads `tasks.md`, computes execution order, and writes `plan.md`.
|
|
740
|
+
|
|
741
|
+
## Step 9: Plan Review & Confirmation Gate
|
|
742
|
+
|
|
743
|
+
If `skipPlanReview` (from Step 3) is `true`, skip directly to Step 10.
|
|
744
|
+
|
|
745
|
+
Read both `tasks.md` and `plan.md` from the plan directory. From `plan.md`, count the total leaf tasks in the `## Execution Order` section. From `tasks.md`, build a condensed tree view showing the full parent-child hierarchy.
|
|
746
|
+
|
|
747
|
+
Present the tree like this:
|
|
748
|
+
|
|
749
|
+
```
|
|
750
|
+
Here is the task breakdown (N leaf tasks will execute in dependency order):
|
|
751
|
+
|
|
752
|
+
- **[1]** Auth system overhaul (Complexity: 8)
|
|
753
|
+
- **[1.1]** Add JWT middleware (Complexity: 4) — `src/middleware/auth.ts`
|
|
754
|
+
- **[1.2]** Update login endpoint (Complexity: 4) — `src/routes/login.ts`, `src/services/auth.ts`
|
|
755
|
+
- **[2]** Add tests (Complexity: 5)
|
|
756
|
+
- **[2.1]** Unit tests (Complexity: 3) — `src/__tests__/auth.test.ts`
|
|
757
|
+
- **[2.2]** Integration tests (Complexity: 2) — `src/__tests__/login.integration.ts`
|
|
758
|
+
|
|
759
|
+
**Summary**: 4 leaf tasks, complexity range 2-4, across ~5 files
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
Format rules:
|
|
763
|
+
- Full parent-child hierarchy with nested `- ` bullets (2-space indent per level)
|
|
764
|
+
- Every task: `**[ID]** Description (Complexity: N)`
|
|
765
|
+
- Leaf tasks only: append `` — `file1`, `file2` `` if files are listed in the task
|
|
766
|
+
- Omit acceptance criteria, dependencies, and tests-required (builder/verifier details, not needed for approval)
|
|
767
|
+
- Summary line at the end: leaf count, complexity range (min-max of leaf tasks), approximate file count (unique files across all leaf tasks)
|
|
768
|
+
|
|
769
|
+
If the plan critic (Step 7.6) found WARN items (`critiqueWarnings` is not empty), surface them before the user options:
|
|
770
|
+
|
|
771
|
+
> **Plan Quality Notices** (from automated review):
|
|
772
|
+
> {list each warning from critiqueWarnings, one per line}
|
|
773
|
+
> These are warnings only — the plan is valid but may benefit from refinement.
|
|
774
|
+
|
|
775
|
+
Then call `AskUserQuestion` with options that adapt based on `linear.enabled`:
|
|
776
|
+
|
|
777
|
+
**If `linear.enabled` is `true`** (3 options):
|
|
778
|
+
- **"Create Linear issues"** — proceed to Step 10
|
|
779
|
+
- **"Skip Linear and proceed"** — skip to Step 11
|
|
780
|
+
- **"Discuss the plan more"** — enter discussion loop
|
|
781
|
+
|
|
782
|
+
**If `linear.enabled` is `false`** (2 options):
|
|
783
|
+
- **"Proceed to implementation"** — skip to Step 11
|
|
784
|
+
- **"Discuss the plan more"** — enter discussion loop
|
|
785
|
+
|
|
786
|
+
**Discussion loop**: If the user picks "Discuss the plan more", address their feedback or questions, then re-present the same options via `AskUserQuestion`. Loop until the user picks a "proceed" or "create" option. This loop is for Q&A only — it does NOT modify plan.md or tasks.md.
|
|
787
|
+
|
|
788
|
+
## Step 10: Linear Sync (Phase 3.5, conditional)
|
|
789
|
+
|
|
790
|
+
Only runs if the user chose "Create Linear issues" in Step 9.
|
|
791
|
+
|
|
792
|
+
Read `plan.md` from the plan directory (`.fractal-planner/plans/<planId>/plan.md`).
|
|
793
|
+
|
|
794
|
+
Spawn the Linear sync agent in the **foreground** (do NOT use `run_in_background`):
|
|
795
|
+
|
|
796
|
+
```
|
|
797
|
+
Task(
|
|
798
|
+
subagent_type: "fp-linear-sync",
|
|
799
|
+
description: "Linear issue sync",
|
|
800
|
+
mode: "acceptEdits",
|
|
801
|
+
prompt: "Create Linear issues for the task tree.
|
|
802
|
+
|
|
803
|
+
The user has already reviewed and approved this plan. Proceed directly to issue creation without an additional preview confirmation.
|
|
804
|
+
|
|
805
|
+
Tasks:
|
|
806
|
+
<paste tasks.md contents>
|
|
807
|
+
|
|
808
|
+
Execution Order:
|
|
809
|
+
<paste plan.md contents>
|
|
810
|
+
|
|
811
|
+
Linear Config:
|
|
812
|
+
- teamId: <linear.teamId from Step 3>
|
|
813
|
+
- projectId: <linear.projectId from Step 3, if set>
|
|
814
|
+
- userId: <linear.userId from Step 3, if set>
|
|
815
|
+
- statusMap: <from config, if set>
|
|
816
|
+
|
|
817
|
+
Plan directory: .fractal-planner/plans/<planId>
|
|
818
|
+
Plan ID: <planId>
|
|
819
|
+
|
|
820
|
+
Write linear-mapping.json to the plan directory."
|
|
821
|
+
)
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
## Step 11: Present Results
|
|
825
|
+
|
|
826
|
+
Read `tasks.md` from the plan directory and present the condensed tree view (same format as Step 9: full parent-child hierarchy with IDs, complexity, and file hints on leaf tasks, plus the summary line). If Step 9 already ran and the tree was shown there, skip re-presenting the tree and just note the plan is ready.
|
|
827
|
+
|
|
828
|
+
After the tree (or the note that it was already shown), always include:
|
|
829
|
+
|
|
830
|
+
```
|
|
831
|
+
## Next Steps
|
|
832
|
+
|
|
833
|
+
To start implementation, clear context and run:
|
|
834
|
+
|
|
835
|
+
/fp:implement <planId>
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
If `planOnly` (from Step 3) is true, note that execution was skipped per config.
|
|
839
|
+
|
|
840
|
+
## Error Handling
|
|
841
|
+
|
|
842
|
+
- If any subagent fails, report the error clearly and suggest next steps
|
|
843
|
+
- If the interview team fails, ensure cleanup: shut down the interviewer and delete the team before reporting the error
|
|
844
|
+
- If the intent classifier or plan generator CLI fails, report the error with the command output
|
|
845
|
+
- If Linear sync fails, log a warning but continue — the plan is still valid without Linear
|
|
846
|
+
|
|
847
|
+
## Important
|
|
848
|
+
|
|
849
|
+
- **ALWAYS** use configuration from Step 3 (pre-injected at skill load time) — config values control complexity thresholds, flow gates, and Linear integration
|
|
850
|
+
- **ALWAYS** run phases in order: interview -> research+context (parallel) -> (approach review) -> decomposition -> (critique) -> planning -> (confirmation gate) -> (linear) -> present results
|
|
851
|
+
- Approach review gate (Step 6.5) fires unless `skipApproachReview === true` — reviews high-level approach before expensive decomposition; distinct from Step 9 which reviews the final task tree
|
|
852
|
+
- **NEVER** skip the interview — even for trivial tasks
|
|
853
|
+
- Pass data between phases via the plan directory files
|
|
854
|
+
- Each agent writes its own artifacts — do not write their files for them
|
|
855
|
+
- Confirmation gate (Step 9) fires for ALL users unless `skipPlanReview === true` in config
|
|
856
|
+
- Step 9 options adapt based on `linear.enabled` — Linear-specific options only shown when Linear is configured
|
|
857
|
+
- Linear sync (Step 10) must run in the **foreground** — never use `run_in_background`
|