agile-context-engineering 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/LICENSE +51 -51
  3. package/README.md +324 -323
  4. package/agents/ace-research-synthesizer.md +228 -228
  5. package/agents/ace-technical-application-architect.md +28 -0
  6. package/agents/ace-wiki-mapper.md +445 -334
  7. package/agile-context-engineering/src/ace-tools.test.js +1089 -1089
  8. package/agile-context-engineering/templates/_command.md +53 -53
  9. package/agile-context-engineering/templates/_workflow.xml +16 -16
  10. package/agile-context-engineering/templates/product/product-backlog.xml +231 -231
  11. package/agile-context-engineering/templates/product/story-integration-solution.xml +1 -0
  12. package/agile-context-engineering/templates/product/story-wiki.xml +4 -0
  13. package/agile-context-engineering/templates/wiki/coding-standards.xml +38 -0
  14. package/agile-context-engineering/templates/wiki/decizions.xml +115 -115
  15. package/agile-context-engineering/templates/wiki/guide.xml +137 -137
  16. package/agile-context-engineering/templates/wiki/module-discovery.xml +174 -174
  17. package/agile-context-engineering/templates/wiki/pattern.xml +159 -159
  18. package/agile-context-engineering/templates/wiki/system-architecture.xml +254 -254
  19. package/agile-context-engineering/templates/wiki/system-cross-cutting.xml +197 -197
  20. package/agile-context-engineering/templates/wiki/system.xml +381 -381
  21. package/agile-context-engineering/templates/wiki/walkthrough.xml +255 -0
  22. package/agile-context-engineering/templates/wiki/wiki-readme.xml +297 -276
  23. package/agile-context-engineering/utils/questioning.xml +110 -110
  24. package/agile-context-engineering/workflows/execute-story.xml +1219 -1145
  25. package/agile-context-engineering/workflows/help.xml +540 -540
  26. package/agile-context-engineering/workflows/init-coding-standards.xml +386 -386
  27. package/agile-context-engineering/workflows/map-story.xml +1046 -797
  28. package/agile-context-engineering/workflows/map-subsystem.xml +2 -1
  29. package/agile-context-engineering/workflows/map-walkthrough.xml +457 -0
  30. package/agile-context-engineering/workflows/plan-feature.xml +1495 -1495
  31. package/agile-context-engineering/workflows/plan-story.xml +36 -1
  32. package/agile-context-engineering/workflows/research-integration-solution.xml +1 -0
  33. package/agile-context-engineering/workflows/research-story-wiki.xml +2 -1
  34. package/agile-context-engineering/workflows/research-technical-solution.xml +1 -0
  35. package/agile-context-engineering/workflows/review-story.xml +281 -281
  36. package/agile-context-engineering/workflows/update.xml +238 -207
  37. package/bin/install.js +8 -0
  38. package/commands/ace/execute-story.md +1 -0
  39. package/commands/ace/help.md +93 -93
  40. package/commands/ace/init-coding-standards.md +83 -83
  41. package/commands/ace/map-story.md +165 -156
  42. package/commands/ace/map-subsystem.md +140 -138
  43. package/commands/ace/map-system.md +92 -92
  44. package/commands/ace/map-walkthrough.md +127 -0
  45. package/commands/ace/plan-feature.md +89 -89
  46. package/commands/ace/plan-story.md +15 -1
  47. package/commands/ace/review-story.md +109 -109
  48. package/commands/ace/update.md +56 -54
  49. package/hooks/ace-check-update.js +62 -62
  50. package/hooks/ace-statusline.js +89 -89
  51. package/package.json +4 -3
@@ -1,1495 +1,1495 @@
1
- <workflow>
2
-
3
- <purpose>
4
- Orchestrate feature planning or refinement: locate a feature in the product backlog,
5
- load foundation context (vision, backlog, architecture), perform targeted wiki and code
6
- research via background sub-agents, conduct deep questioning to define feature scope,
7
- acceptance criteria, and story breakdown, then write the feature specification document.
8
- Optionally syncs with GitHub issues.
9
-
10
- Produces `.ace/artifacts/product/<id-epic_name>/<id-feature_name>/<id-feature_name>.md`
11
- — a complete feature specification with benefit hypothesis, scope, acceptance criteria,
12
- and story descriptions with rough Fibonacci estimates.
13
-
14
- Can be run multiple times on the same feature for refinement. Supports both CREATE
15
- (new feature) and REFINE (existing feature) modes.
16
- </purpose>
17
-
18
- <mandatory-context>
19
- Read all files referenced by the invoking command's execution-context before starting.
20
- Also read any document or text passed as parameter ($ARGUMENTS) in the invoking command.
21
- </mandatory-context>
22
-
23
- <process>
24
-
25
- <!-- ══════════════════════════════════════════════════════════════════ -->
26
- <!-- STEP 1: SETUP -->
27
- <!-- ══════════════════════════════════════════════════════════════════ -->
28
-
29
- <step name="setup" order="1">
30
- **MANDATORY FIRST STEP — Execute environment detection before any user interaction:**
31
-
32
- ```bash
33
- INIT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js init plan-feature)
34
- ```
35
-
36
- Parse JSON for: `product_owner_model`, `researcher_model`, `commit_docs`,
37
- `has_product_vision`, `has_product_backlog`,
38
- `has_wiki_analysis`,
39
- `is_brownfield`, `is_greenfield`,
40
- `has_existing_code`, `has_package_file`, `has_wiki`, `has_wiki_system_wide`,
41
- `has_wiki_subsystems`, `wiki_subsystem_names`, `has_system_architecture`,
42
- `has_system_structure`, `has_testing_framework`, `has_git`, `has_gh_cli`,
43
- `github_project` (object: `enabled`, `gh_installed`, `repo`, `project_number`, `owner`).
44
-
45
- Also resolve the product owner model for spawning agents:
46
- ```bash
47
- PO_MODEL=$(node ~/.claude/agile-context-engineering/src/ace-tools.js resolve-model ace-product-owner --raw)
48
- ```
49
-
50
- Display stage banner:
51
-
52
- ```
53
- ╔══════════════════════════════════════════════════╗
54
- ║ ACE > Plan Feature ║
55
- ╚══════════════════════════════════════════════════╝
56
- ```
57
-
58
- **If `has_git` is false:** Initialize git:
59
- ```bash
60
- git init
61
- ```
62
- </step>
63
-
64
- <!-- ══════════════════════════════════════════════════════════════════ -->
65
- <!-- STEP 2: LOCATE FEATURE -->
66
- <!-- ══════════════════════════════════════════════════════════════════ -->
67
-
68
- <step name="locate-feature" order="2">
69
-
70
- <!-- ── 2a: Check backlog exists ─────────────────────────────────── -->
71
-
72
- **If `has_product_backlog` is false:**
73
-
74
- Display error:
75
- ```
76
- x No product backlog found. Feature planning requires a backlog.
77
- The backlog defines epics and features that drive feature planning.
78
- ```
79
-
80
- Display next action:
81
- ```
82
- ┌──────────────────────────────────────────────────┐
83
- │ Next > /ace:plan-backlog │
84
- │ Create the product backlog first, then │
85
- │ re-run /ace:plan-feature │
86
- └──────────────────────────────────────────────────┘
87
- ```
88
-
89
- Exit workflow.
90
-
91
- <!-- ── 2b: Read backlog and parse features ──────────────────────── -->
92
-
93
- **If `has_product_backlog` is true:**
94
-
95
- Read `.ace/artifacts/product/product-backlog.md`. Parse:
96
- - All epics: extract ID, Title, Status, Milestone, Link
97
- - All features per epic: extract ID, Title, Description, Status, Priority, Size, Sprint, Milestone, Link
98
- - Build a BACKLOG_INDEX: `{ epics: [...], features: [...] }` with parent epic references
99
-
100
- <!-- ── 2c: Resolve target feature ───────────────────────────────── -->
101
-
102
- Check if `$ARGUMENTS` contains a feature identifier (first positional argument before `context=`):
103
- - Could be: `F3`, `#78`, or absent
104
-
105
- **If feature ID is provided:**
106
- - Search BACKLOG_INDEX for matching feature by ID (F[N] or #[N])
107
- - If found: set `TARGET_FEATURE` from backlog data, set `FEATURE_IN_BACKLOG = true`
108
- - If NOT found: set `FEATURE_IN_BACKLOG = false`, set `NEEDS_BACKLOG_ADD = true`,
109
- hold the user-provided ID/name as seed context
110
-
111
- **If feature ID is NOT provided:**
112
-
113
- Present the backlog's feature list for selection:
114
- ```
115
- ┌──────────────────────────────────────────────────┐
116
- │ ACE > Plan Feature > Select Feature │
117
- └──────────────────────────────────────────────────┘
118
- ```
119
-
120
- Display features grouped by epic as a tree:
121
- ```
122
- E1 User Authentication
123
- ├── F1 OAuth2 Login Flow [Todo]
124
- ├── F2 Session Management [Todo]
125
- └── F3 Password Reset [Refined]
126
- E2 Data Export Pipeline
127
- ├── F4 CSV Bulk Export [Todo]
128
- └── F5 Scheduled Exports [Todo]
129
- ```
130
-
131
- Use AskUserQuestion:
132
- - header: "Feature"
133
- - question: "Which feature would you like to plan? Pick from the list, or describe a new feature."
134
- - options: list feature IDs + titles (up to 4), plus "New feature — describe it"
135
-
136
- If user picks an existing feature: set `TARGET_FEATURE`, set `FEATURE_IN_BACKLOG = true`
137
- If user picks "New feature": ask to describe the feature + pick parent epic
138
- (or create under new epic), set `NEEDS_BACKLOG_ADD = true`.
139
- The feature gets a provisional ID (next F[N]) and user-provided title.
140
-
141
- <!-- ── 2d: Resolve directory paths ──────────────────────────────── -->
142
-
143
- Using `TARGET_FEATURE` (or user-described new feature), compute:
144
- ```bash
145
- EPIC_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Epic ID}-{Epic Title}" --raw)
146
- FEATURE_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Feature ID}-{Feature Title}" --raw)
147
- ```
148
-
149
- Set `FEATURE_DIR = .ace/artifacts/product/{EPIC_SLUG}/{FEATURE_SLUG}`
150
- Set `FEATURE_FILE = {FEATURE_DIR}/{FEATURE_SLUG}.md`
151
-
152
- <!-- ── 2e: Check for existing feature file (REFINE mode) ────────── -->
153
-
154
- Check if `FEATURE_FILE` exists:
155
- ```bash
156
- EXISTING_FEATURE=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_FILE} --raw)
157
- ```
158
-
159
- If exists: set `RUN_MODE = REFINE`
160
-
161
- Use AskUserQuestion:
162
- - header: "Feature exists"
163
- - question: "A feature spec already exists at `{FEATURE_FILE}`. What would you like to do?"
164
- - options:
165
- - "Refine it" — Review and update the existing specification
166
- - "Start fresh" — Discard and create a new specification from scratch
167
- - "Skip" — Keep the current specification as-is
168
-
169
- If "Refine it": read the existing file, hold as `EXISTING_FEATURE_DOC`, continue.
170
- If "Start fresh": set `RUN_MODE = CREATE`, set `EXISTING_FEATURE_DOC = null`, continue.
171
- If "Skip": Exit workflow.
172
-
173
- If not exists: set `RUN_MODE = CREATE`, set `EXISTING_FEATURE_DOC = null`
174
-
175
- <!-- ── 2f: Check GitHub for feature issue ───────────────────────── -->
176
-
177
- **If `github_project.enabled` is true AND `github_project.gh_installed` is true:**
178
-
179
- - If TARGET_FEATURE has a GitHub link (#N):
180
- set `GITHUB_FEATURE_ISSUE = true`, store issue number.
181
- Fetch:
182
- ```bash
183
- GH_FEATURE_DATA=$(gh issue view {issue_number} --repo {REPO} --json title,body,labels,state,comments,milestone)
184
- ```
185
- Hold parsed JSON as `GITHUB_FEATURE_DATA`.
186
- Compare with `EXISTING_FEATURE_DOC` (if both exist) — note any differences.
187
-
188
- - If TARGET_FEATURE has no GitHub link:
189
- set `GITHUB_FEATURE_ISSUE = false`, set `NEEDS_GITHUB_CREATE = true`
190
-
191
- **If GitHub not enabled:** set `GITHUB_FEATURE_ISSUE = null`
192
-
193
- **Display (after resolution):**
194
-
195
- For CREATE mode:
196
- ```
197
- i Feature: {Feature ID} — {Feature Title}
198
- Epic: {Epic ID} — {Epic Title}
199
- Mode: New feature specification
200
- Output: {FEATURE_FILE}
201
- ```
202
-
203
- For REFINE mode:
204
- ```
205
- i Feature: {Feature ID} — {Feature Title}
206
- Epic: {Epic ID} — {Epic Title}
207
- Mode: Refinement (#{refinement_count + 1})
208
- Existing: {FEATURE_FILE}
209
- ```
210
- </step>
211
-
212
- <!-- ══════════════════════════════════════════════════════════════════ -->
213
- <!-- STEP 3: LOAD FOUNDATION -->
214
- <!-- ══════════════════════════════════════════════════════════════════ -->
215
-
216
- <step name="load-foundation" order="3">
217
-
218
- **3a. Load product vision (if exists):**
219
-
220
- If `has_product_vision` is true:
221
- - Read `.docs/product/product-vision.md`
222
- - Extract and hold as VISION context: Vision Statement, Target Audience,
223
- High-Level Capabilities, Key Objectives, Constraints
224
-
225
- If false: set `VISION = null` (acceptable — the backlog already encapsulates vision direction)
226
-
227
- **3b. Load product backlog:**
228
-
229
- Already loaded in step 2. Hold the full parsed BACKLOG_INDEX and specifically
230
- the TARGET_FEATURE's parent epic details.
231
-
232
- **3c. Load system architecture (if exists):**
233
-
234
- If `has_system_architecture` is true:
235
- - Read `.docs/wiki/system-wide/system-architecture.md`
236
- - Hold as `SYSTEM_ARCHITECTURE` context
237
-
238
- If false: set `SYSTEM_ARCHITECTURE = null`
239
- </step>
240
-
241
- <!-- ══════════════════════════════════════════════════════════════════ -->
242
- <!-- STEP 4: AGGREGATE EXISTING INFO -->
243
- <!-- ══════════════════════════════════════════════════════════════════ -->
244
-
245
- <step name="aggregate-existing" order="4">
246
-
247
- **4a. Existing feature file:**
248
-
249
- If `RUN_MODE` is REFINE:
250
- - `EXISTING_FEATURE_DOC` already loaded in step 2e
251
- - Parse: Description, Benefit Hypothesis, Scope, Acceptance Criteria,
252
- Story Breakdown, Technical Context, Dependencies, Metadata (refinement count, dates)
253
-
254
- If CREATE: `EXISTING_FEATURE_DOC = null`
255
-
256
- **4b. GitHub issue data (if enabled and linked):**
257
-
258
- If `GITHUB_FEATURE_ISSUE` is true:
259
- - `GITHUB_FEATURE_DATA` already loaded in step 2f
260
- - Compare with `EXISTING_FEATURE_DOC` (if both exist) — note any differences
261
- (e.g., status drift, updated description in GitHub)
262
-
263
- If not applicable: `GITHUB_FEATURE_DATA = null`
264
-
265
- **4c. Optional parameter text/file:**
266
-
267
- If `$ARGUMENTS` contains `context=` parameter:
268
- - If it is a file path: read the file
269
- - If it is inline text: hold as-is
270
- - Hold as `INPUT_CONTEXT`
271
- - Categorize: does it contain acceptance criteria? Story suggestions?
272
- Technical constraints? Scope details?
273
-
274
- If no context parameter: `INPUT_CONTEXT = null`
275
-
276
- Continue to step 5.
277
- </step>
278
-
279
- <!-- ══════════════════════════════════════════════════════════════════ -->
280
- <!-- STEP 5: WIKI RESEARCH (Subagent) -->
281
- <!-- ══════════════════════════════════════════════════════════════════ -->
282
-
283
- <step name="wiki-research" order="5">
284
-
285
- **If `is_greenfield` OR `has_wiki` is false:**
286
-
287
- Set RELEVANT_WIKI = null.
288
- Continue to step 6.
289
-
290
- **If `is_brownfield` AND `has_wiki` is true:**
291
-
292
- <!-- ── 5a: Check for existing research ──────────────────────────── -->
293
-
294
- Check if `{FEATURE_DIR}/relevant-wiki.md` exists:
295
- ```bash
296
- HAS_WIKI_RESEARCH=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_DIR}/relevant-wiki.md --raw)
297
- ```
298
-
299
- If `HAS_WIKI_RESEARCH` is TRUE:
300
- - Use AskUserQuestion:
301
- - header: "Wiki Research"
302
- - question: "Previous wiki analysis exists for this feature (`{FEATURE_DIR}/relevant-wiki.md`). What would you like to do?"
303
- - options:
304
- - "Use existing" — Skip wiki analysis, load the existing file
305
- - "Regenerate" — Re-analyze wiki docs for this feature
306
- - "Skip" — Don't use wiki analysis for this planning session
307
-
308
- - If "Use existing": read `{FEATURE_DIR}/relevant-wiki.md`, hold as RELEVANT_WIKI.
309
- Set `WIKI_FROM_CACHE = true`. Continue to step 6.
310
- - If "Skip": set `RELEVANT_WIKI = null`. Continue to step 6.
311
- - If "Regenerate": proceed to 5b.
312
-
313
- If `HAS_WIKI_RESEARCH` is FALSE: proceed to 5b.
314
-
315
- <!-- ── 5b: Spawn wiki research subagent ─────────────────────────── -->
316
-
317
- Create the target directory:
318
- ```bash
319
- mkdir -p {FEATURE_DIR}
320
- ```
321
-
322
- Display:
323
- ```
324
- ┌──────────────────────────────────────────────────┐
325
- │ ACE > Plan Feature > Wiki Research │
326
- └──────────────────────────────────────────────────┘
327
-
328
- i Analyzing wiki documentation relevant to feature:
329
- {Feature ID} — {Feature Title}
330
- Writing to: {FEATURE_DIR}/relevant-wiki.md
331
- ```
332
-
333
- **CRITICAL — Context Window Protection:**
334
- The `ace-product-owner` agent has a built-in `<structured-returns>` protocol:
335
- when spawned as a background agent, it writes to disk and returns ONLY a ~10-line
336
- confirmation (file path + line count). This prevents agent output from inflating
337
- the main context window.
338
-
339
- **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
340
- After spawning the background agent, do NOT call TaskOutput to read its results.
341
- You will be automatically notified when the agent completes — IGNORE those notifications.
342
- The agent writes to `{FEATURE_DIR}/relevant-wiki.md` on disk. You do not need the return message.
343
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
344
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
345
- After the notification arrives, verify the file with `wc -l {FEATURE_DIR}/relevant-wiki.md`,
346
- then READ the file directly from disk using the Read tool. That is how you get the results.
347
-
348
- Task tool parameters:
349
- ```
350
- subagent_type: "ace-product-owner"
351
- model: "{PO_MODEL}"
352
- run_in_background: true
353
- description: "Wiki research for {Feature ID}"
354
- ```
355
-
356
- Prompt:
357
- ```
358
- You are analyzing wiki documentation to extract information relevant to a specific feature.
359
-
360
- **Feature context:**
361
- - Feature: {Feature ID} — {Feature Title}
362
- - Epic: {Epic ID} — {Epic Title}
363
- - Feature description (from backlog): {TARGET_FEATURE.description}
364
-
365
- **Step 1 — Read the system-level wiki analysis first:**
366
- Read `.ace/artifacts/wiki/wiki-analysis.md` if it exists.
367
- This gives you the map of what subsystems exist and their responsibilities.
368
-
369
- **Step 2 — Identify relevant subsystems:**
370
- Based on the feature's scope, identify which subsystems from the wiki are relevant.
371
-
372
- **Step 3 — Deep-read relevant wiki docs:**
373
- For each relevant subsystem, read:
374
- - .docs/wiki/subsystems/{subsystem_name}/architecture.md
375
- - .docs/wiki/subsystems/{subsystem_name}/structure.md
376
-
377
- Also read system-wide docs if relevant:
378
- - .docs/wiki/system-wide/system-architecture.md
379
- - .docs/wiki/system-wide/system-structure.md
380
-
381
- **Step 4 — Write structured analysis to `{FEATURE_DIR}/relevant-wiki.md`:**
382
-
383
- # Wiki Analysis: {Feature ID} — {Feature Title}
384
-
385
- ## Relevant Subsystems
386
- - [Subsystem]: [Why relevant to this feature]
387
-
388
- ## Existing Capabilities
389
- - [What already exists that this feature builds on or interacts with]
390
-
391
- ## Architecture Patterns
392
- - [Relevant patterns from wiki that affect this feature's design]
393
-
394
- ## Data Flows
395
- - [Relevant data ownership and flows]
396
-
397
- ## Integration Points
398
- - [Where this feature connects to existing subsystems]
399
-
400
- ## Constraints
401
- - [Architectural constraints from existing system that affect this feature]
402
-
403
- ## Gaps
404
- - [What the wiki doesn't cover that this feature will need]
405
-
406
- IMPORTANT: Write to `{FEATURE_DIR}/relevant-wiki.md` using the Write tool.
407
-
408
- **WRITE TO FILE DIRECTLY. RETURN ONLY CONFIRMATION.**
409
- Your response must be ~10 lines max. Just confirm what was written and the line count.
410
- Do NOT return file contents in your response.
411
- ```
412
-
413
- **After background notification arrives — IGNORE it:**
414
-
415
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
416
- Just verify the file and read it directly from disk:
417
- ```bash
418
- wc -l {FEATURE_DIR}/relevant-wiki.md
419
- ```
420
-
421
- Read `{FEATURE_DIR}/relevant-wiki.md` using the Read tool, hold as `RELEVANT_WIKI`.
422
- Set `WIKI_FROM_CACHE = false`.
423
-
424
- Continue to step 6.
425
- </step>
426
-
427
- <!-- ══════════════════════════════════════════════════════════════════ -->
428
- <!-- STEP 6: CODE RESEARCH (Subagent) -->
429
- <!-- ══════════════════════════════════════════════════════════════════ -->
430
-
431
- <step name="code-research" order="6">
432
-
433
- **If `is_greenfield`:**
434
-
435
- Set RELEVANT_CODE = null.
436
- Continue to step 7.
437
-
438
- **If `is_brownfield`:**
439
-
440
- **Parallelism rule:** If wiki research was served from cache (`WIKI_FROM_CACHE = true`
441
- in step 5a), code research can start immediately — the `relevant-wiki.md` file is
442
- already on disk. If wiki research had to regenerate (step 5b with a background agent),
443
- code research waits for that background agent to complete first before spawning.
444
-
445
- <!-- ── 6a: Check for existing code research ─────────────────────── -->
446
-
447
- Check if `{FEATURE_DIR}/relevant-code.md` exists:
448
- ```bash
449
- HAS_CODE_RESEARCH=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_DIR}/relevant-code.md --raw)
450
- ```
451
-
452
- If `HAS_CODE_RESEARCH` is TRUE:
453
- - Use AskUserQuestion:
454
- - header: "Code Research"
455
- - question: "Previous code analysis exists for this feature (`{FEATURE_DIR}/relevant-code.md`). What would you like to do?"
456
- - options:
457
- - "Use existing" — Skip code analysis, load the existing file
458
- - "Regenerate" — Re-analyze codebase for this feature
459
- - "Skip" — Don't use code analysis for this planning session
460
-
461
- - If "Use existing": read the file, hold as `RELEVANT_CODE`. Continue to step 7.
462
- - If "Skip": set `RELEVANT_CODE = null`. Continue to step 7.
463
- - If "Regenerate": proceed to 6b.
464
-
465
- If `HAS_CODE_RESEARCH` is FALSE: proceed to 6b.
466
-
467
- <!-- ── 6b: Spawn code research subagent ─────────────────────────── -->
468
-
469
- Display:
470
- ```
471
- ┌──────────────────────────────────────────────────┐
472
- │ ACE > Plan Feature > Code Research │
473
- └──────────────────────────────────────────────────┘
474
-
475
- i Analyzing codebase for existing implementation
476
- relevant to feature: {Feature ID} — {Feature Title}
477
- Writing to: {FEATURE_DIR}/relevant-code.md
478
- ```
479
-
480
- **CRITICAL — Context Window Protection:**
481
- The agent writes to disk and returns ONLY a ~10-line confirmation.
482
- This prevents agent output from inflating the main context window.
483
-
484
- **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
485
- After spawning the background agent, do NOT call TaskOutput to read its results.
486
- You will be automatically notified when the agent completes — IGNORE those notifications.
487
- The agent writes to `{FEATURE_DIR}/relevant-code.md` on disk. You do not need the return message.
488
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
489
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
490
- After the notification arrives, verify the file with `wc -l {FEATURE_DIR}/relevant-code.md`,
491
- then READ the file directly from disk using the Read tool. That is how you get the results.
492
-
493
- Resolve the researcher model:
494
- ```bash
495
- RESEARCHER_MODEL=$(node ~/.claude/agile-context-engineering/src/ace-tools.js resolve-model ace-project-researcher --raw)
496
- ```
497
-
498
- Task tool parameters:
499
- ```
500
- subagent_type: "general-purpose"
501
- model: "{RESEARCHER_MODEL}"
502
- run_in_background: true
503
- description: "Code research for {Feature ID}"
504
- ```
505
-
506
- Prompt:
507
- ```
508
- First, read ~/.claude/agents/ace-project-researcher.md for your role and instructions.
509
-
510
- **Feature context:**
511
- - Feature: {Feature ID} — {Feature Title}
512
- - Epic: {Epic ID} — {Epic Title}
513
- - Feature description (from backlog): {TARGET_FEATURE.description}
514
-
515
- **Read these context files (if they exist):**
516
- - {FEATURE_DIR}/relevant-wiki.md (wiki analysis for this feature)
517
- - .docs/wiki/system-wide/system-architecture.md (system architecture)
518
-
519
- **Your job:** Drill into the actual codebase to discover what is already implemented
520
- that relates to this feature. Focus on:
521
-
522
- 1. **Existing Components & Modules** — What code already exists that this feature
523
- will build on, extend, or integrate with?
524
- 2. **APIs & Interfaces** — Existing endpoints, function signatures, data contracts
525
- 3. **Partial Implementations** — Code that partially addresses this feature's scope
526
- 4. **System Boundaries** — Where this feature sits in the overall architecture
527
- 5. **Integration Points** — APIs, events, data flows this feature connects to
528
- 6. **Cross-Cutting Concerns** — Security, logging, error handling patterns in use
529
- 7. **Non-Functional Patterns** — Performance patterns, caching, rate limiting in use
530
-
531
- **Write structured analysis to `{FEATURE_DIR}/relevant-code.md`:**
532
-
533
- # Code Analysis: {Feature ID} — {Feature Title}
534
-
535
- ## Existing Components
536
- - [Component/module path — what it does, relevance to this feature]
537
-
538
- ## APIs & Interfaces
539
- - [Endpoint/interface — current capability, what this feature extends]
540
-
541
- ## Partial Implementations
542
- - [What's partially built — what remains]
543
-
544
- ## System Boundaries
545
- - [Where this feature sits in the architecture]
546
-
547
- ## Integration Points
548
- - [How this feature connects to existing code]
549
-
550
- ## Cross-Cutting Concerns
551
- - [Security, observability, error handling patterns to follow]
552
-
553
- ## Non-Functional Patterns
554
- - [Performance, caching, scalability patterns in use]
555
-
556
- ## Architectural Constraints
557
- - [Constraints that affect this feature's design]
558
-
559
- Write to `{FEATURE_DIR}/relevant-code.md` using the Write tool.
560
-
561
- **WRITE TO FILE DIRECTLY. RETURN ONLY CONFIRMATION.**
562
- Your response must be ~10 lines max. Just confirm what was written and the line count.
563
- Do NOT return file contents or analysis results in your response.
564
- ```
565
-
566
- **After background notification arrives — IGNORE it:**
567
-
568
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
569
- Just verify the file and read it directly from disk:
570
- ```bash
571
- wc -l {FEATURE_DIR}/relevant-code.md
572
- ```
573
-
574
- Read `{FEATURE_DIR}/relevant-code.md` using the Read tool, hold as `RELEVANT_CODE`.
575
-
576
- Continue to step 7.
577
- </step>
578
-
579
- <!-- ══════════════════════════════════════════════════════════════════ -->
580
- <!-- STEP 7: LOAD RESEARCH RESULTS -->
581
- <!-- ══════════════════════════════════════════════════════════════════ -->
582
-
583
- <step name="load-research" order="7">
584
-
585
- Build `CONTEXT_INVENTORY` by loading all available context:
586
-
587
- 1. `VISION` — product vision (from step 3, if available)
588
- 2. `BACKLOG_INDEX` — product backlog with all epics/features (from step 2/3)
589
- 3. `SYSTEM_ARCHITECTURE` — system architecture doc (from step 3, if available)
590
- 4. `RELEVANT_WIKI` — wiki analysis for this feature (from step 5, if available)
591
- 5. `RELEVANT_CODE` — code analysis for this feature (from step 6, if available)
592
- 6. `INPUT_CONTEXT` — user-provided context text/file (from step 4, if available)
593
- 7. `EXISTING_FEATURE_DOC` — existing feature file contents (from step 4, if REFINE mode)
594
- 8. `GITHUB_FEATURE_DATA` — GitHub issue data (from step 2f, if different from file)
595
-
596
- Compute `CONTEXT_RICHNESS`:
597
- - **RICH**: RELEVANT_WIKI is set OR RELEVANT_CODE is set (brownfield with research)
598
- - **MODERATE**: VISION is set AND (BACKLOG has detailed descriptions)
599
- - **LEAN**: Only INPUT_CONTEXT available beyond the backlog entry
600
- - **BARE**: Only the backlog's 1-2 sentence description
601
-
602
- Display loaded context summary:
603
- ```
604
- i Context loaded for questioning:
605
- [+] Product vision
606
- [+] Product backlog (parent epic context)
607
- [+] System architecture
608
- [+] Wiki analysis (127 lines)
609
- [+] Code analysis (89 lines)
610
- [ ] User-provided context (none)
611
- [+] Existing feature doc (refinement mode)
612
- ```
613
-
614
- Continue to step 8.
615
- </step>
616
-
617
- <!-- ══════════════════════════════════════════════════════════════════ -->
618
- <!-- STEP 8: DEEP QUESTIONING -->
619
- <!-- ══════════════════════════════════════════════════════════════════ -->
620
-
621
- <step name="deep-questioning" order="8">
622
- Follow the questioning guide from `questioning.xml`. You are a thinking partner,
623
- not an interviewer.
624
-
625
- Display:
626
- ```
627
- ┌──────────────────────────────────────────────────┐
628
- │ ACE > Plan Feature > Questioning │
629
- └──────────────────────────────────────────────────┘
630
- ```
631
-
632
- <!-- ── 8a: Mode-adapted opening ─────────────────────────────────── -->
633
-
634
- **If RUN_MODE is REFINE:**
635
-
636
- Read EXISTING_FEATURE_DOC and present current state:
637
- ```
638
- i Refinement mode — existing feature specification found.
639
- Stories: {N} | Size: {size} | Status: {status}
640
- Last refined: {date} | Refinements: {count}
641
- ```
642
-
643
- Use AskUserQuestion:
644
- - header: "Refinement"
645
- - question: "What would you like to refine about this feature?"
646
- - options:
647
- - "Update scope" — Add or remove items from scope
648
- - "Revise stories" — Change story breakdown
649
- - "Update acceptance criteria" — Revise success conditions
650
- - "Full review" — Walk through the entire feature specification
651
-
652
- Proceed to questioning with the relevant focus area.
653
-
654
- **If RUN_MODE is CREATE:**
655
-
656
- Adapt opening based on `CONTEXT_RICHNESS`:
657
-
658
- If **RICH** (wiki + code research available):
659
- - "Based on my analysis of your codebase and documentation, here's what I
660
- understand about {Feature Title}..."
661
- - Present synthesis: what already exists, what needs to be built, where it
662
- fits in the architecture
663
- - "The backlog says: '{TARGET_FEATURE.description}'. Based on the code analysis,
664
- here's what's already implemented and what remains..."
665
- - Probe: "Does this match your understanding? What am I missing?"
666
-
667
- If **MODERATE** (vision + backlog context):
668
- - "Your backlog describes this feature as: '{TARGET_FEATURE.description}'.
669
- It sits under the {Epic Title} epic with priority {priority}."
670
- - "Let's make this concrete. Walk me through what a user actually does when
671
- this feature is working."
672
-
673
- If **LEAN** (only INPUT_CONTEXT or backlog entry):
674
- - "I have the backlog entry and your context. Let me make sure I understand
675
- the full picture."
676
- - Probe the most important unknowns first.
677
-
678
- If **BARE** (just a backlog entry name):
679
- - "The backlog lists this as '{Feature Title}' under {Epic Title}. Tell me
680
- more — what does this feature actually deliver?"
681
-
682
- <!-- ── 8b: Template-field questioning ────────────────────────────── -->
683
-
684
- **Map answers to feature.xml template structure (background, not out loud).**
685
-
686
- As you question, mentally track coverage against feature.xml template fields:
687
- - [ ] **Description** — What this feature delivers end-to-end (2-4 sentences, vertical slice)
688
- - [ ] **Benefit Hypothesis** — SAFe format: "We believe [outcome] will be achieved
689
- if [users] successfully [action] with [feature]."
690
- - Challenge vagueness: outcome must be measurable and falsifiable
691
- - If user says "users will like it" — probe: "How will you measure that? What changes?"
692
- - Bad: "Users will like the new login." (not measurable)
693
- - Good: "We believe a 25% reduction in login support tickets will be achieved
694
- if returning customers successfully authenticate via social providers
695
- with the OAuth2 Login feature."
696
- - [ ] **Scope: Includes** — Exhaustive list of capabilities in scope
697
- - [ ] **Scope: Out of Scope** — Things someone might reasonably assume are included but are NOT
698
- - [ ] **Acceptance Criteria** — 3-7 high-level, measurable conditions (NOT Gherkin scenarios)
699
- - These validate the benefit hypothesis, not implementation details
700
- - Each must be independently verifiable
701
- - [ ] **Existing Implementation** (brownfield only) — Seeded from RELEVANT_CODE
702
- - Confirm with user: "Based on the code analysis, these components exist: [list]. Correct?"
703
- - [ ] **Technical Context** — System boundaries, integration points, cross-cutting concerns, NFRs
704
- - Seeded from RELEVANT_WIKI and RELEVANT_CODE
705
- - [ ] **Dependencies** — Requires, Enables, External
706
- - [ ] **Story Breakdown** — stories as many as naturally emerge (see 8c)
707
-
708
- Don't walk through this as a checklist. Weave questions naturally based on
709
- the conversation. If gaps remain after the conversation feels complete, probe
710
- those specific areas.
711
-
712
- <!-- ── 8c: Story breakdown questioning ──────────────────────────── -->
713
-
714
- Once feature scope is clear:
715
-
716
- Display:
717
- ```
718
- i Feature scope is taking shape. Let's break it into stories.
719
- Each story must be a VERTICAL SLICE delivering real user-facing value.
720
- ```
721
-
722
- **VERTICAL SLICE RULE — This is non-negotiable:**
723
-
724
- Every story MUST cut through the architectural layers needed to deliver a
725
- complete, user-facing capability. In most cases this means both backend AND
726
- frontend work in the same story. A user should be able to USE the functionality
727
- when the story is done — not just see a database schema, or just see a UI
728
- with no backend, or just an API with no way to reach it.
729
-
730
- **Anti-patterns — NEVER do these:**
731
- - "Set up the database schema" — horizontal, not a story
732
- - "Create the API endpoints" — horizontal, not a story
733
- - "Build the UI components" — horizontal, not a story
734
- - "Add validation" — cross-cutting concern, fold into the story that needs it
735
- - "Add error handling" — fold into the story where errors occur
736
- - "Write tests" — testing is part of every story's Definition of Done, not a separate story
737
- - Splitting backend and frontend of the SAME functionality into separate stories
738
-
739
- **Good vertical slices:**
740
- - "User can log in with Google" — touches auth config, backend OAuth flow, UI login button, session handling
741
- - "User can export their data as CSV" — touches export logic, file generation, download UI
742
- - "Admin can disable a user account" — touches admin UI, API, domain logic, notifications
743
-
744
- **Story sizing guidance:**
745
-
746
- AIM for 8sp and 5sp stories. These are the sweet spot — large enough to deliver
747
- meaningful vertical slices, small enough to complete in a sprint.
748
-
749
- - **8sp** — The default target. A solid vertical slice with real depth.
750
- - **5sp** — Good for slightly smaller slices that still deliver end-to-end value.
751
- - **3sp** — Acceptable occasionally for genuinely small but still vertical slices.
752
- - **2sp** — Rare. Only when the slice is truly thin but still cuts through layers.
753
- - **1sp** — Almost never. Only for trivial configuration or copy changes.
754
-
755
- If most stories in your breakdown are 2-3sp, you have OVER-DECOMPOSED.
756
- Merge related small stories into fewer, meatier vertical slices.
757
-
758
- **Approach for eliciting good stories:**
759
-
760
- 1. Start from the user journey: "Walk me through the happy path.
761
- What's the first thing the user does? What happens next?"
762
-
763
- 2. Identify natural cut points where a user gets a COMPLETE new capability.
764
- Each story = one thing the user can DO that they couldn't before.
765
-
766
- 3. If brownfield, use RELEVANT_CODE to inform decomposition:
767
- "The code analysis shows {component} already handles {partial capability}.
768
- That suggests we can scope a story around extending it to do {new thing}."
769
-
770
- 4. Present a draft story list when you have enough context:
771
- ```
772
- Here's how I'd break this down:
773
-
774
- S1: [Title] — [1-sentence scope] (8sp)
775
- S2: [Title] — [1-sentence scope] (5sp)
776
- S3: [Title] — [1-sentence scope] (8sp)
777
- ...
778
-
779
- Each story is a vertical slice — the user gets a complete capability when it's done.
780
- ```
781
-
782
- 5. **Sanity check before presenting:** Review your story list:
783
- - Are most stories 5sp or 8sp? If not, merge the small ones.
784
- - Does every story deliver something user-facing? If not, fold it into one that does.
785
- - Could a non-technical stakeholder understand what each story delivers? If not, reframe.
786
-
787
- 6. Use AskUserQuestion:
788
- - header: "Stories"
789
- - question: "Here's the story breakdown. What would you like to adjust?"
790
- - options:
791
- - "Looks good" — Stories are well-scoped
792
- - "Split a story" — One of these is too big
793
- - "Merge stories" — Some of these should be combined
794
- - "Add a story" — Something is missing
795
-
796
- 7. For each story, confirm or discuss:
797
- - Title (short descriptive name)
798
- - Scope description (rich, multi-paragraph plain text — NOT a formal user story.
799
- The `plan-story` command handles formal specification later.)
800
- - Key behaviors and edge cases to consider
801
- - Relationship to other stories in the feature
802
- - **Rough Fibonacci estimate** (1, 2, 3, 5, 8) — aim for 8sp and 5sp.
803
- `plan-story` can refine later after detailed specification.
804
-
805
- 8. Validate coverage: "Do these {N} stories cover 100% of the feature scope?
806
- The includes list is: [list scope items]. Every item should map to at least one story."
807
-
808
- <!-- ── 8d: Decision gate ────────────────────────────────────────── -->
809
-
810
- When the feature specification feels complete:
811
-
812
- Use AskUserQuestion:
813
- - header: "Ready?"
814
- - question: "I have the full feature spec: {description summary}, {N} acceptance criteria, {M} stories. Ready to write the feature document?"
815
- - options:
816
- - "Write feature document" — Let's create it
817
- - "Keep exploring" — I want to add more or adjust
818
- - "Show me what you have" — Summary before deciding
819
-
820
- If "Show me what you have":
821
- - Display a structured summary:
822
- ```
823
- Feature: {ID} — {Title}
824
- Epic: {Epic ID} — {Epic Title}
825
- Size: {size} | Priority: {priority} | Milestone: {milestone}
826
-
827
- Description: {2-4 sentence description}
828
-
829
- Benefit Hypothesis:
830
- > We believe {outcome} if {users} {action} with {feature}.
831
-
832
- Acceptance Criteria: {count}
833
- Stories: {count}
834
- | ID | Title | Size |
835
- |----|-------------------|------|
836
- | S1 | {story title} | {est}|
837
- | S2 | {story title} | {est}|
838
- ...
839
- ```
840
- - Return to decision gate.
841
-
842
- If "Keep exploring" — ask what they want to add, or identify gaps and probe naturally.
843
-
844
- Loop until "Write feature document" selected.
845
- </step>
846
-
847
- <!-- ══════════════════════════════════════════════════════════════════ -->
848
- <!-- STEP 9: WRITE FEATURE DOCUMENT -->
849
- <!-- ══════════════════════════════════════════════════════════════════ -->
850
-
851
- <step name="write-feature" order="9">
852
-
853
- Display:
854
- ```
855
- ┌──────────────────────────────────────────────────┐
856
- │ ACE > Plan Feature > Writing Document │
857
- └──────────────────────────────────────────────────┘
858
-
859
- i Spawning product owner agent to write feature
860
- specification...
861
- Output: {FEATURE_FILE}
862
- ```
863
-
864
- Create directory structure:
865
- ```bash
866
- mkdir -p {FEATURE_DIR}
867
- ```
868
-
869
- Prepare a context brief (800 words max) that distills all questioning results:
870
- - Feature header fields: ID, Title, Epic reference, Status, Priority, Size (Fibonacci x10),
871
- Sprint, Milestone, Link
872
- - Complete Description (2-4 sentences)
873
- - Benefit Hypothesis (SAFe format)
874
- - Scope: Includes + Out of Scope
875
- - Acceptance Criteria (3-7 items)
876
- - Existing Implementation (brownfield only — from RELEVANT_CODE, confirmed by user)
877
- - Story Breakdown: index table with rough Fibonacci estimates + rich descriptions for each story
878
- - Technical Context: System Boundaries, Integration Points, Cross-Cutting Concerns, NFRs
879
- - Dependencies: Requires, Enables, External
880
- - Metadata: current date, refinement count
881
- - Research artifact paths for metadata section
882
-
883
- <!-- ── 9a: CREATE mode — write new feature ──────────────────────── -->
884
-
885
- **If RUN_MODE is CREATE:**
886
-
887
- Spawn the feature-writing agent:
888
-
889
- ```
890
- Task(
891
- prompt="You are an Agile Product Owner writing a feature specification document.
892
-
893
- **Context brief from questioning session:**
894
- {paste the context brief here}
895
-
896
- **Instructions:**
897
- 1. Read the feature template: ~/.claude/agile-context-engineering/templates/product/feature.xml
898
- 2. Write `{FEATURE_FILE}` following the template structure exactly
899
- 3. Include ALL sections: Header, Description, Benefit Hypothesis, Scope,
900
- Acceptance Criteria, [Existing Implementation if brownfield],
901
- Story Breakdown (index + detail per story), Technical Context,
902
- Dependencies, Metadata
903
- 4. Story descriptions must be RICH and detailed — multiple paragraphs. Cover:
904
- scope, user-facing behavior, value, key behaviors, edge cases, constraints,
905
- relationships to other stories.
906
- These are NOT formal user stories — they are thorough descriptions of intent
907
- and scope. The `plan-story` command handles formal specification later.
908
- 5. Story index table:
909
- - ID = S[N], sequential within this feature
910
- - Size = rough Fibonacci estimate (1, 2, 3, 5, 8) from the questioning session
911
- - Status = Todo
912
- - Sprint = —
913
- - Link = —
914
- 6. Follow all field definitions from the template:
915
- - Feature Status: Refined (stories well-defined) or Todo (if still rough)
916
- - Feature Size: Fibonacci x10 values only (10, 20, 30, 50, 80)
917
- - Priority: Critical | High | Medium | Low
918
- 7. Benefit Hypothesis MUST follow SAFe format exactly:
919
- 'We believe [outcome] will be achieved if [users] successfully [action] with [feature].'
920
- The outcome must be measurable and falsifiable.
921
- 8. Acceptance Criteria are HIGH-LEVEL business validation — NOT Gherkin scenarios.
922
- 3-7 criteria, each independently verifiable.
923
- 9. Table formatting (CRITICAL): pad ALL cells with spaces so | separators align
924
- vertically across all rows. Follow the table-formatting guideline from the
925
- template for minimum column widths.
926
- 10. GitHub identity: use #[issue_number] for GitHub-linked items, S[N] for local stories
927
- 11. Metadata: Created={today}, Last refined={today}, Refinements=1
928
- Research artifacts: include paths to relevant-wiki.md and relevant-code.md if they exist,
929
- otherwise use '—'
930
-
931
- Write the file using the Write tool.
932
-
933
- **Return format — ONLY this, nothing else:**
934
- DONE
935
- - Feature: {ID} — {Title}
936
- - Stories: {count}
937
- - Acceptance criteria: {count}
938
- - File: {FEATURE_FILE}
939
- - Lines: {line count}",
940
- subagent_type="ace-product-owner",
941
- model="{PO_MODEL}",
942
- description="Write feature specification"
943
- )
944
- ```
945
-
946
- <!-- ── 9b: REFINE mode — update existing feature ────────────────── -->
947
-
948
- **If RUN_MODE is REFINE:**
949
-
950
- Prepare a change brief describing exactly what changed during questioning:
951
- - **Additions:** new scope items, new stories (with all details), new acceptance criteria
952
- - New Story IDs continue from the highest existing S[N] in the feature
953
- - **Removals:** items to delete (by ID or description)
954
- - **Modifications:** changed descriptions, updated scope, revised hypothesis, resized stories
955
- - **Unchanged:** items to preserve as-is
956
-
957
- Spawn the feature-editing agent:
958
-
959
- ```
960
- Task(
961
- prompt="You are an Agile Product Owner updating an existing feature specification.
962
-
963
- **Read the current feature:** `{FEATURE_FILE}`
964
- **Read the template for reference:** `~/.claude/agile-context-engineering/templates/product/feature.xml`
965
-
966
- **Changes to apply:**
967
- {paste the change brief here}
968
-
969
- **Rules:**
970
- - PRESERVE existing story IDs (S[N] or #[N]) — never renumber after assignment
971
- - Update the story index table to reflect any additions, removals, or changes
972
- - Increment metadata refinement count
973
- - Update 'Last refined' date to today
974
- - Maintain all template formatting — especially table column alignment:
975
- pad cells with spaces so | separators align vertically across all rows
976
- - If adding new stories, use next available S[N]
977
- - Story sizes: keep existing estimates unless explicitly changed, use Fibonacci (1,2,3,5,8)
978
- - Do NOT change stories or sections that aren't in the change brief
979
- - Benefit Hypothesis must follow SAFe format
980
- - Acceptance criteria are feature-level, NOT Gherkin
981
-
982
- Use Edit or Write tool as appropriate. If changes are extensive (new stories added,
983
- major scope revision), use the Write tool to rewrite the file completely.
984
-
985
- **Return format — ONLY this, nothing else:**
986
- DONE
987
- - Feature: {ID} — {Title}
988
- - Stories: {count} (added: {N}, removed: {N}, unchanged: {N})
989
- - Refinements: {new count}
990
- - File: {FEATURE_FILE}",
991
- subagent_type="ace-product-owner",
992
- model="{PO_MODEL}",
993
- description="Update feature specification"
994
- )
995
- ```
996
-
997
- <!-- ── 9c: Create individual story files ────────────────────────── -->
998
-
999
- **After the feature document is written (both CREATE and REFINE modes):**
1000
-
1001
- For each story in the feature's story breakdown, create a stub story file at:
1002
- `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1003
-
1004
- Each story gets its own subdirectory within the feature directory.
1005
-
1006
- Compute story slugs:
1007
- ```bash
1008
- STORY_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Story ID}-{Story Title}" --raw)
1009
- ```
1010
-
1011
- For each story, check if the file already exists:
1012
- - If exists: **do NOT overwrite** — it may have been refined by `plan-story` already.
1013
- Skip silently.
1014
- - If not exists: create a stub file seeded from the story description in the feature doc.
1015
-
1016
- Spawn a Task agent to create all missing story files:
1017
-
1018
- ```
1019
- Task(
1020
- prompt="You are creating stub story files for a feature.
1021
-
1022
- **Read the feature document:** `{FEATURE_FILE}`
1023
-
1024
- **For each story in the Story Breakdown section, create a stub file IF it does not already exist.**
1025
-
1026
- File path pattern: `{FEATURE_DIR}/{story_slug}/{story_slug}.md`
1027
- where story_slug = generate-slug of '{Story ID}-{Story Title}'
1028
- (use Bash: `node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug '{Story ID}-{Story Title}' --raw`)
1029
-
1030
- Each story gets its own subdirectory. Create the directory with `mkdir -p` before writing.
1031
-
1032
- **Before writing each file, check if it exists.** If it exists, skip it — do NOT overwrite.
1033
- Existing files may have been formally refined by plan-story.
1034
-
1035
- **Stub file content for each new story:**
1036
-
1037
- # {Story ID}: {Story Title}
1038
-
1039
- **Feature**: {Feature ID} {Feature Title} | **Status**: Todo | **Size**: {estimate}
1040
-
1041
- ## Description
1042
-
1043
- {Copy the rich plain-text description from the feature document's story detail section verbatim.}
1044
-
1045
- ---
1046
- *Stub created by plan-feature. Run `/ace:plan-story {Story ID}` for formal specification with INVEST criteria and Gherkin acceptance scenarios.*
1047
-
1048
- **Return format — ONLY this, nothing else:**
1049
- DONE
1050
- - Created: {N} story files
1051
- - Skipped: {M} (already exist)
1052
- - Directory: {FEATURE_DIR}",
1053
- subagent_type="general-purpose",
1054
- model="{PO_MODEL}",
1055
- description="Create story stub files"
1056
- )
1057
- ```
1058
-
1059
- Display:
1060
- ```
1061
- + Created {N} story stub files in {FEATURE_DIR}/
1062
- [If skipped: Skipped {M} existing story files (already refined)]
1063
- ```
1064
- </step>
1065
-
1066
- <!-- ══════════════════════════════════════════════════════════════════ -->
1067
- <!-- STEP 10: UPDATE BACKLOG -->
1068
- <!-- ══════════════════════════════════════════════════════════════════ -->
1069
-
1070
- <step name="update-backlog" order="10">
1071
-
1072
- <!-- ── 10a: New feature — add to backlog ────────────────────────── -->
1073
-
1074
- **If `NEEDS_BACKLOG_ADD` is true (new feature not in backlog):**
1075
-
1076
- Spawn a Task agent to add the feature to the backlog:
1077
- ```
1078
- Task(
1079
- prompt="Read `.ace/artifacts/product/product-backlog.md` and add a new feature
1080
- to the {Epic Title} epic's feature table:
1081
-
1082
- - ID: {new F[N] — next sequential from highest existing F[N]}
1083
- - Title: {Feature Title}
1084
- - Description: {1-2 sentence description}
1085
- - Status: Refined
1086
- - Priority: {priority}
1087
- - Size: {size}
1088
- - Sprint: —
1089
- - Milestone: {milestone}
1090
- - Link: —
1091
-
1092
- Rules:
1093
- - Feature ID continues from highest existing F[N] in the entire backlog
1094
- - Insert in the correct epic's detail section, ordered by delivery sequence
1095
- - Update the Epic Index table if needed (aggregate status change)
1096
- - Maintain table formatting — pad ALL cells so | separators align vertically
1097
- - Read template for reference: ~/.claude/agile-context-engineering/templates/product/product-backlog.xml
1098
-
1099
- Use Edit tool to modify in place. Return only a confirmation of what changed.",
1100
- subagent_type="ace-product-owner",
1101
- model="{PO_MODEL}",
1102
- description="Add feature to backlog"
1103
- )
1104
- ```
1105
-
1106
- Display:
1107
- ```
1108
- + Added {Feature ID} — {Feature Title} to product backlog.
1109
- ```
1110
-
1111
- <!-- ── 10b: Existing feature — update status ────────────────────── -->
1112
-
1113
- **If `FEATURE_IN_BACKLOG` is true (feature already existed):**
1114
-
1115
- Spawn a Task agent to update the feature's status and any changed fields:
1116
- ```
1117
- Task(
1118
- prompt="Read `.ace/artifacts/product/product-backlog.md` and update feature {Feature ID}:
1119
- - Status: Refined
1120
- {any other field changes from the planning session — size, priority, etc.}
1121
-
1122
- Rules:
1123
- - Maintain table formatting — pad ALL cells so | separators align vertically
1124
- - Update Epic aggregate status if needed
1125
- - Do NOT change other items
1126
-
1127
- Use Edit tool to modify in place. Return only a confirmation of what changed.",
1128
- subagent_type="general-purpose",
1129
- model="{PO_MODEL}",
1130
- description="Update feature status in backlog"
1131
- )
1132
- ```
1133
-
1134
- Display:
1135
- ```
1136
- ~ Updated {Feature ID} status to Refined in product backlog.
1137
- ```
1138
- </step>
1139
-
1140
- <!-- ══════════════════════════════════════════════════════════════════ -->
1141
- <!-- STEP 11: REVIEW AND APPROVE -->
1142
- <!-- ══════════════════════════════════════════════════════════════════ -->
1143
-
1144
- <step name="review" order="11">
1145
- Show the agent's returned summary to the user (from step 9). Then:
1146
-
1147
- Use AskUserQuestion:
1148
- - header: "Feature"
1149
- - question: "Feature specification written to `{FEATURE_FILE}`. Does this look right? Review the full file in your editor for details."
1150
- - options:
1151
- - "Approve" — Looks good, commit it
1152
- - "Adjust" — I want to change some things
1153
- - "Redo questioning" — Let's go back and explore more
1154
-
1155
- **If "Adjust":**
1156
- - Ask what they want to change (scope, stories, criteria, hypothesis, etc.)
1157
- - Spawn a Task agent to edit:
1158
- ```
1159
- Task(
1160
- prompt="Read `{FEATURE_FILE}` and make these changes:
1161
- {user's requested changes}.
1162
-
1163
- **Rules:**
1164
- - Read the template for reference: ~/.claude/agile-context-engineering/templates/product/feature.xml
1165
- - Maintain all template formatting — especially table column alignment:
1166
- pad cells with spaces so | separators align vertically across all rows
1167
- - Keep Story IDs stable — do NOT renumber
1168
- - If adding stories, use next available S[N]
1169
- - Benefit Hypothesis must follow SAFe format
1170
- - Acceptance criteria are feature-level, NOT Gherkin
1171
- - Story sizes: Fibonacci (1, 2, 3, 5, 8)
1172
-
1173
- Use the Edit tool to modify in place. Return only a confirmation of what changed.",
1174
- subagent_type="general-purpose",
1175
- model="{PO_MODEL}",
1176
- description="Adjust feature specification"
1177
- )
1178
- ```
1179
- - Present for review again. Loop until approved.
1180
-
1181
- **If "Redo questioning":**
1182
- - Return to step 8 (deep-questioning)
1183
- - Preserve VISION, RELEVANT_WIKI, RELEVANT_CODE, SYSTEM_ARCHITECTURE, INPUT_CONTEXT
1184
- - Hold previous answers as additional context
1185
-
1186
- **If "Approve":**
1187
- Continue to step 12.
1188
- </step>
1189
-
1190
- <!-- ══════════════════════════════════════════════════════════════════ -->
1191
- <!-- STEP 12: GITHUB SYNC -->
1192
- <!-- ══════════════════════════════════════════════════════════════════ -->
1193
-
1194
- <step name="github-sync" order="12">
1195
-
1196
- **If `github_project.enabled` is false OR `github_project.gh_installed` is false:**
1197
-
1198
- Skip to step 13.
1199
-
1200
- **If `github_project.enabled` is true AND `github_project.gh_installed` is true:**
1201
-
1202
- Extract settings: REPO = `github_project.repo`, PROJECT_NUMBER = `github_project.project_number`,
1203
- OWNER = `github_project.owner`.
1204
-
1205
- <!-- ── 12a: Identify sync actions ───────────────────────────────── -->
1206
-
1207
- Read the approved `{FEATURE_FILE}` and cross-reference with GitHub state:
1208
-
1209
- - **Feature issue:** Does `NEEDS_GITHUB_CREATE` flag indicate we need to create the feature issue?
1210
- If REFINE mode and the feature already has a GitHub issue, check if any fields changed.
1211
- - **Story sub-issues:** Parse the story index table. All stories with Link = "—" are
1212
- candidates for creation.
1213
-
1214
- If no sync actions needed (feature linked, all stories linked):
1215
- - Display: "All items already synced with GitHub."
1216
- - Continue to step 13.
1217
-
1218
- <!-- ── 12b: Present sync plan ───────────────────────────────────── -->
1219
-
1220
- ```
1221
- GitHub Sync Summary:
1222
- - Feature issue: {create / update / already synced}
1223
- - Story sub-issues: {N} to create, {M} already linked
1224
- ```
1225
-
1226
- Use AskUserQuestion:
1227
- - header: "GitHub Sync"
1228
- - question: "How would you like to sync with GitHub?"
1229
- - options:
1230
- - "Sync all (Recommended)" — Create/update feature and story issues
1231
- - "Feature only" — Only create/update the feature issue
1232
- - "Skip" — Don't sync to GitHub
1233
-
1234
- **If "Skip":**
1235
- Continue to step 13.
1236
-
1237
- <!-- ── 12c: Execute sync ────────────────────────────────────────── -->
1238
-
1239
- Display:
1240
- ```
1241
- ┌──────────────────────────────────────────────────┐
1242
- │ ACE > Plan Feature > GitHub Sync │
1243
- └──────────────────────────────────────────────────┘
1244
-
1245
- i Syncing with GitHub...
1246
- Repo: {REPO} | Project: #{PROJECT_NUMBER}
1247
- ```
1248
-
1249
- **Prerequisite — Resolve all field and type IDs (once, before creating any issues):**
1250
-
1251
- ```bash
1252
- GH_FIELDS=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github resolve-fields repo={REPO} owner={OWNER} project={PROJECT_NUMBER})
1253
- ```
1254
-
1255
- Parse the JSON response. Extract and cache:
1256
- - `issue_types.Feature` -> FEATURE_TYPE_ID
1257
- - `issue_types.Story` -> STORY_TYPE_ID (if exists; handle gracefully if not)
1258
- - `project_id` -> PROJECT_ID
1259
- - `fields.Status.id` -> STATUS_FIELD_ID
1260
- - `fields.Status.options` -> STATUS_OPTIONS map
1261
- - `fields.Priority.id` -> PRIORITY_FIELD_ID (if exists)
1262
- - `fields.Priority.options` -> PRIORITY_OPTIONS map
1263
- - `fields.Estimate.id` -> ESTIMATE_FIELD_ID (if exists)
1264
-
1265
- **Create feature issue (if `NEEDS_GITHUB_CREATE` is true):**
1266
-
1267
- Determine the parent epic's GitHub issue number from BACKLOG_INDEX:
1268
- - If the parent epic has a Link column value like `[#45](url)`, extract issue number 45.
1269
- - If the parent epic has no GitHub issue (Link = "—"), warn user and skip parent assignment.
1270
-
1271
- ```bash
1272
- FEATURE_RESULT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github create-issue \
1273
- type=Feature \
1274
- "title={Feature Title}" \
1275
- body_file={FEATURE_FILE} \
1276
- repo={REPO} \
1277
- owner={OWNER} \
1278
- project={PROJECT_NUMBER} \
1279
- project_id={PROJECT_ID} \
1280
- type_id={FEATURE_TYPE_ID} \
1281
- status_field_id={STATUS_FIELD_ID} \
1282
- status_option_id={STATUS_OPTIONS[status]} \
1283
- estimate_field_id={ESTIMATE_FIELD_ID} \
1284
- estimate={size_value} \
1285
- [priority_field_id={PRIORITY_FIELD_ID} priority_option_id={PRIORITY_OPTIONS[priority]}] \
1286
- [parent={epic_issue_number}] \
1287
- [milestone={Milestone}])
1288
- ```
1289
-
1290
- Parse the JSON response: `number`, `url`, `item_id`.
1291
- Store the feature's issue number for use as parent when creating stories.
1292
-
1293
- Display:
1294
- ```
1295
- + Created [Feature] {Title} -> #{number} (parent: #{epic_number})
1296
- ```
1297
-
1298
- **Update existing feature issue (if `GITHUB_FEATURE_ISSUE` is true — feature already has a GitHub issue):**
1299
-
1300
- The feature file IS the body. 100% of `{FEATURE_FILE}` goes to GitHub as-is.
1301
-
1302
- ```bash
1303
- node ~/.claude/agile-context-engineering/src/ace-tools.js github update-issue \
1304
- number={feature_issue_number} \
1305
- repo={REPO} \
1306
- "title={Feature Title}" \
1307
- body_file={FEATURE_FILE}
1308
- ```
1309
-
1310
- Display:
1311
- ```
1312
- ~ Updated [Feature] #{feature_issue_number} — {Title}
1313
- ```
1314
-
1315
- **If "Sync all" selected, sync ALL story issues:**
1316
-
1317
- For each story in the story breakdown:
1318
-
1319
- **If the story has NO GitHub issue (Link = "—") — CREATE:**
1320
-
1321
- The story stub file IS the body. 100% of `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1322
- goes to GitHub as-is. The story stub files were created in step 9c.
1323
-
1324
- ```bash
1325
- STORY_RESULT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github create-issue \
1326
- type=Story \
1327
- "title={Story Title}" \
1328
- body_file={FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md \
1329
- repo={REPO} \
1330
- owner={OWNER} \
1331
- project={PROJECT_NUMBER} \
1332
- project_id={PROJECT_ID} \
1333
- [type_id={STORY_TYPE_ID}] \
1334
- status_field_id={STATUS_FIELD_ID} \
1335
- status_option_id={STATUS_OPTIONS["Todo"]} \
1336
- estimate_field_id={ESTIMATE_FIELD_ID} \
1337
- estimate={story_size_value} \
1338
- [parent={feature_issue_number}])
1339
- ```
1340
-
1341
- Parse response: `number`, `url`.
1342
-
1343
- Display:
1344
- ```
1345
- + Created [Story] {Title} -> #{number} (parent: #{feature_number})
1346
- ```
1347
-
1348
- **If the story ALREADY has a GitHub issue (Link != "—") — UPDATE:**
1349
-
1350
- The story stub file IS the body. 100% of `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1351
- goes to GitHub as-is.
1352
-
1353
- ```bash
1354
- node ~/.claude/agile-context-engineering/src/ace-tools.js github update-issue \
1355
- number={story_issue_number} \
1356
- repo={REPO} \
1357
- "title={Story Title}" \
1358
- body_file={FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md
1359
- ```
1360
-
1361
- Display:
1362
- ```
1363
- ~ Updated [Story] #{story_issue_number} — {Title}
1364
- ```
1365
-
1366
- Each story's **parent is set to the feature's GitHub issue number** (either pre-existing
1367
- or just created above). Stories get their rough Fibonacci estimate from the feature
1368
- planning session (plan-story may refine later).
1369
-
1370
- <!-- ── 12d: Update feature file and story files with GitHub links ── -->
1371
-
1372
- After all creates, read `{FEATURE_FILE}` and update:
1373
- - Feature header Link field: from "—" to `[#N](url)`
1374
- - Feature header ID: from F[N] to #[N] if feature issue was created
1375
- - Story index table Link column: from "—" to `[#N](url)` for each newly created story
1376
- - Story index table ID: from S[N] to #[N] for each newly created story
1377
-
1378
- Use the Edit tool for targeted replacements in the markdown.
1379
-
1380
- Also update each story stub file in `{FEATURE_DIR}/{story_slug}/`:
1381
- - If the story file exists and was just linked to a GitHub issue, update its header
1382
- to reflect the new issue number and link.
1383
- - If the ID changed (e.g., S1 became #92), rename the story directory and file:
1384
- rename `{FEATURE_DIR}/{old_story_slug}/` to `{FEATURE_DIR}/{new_story_slug}/`
1385
- and rename the file inside from `{old_story_slug}.md` to `{new_story_slug}.md`.
1386
-
1387
- <!-- ── 12e: Sync new feature GitHub ID back to product-backlog.md ── -->
1388
-
1389
- If a feature GitHub issue was created, read `.ace/artifacts/product/product-backlog.md`
1390
- and update the feature row in the parent epic's detail table:
1391
- - ID column: change F[N] to #[issue_number]
1392
- - Link column: change "—" to `[#N](https://github.com/{REPO}/issues/N)`
1393
- - Title: update to match the GitHub issue title exactly
1394
-
1395
- Stories are NOT tracked in the backlog — only update the feature row.
1396
-
1397
- Use the Edit tool for targeted replacements in the markdown.
1398
- Preserve table alignment — pad ALL cells so | separators align vertically.
1399
-
1400
- Display summary:
1401
- ```
1402
- + Created {N} GitHub issues.
1403
- Synced feature ID back to product-backlog.md.
1404
- Updated feature file and story files with GitHub links.
1405
- ```
1406
-
1407
- Continue to step 13.
1408
- </step>
1409
-
1410
- <!-- ══════════════════════════════════════════════════════════════════ -->
1411
- <!-- STEP 13: COMMIT -->
1412
- <!-- ══════════════════════════════════════════════════════════════════ -->
1413
-
1414
- <step name="commit" order="13">
1415
- Stage and commit all changed files in a single commit.
1416
- Only stage files that actually changed (use `git diff` / `git status` to check).
1417
-
1418
- Files that may have changed:
1419
- - `{FEATURE_FILE}` — always (this is the main output)
1420
- - `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md` — story stub files created in step 9c
1421
- - `{FEATURE_DIR}/relevant-wiki.md` — if wiki research was run/regenerated in step 5
1422
- - `{FEATURE_DIR}/relevant-code.md` — if code research was run/regenerated in step 6
1423
- - `.ace/artifacts/product/product-backlog.md` — if feature was added or status updated
1424
-
1425
- Stage specifically:
1426
- ```bash
1427
- git add {FEATURE_DIR}/
1428
- git add .ace/artifacts/product/product-backlog.md
1429
- ```
1430
-
1431
- Commit with a message that reflects what happened:
1432
- - CREATE mode: `git commit -m "docs: plan feature {Feature ID} — {Feature Title}"`
1433
- - REFINE mode: `git commit -m "docs: refine feature {Feature ID} — {brief summary of changes}"`
1434
- Examples:
1435
- - "docs: refine feature F3 — add 2 stories, update scope"
1436
- - "docs: refine feature #78 — revise acceptance criteria"
1437
-
1438
- Display completion (adapt banner to mode):
1439
-
1440
- ```
1441
- ╔══════════════════════════════════════════════════╗
1442
- ║ ACE > Feature [Planned | Refined] ║
1443
- ║ {Feature ID} "{Feature Title}" ║
1444
- ╚══════════════════════════════════════════════════╝
1445
-
1446
- + {FEATURE_FILE} committed.
1447
- [If REFINE: Refinement #{count}]
1448
-
1449
- Summary:
1450
- ────────
1451
- {N} stories | Size: {size} | Priority: {priority}
1452
- Acceptance criteria: {M}
1453
- [If brownfield: Existing implementation documented]
1454
-
1455
- i Story descriptions are ready for formal planning.
1456
- Run plan-story on each to create INVEST stories
1457
- with Gherkin acceptance criteria.
1458
-
1459
- Next > /ace:plan-story {Feature ID}-S1
1460
- Plan the first story with formal specification.
1461
- > /ace:plan-feature {next feature ID}
1462
- Plan the next feature in the backlog.
1463
- ```
1464
- </step>
1465
-
1466
- </process>
1467
-
1468
- <success_criteria>
1469
- - Init function executed (environment detected, brownfield status checked, GitHub settings loaded)
1470
- - Feature located in product backlog (or marked for addition if new)
1471
- - CREATE vs REFINE mode correctly determined
1472
- - Product vision and backlog loaded as foundation context
1473
- - Wiki research: reused from cache, regenerated, or skipped (brownfield only)
1474
- - Code research: reused from cache, regenerated, or skipped (brownfield only)
1475
- - Parallelism rule applied: code research runs immediately if wiki from cache, waits if wiki regenerating
1476
- - Both research agents follow context window protection (write to disk, return ~10 lines only)
1477
- - No TaskOutput called after background agent spawning
1478
- - Deep questioning adapted to mode (CREATE vs REFINE) and context richness (RICH/MODERATE/LEAN/BARE)
1479
- - All feature.xml template fields addressed during questioning
1480
- - Benefit hypothesis follows SAFe format (measurable, falsifiable, user-focused)
1481
- - Acceptance criteria are feature-level (NOT Gherkin)
1482
- - Story breakdown: as many stories as naturally emerge, each a vertical slice with rich plain-text description
1483
- - Story sizes: rough Fibonacci estimates (1, 2, 3, 5, 8) assigned during questioning
1484
- - Feature document written following template structure exactly
1485
- - Individual story stub files created in {FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md (each story in own subdirectory, skipping already-existing files)
1486
- - Existing IDs and GitHub links preserved during refinement
1487
- - Backlog updated: new feature added or status changed to Refined
1488
- - User reviewed and approved the document
1489
- - GitHub sync: feature parent set to epic issue, story parents set to feature issue
1490
- - GitHub identity preservation: #N for linked items, S[N] for local stories
1491
- - Link columns updated after GitHub issue creation (both feature file and backlog)
1492
- - Document committed with mode-appropriate message
1493
- </success_criteria>
1494
-
1495
- </workflow>
1
+ <workflow>
2
+
3
+ <purpose>
4
+ Orchestrate feature planning or refinement: locate a feature in the product backlog,
5
+ load foundation context (vision, backlog, architecture), perform targeted wiki and code
6
+ research via background sub-agents, conduct deep questioning to define feature scope,
7
+ acceptance criteria, and story breakdown, then write the feature specification document.
8
+ Optionally syncs with GitHub issues.
9
+
10
+ Produces `.ace/artifacts/product/<id-epic_name>/<id-feature_name>/<id-feature_name>.md`
11
+ — a complete feature specification with benefit hypothesis, scope, acceptance criteria,
12
+ and story descriptions with rough Fibonacci estimates.
13
+
14
+ Can be run multiple times on the same feature for refinement. Supports both CREATE
15
+ (new feature) and REFINE (existing feature) modes.
16
+ </purpose>
17
+
18
+ <mandatory-context>
19
+ Read all files referenced by the invoking command's execution-context before starting.
20
+ Also read any document or text passed as parameter ($ARGUMENTS) in the invoking command.
21
+ </mandatory-context>
22
+
23
+ <process>
24
+
25
+ <!-- ══════════════════════════════════════════════════════════════════ -->
26
+ <!-- STEP 1: SETUP -->
27
+ <!-- ══════════════════════════════════════════════════════════════════ -->
28
+
29
+ <step name="setup" order="1">
30
+ **MANDATORY FIRST STEP — Execute environment detection before any user interaction:**
31
+
32
+ ```bash
33
+ INIT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js init plan-feature)
34
+ ```
35
+
36
+ Parse JSON for: `product_owner_model`, `researcher_model`, `commit_docs`,
37
+ `has_product_vision`, `has_product_backlog`,
38
+ `has_wiki_analysis`,
39
+ `is_brownfield`, `is_greenfield`,
40
+ `has_existing_code`, `has_package_file`, `has_wiki`, `has_wiki_system_wide`,
41
+ `has_wiki_subsystems`, `wiki_subsystem_names`, `has_system_architecture`,
42
+ `has_system_structure`, `has_testing_framework`, `has_git`, `has_gh_cli`,
43
+ `github_project` (object: `enabled`, `gh_installed`, `repo`, `project_number`, `owner`).
44
+
45
+ Also resolve the product owner model for spawning agents:
46
+ ```bash
47
+ PO_MODEL=$(node ~/.claude/agile-context-engineering/src/ace-tools.js resolve-model ace-product-owner --raw)
48
+ ```
49
+
50
+ Display stage banner:
51
+
52
+ ```
53
+ ╔══════════════════════════════════════════════════╗
54
+ ║ ACE > Plan Feature ║
55
+ ╚══════════════════════════════════════════════════╝
56
+ ```
57
+
58
+ **If `has_git` is false:** Initialize git:
59
+ ```bash
60
+ git init
61
+ ```
62
+ </step>
63
+
64
+ <!-- ══════════════════════════════════════════════════════════════════ -->
65
+ <!-- STEP 2: LOCATE FEATURE -->
66
+ <!-- ══════════════════════════════════════════════════════════════════ -->
67
+
68
+ <step name="locate-feature" order="2">
69
+
70
+ <!-- ── 2a: Check backlog exists ─────────────────────────────────── -->
71
+
72
+ **If `has_product_backlog` is false:**
73
+
74
+ Display error:
75
+ ```
76
+ x No product backlog found. Feature planning requires a backlog.
77
+ The backlog defines epics and features that drive feature planning.
78
+ ```
79
+
80
+ Display next action:
81
+ ```
82
+ ┌──────────────────────────────────────────────────┐
83
+ │ Next > /ace:plan-backlog │
84
+ │ Create the product backlog first, then │
85
+ │ re-run /ace:plan-feature │
86
+ └──────────────────────────────────────────────────┘
87
+ ```
88
+
89
+ Exit workflow.
90
+
91
+ <!-- ── 2b: Read backlog and parse features ──────────────────────── -->
92
+
93
+ **If `has_product_backlog` is true:**
94
+
95
+ Read `.ace/artifacts/product/product-backlog.md`. Parse:
96
+ - All epics: extract ID, Title, Status, Milestone, Link
97
+ - All features per epic: extract ID, Title, Description, Status, Priority, Size, Sprint, Milestone, Link
98
+ - Build a BACKLOG_INDEX: `{ epics: [...], features: [...] }` with parent epic references
99
+
100
+ <!-- ── 2c: Resolve target feature ───────────────────────────────── -->
101
+
102
+ Check if `$ARGUMENTS` contains a feature identifier (first positional argument before `context=`):
103
+ - Could be: `F3`, `#78`, or absent
104
+
105
+ **If feature ID is provided:**
106
+ - Search BACKLOG_INDEX for matching feature by ID (F[N] or #[N])
107
+ - If found: set `TARGET_FEATURE` from backlog data, set `FEATURE_IN_BACKLOG = true`
108
+ - If NOT found: set `FEATURE_IN_BACKLOG = false`, set `NEEDS_BACKLOG_ADD = true`,
109
+ hold the user-provided ID/name as seed context
110
+
111
+ **If feature ID is NOT provided:**
112
+
113
+ Present the backlog's feature list for selection:
114
+ ```
115
+ ┌──────────────────────────────────────────────────┐
116
+ │ ACE > Plan Feature > Select Feature │
117
+ └──────────────────────────────────────────────────┘
118
+ ```
119
+
120
+ Display features grouped by epic as a tree:
121
+ ```
122
+ E1 User Authentication
123
+ ├── F1 OAuth2 Login Flow [Todo]
124
+ ├── F2 Session Management [Todo]
125
+ └── F3 Password Reset [Refined]
126
+ E2 Data Export Pipeline
127
+ ├── F4 CSV Bulk Export [Todo]
128
+ └── F5 Scheduled Exports [Todo]
129
+ ```
130
+
131
+ Use AskUserQuestion:
132
+ - header: "Feature"
133
+ - question: "Which feature would you like to plan? Pick from the list, or describe a new feature."
134
+ - options: list feature IDs + titles (up to 4), plus "New feature — describe it"
135
+
136
+ If user picks an existing feature: set `TARGET_FEATURE`, set `FEATURE_IN_BACKLOG = true`
137
+ If user picks "New feature": ask to describe the feature + pick parent epic
138
+ (or create under new epic), set `NEEDS_BACKLOG_ADD = true`.
139
+ The feature gets a provisional ID (next F[N]) and user-provided title.
140
+
141
+ <!-- ── 2d: Resolve directory paths ──────────────────────────────── -->
142
+
143
+ Using `TARGET_FEATURE` (or user-described new feature), compute:
144
+ ```bash
145
+ EPIC_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Epic ID}-{Epic Title}" --raw)
146
+ FEATURE_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Feature ID}-{Feature Title}" --raw)
147
+ ```
148
+
149
+ Set `FEATURE_DIR = .ace/artifacts/product/{EPIC_SLUG}/{FEATURE_SLUG}`
150
+ Set `FEATURE_FILE = {FEATURE_DIR}/{FEATURE_SLUG}.md`
151
+
152
+ <!-- ── 2e: Check for existing feature file (REFINE mode) ────────── -->
153
+
154
+ Check if `FEATURE_FILE` exists:
155
+ ```bash
156
+ EXISTING_FEATURE=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_FILE} --raw)
157
+ ```
158
+
159
+ If exists: set `RUN_MODE = REFINE`
160
+
161
+ Use AskUserQuestion:
162
+ - header: "Feature exists"
163
+ - question: "A feature spec already exists at `{FEATURE_FILE}`. What would you like to do?"
164
+ - options:
165
+ - "Refine it" — Review and update the existing specification
166
+ - "Start fresh" — Discard and create a new specification from scratch
167
+ - "Skip" — Keep the current specification as-is
168
+
169
+ If "Refine it": read the existing file, hold as `EXISTING_FEATURE_DOC`, continue.
170
+ If "Start fresh": set `RUN_MODE = CREATE`, set `EXISTING_FEATURE_DOC = null`, continue.
171
+ If "Skip": Exit workflow.
172
+
173
+ If not exists: set `RUN_MODE = CREATE`, set `EXISTING_FEATURE_DOC = null`
174
+
175
+ <!-- ── 2f: Check GitHub for feature issue ───────────────────────── -->
176
+
177
+ **If `github_project.enabled` is true AND `github_project.gh_installed` is true:**
178
+
179
+ - If TARGET_FEATURE has a GitHub link (#N):
180
+ set `GITHUB_FEATURE_ISSUE = true`, store issue number.
181
+ Fetch:
182
+ ```bash
183
+ GH_FEATURE_DATA=$(gh issue view {issue_number} --repo {REPO} --json title,body,labels,state,comments,milestone)
184
+ ```
185
+ Hold parsed JSON as `GITHUB_FEATURE_DATA`.
186
+ Compare with `EXISTING_FEATURE_DOC` (if both exist) — note any differences.
187
+
188
+ - If TARGET_FEATURE has no GitHub link:
189
+ set `GITHUB_FEATURE_ISSUE = false`, set `NEEDS_GITHUB_CREATE = true`
190
+
191
+ **If GitHub not enabled:** set `GITHUB_FEATURE_ISSUE = null`
192
+
193
+ **Display (after resolution):**
194
+
195
+ For CREATE mode:
196
+ ```
197
+ i Feature: {Feature ID} — {Feature Title}
198
+ Epic: {Epic ID} — {Epic Title}
199
+ Mode: New feature specification
200
+ Output: {FEATURE_FILE}
201
+ ```
202
+
203
+ For REFINE mode:
204
+ ```
205
+ i Feature: {Feature ID} — {Feature Title}
206
+ Epic: {Epic ID} — {Epic Title}
207
+ Mode: Refinement (#{refinement_count + 1})
208
+ Existing: {FEATURE_FILE}
209
+ ```
210
+ </step>
211
+
212
+ <!-- ══════════════════════════════════════════════════════════════════ -->
213
+ <!-- STEP 3: LOAD FOUNDATION -->
214
+ <!-- ══════════════════════════════════════════════════════════════════ -->
215
+
216
+ <step name="load-foundation" order="3">
217
+
218
+ **3a. Load product vision (if exists):**
219
+
220
+ If `has_product_vision` is true:
221
+ - Read `.docs/product/product-vision.md`
222
+ - Extract and hold as VISION context: Vision Statement, Target Audience,
223
+ High-Level Capabilities, Key Objectives, Constraints
224
+
225
+ If false: set `VISION = null` (acceptable — the backlog already encapsulates vision direction)
226
+
227
+ **3b. Load product backlog:**
228
+
229
+ Already loaded in step 2. Hold the full parsed BACKLOG_INDEX and specifically
230
+ the TARGET_FEATURE's parent epic details.
231
+
232
+ **3c. Load system architecture (if exists):**
233
+
234
+ If `has_system_architecture` is true:
235
+ - Read `.docs/wiki/system-wide/system-architecture.md`
236
+ - Hold as `SYSTEM_ARCHITECTURE` context
237
+
238
+ If false: set `SYSTEM_ARCHITECTURE = null`
239
+ </step>
240
+
241
+ <!-- ══════════════════════════════════════════════════════════════════ -->
242
+ <!-- STEP 4: AGGREGATE EXISTING INFO -->
243
+ <!-- ══════════════════════════════════════════════════════════════════ -->
244
+
245
+ <step name="aggregate-existing" order="4">
246
+
247
+ **4a. Existing feature file:**
248
+
249
+ If `RUN_MODE` is REFINE:
250
+ - `EXISTING_FEATURE_DOC` already loaded in step 2e
251
+ - Parse: Description, Benefit Hypothesis, Scope, Acceptance Criteria,
252
+ Story Breakdown, Technical Context, Dependencies, Metadata (refinement count, dates)
253
+
254
+ If CREATE: `EXISTING_FEATURE_DOC = null`
255
+
256
+ **4b. GitHub issue data (if enabled and linked):**
257
+
258
+ If `GITHUB_FEATURE_ISSUE` is true:
259
+ - `GITHUB_FEATURE_DATA` already loaded in step 2f
260
+ - Compare with `EXISTING_FEATURE_DOC` (if both exist) — note any differences
261
+ (e.g., status drift, updated description in GitHub)
262
+
263
+ If not applicable: `GITHUB_FEATURE_DATA = null`
264
+
265
+ **4c. Optional parameter text/file:**
266
+
267
+ If `$ARGUMENTS` contains `context=` parameter:
268
+ - If it is a file path: read the file
269
+ - If it is inline text: hold as-is
270
+ - Hold as `INPUT_CONTEXT`
271
+ - Categorize: does it contain acceptance criteria? Story suggestions?
272
+ Technical constraints? Scope details?
273
+
274
+ If no context parameter: `INPUT_CONTEXT = null`
275
+
276
+ Continue to step 5.
277
+ </step>
278
+
279
+ <!-- ══════════════════════════════════════════════════════════════════ -->
280
+ <!-- STEP 5: WIKI RESEARCH (Subagent) -->
281
+ <!-- ══════════════════════════════════════════════════════════════════ -->
282
+
283
+ <step name="wiki-research" order="5">
284
+
285
+ **If `is_greenfield` OR `has_wiki` is false:**
286
+
287
+ Set RELEVANT_WIKI = null.
288
+ Continue to step 6.
289
+
290
+ **If `is_brownfield` AND `has_wiki` is true:**
291
+
292
+ <!-- ── 5a: Check for existing research ──────────────────────────── -->
293
+
294
+ Check if `{FEATURE_DIR}/relevant-wiki.md` exists:
295
+ ```bash
296
+ HAS_WIKI_RESEARCH=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_DIR}/relevant-wiki.md --raw)
297
+ ```
298
+
299
+ If `HAS_WIKI_RESEARCH` is TRUE:
300
+ - Use AskUserQuestion:
301
+ - header: "Wiki Research"
302
+ - question: "Previous wiki analysis exists for this feature (`{FEATURE_DIR}/relevant-wiki.md`). What would you like to do?"
303
+ - options:
304
+ - "Use existing" — Skip wiki analysis, load the existing file
305
+ - "Regenerate" — Re-analyze wiki docs for this feature
306
+ - "Skip" — Don't use wiki analysis for this planning session
307
+
308
+ - If "Use existing": read `{FEATURE_DIR}/relevant-wiki.md`, hold as RELEVANT_WIKI.
309
+ Set `WIKI_FROM_CACHE = true`. Continue to step 6.
310
+ - If "Skip": set `RELEVANT_WIKI = null`. Continue to step 6.
311
+ - If "Regenerate": proceed to 5b.
312
+
313
+ If `HAS_WIKI_RESEARCH` is FALSE: proceed to 5b.
314
+
315
+ <!-- ── 5b: Spawn wiki research subagent ─────────────────────────── -->
316
+
317
+ Create the target directory:
318
+ ```bash
319
+ mkdir -p {FEATURE_DIR}
320
+ ```
321
+
322
+ Display:
323
+ ```
324
+ ┌──────────────────────────────────────────────────┐
325
+ │ ACE > Plan Feature > Wiki Research │
326
+ └──────────────────────────────────────────────────┘
327
+
328
+ i Analyzing wiki documentation relevant to feature:
329
+ {Feature ID} — {Feature Title}
330
+ Writing to: {FEATURE_DIR}/relevant-wiki.md
331
+ ```
332
+
333
+ **CRITICAL — Context Window Protection:**
334
+ The `ace-product-owner` agent has a built-in `<structured-returns>` protocol:
335
+ when spawned as a background agent, it writes to disk and returns ONLY a ~10-line
336
+ confirmation (file path + line count). This prevents agent output from inflating
337
+ the main context window.
338
+
339
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
340
+ After spawning the background agent, do NOT call TaskOutput to read its results.
341
+ You will be automatically notified when the agent completes — IGNORE those notifications.
342
+ The agent writes to `{FEATURE_DIR}/relevant-wiki.md` on disk. You do not need the return message.
343
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
344
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
345
+ After the notification arrives, verify the file with `wc -l {FEATURE_DIR}/relevant-wiki.md`,
346
+ then READ the file directly from disk using the Read tool. That is how you get the results.
347
+
348
+ Task tool parameters:
349
+ ```
350
+ subagent_type: "ace-product-owner"
351
+ model: "{PO_MODEL}"
352
+ run_in_background: true
353
+ description: "Wiki research for {Feature ID}"
354
+ ```
355
+
356
+ Prompt:
357
+ ```
358
+ You are analyzing wiki documentation to extract information relevant to a specific feature.
359
+
360
+ **Feature context:**
361
+ - Feature: {Feature ID} — {Feature Title}
362
+ - Epic: {Epic ID} — {Epic Title}
363
+ - Feature description (from backlog): {TARGET_FEATURE.description}
364
+
365
+ **Step 1 — Read the system-level wiki analysis first:**
366
+ Read `.ace/artifacts/wiki/wiki-analysis.md` if it exists.
367
+ This gives you the map of what subsystems exist and their responsibilities.
368
+
369
+ **Step 2 — Identify relevant subsystems:**
370
+ Based on the feature's scope, identify which subsystems from the wiki are relevant.
371
+
372
+ **Step 3 — Deep-read relevant wiki docs:**
373
+ For each relevant subsystem, read:
374
+ - .docs/wiki/subsystems/{subsystem_name}/architecture.md
375
+ - .docs/wiki/subsystems/{subsystem_name}/structure.md
376
+
377
+ Also read system-wide docs if relevant:
378
+ - .docs/wiki/system-wide/system-architecture.md
379
+ - .docs/wiki/system-wide/system-structure.md
380
+
381
+ **Step 4 — Write structured analysis to `{FEATURE_DIR}/relevant-wiki.md`:**
382
+
383
+ # Wiki Analysis: {Feature ID} — {Feature Title}
384
+
385
+ ## Relevant Subsystems
386
+ - [Subsystem]: [Why relevant to this feature]
387
+
388
+ ## Existing Capabilities
389
+ - [What already exists that this feature builds on or interacts with]
390
+
391
+ ## Architecture Patterns
392
+ - [Relevant patterns from wiki that affect this feature's design]
393
+
394
+ ## Data Flows
395
+ - [Relevant data ownership and flows]
396
+
397
+ ## Integration Points
398
+ - [Where this feature connects to existing subsystems]
399
+
400
+ ## Constraints
401
+ - [Architectural constraints from existing system that affect this feature]
402
+
403
+ ## Gaps
404
+ - [What the wiki doesn't cover that this feature will need]
405
+
406
+ IMPORTANT: Write to `{FEATURE_DIR}/relevant-wiki.md` using the Write tool.
407
+
408
+ **WRITE TO FILE DIRECTLY. RETURN ONLY CONFIRMATION.**
409
+ Your response must be ~10 lines max. Just confirm what was written and the line count.
410
+ Do NOT return file contents in your response.
411
+ ```
412
+
413
+ **After background notification arrives — IGNORE it:**
414
+
415
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
416
+ Just verify the file and read it directly from disk:
417
+ ```bash
418
+ wc -l {FEATURE_DIR}/relevant-wiki.md
419
+ ```
420
+
421
+ Read `{FEATURE_DIR}/relevant-wiki.md` using the Read tool, hold as `RELEVANT_WIKI`.
422
+ Set `WIKI_FROM_CACHE = false`.
423
+
424
+ Continue to step 6.
425
+ </step>
426
+
427
+ <!-- ══════════════════════════════════════════════════════════════════ -->
428
+ <!-- STEP 6: CODE RESEARCH (Subagent) -->
429
+ <!-- ══════════════════════════════════════════════════════════════════ -->
430
+
431
+ <step name="code-research" order="6">
432
+
433
+ **If `is_greenfield`:**
434
+
435
+ Set RELEVANT_CODE = null.
436
+ Continue to step 7.
437
+
438
+ **If `is_brownfield`:**
439
+
440
+ **Parallelism rule:** If wiki research was served from cache (`WIKI_FROM_CACHE = true`
441
+ in step 5a), code research can start immediately — the `relevant-wiki.md` file is
442
+ already on disk. If wiki research had to regenerate (step 5b with a background agent),
443
+ code research waits for that background agent to complete first before spawning.
444
+
445
+ <!-- ── 6a: Check for existing code research ─────────────────────── -->
446
+
447
+ Check if `{FEATURE_DIR}/relevant-code.md` exists:
448
+ ```bash
449
+ HAS_CODE_RESEARCH=$(node ~/.claude/agile-context-engineering/src/ace-tools.js verify-path-exists {FEATURE_DIR}/relevant-code.md --raw)
450
+ ```
451
+
452
+ If `HAS_CODE_RESEARCH` is TRUE:
453
+ - Use AskUserQuestion:
454
+ - header: "Code Research"
455
+ - question: "Previous code analysis exists for this feature (`{FEATURE_DIR}/relevant-code.md`). What would you like to do?"
456
+ - options:
457
+ - "Use existing" — Skip code analysis, load the existing file
458
+ - "Regenerate" — Re-analyze codebase for this feature
459
+ - "Skip" — Don't use code analysis for this planning session
460
+
461
+ - If "Use existing": read the file, hold as `RELEVANT_CODE`. Continue to step 7.
462
+ - If "Skip": set `RELEVANT_CODE = null`. Continue to step 7.
463
+ - If "Regenerate": proceed to 6b.
464
+
465
+ If `HAS_CODE_RESEARCH` is FALSE: proceed to 6b.
466
+
467
+ <!-- ── 6b: Spawn code research subagent ─────────────────────────── -->
468
+
469
+ Display:
470
+ ```
471
+ ┌──────────────────────────────────────────────────┐
472
+ │ ACE > Plan Feature > Code Research │
473
+ └──────────────────────────────────────────────────┘
474
+
475
+ i Analyzing codebase for existing implementation
476
+ relevant to feature: {Feature ID} — {Feature Title}
477
+ Writing to: {FEATURE_DIR}/relevant-code.md
478
+ ```
479
+
480
+ **CRITICAL — Context Window Protection:**
481
+ The agent writes to disk and returns ONLY a ~10-line confirmation.
482
+ This prevents agent output from inflating the main context window.
483
+
484
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
485
+ After spawning the background agent, do NOT call TaskOutput to read its results.
486
+ You will be automatically notified when the agent completes — IGNORE those notifications.
487
+ The agent writes to `{FEATURE_DIR}/relevant-code.md` on disk. You do not need the return message.
488
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
489
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
490
+ After the notification arrives, verify the file with `wc -l {FEATURE_DIR}/relevant-code.md`,
491
+ then READ the file directly from disk using the Read tool. That is how you get the results.
492
+
493
+ Resolve the researcher model:
494
+ ```bash
495
+ RESEARCHER_MODEL=$(node ~/.claude/agile-context-engineering/src/ace-tools.js resolve-model ace-project-researcher --raw)
496
+ ```
497
+
498
+ Task tool parameters:
499
+ ```
500
+ subagent_type: "general-purpose"
501
+ model: "{RESEARCHER_MODEL}"
502
+ run_in_background: true
503
+ description: "Code research for {Feature ID}"
504
+ ```
505
+
506
+ Prompt:
507
+ ```
508
+ First, read ~/.claude/agents/ace-project-researcher.md for your role and instructions.
509
+
510
+ **Feature context:**
511
+ - Feature: {Feature ID} — {Feature Title}
512
+ - Epic: {Epic ID} — {Epic Title}
513
+ - Feature description (from backlog): {TARGET_FEATURE.description}
514
+
515
+ **Read these context files (if they exist):**
516
+ - {FEATURE_DIR}/relevant-wiki.md (wiki analysis for this feature)
517
+ - .docs/wiki/system-wide/system-architecture.md (system architecture)
518
+
519
+ **Your job:** Drill into the actual codebase to discover what is already implemented
520
+ that relates to this feature. Focus on:
521
+
522
+ 1. **Existing Components & Modules** — What code already exists that this feature
523
+ will build on, extend, or integrate with?
524
+ 2. **APIs & Interfaces** — Existing endpoints, function signatures, data contracts
525
+ 3. **Partial Implementations** — Code that partially addresses this feature's scope
526
+ 4. **System Boundaries** — Where this feature sits in the overall architecture
527
+ 5. **Integration Points** — APIs, events, data flows this feature connects to
528
+ 6. **Cross-Cutting Concerns** — Security, logging, error handling patterns in use
529
+ 7. **Non-Functional Patterns** — Performance patterns, caching, rate limiting in use
530
+
531
+ **Write structured analysis to `{FEATURE_DIR}/relevant-code.md`:**
532
+
533
+ # Code Analysis: {Feature ID} — {Feature Title}
534
+
535
+ ## Existing Components
536
+ - [Component/module path — what it does, relevance to this feature]
537
+
538
+ ## APIs & Interfaces
539
+ - [Endpoint/interface — current capability, what this feature extends]
540
+
541
+ ## Partial Implementations
542
+ - [What's partially built — what remains]
543
+
544
+ ## System Boundaries
545
+ - [Where this feature sits in the architecture]
546
+
547
+ ## Integration Points
548
+ - [How this feature connects to existing code]
549
+
550
+ ## Cross-Cutting Concerns
551
+ - [Security, observability, error handling patterns to follow]
552
+
553
+ ## Non-Functional Patterns
554
+ - [Performance, caching, scalability patterns in use]
555
+
556
+ ## Architectural Constraints
557
+ - [Constraints that affect this feature's design]
558
+
559
+ Write to `{FEATURE_DIR}/relevant-code.md` using the Write tool.
560
+
561
+ **WRITE TO FILE DIRECTLY. RETURN ONLY CONFIRMATION.**
562
+ Your response must be ~10 lines max. Just confirm what was written and the line count.
563
+ Do NOT return file contents or analysis results in your response.
564
+ ```
565
+
566
+ **After background notification arrives — IGNORE it:**
567
+
568
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
569
+ Just verify the file and read it directly from disk:
570
+ ```bash
571
+ wc -l {FEATURE_DIR}/relevant-code.md
572
+ ```
573
+
574
+ Read `{FEATURE_DIR}/relevant-code.md` using the Read tool, hold as `RELEVANT_CODE`.
575
+
576
+ Continue to step 7.
577
+ </step>
578
+
579
+ <!-- ══════════════════════════════════════════════════════════════════ -->
580
+ <!-- STEP 7: LOAD RESEARCH RESULTS -->
581
+ <!-- ══════════════════════════════════════════════════════════════════ -->
582
+
583
+ <step name="load-research" order="7">
584
+
585
+ Build `CONTEXT_INVENTORY` by loading all available context:
586
+
587
+ 1. `VISION` — product vision (from step 3, if available)
588
+ 2. `BACKLOG_INDEX` — product backlog with all epics/features (from step 2/3)
589
+ 3. `SYSTEM_ARCHITECTURE` — system architecture doc (from step 3, if available)
590
+ 4. `RELEVANT_WIKI` — wiki analysis for this feature (from step 5, if available)
591
+ 5. `RELEVANT_CODE` — code analysis for this feature (from step 6, if available)
592
+ 6. `INPUT_CONTEXT` — user-provided context text/file (from step 4, if available)
593
+ 7. `EXISTING_FEATURE_DOC` — existing feature file contents (from step 4, if REFINE mode)
594
+ 8. `GITHUB_FEATURE_DATA` — GitHub issue data (from step 2f, if different from file)
595
+
596
+ Compute `CONTEXT_RICHNESS`:
597
+ - **RICH**: RELEVANT_WIKI is set OR RELEVANT_CODE is set (brownfield with research)
598
+ - **MODERATE**: VISION is set AND (BACKLOG has detailed descriptions)
599
+ - **LEAN**: Only INPUT_CONTEXT available beyond the backlog entry
600
+ - **BARE**: Only the backlog's 1-2 sentence description
601
+
602
+ Display loaded context summary:
603
+ ```
604
+ i Context loaded for questioning:
605
+ [+] Product vision
606
+ [+] Product backlog (parent epic context)
607
+ [+] System architecture
608
+ [+] Wiki analysis (127 lines)
609
+ [+] Code analysis (89 lines)
610
+ [ ] User-provided context (none)
611
+ [+] Existing feature doc (refinement mode)
612
+ ```
613
+
614
+ Continue to step 8.
615
+ </step>
616
+
617
+ <!-- ══════════════════════════════════════════════════════════════════ -->
618
+ <!-- STEP 8: DEEP QUESTIONING -->
619
+ <!-- ══════════════════════════════════════════════════════════════════ -->
620
+
621
+ <step name="deep-questioning" order="8">
622
+ Follow the questioning guide from `questioning.xml`. You are a thinking partner,
623
+ not an interviewer.
624
+
625
+ Display:
626
+ ```
627
+ ┌──────────────────────────────────────────────────┐
628
+ │ ACE > Plan Feature > Questioning │
629
+ └──────────────────────────────────────────────────┘
630
+ ```
631
+
632
+ <!-- ── 8a: Mode-adapted opening ─────────────────────────────────── -->
633
+
634
+ **If RUN_MODE is REFINE:**
635
+
636
+ Read EXISTING_FEATURE_DOC and present current state:
637
+ ```
638
+ i Refinement mode — existing feature specification found.
639
+ Stories: {N} | Size: {size} | Status: {status}
640
+ Last refined: {date} | Refinements: {count}
641
+ ```
642
+
643
+ Use AskUserQuestion:
644
+ - header: "Refinement"
645
+ - question: "What would you like to refine about this feature?"
646
+ - options:
647
+ - "Update scope" — Add or remove items from scope
648
+ - "Revise stories" — Change story breakdown
649
+ - "Update acceptance criteria" — Revise success conditions
650
+ - "Full review" — Walk through the entire feature specification
651
+
652
+ Proceed to questioning with the relevant focus area.
653
+
654
+ **If RUN_MODE is CREATE:**
655
+
656
+ Adapt opening based on `CONTEXT_RICHNESS`:
657
+
658
+ If **RICH** (wiki + code research available):
659
+ - "Based on my analysis of your codebase and documentation, here's what I
660
+ understand about {Feature Title}..."
661
+ - Present synthesis: what already exists, what needs to be built, where it
662
+ fits in the architecture
663
+ - "The backlog says: '{TARGET_FEATURE.description}'. Based on the code analysis,
664
+ here's what's already implemented and what remains..."
665
+ - Probe: "Does this match your understanding? What am I missing?"
666
+
667
+ If **MODERATE** (vision + backlog context):
668
+ - "Your backlog describes this feature as: '{TARGET_FEATURE.description}'.
669
+ It sits under the {Epic Title} epic with priority {priority}."
670
+ - "Let's make this concrete. Walk me through what a user actually does when
671
+ this feature is working."
672
+
673
+ If **LEAN** (only INPUT_CONTEXT or backlog entry):
674
+ - "I have the backlog entry and your context. Let me make sure I understand
675
+ the full picture."
676
+ - Probe the most important unknowns first.
677
+
678
+ If **BARE** (just a backlog entry name):
679
+ - "The backlog lists this as '{Feature Title}' under {Epic Title}. Tell me
680
+ more — what does this feature actually deliver?"
681
+
682
+ <!-- ── 8b: Template-field questioning ────────────────────────────── -->
683
+
684
+ **Map answers to feature.xml template structure (background, not out loud).**
685
+
686
+ As you question, mentally track coverage against feature.xml template fields:
687
+ - [ ] **Description** — What this feature delivers end-to-end (2-4 sentences, vertical slice)
688
+ - [ ] **Benefit Hypothesis** — SAFe format: "We believe [outcome] will be achieved
689
+ if [users] successfully [action] with [feature]."
690
+ - Challenge vagueness: outcome must be measurable and falsifiable
691
+ - If user says "users will like it" — probe: "How will you measure that? What changes?"
692
+ - Bad: "Users will like the new login." (not measurable)
693
+ - Good: "We believe a 25% reduction in login support tickets will be achieved
694
+ if returning customers successfully authenticate via social providers
695
+ with the OAuth2 Login feature."
696
+ - [ ] **Scope: Includes** — Exhaustive list of capabilities in scope
697
+ - [ ] **Scope: Out of Scope** — Things someone might reasonably assume are included but are NOT
698
+ - [ ] **Acceptance Criteria** — 3-7 high-level, measurable conditions (NOT Gherkin scenarios)
699
+ - These validate the benefit hypothesis, not implementation details
700
+ - Each must be independently verifiable
701
+ - [ ] **Existing Implementation** (brownfield only) — Seeded from RELEVANT_CODE
702
+ - Confirm with user: "Based on the code analysis, these components exist: [list]. Correct?"
703
+ - [ ] **Technical Context** — System boundaries, integration points, cross-cutting concerns, NFRs
704
+ - Seeded from RELEVANT_WIKI and RELEVANT_CODE
705
+ - [ ] **Dependencies** — Requires, Enables, External
706
+ - [ ] **Story Breakdown** — stories as many as naturally emerge (see 8c)
707
+
708
+ Don't walk through this as a checklist. Weave questions naturally based on
709
+ the conversation. If gaps remain after the conversation feels complete, probe
710
+ those specific areas.
711
+
712
+ <!-- ── 8c: Story breakdown questioning ──────────────────────────── -->
713
+
714
+ Once feature scope is clear:
715
+
716
+ Display:
717
+ ```
718
+ i Feature scope is taking shape. Let's break it into stories.
719
+ Each story must be a VERTICAL SLICE delivering real user-facing value.
720
+ ```
721
+
722
+ **VERTICAL SLICE RULE — This is non-negotiable:**
723
+
724
+ Every story MUST cut through the architectural layers needed to deliver a
725
+ complete, user-facing capability. In most cases this means both backend AND
726
+ frontend work in the same story. A user should be able to USE the functionality
727
+ when the story is done — not just see a database schema, or just see a UI
728
+ with no backend, or just an API with no way to reach it.
729
+
730
+ **Anti-patterns — NEVER do these:**
731
+ - "Set up the database schema" — horizontal, not a story
732
+ - "Create the API endpoints" — horizontal, not a story
733
+ - "Build the UI components" — horizontal, not a story
734
+ - "Add validation" — cross-cutting concern, fold into the story that needs it
735
+ - "Add error handling" — fold into the story where errors occur
736
+ - "Write tests" — testing is part of every story's Definition of Done, not a separate story
737
+ - Splitting backend and frontend of the SAME functionality into separate stories
738
+
739
+ **Good vertical slices:**
740
+ - "User can log in with Google" — touches auth config, backend OAuth flow, UI login button, session handling
741
+ - "User can export their data as CSV" — touches export logic, file generation, download UI
742
+ - "Admin can disable a user account" — touches admin UI, API, domain logic, notifications
743
+
744
+ **Story sizing guidance:**
745
+
746
+ AIM for 8sp and 5sp stories. These are the sweet spot — large enough to deliver
747
+ meaningful vertical slices, small enough to complete in a sprint.
748
+
749
+ - **8sp** — The default target. A solid vertical slice with real depth.
750
+ - **5sp** — Good for slightly smaller slices that still deliver end-to-end value.
751
+ - **3sp** — Acceptable occasionally for genuinely small but still vertical slices.
752
+ - **2sp** — Rare. Only when the slice is truly thin but still cuts through layers.
753
+ - **1sp** — Almost never. Only for trivial configuration or copy changes.
754
+
755
+ If most stories in your breakdown are 2-3sp, you have OVER-DECOMPOSED.
756
+ Merge related small stories into fewer, meatier vertical slices.
757
+
758
+ **Approach for eliciting good stories:**
759
+
760
+ 1. Start from the user journey: "Walk me through the happy path.
761
+ What's the first thing the user does? What happens next?"
762
+
763
+ 2. Identify natural cut points where a user gets a COMPLETE new capability.
764
+ Each story = one thing the user can DO that they couldn't before.
765
+
766
+ 3. If brownfield, use RELEVANT_CODE to inform decomposition:
767
+ "The code analysis shows {component} already handles {partial capability}.
768
+ That suggests we can scope a story around extending it to do {new thing}."
769
+
770
+ 4. Present a draft story list when you have enough context:
771
+ ```
772
+ Here's how I'd break this down:
773
+
774
+ S1: [Title] — [1-sentence scope] (8sp)
775
+ S2: [Title] — [1-sentence scope] (5sp)
776
+ S3: [Title] — [1-sentence scope] (8sp)
777
+ ...
778
+
779
+ Each story is a vertical slice — the user gets a complete capability when it's done.
780
+ ```
781
+
782
+ 5. **Sanity check before presenting:** Review your story list:
783
+ - Are most stories 5sp or 8sp? If not, merge the small ones.
784
+ - Does every story deliver something user-facing? If not, fold it into one that does.
785
+ - Could a non-technical stakeholder understand what each story delivers? If not, reframe.
786
+
787
+ 6. Use AskUserQuestion:
788
+ - header: "Stories"
789
+ - question: "Here's the story breakdown. What would you like to adjust?"
790
+ - options:
791
+ - "Looks good" — Stories are well-scoped
792
+ - "Split a story" — One of these is too big
793
+ - "Merge stories" — Some of these should be combined
794
+ - "Add a story" — Something is missing
795
+
796
+ 7. For each story, confirm or discuss:
797
+ - Title (short descriptive name)
798
+ - Scope description (rich, multi-paragraph plain text — NOT a formal user story.
799
+ The `plan-story` command handles formal specification later.)
800
+ - Key behaviors and edge cases to consider
801
+ - Relationship to other stories in the feature
802
+ - **Rough Fibonacci estimate** (1, 2, 3, 5, 8) — aim for 8sp and 5sp.
803
+ `plan-story` can refine later after detailed specification.
804
+
805
+ 8. Validate coverage: "Do these {N} stories cover 100% of the feature scope?
806
+ The includes list is: [list scope items]. Every item should map to at least one story."
807
+
808
+ <!-- ── 8d: Decision gate ────────────────────────────────────────── -->
809
+
810
+ When the feature specification feels complete:
811
+
812
+ Use AskUserQuestion:
813
+ - header: "Ready?"
814
+ - question: "I have the full feature spec: {description summary}, {N} acceptance criteria, {M} stories. Ready to write the feature document?"
815
+ - options:
816
+ - "Write feature document" — Let's create it
817
+ - "Keep exploring" — I want to add more or adjust
818
+ - "Show me what you have" — Summary before deciding
819
+
820
+ If "Show me what you have":
821
+ - Display a structured summary:
822
+ ```
823
+ Feature: {ID} — {Title}
824
+ Epic: {Epic ID} — {Epic Title}
825
+ Size: {size} | Priority: {priority} | Milestone: {milestone}
826
+
827
+ Description: {2-4 sentence description}
828
+
829
+ Benefit Hypothesis:
830
+ > We believe {outcome} if {users} {action} with {feature}.
831
+
832
+ Acceptance Criteria: {count}
833
+ Stories: {count}
834
+ | ID | Title | Size |
835
+ |----|-------------------|------|
836
+ | S1 | {story title} | {est}|
837
+ | S2 | {story title} | {est}|
838
+ ...
839
+ ```
840
+ - Return to decision gate.
841
+
842
+ If "Keep exploring" — ask what they want to add, or identify gaps and probe naturally.
843
+
844
+ Loop until "Write feature document" selected.
845
+ </step>
846
+
847
+ <!-- ══════════════════════════════════════════════════════════════════ -->
848
+ <!-- STEP 9: WRITE FEATURE DOCUMENT -->
849
+ <!-- ══════════════════════════════════════════════════════════════════ -->
850
+
851
+ <step name="write-feature" order="9">
852
+
853
+ Display:
854
+ ```
855
+ ┌──────────────────────────────────────────────────┐
856
+ │ ACE > Plan Feature > Writing Document │
857
+ └──────────────────────────────────────────────────┘
858
+
859
+ i Spawning product owner agent to write feature
860
+ specification...
861
+ Output: {FEATURE_FILE}
862
+ ```
863
+
864
+ Create directory structure:
865
+ ```bash
866
+ mkdir -p {FEATURE_DIR}
867
+ ```
868
+
869
+ Prepare a context brief (800 words max) that distills all questioning results:
870
+ - Feature header fields: ID, Title, Epic reference, Status, Priority, Size (Fibonacci x10),
871
+ Sprint, Milestone, Link
872
+ - Complete Description (2-4 sentences)
873
+ - Benefit Hypothesis (SAFe format)
874
+ - Scope: Includes + Out of Scope
875
+ - Acceptance Criteria (3-7 items)
876
+ - Existing Implementation (brownfield only — from RELEVANT_CODE, confirmed by user)
877
+ - Story Breakdown: index table with rough Fibonacci estimates + rich descriptions for each story
878
+ - Technical Context: System Boundaries, Integration Points, Cross-Cutting Concerns, NFRs
879
+ - Dependencies: Requires, Enables, External
880
+ - Metadata: current date, refinement count
881
+ - Research artifact paths for metadata section
882
+
883
+ <!-- ── 9a: CREATE mode — write new feature ──────────────────────── -->
884
+
885
+ **If RUN_MODE is CREATE:**
886
+
887
+ Spawn the feature-writing agent:
888
+
889
+ ```
890
+ Task(
891
+ prompt="You are an Agile Product Owner writing a feature specification document.
892
+
893
+ **Context brief from questioning session:**
894
+ {paste the context brief here}
895
+
896
+ **Instructions:**
897
+ 1. Read the feature template: ~/.claude/agile-context-engineering/templates/product/feature.xml
898
+ 2. Write `{FEATURE_FILE}` following the template structure exactly
899
+ 3. Include ALL sections: Header, Description, Benefit Hypothesis, Scope,
900
+ Acceptance Criteria, [Existing Implementation if brownfield],
901
+ Story Breakdown (index + detail per story), Technical Context,
902
+ Dependencies, Metadata
903
+ 4. Story descriptions must be RICH and detailed — multiple paragraphs. Cover:
904
+ scope, user-facing behavior, value, key behaviors, edge cases, constraints,
905
+ relationships to other stories.
906
+ These are NOT formal user stories — they are thorough descriptions of intent
907
+ and scope. The `plan-story` command handles formal specification later.
908
+ 5. Story index table:
909
+ - ID = S[N], sequential within this feature
910
+ - Size = rough Fibonacci estimate (1, 2, 3, 5, 8) from the questioning session
911
+ - Status = Todo
912
+ - Sprint = —
913
+ - Link = —
914
+ 6. Follow all field definitions from the template:
915
+ - Feature Status: Refined (stories well-defined) or Todo (if still rough)
916
+ - Feature Size: Fibonacci x10 values only (10, 20, 30, 50, 80)
917
+ - Priority: Critical | High | Medium | Low
918
+ 7. Benefit Hypothesis MUST follow SAFe format exactly:
919
+ 'We believe [outcome] will be achieved if [users] successfully [action] with [feature].'
920
+ The outcome must be measurable and falsifiable.
921
+ 8. Acceptance Criteria are HIGH-LEVEL business validation — NOT Gherkin scenarios.
922
+ 3-7 criteria, each independently verifiable.
923
+ 9. Table formatting (CRITICAL): pad ALL cells with spaces so | separators align
924
+ vertically across all rows. Follow the table-formatting guideline from the
925
+ template for minimum column widths.
926
+ 10. GitHub identity: use #[issue_number] for GitHub-linked items, S[N] for local stories
927
+ 11. Metadata: Created={today}, Last refined={today}, Refinements=1
928
+ Research artifacts: include paths to relevant-wiki.md and relevant-code.md if they exist,
929
+ otherwise use '—'
930
+
931
+ Write the file using the Write tool.
932
+
933
+ **Return format — ONLY this, nothing else:**
934
+ DONE
935
+ - Feature: {ID} — {Title}
936
+ - Stories: {count}
937
+ - Acceptance criteria: {count}
938
+ - File: {FEATURE_FILE}
939
+ - Lines: {line count}",
940
+ subagent_type="ace-product-owner",
941
+ model="{PO_MODEL}",
942
+ description="Write feature specification"
943
+ )
944
+ ```
945
+
946
+ <!-- ── 9b: REFINE mode — update existing feature ────────────────── -->
947
+
948
+ **If RUN_MODE is REFINE:**
949
+
950
+ Prepare a change brief describing exactly what changed during questioning:
951
+ - **Additions:** new scope items, new stories (with all details), new acceptance criteria
952
+ - New Story IDs continue from the highest existing S[N] in the feature
953
+ - **Removals:** items to delete (by ID or description)
954
+ - **Modifications:** changed descriptions, updated scope, revised hypothesis, resized stories
955
+ - **Unchanged:** items to preserve as-is
956
+
957
+ Spawn the feature-editing agent:
958
+
959
+ ```
960
+ Task(
961
+ prompt="You are an Agile Product Owner updating an existing feature specification.
962
+
963
+ **Read the current feature:** `{FEATURE_FILE}`
964
+ **Read the template for reference:** `~/.claude/agile-context-engineering/templates/product/feature.xml`
965
+
966
+ **Changes to apply:**
967
+ {paste the change brief here}
968
+
969
+ **Rules:**
970
+ - PRESERVE existing story IDs (S[N] or #[N]) — never renumber after assignment
971
+ - Update the story index table to reflect any additions, removals, or changes
972
+ - Increment metadata refinement count
973
+ - Update 'Last refined' date to today
974
+ - Maintain all template formatting — especially table column alignment:
975
+ pad cells with spaces so | separators align vertically across all rows
976
+ - If adding new stories, use next available S[N]
977
+ - Story sizes: keep existing estimates unless explicitly changed, use Fibonacci (1,2,3,5,8)
978
+ - Do NOT change stories or sections that aren't in the change brief
979
+ - Benefit Hypothesis must follow SAFe format
980
+ - Acceptance criteria are feature-level, NOT Gherkin
981
+
982
+ Use Edit or Write tool as appropriate. If changes are extensive (new stories added,
983
+ major scope revision), use the Write tool to rewrite the file completely.
984
+
985
+ **Return format — ONLY this, nothing else:**
986
+ DONE
987
+ - Feature: {ID} — {Title}
988
+ - Stories: {count} (added: {N}, removed: {N}, unchanged: {N})
989
+ - Refinements: {new count}
990
+ - File: {FEATURE_FILE}",
991
+ subagent_type="ace-product-owner",
992
+ model="{PO_MODEL}",
993
+ description="Update feature specification"
994
+ )
995
+ ```
996
+
997
+ <!-- ── 9c: Create individual story files ────────────────────────── -->
998
+
999
+ **After the feature document is written (both CREATE and REFINE modes):**
1000
+
1001
+ For each story in the feature's story breakdown, create a stub story file at:
1002
+ `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1003
+
1004
+ Each story gets its own subdirectory within the feature directory.
1005
+
1006
+ Compute story slugs:
1007
+ ```bash
1008
+ STORY_SLUG=$(node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug "{Story ID}-{Story Title}" --raw)
1009
+ ```
1010
+
1011
+ For each story, check if the file already exists:
1012
+ - If exists: **do NOT overwrite** — it may have been refined by `plan-story` already.
1013
+ Skip silently.
1014
+ - If not exists: create a stub file seeded from the story description in the feature doc.
1015
+
1016
+ Spawn a Task agent to create all missing story files:
1017
+
1018
+ ```
1019
+ Task(
1020
+ prompt="You are creating stub story files for a feature.
1021
+
1022
+ **Read the feature document:** `{FEATURE_FILE}`
1023
+
1024
+ **For each story in the Story Breakdown section, create a stub file IF it does not already exist.**
1025
+
1026
+ File path pattern: `{FEATURE_DIR}/{story_slug}/{story_slug}.md`
1027
+ where story_slug = generate-slug of '{Story ID}-{Story Title}'
1028
+ (use Bash: `node ~/.claude/agile-context-engineering/src/ace-tools.js generate-slug '{Story ID}-{Story Title}' --raw`)
1029
+
1030
+ Each story gets its own subdirectory. Create the directory with `mkdir -p` before writing.
1031
+
1032
+ **Before writing each file, check if it exists.** If it exists, skip it — do NOT overwrite.
1033
+ Existing files may have been formally refined by plan-story.
1034
+
1035
+ **Stub file content for each new story:**
1036
+
1037
+ # {Story ID}: {Story Title}
1038
+
1039
+ **Feature**: {Feature ID} {Feature Title} | **Status**: Todo | **Size**: {estimate}
1040
+
1041
+ ## Description
1042
+
1043
+ {Copy the rich plain-text description from the feature document's story detail section verbatim.}
1044
+
1045
+ ---
1046
+ *Stub created by plan-feature. Run `/ace:plan-story {Story ID}` for formal specification with INVEST criteria and Gherkin acceptance scenarios.*
1047
+
1048
+ **Return format — ONLY this, nothing else:**
1049
+ DONE
1050
+ - Created: {N} story files
1051
+ - Skipped: {M} (already exist)
1052
+ - Directory: {FEATURE_DIR}",
1053
+ subagent_type="general-purpose",
1054
+ model="{PO_MODEL}",
1055
+ description="Create story stub files"
1056
+ )
1057
+ ```
1058
+
1059
+ Display:
1060
+ ```
1061
+ + Created {N} story stub files in {FEATURE_DIR}/
1062
+ [If skipped: Skipped {M} existing story files (already refined)]
1063
+ ```
1064
+ </step>
1065
+
1066
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1067
+ <!-- STEP 10: UPDATE BACKLOG -->
1068
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1069
+
1070
+ <step name="update-backlog" order="10">
1071
+
1072
+ <!-- ── 10a: New feature — add to backlog ────────────────────────── -->
1073
+
1074
+ **If `NEEDS_BACKLOG_ADD` is true (new feature not in backlog):**
1075
+
1076
+ Spawn a Task agent to add the feature to the backlog:
1077
+ ```
1078
+ Task(
1079
+ prompt="Read `.ace/artifacts/product/product-backlog.md` and add a new feature
1080
+ to the {Epic Title} epic's feature table:
1081
+
1082
+ - ID: {new F[N] — next sequential from highest existing F[N]}
1083
+ - Title: {Feature Title}
1084
+ - Description: {1-2 sentence description}
1085
+ - Status: Refined
1086
+ - Priority: {priority}
1087
+ - Size: {size}
1088
+ - Sprint: —
1089
+ - Milestone: {milestone}
1090
+ - Link: —
1091
+
1092
+ Rules:
1093
+ - Feature ID continues from highest existing F[N] in the entire backlog
1094
+ - Insert in the correct epic's detail section, ordered by delivery sequence
1095
+ - Update the Epic Index table if needed (aggregate status change)
1096
+ - Maintain table formatting — pad ALL cells so | separators align vertically
1097
+ - Read template for reference: ~/.claude/agile-context-engineering/templates/product/product-backlog.xml
1098
+
1099
+ Use Edit tool to modify in place. Return only a confirmation of what changed.",
1100
+ subagent_type="ace-product-owner",
1101
+ model="{PO_MODEL}",
1102
+ description="Add feature to backlog"
1103
+ )
1104
+ ```
1105
+
1106
+ Display:
1107
+ ```
1108
+ + Added {Feature ID} — {Feature Title} to product backlog.
1109
+ ```
1110
+
1111
+ <!-- ── 10b: Existing feature — update status ────────────────────── -->
1112
+
1113
+ **If `FEATURE_IN_BACKLOG` is true (feature already existed):**
1114
+
1115
+ Spawn a Task agent to update the feature's status and any changed fields:
1116
+ ```
1117
+ Task(
1118
+ prompt="Read `.ace/artifacts/product/product-backlog.md` and update feature {Feature ID}:
1119
+ - Status: Refined
1120
+ {any other field changes from the planning session — size, priority, etc.}
1121
+
1122
+ Rules:
1123
+ - Maintain table formatting — pad ALL cells so | separators align vertically
1124
+ - Update Epic aggregate status if needed
1125
+ - Do NOT change other items
1126
+
1127
+ Use Edit tool to modify in place. Return only a confirmation of what changed.",
1128
+ subagent_type="general-purpose",
1129
+ model="{PO_MODEL}",
1130
+ description="Update feature status in backlog"
1131
+ )
1132
+ ```
1133
+
1134
+ Display:
1135
+ ```
1136
+ ~ Updated {Feature ID} status to Refined in product backlog.
1137
+ ```
1138
+ </step>
1139
+
1140
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1141
+ <!-- STEP 11: REVIEW AND APPROVE -->
1142
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1143
+
1144
+ <step name="review" order="11">
1145
+ Show the agent's returned summary to the user (from step 9). Then:
1146
+
1147
+ Use AskUserQuestion:
1148
+ - header: "Feature"
1149
+ - question: "Feature specification written to `{FEATURE_FILE}`. Does this look right? Review the full file in your editor for details."
1150
+ - options:
1151
+ - "Approve" — Looks good, commit it
1152
+ - "Adjust" — I want to change some things
1153
+ - "Redo questioning" — Let's go back and explore more
1154
+
1155
+ **If "Adjust":**
1156
+ - Ask what they want to change (scope, stories, criteria, hypothesis, etc.)
1157
+ - Spawn a Task agent to edit:
1158
+ ```
1159
+ Task(
1160
+ prompt="Read `{FEATURE_FILE}` and make these changes:
1161
+ {user's requested changes}.
1162
+
1163
+ **Rules:**
1164
+ - Read the template for reference: ~/.claude/agile-context-engineering/templates/product/feature.xml
1165
+ - Maintain all template formatting — especially table column alignment:
1166
+ pad cells with spaces so | separators align vertically across all rows
1167
+ - Keep Story IDs stable — do NOT renumber
1168
+ - If adding stories, use next available S[N]
1169
+ - Benefit Hypothesis must follow SAFe format
1170
+ - Acceptance criteria are feature-level, NOT Gherkin
1171
+ - Story sizes: Fibonacci (1, 2, 3, 5, 8)
1172
+
1173
+ Use the Edit tool to modify in place. Return only a confirmation of what changed.",
1174
+ subagent_type="general-purpose",
1175
+ model="{PO_MODEL}",
1176
+ description="Adjust feature specification"
1177
+ )
1178
+ ```
1179
+ - Present for review again. Loop until approved.
1180
+
1181
+ **If "Redo questioning":**
1182
+ - Return to step 8 (deep-questioning)
1183
+ - Preserve VISION, RELEVANT_WIKI, RELEVANT_CODE, SYSTEM_ARCHITECTURE, INPUT_CONTEXT
1184
+ - Hold previous answers as additional context
1185
+
1186
+ **If "Approve":**
1187
+ Continue to step 12.
1188
+ </step>
1189
+
1190
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1191
+ <!-- STEP 12: GITHUB SYNC -->
1192
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1193
+
1194
+ <step name="github-sync" order="12">
1195
+
1196
+ **If `github_project.enabled` is false OR `github_project.gh_installed` is false:**
1197
+
1198
+ Skip to step 13.
1199
+
1200
+ **If `github_project.enabled` is true AND `github_project.gh_installed` is true:**
1201
+
1202
+ Extract settings: REPO = `github_project.repo`, PROJECT_NUMBER = `github_project.project_number`,
1203
+ OWNER = `github_project.owner`.
1204
+
1205
+ <!-- ── 12a: Identify sync actions ───────────────────────────────── -->
1206
+
1207
+ Read the approved `{FEATURE_FILE}` and cross-reference with GitHub state:
1208
+
1209
+ - **Feature issue:** Does `NEEDS_GITHUB_CREATE` flag indicate we need to create the feature issue?
1210
+ If REFINE mode and the feature already has a GitHub issue, check if any fields changed.
1211
+ - **Story sub-issues:** Parse the story index table. All stories with Link = "—" are
1212
+ candidates for creation.
1213
+
1214
+ If no sync actions needed (feature linked, all stories linked):
1215
+ - Display: "All items already synced with GitHub."
1216
+ - Continue to step 13.
1217
+
1218
+ <!-- ── 12b: Present sync plan ───────────────────────────────────── -->
1219
+
1220
+ ```
1221
+ GitHub Sync Summary:
1222
+ - Feature issue: {create / update / already synced}
1223
+ - Story sub-issues: {N} to create, {M} already linked
1224
+ ```
1225
+
1226
+ Use AskUserQuestion:
1227
+ - header: "GitHub Sync"
1228
+ - question: "How would you like to sync with GitHub?"
1229
+ - options:
1230
+ - "Sync all (Recommended)" — Create/update feature and story issues
1231
+ - "Feature only" — Only create/update the feature issue
1232
+ - "Skip" — Don't sync to GitHub
1233
+
1234
+ **If "Skip":**
1235
+ Continue to step 13.
1236
+
1237
+ <!-- ── 12c: Execute sync ────────────────────────────────────────── -->
1238
+
1239
+ Display:
1240
+ ```
1241
+ ┌──────────────────────────────────────────────────┐
1242
+ │ ACE > Plan Feature > GitHub Sync │
1243
+ └──────────────────────────────────────────────────┘
1244
+
1245
+ i Syncing with GitHub...
1246
+ Repo: {REPO} | Project: #{PROJECT_NUMBER}
1247
+ ```
1248
+
1249
+ **Prerequisite — Resolve all field and type IDs (once, before creating any issues):**
1250
+
1251
+ ```bash
1252
+ GH_FIELDS=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github resolve-fields repo={REPO} owner={OWNER} project={PROJECT_NUMBER})
1253
+ ```
1254
+
1255
+ Parse the JSON response. Extract and cache:
1256
+ - `issue_types.Feature` -> FEATURE_TYPE_ID
1257
+ - `issue_types.Story` -> STORY_TYPE_ID (if exists; handle gracefully if not)
1258
+ - `project_id` -> PROJECT_ID
1259
+ - `fields.Status.id` -> STATUS_FIELD_ID
1260
+ - `fields.Status.options` -> STATUS_OPTIONS map
1261
+ - `fields.Priority.id` -> PRIORITY_FIELD_ID (if exists)
1262
+ - `fields.Priority.options` -> PRIORITY_OPTIONS map
1263
+ - `fields.Estimate.id` -> ESTIMATE_FIELD_ID (if exists)
1264
+
1265
+ **Create feature issue (if `NEEDS_GITHUB_CREATE` is true):**
1266
+
1267
+ Determine the parent epic's GitHub issue number from BACKLOG_INDEX:
1268
+ - If the parent epic has a Link column value like `[#45](url)`, extract issue number 45.
1269
+ - If the parent epic has no GitHub issue (Link = "—"), warn user and skip parent assignment.
1270
+
1271
+ ```bash
1272
+ FEATURE_RESULT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github create-issue \
1273
+ type=Feature \
1274
+ "title={Feature Title}" \
1275
+ body_file={FEATURE_FILE} \
1276
+ repo={REPO} \
1277
+ owner={OWNER} \
1278
+ project={PROJECT_NUMBER} \
1279
+ project_id={PROJECT_ID} \
1280
+ type_id={FEATURE_TYPE_ID} \
1281
+ status_field_id={STATUS_FIELD_ID} \
1282
+ status_option_id={STATUS_OPTIONS[status]} \
1283
+ estimate_field_id={ESTIMATE_FIELD_ID} \
1284
+ estimate={size_value} \
1285
+ [priority_field_id={PRIORITY_FIELD_ID} priority_option_id={PRIORITY_OPTIONS[priority]}] \
1286
+ [parent={epic_issue_number}] \
1287
+ [milestone={Milestone}])
1288
+ ```
1289
+
1290
+ Parse the JSON response: `number`, `url`, `item_id`.
1291
+ Store the feature's issue number for use as parent when creating stories.
1292
+
1293
+ Display:
1294
+ ```
1295
+ + Created [Feature] {Title} -> #{number} (parent: #{epic_number})
1296
+ ```
1297
+
1298
+ **Update existing feature issue (if `GITHUB_FEATURE_ISSUE` is true — feature already has a GitHub issue):**
1299
+
1300
+ The feature file IS the body. 100% of `{FEATURE_FILE}` goes to GitHub as-is.
1301
+
1302
+ ```bash
1303
+ node ~/.claude/agile-context-engineering/src/ace-tools.js github update-issue \
1304
+ number={feature_issue_number} \
1305
+ repo={REPO} \
1306
+ "title={Feature Title}" \
1307
+ body_file={FEATURE_FILE}
1308
+ ```
1309
+
1310
+ Display:
1311
+ ```
1312
+ ~ Updated [Feature] #{feature_issue_number} — {Title}
1313
+ ```
1314
+
1315
+ **If "Sync all" selected, sync ALL story issues:**
1316
+
1317
+ For each story in the story breakdown:
1318
+
1319
+ **If the story has NO GitHub issue (Link = "—") — CREATE:**
1320
+
1321
+ The story stub file IS the body. 100% of `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1322
+ goes to GitHub as-is. The story stub files were created in step 9c.
1323
+
1324
+ ```bash
1325
+ STORY_RESULT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js github create-issue \
1326
+ type=Story \
1327
+ "title={Story Title}" \
1328
+ body_file={FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md \
1329
+ repo={REPO} \
1330
+ owner={OWNER} \
1331
+ project={PROJECT_NUMBER} \
1332
+ project_id={PROJECT_ID} \
1333
+ [type_id={STORY_TYPE_ID}] \
1334
+ status_field_id={STATUS_FIELD_ID} \
1335
+ status_option_id={STATUS_OPTIONS["Todo"]} \
1336
+ estimate_field_id={ESTIMATE_FIELD_ID} \
1337
+ estimate={story_size_value} \
1338
+ [parent={feature_issue_number}])
1339
+ ```
1340
+
1341
+ Parse response: `number`, `url`.
1342
+
1343
+ Display:
1344
+ ```
1345
+ + Created [Story] {Title} -> #{number} (parent: #{feature_number})
1346
+ ```
1347
+
1348
+ **If the story ALREADY has a GitHub issue (Link != "—") — UPDATE:**
1349
+
1350
+ The story stub file IS the body. 100% of `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md`
1351
+ goes to GitHub as-is.
1352
+
1353
+ ```bash
1354
+ node ~/.claude/agile-context-engineering/src/ace-tools.js github update-issue \
1355
+ number={story_issue_number} \
1356
+ repo={REPO} \
1357
+ "title={Story Title}" \
1358
+ body_file={FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md
1359
+ ```
1360
+
1361
+ Display:
1362
+ ```
1363
+ ~ Updated [Story] #{story_issue_number} — {Title}
1364
+ ```
1365
+
1366
+ Each story's **parent is set to the feature's GitHub issue number** (either pre-existing
1367
+ or just created above). Stories get their rough Fibonacci estimate from the feature
1368
+ planning session (plan-story may refine later).
1369
+
1370
+ <!-- ── 12d: Update feature file and story files with GitHub links ── -->
1371
+
1372
+ After all creates, read `{FEATURE_FILE}` and update:
1373
+ - Feature header Link field: from "—" to `[#N](url)`
1374
+ - Feature header ID: from F[N] to #[N] if feature issue was created
1375
+ - Story index table Link column: from "—" to `[#N](url)` for each newly created story
1376
+ - Story index table ID: from S[N] to #[N] for each newly created story
1377
+
1378
+ Use the Edit tool for targeted replacements in the markdown.
1379
+
1380
+ Also update each story stub file in `{FEATURE_DIR}/{story_slug}/`:
1381
+ - If the story file exists and was just linked to a GitHub issue, update its header
1382
+ to reflect the new issue number and link.
1383
+ - If the ID changed (e.g., S1 became #92), rename the story directory and file:
1384
+ rename `{FEATURE_DIR}/{old_story_slug}/` to `{FEATURE_DIR}/{new_story_slug}/`
1385
+ and rename the file inside from `{old_story_slug}.md` to `{new_story_slug}.md`.
1386
+
1387
+ <!-- ── 12e: Sync new feature GitHub ID back to product-backlog.md ── -->
1388
+
1389
+ If a feature GitHub issue was created, read `.ace/artifacts/product/product-backlog.md`
1390
+ and update the feature row in the parent epic's detail table:
1391
+ - ID column: change F[N] to #[issue_number]
1392
+ - Link column: change "—" to `[#N](https://github.com/{REPO}/issues/N)`
1393
+ - Title: update to match the GitHub issue title exactly
1394
+
1395
+ Stories are NOT tracked in the backlog — only update the feature row.
1396
+
1397
+ Use the Edit tool for targeted replacements in the markdown.
1398
+ Preserve table alignment — pad ALL cells so | separators align vertically.
1399
+
1400
+ Display summary:
1401
+ ```
1402
+ + Created {N} GitHub issues.
1403
+ Synced feature ID back to product-backlog.md.
1404
+ Updated feature file and story files with GitHub links.
1405
+ ```
1406
+
1407
+ Continue to step 13.
1408
+ </step>
1409
+
1410
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1411
+ <!-- STEP 13: COMMIT -->
1412
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1413
+
1414
+ <step name="commit" order="13">
1415
+ Stage and commit all changed files in a single commit.
1416
+ Only stage files that actually changed (use `git diff` / `git status` to check).
1417
+
1418
+ Files that may have changed:
1419
+ - `{FEATURE_FILE}` — always (this is the main output)
1420
+ - `{FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md` — story stub files created in step 9c
1421
+ - `{FEATURE_DIR}/relevant-wiki.md` — if wiki research was run/regenerated in step 5
1422
+ - `{FEATURE_DIR}/relevant-code.md` — if code research was run/regenerated in step 6
1423
+ - `.ace/artifacts/product/product-backlog.md` — if feature was added or status updated
1424
+
1425
+ Stage specifically:
1426
+ ```bash
1427
+ git add {FEATURE_DIR}/
1428
+ git add .ace/artifacts/product/product-backlog.md
1429
+ ```
1430
+
1431
+ Commit with a message that reflects what happened:
1432
+ - CREATE mode: `git commit -m "docs: plan feature {Feature ID} — {Feature Title}"`
1433
+ - REFINE mode: `git commit -m "docs: refine feature {Feature ID} — {brief summary of changes}"`
1434
+ Examples:
1435
+ - "docs: refine feature F3 — add 2 stories, update scope"
1436
+ - "docs: refine feature #78 — revise acceptance criteria"
1437
+
1438
+ Display completion (adapt banner to mode):
1439
+
1440
+ ```
1441
+ ╔══════════════════════════════════════════════════╗
1442
+ ║ ACE > Feature [Planned | Refined] ║
1443
+ ║ {Feature ID} "{Feature Title}" ║
1444
+ ╚══════════════════════════════════════════════════╝
1445
+
1446
+ + {FEATURE_FILE} committed.
1447
+ [If REFINE: Refinement #{count}]
1448
+
1449
+ Summary:
1450
+ ────────
1451
+ {N} stories | Size: {size} | Priority: {priority}
1452
+ Acceptance criteria: {M}
1453
+ [If brownfield: Existing implementation documented]
1454
+
1455
+ i Story descriptions are ready for formal planning.
1456
+ Run plan-story on each to create INVEST stories
1457
+ with Gherkin acceptance criteria.
1458
+
1459
+ Next > /ace:plan-story {Feature ID}-S1
1460
+ Plan the first story with formal specification.
1461
+ > /ace:plan-feature {next feature ID}
1462
+ Plan the next feature in the backlog.
1463
+ ```
1464
+ </step>
1465
+
1466
+ </process>
1467
+
1468
+ <success_criteria>
1469
+ - Init function executed (environment detected, brownfield status checked, GitHub settings loaded)
1470
+ - Feature located in product backlog (or marked for addition if new)
1471
+ - CREATE vs REFINE mode correctly determined
1472
+ - Product vision and backlog loaded as foundation context
1473
+ - Wiki research: reused from cache, regenerated, or skipped (brownfield only)
1474
+ - Code research: reused from cache, regenerated, or skipped (brownfield only)
1475
+ - Parallelism rule applied: code research runs immediately if wiki from cache, waits if wiki regenerating
1476
+ - Both research agents follow context window protection (write to disk, return ~10 lines only)
1477
+ - No TaskOutput called after background agent spawning
1478
+ - Deep questioning adapted to mode (CREATE vs REFINE) and context richness (RICH/MODERATE/LEAN/BARE)
1479
+ - All feature.xml template fields addressed during questioning
1480
+ - Benefit hypothesis follows SAFe format (measurable, falsifiable, user-focused)
1481
+ - Acceptance criteria are feature-level (NOT Gherkin)
1482
+ - Story breakdown: as many stories as naturally emerge, each a vertical slice with rich plain-text description
1483
+ - Story sizes: rough Fibonacci estimates (1, 2, 3, 5, 8) assigned during questioning
1484
+ - Feature document written following template structure exactly
1485
+ - Individual story stub files created in {FEATURE_DIR}/{STORY_SLUG}/{STORY_SLUG}.md (each story in own subdirectory, skipping already-existing files)
1486
+ - Existing IDs and GitHub links preserved during refinement
1487
+ - Backlog updated: new feature added or status changed to Refined
1488
+ - User reviewed and approved the document
1489
+ - GitHub sync: feature parent set to epic issue, story parents set to feature issue
1490
+ - GitHub identity preservation: #N for linked items, S[N] for local stories
1491
+ - Link columns updated after GitHub issue creation (both feature file and backlog)
1492
+ - Document committed with mode-appropriate message
1493
+ </success_criteria>
1494
+
1495
+ </workflow>