agile-context-engineering 0.3.0 → 0.5.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 (147) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/LICENSE +51 -51
  3. package/README.md +332 -324
  4. package/agents/ace-product-owner.md +1 -1
  5. package/agents/ace-research-synthesizer.md +228 -228
  6. package/agents/ace-wiki-mapper.md +449 -445
  7. package/bin/install.js +60 -64
  8. package/hooks/ace-check-update.js +70 -62
  9. package/hooks/ace-statusline.js +89 -89
  10. package/package.json +5 -4
  11. package/shared/lib/ace-core.js +308 -0
  12. package/shared/lib/ace-core.test.js +308 -0
  13. package/shared/lib/ace-github.js +753 -0
  14. package/shared/lib/ace-story.js +400 -0
  15. package/shared/lib/ace-story.test.js +250 -0
  16. package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
  17. package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
  18. package/skills/execute-story/SKILL.md +110 -0
  19. package/skills/execute-story/script.js +305 -0
  20. package/skills/execute-story/script.test.js +261 -0
  21. package/skills/execute-story/walkthrough-template.xml +255 -0
  22. package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1219 -1219
  23. package/skills/help/SKILL.md +69 -0
  24. package/skills/help/script.js +318 -0
  25. package/skills/help/script.test.js +183 -0
  26. package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +540 -540
  27. package/skills/init-coding-standards/SKILL.md +72 -0
  28. package/skills/init-coding-standards/script.js +59 -0
  29. package/skills/init-coding-standards/script.test.js +70 -0
  30. package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
  31. package/skills/map-cross-cutting/SKILL.md +89 -0
  32. package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
  33. package/skills/map-cross-cutting/workflow.xml +330 -0
  34. package/skills/map-guide/SKILL.md +89 -0
  35. package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
  36. package/skills/map-guide/workflow.xml +320 -0
  37. package/skills/map-pattern/SKILL.md +89 -0
  38. package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
  39. package/skills/map-pattern/workflow.xml +331 -0
  40. package/skills/map-story/SKILL.md +127 -0
  41. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
  42. package/skills/map-story/templates/guide.xml +137 -0
  43. package/skills/map-story/templates/pattern.xml +159 -0
  44. package/skills/map-story/templates/system-cross-cutting.xml +197 -0
  45. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
  46. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
  47. package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
  48. package/skills/map-subsystem/SKILL.md +111 -0
  49. package/skills/map-subsystem/script.js +60 -0
  50. package/skills/map-subsystem/script.test.js +68 -0
  51. package/skills/map-subsystem/templates/decizions.xml +115 -0
  52. package/skills/map-subsystem/templates/guide.xml +137 -0
  53. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
  54. package/skills/map-subsystem/templates/pattern.xml +159 -0
  55. package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
  56. package/skills/map-subsystem/templates/system.xml +381 -0
  57. package/skills/map-subsystem/templates/walkthrough.xml +255 -0
  58. package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +15 -20
  59. package/skills/map-sys-doc/SKILL.md +90 -0
  60. package/skills/map-sys-doc/system.xml +381 -0
  61. package/skills/map-sys-doc/workflow.xml +336 -0
  62. package/skills/map-system/SKILL.md +85 -0
  63. package/skills/map-system/script.js +84 -0
  64. package/skills/map-system/script.test.js +73 -0
  65. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
  66. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
  67. package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +11 -16
  68. package/skills/map-walkthrough/SKILL.md +92 -0
  69. package/skills/map-walkthrough/walkthrough.xml +255 -0
  70. package/skills/plan-backlog/SKILL.md +75 -0
  71. package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
  72. package/skills/plan-backlog/script.js +136 -0
  73. package/skills/plan-backlog/script.test.js +83 -0
  74. package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +13 -21
  75. package/skills/plan-feature/SKILL.md +76 -0
  76. package/skills/plan-feature/script.js +148 -0
  77. package/skills/plan-feature/script.test.js +80 -0
  78. package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
  79. package/skills/plan-product-vision/SKILL.md +75 -0
  80. package/skills/plan-product-vision/script.js +60 -0
  81. package/skills/plan-product-vision/script.test.js +69 -0
  82. package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +4 -9
  83. package/skills/plan-story/SKILL.md +116 -0
  84. package/skills/plan-story/script.js +326 -0
  85. package/skills/plan-story/script.test.js +240 -0
  86. package/skills/plan-story/story-template.xml +451 -0
  87. package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1285 -944
  88. package/skills/research-external-solution/SKILL.md +107 -0
  89. package/skills/research-external-solution/script.js +238 -0
  90. package/skills/research-external-solution/script.test.js +134 -0
  91. package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +4 -6
  92. package/skills/research-integration-solution/SKILL.md +98 -0
  93. package/skills/research-integration-solution/script.js +231 -0
  94. package/skills/research-integration-solution/script.test.js +134 -0
  95. package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +3 -5
  96. package/skills/research-story-wiki/SKILL.md +92 -0
  97. package/skills/research-story-wiki/script.js +231 -0
  98. package/skills/research-story-wiki/script.test.js +138 -0
  99. package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +3 -5
  100. package/skills/research-technical-solution/SKILL.md +103 -0
  101. package/skills/research-technical-solution/script.js +231 -0
  102. package/skills/research-technical-solution/script.test.js +134 -0
  103. package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +3 -5
  104. package/skills/review-story/SKILL.md +100 -0
  105. package/skills/review-story/script.js +257 -0
  106. package/skills/review-story/script.test.js +169 -0
  107. package/skills/review-story/story-template.xml +451 -0
  108. package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
  109. package/skills/update/SKILL.md +53 -0
  110. package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +12 -13
  111. package/agile-context-engineering/src/ace-tools.js +0 -2881
  112. package/agile-context-engineering/src/ace-tools.test.js +0 -1089
  113. package/agile-context-engineering/templates/_command.md +0 -54
  114. package/agile-context-engineering/templates/_workflow.xml +0 -17
  115. package/agile-context-engineering/templates/config.json +0 -0
  116. package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
  117. package/commands/ace/execute-story.md +0 -138
  118. package/commands/ace/help.md +0 -93
  119. package/commands/ace/init-coding-standards.md +0 -83
  120. package/commands/ace/map-story.md +0 -165
  121. package/commands/ace/map-subsystem.md +0 -140
  122. package/commands/ace/map-system.md +0 -92
  123. package/commands/ace/map-walkthrough.md +0 -127
  124. package/commands/ace/plan-backlog.md +0 -83
  125. package/commands/ace/plan-feature.md +0 -89
  126. package/commands/ace/plan-product-vision.md +0 -81
  127. package/commands/ace/plan-story.md +0 -159
  128. package/commands/ace/research-external-solution.md +0 -138
  129. package/commands/ace/research-integration-solution.md +0 -135
  130. package/commands/ace/research-story-wiki.md +0 -116
  131. package/commands/ace/research-technical-solution.md +0 -147
  132. package/commands/ace/review-story.md +0 -109
  133. package/commands/ace/update.md +0 -56
  134. /package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +0 -0
  135. /package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +0 -0
  136. /package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +0 -0
  137. /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +0 -0
  138. /package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +0 -0
  139. /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +0 -0
  140. /package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +0 -0
  141. /package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +0 -0
  142. /package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +0 -0
  143. /package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +0 -0
  144. /package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +0 -0
  145. /package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +0 -0
  146. /package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +0 -0
  147. /package/{agile-context-engineering/templates/product/story-technical-solution.xml → skills/research-technical-solution/technical-solution-template.xml} +0 -0
@@ -1,944 +1,1285 @@
1
- <workflow>
2
-
3
- <purpose>
4
- Orchestrate story specification: load a story seed (from file or GitHub issue),
5
- absorb any existing description, conduct deep questioning to define CRYSTAL-CLEAR
6
- acceptance criteria with ZERO ambiguity, write the story specification (pass 1),
7
- then dispatch passes 2-5 as background agents that write their outputs directly
8
- to files — keeping this orchestrator's context window clean.
9
-
10
- Produces `.ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/&lt;id-story_name&gt;.md`
11
- — a complete story specification with INVEST-compliant user story, Gherkin acceptance
12
- criteria, definition of done, scope boundaries, and relevant wiki references.
13
-
14
- Additionally produces (via background agents):
15
- - `external-analysis.md` in story directory (OPTIONAL — pass 3)
16
- - `integration-analysis.md` in story directory (pass 4)
17
- - Technical Solution section appended to story file (pass 5)
18
-
19
- The orchestrator's context window contains ONLY story requirements information.
20
- Passes 2-5 write to disk and return only completion confirmations.
21
- The orchestrator MUST NOT call TaskOutput on any background agent.
22
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
23
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
24
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
25
- </purpose>
26
-
27
- <mandatory-context>
28
- Read all files referenced by the invoking command's execution-context before starting.
29
- Also read any document or text passed as parameter ($ARGUMENTS) in the invoking command.
30
- </mandatory-context>
31
-
32
- <process>
33
-
34
- <!-- ══════════════════════════════════════════════════════════════════ -->
35
- <!-- STEP 1: SETUP -->
36
- <!-- ══════════════════════════════════════════════════════════════════ -->
37
-
38
- <step name="setup" order="1">
39
- **MANDATORY FIRST STEP — Execute environment detection before any user interaction:**
40
-
41
- Parse `$ARGUMENTS` to extract:
42
- - `story` (REQUIRED): file path or GitHub URL/issue number
43
- - `external-codebase` (OPTIONAL): path or GitHub URL to external system
44
- - `external-docs` (OPTIONAL): weblink or filepath to external docs
45
- - `lib-docs` (OPTIONAL): space-separated weblinks and/or filepaths to library documentation
46
-
47
- ```bash
48
- INIT=$(node ~/.claude/agile-context-engineering/src/ace-tools.js init plan-story {story_param})
49
- ```
50
-
51
- Parse INIT JSON for:
52
- - `product_owner_model`, `commit_docs`
53
- - `has_git`, `has_gh_cli`, `github_project`
54
- - `is_brownfield`, `is_greenfield`, `has_wiki`
55
- - `has_product_vision`, `has_product_backlog`
56
- - `story_source`, `story_valid`, `story_error`, `story_content`
57
- - `story` (id, title, status, size), `feature` (id, title), `epic` (id, title)
58
- - `user_story`, `description`, `acceptance_criteria_count`
59
- - `paths.*` (story_dir, story_file, feature_dir, feature_file, etc.)
60
- - `has_external_analysis`, `has_integration_analysis`, `has_feature_file`, `has_story_file`
61
-
62
- Also resolve the product owner model:
63
- ```bash
64
- PO_MODEL=$(node ~/.claude/agile-context-engineering/src/ace-tools.js resolve-model ace-product-owner --raw)
65
- ```
66
-
67
- Display stage banner:
68
-
69
- ```
70
- ╔══════════════════════════════════════════════════╗
71
- ║ ACE > Plan Story ║
72
- ╚══════════════════════════════════════════════════╝
73
- ```
74
-
75
- **If `has_git` is false:** Initialize git:
76
- ```bash
77
- git init
78
- ```
79
-
80
- **If `INIT.story_valid` is false:**
81
- Display error using `INIT.story_error` and exit:
82
- ```
83
- x {INIT.story_error}
84
- Provide a valid story file path or GitHub issue.
85
- ```
86
-
87
- Store `EXTERNAL_CODEBASE`, `EXTERNAL_DOCS`, and `LIB_DOCS` from parsed arguments (may be null).
88
- `LIB_DOCS` is a space-separated string of weblinks and/or filepaths.
89
- </step>
90
-
91
- <!-- ══════════════════════════════════════════════════════════════════ -->
92
- <!-- STEP 2: LOAD STORY SEED -->
93
- <!-- ══════════════════════════════════════════════════════════════════ -->
94
-
95
- <step name="load-story-seed" order="2">
96
-
97
- The story seed is the raw description of what needs to be built.
98
- It may come from:
99
- - A stub file created by `plan-feature` (has Description section)
100
- - A GitHub issue with free-text description
101
- - Any markdown file with story context
102
-
103
- **Read the story content** (already available in `INIT.story_content`).
104
- Parse and hold as `STORY_SEED`:
105
- - Title (from header or first heading)
106
- - Description (any free-text description of what needs to be done)
107
- - Any existing AC scenarios (if the story was previously partially refined)
108
- - Any images referenced (markdown `![](path)` or HTML `&lt;img src="path"&gt;`)
109
-
110
- <!-- ── 2a: Image validation ──────────────────────────────────── -->
111
-
112
- Extract ALL image references from the story content:
113
- - Markdown: `![alt](path)`
114
- - HTML: `&lt;img src="path"&gt;`
115
-
116
- For EACH image reference, attempt to READ it using the Read tool.
117
-
118
- **IF ANY IMAGE CANNOT BE READ:**
119
- ```
120
- x STOP: Cannot proceed — Referenced images are not accessible.
121
-
122
- Image validation results:
123
- - [image1.png] -> SUCCESS
124
- - [image2.png] -> FAILED: File not found
125
-
126
- Please provide correct paths or describe what each missing image contains.
127
- ```
128
- Wait for user response before proceeding.
129
-
130
- <!-- ── 2b: Detect run mode ───────────────────────────────────── -->
131
-
132
- **If `INIT.acceptance_criteria_count > 0`:**
133
- The story has existing AC — this is a REFINE run.
134
- Set `RUN_MODE = REFINE`.
135
-
136
- Use AskUserQuestion:
137
- - header: "Story exists"
138
- - question: "This story already has {INIT.acceptance_criteria_count} acceptance criteria scenarios. What would you like to do?"
139
- - options:
140
- - "Refine it" — Review and update the existing specification
141
- - "Start fresh" — Discard existing AC and rebuild from the description
142
- - "Skip to research" — Keep current AC, skip to passes 2-5
143
-
144
- If "Start fresh": set `RUN_MODE = CREATE`, clear existing AC from working copy.
145
- If "Skip to research": jump directly to step 7 (dispatch passes 2-5).
146
- If "Refine it": continue to step 3 with existing content as context.
147
-
148
- **If `INIT.acceptance_criteria_count == 0`:**
149
- Set `RUN_MODE = CREATE`. Continue to step 3.
150
-
151
- Display:
152
- ```
153
- i Story loaded: {title}
154
- Source: {file path or GitHub issue}
155
- Mode: {CREATE | REFINE}
156
- Description: {first 100 chars of description}...
157
- ```
158
- </step>
159
-
160
- <!-- ══════════════════════════════════════════════════════════════════ -->
161
- <!-- STEP 3: LOAD FOUNDATION CONTEXT -->
162
- <!-- ══════════════════════════════════════════════════════════════════ -->
163
-
164
- <step name="load-foundation" order="3">
165
-
166
- **3a. Load parent feature document (if exists):**
167
-
168
- If `INIT.has_feature_file` is true:
169
- - Read the feature document at `INIT.paths.feature_file`
170
- - Extract: Feature description, scope (includes/excludes), benefit hypothesis,
171
- story breakdown (other stories and their scopes), acceptance criteria, technical context
172
- - Hold as `FEATURE_CONTEXT`
173
-
174
- If false: set `FEATURE_CONTEXT = null`
175
-
176
- **3b. Load product vision (if exists):**
177
-
178
- If `INIT.has_product_vision` is true:
179
- - Read `.docs/product/product-vision.md`
180
- - Extract personas, target audience, key objectives
181
- - Hold as `VISION` (used to validate persona in user story statement)
182
-
183
- If false: set `VISION = null`
184
-
185
- **3c. Load product backlog (if exists):**
186
-
187
- If `INIT.has_product_backlog` is true:
188
- - Read `.ace/artifacts/product/product-backlog.md`
189
- - Extract the parent epic's context and any related features
190
- - Hold as `BACKLOG_CONTEXT`
191
-
192
- If false: set `BACKLOG_CONTEXT = null`
193
-
194
- Display loaded context:
195
- ```
196
- i Context loaded:
197
- [+] Parent feature document ({lines} lines)
198
- [+] Product vision (personas: {list})
199
- [ ] Product backlog (not found)
200
- ```
201
- </step>
202
-
203
- <!-- ══════════════════════════════════════════════════════════════════ -->
204
- <!-- STEP 4: DEEP QUESTIONING -->
205
- <!-- ══════════════════════════════════════════════════════════════════ -->
206
-
207
- <step name="deep-questioning" order="4">
208
- Follow the questioning guide from `questioning.xml`. You are a thinking partner,
209
- not an interviewer.
210
-
211
- Display:
212
- ```
213
- ┌──────────────────────────────────────────────────┐
214
- │ ACE > Plan Story > Questioning │
215
- └──────────────────────────────────────────────────┘
216
- ```
217
-
218
- <!-- ── 4a: Opening present what you know ───────────────────── -->
219
-
220
- Start by presenting your understanding of the story from the seed:
221
-
222
- "Based on the story description and feature context, here's what I understand
223
- this story delivers: {summary}. Let me ask some questions to make sure the
224
- acceptance criteria are crystal clear."
225
-
226
- If FEATURE_CONTEXT is available, reference the story's position within
227
- the feature what it builds on and what it enables.
228
-
229
- <!-- ── 4b: ZERO-ASSUMPTION questioning ───────────────────────── -->
230
-
231
- **CRITICAL MANDATE: ZERO ASSUMPTIONS**
232
-
233
- Every acceptance criterion MUST be so explicit that an AI agent with NO prior
234
- context can implement it correctly. This means:
235
-
236
- **For EVERY behavior, probe until you have:**
237
- 1. **Exact trigger** What SPECIFIC user action or system event starts this?
238
- - Bad: "When the user submits" Submit what? Where? How?
239
- - Good: "When the user clicks the 'Save' button on the Settings page"
240
-
241
- 2. **Exact preconditions** What state MUST exist before the trigger?
242
- - Bad: "Given the user is logged in" → What kind of user? What permissions?
243
- - Good: "Given a user with 'admin' role is authenticated and on the Dashboard page"
244
-
245
- 3. **Exact expected outcome** What OBSERVABLE result occurs?
246
- - Bad: "Then it works" How do you KNOW it works?
247
- - Bad: "Then the data is saved" → Saved WHERE? What confirmation does the user see?
248
- - Good: "Then a success toast appears with message 'Settings saved' and the page
249
- reflects the updated value without requiring a refresh"
250
-
251
- 4. **Exact data/values** — What SPECIFIC data is involved?
252
- - Bad: "The form has fields" → Which fields? What types? What validation?
253
- - Good: "The form contains: Name (text, required, max 100 chars), Email (email format,
254
- required), Role (dropdown: Admin/Editor/Viewer, default: Viewer)"
255
-
256
- 5. **Exact error handling** — What happens when things go wrong?
257
- - Bad: "Show an error" → What error? Where? What message?
258
- - Good: "Display inline validation error below the Email field: 'Please enter a valid
259
- email address' in red (#DC3545), field border turns red"
260
-
261
- 6. **Exact edge cases** — What happens at boundaries?
262
- - What if the list is empty? What placeholder is shown?
263
- - What if the input is at max length? What happens at max+1?
264
- - What if the network request fails? Timeout? 403? 500?
265
- - What if the user double-clicks? Navigates away mid-operation?
266
-
267
- **QUESTIONING TECHNIQUES for extracting precision:**
268
-
269
- - "You said [vague thing]. What does that actually look like on screen?"
270
- - "Walk me through exactly what happens, step by step, from the user's perspective."
271
- - "What does the user SEE when this succeeds? What EXACT message, where on the page?"
272
- - "What if [edge case]? What should happen? What should the user see?"
273
- - "You mentioned [behavior]. Is that a modal dialog, an inline message, a page redirect, or something else?"
274
- - "When you say 'update', do you mean replace the entire record, merge specific fields, or append?"
275
- - "What validation rules apply? Be specific: required/optional, min/max, format, allowed values."
276
- - "How does the user know this worked? What visual feedback do they get?"
277
-
278
- **USE AskUserQuestion for specific clarification:**
279
-
280
- When the user gives a vague answer, present concrete interpretations:
281
-
282
- ```
283
- header: "Behavior"
284
- question: "When the save fails due to network error, what should the user see?"
285
- options:
286
- - "Toast notification" — Non-blocking message at top of page
287
- - "Modal dialog" — Blocking popup requiring acknowledgment
288
- - "Inline error" — Error message below the form
289
- - "Let me explain" — Different approach
290
- ```
291
-
292
- <!-- ── 4c: Template-field coverage (background checklist) ────── -->
293
-
294
- As you question, mentally track coverage against story.xml template sections:
295
- - [ ] **User Story** — As/I want/So that (persona must match vision if available)
296
- - [ ] **Description** 2-4 sentences of observable user behavior and feature context
297
- - [ ] **Acceptance Criteria** — ALL scenarios with EXACT Given/When/Then
298
- - [ ] Happy path(s) — main success scenario(s)
299
- - [ ] Edge cases — boundary conditions, empty states, max limits
300
- - [ ] Error paths — validation failures, network errors, permission issues
301
- - [ ] Each scenario: EXACT trigger, EXACT precondition, EXACT outcome
302
- - [ ] **Out of Scope** Things someone might assume are included but are NOT
303
- - [ ] **Dependencies**Blocked by, Blocks, External
304
- - [ ] **Definition of Done** Any story-specific additions to the default checklist
305
- - [ ] **Size** — Fibonacci estimate (1, 2, 3, 5, 8)
306
-
307
- Don't walk through this as a checklist. Weave questions naturally.
308
- When gaps remain after conversation feels complete, probe those areas.
309
-
310
- <!-- ── 4d: AC Scenario crafting ──────────────────────────────── -->
311
-
312
- Once you have enough context, draft the Gherkin scenarios:
313
-
314
- Present each scenario and VALIDATE with the user:
315
-
316
- ```
317
- Here's what I have so far:
318
-
319
- ### Scenario: Successful settings save
320
- **Given** an admin user is on the Settings page with unsaved changes
321
- **When** they click the "Save Settings" button
322
- **Then** a success toast appears with message "Settings saved successfully"
323
- **And** the updated values are reflected on the page without refresh
324
- **And** the "Save Settings" button becomes disabled (no unsaved changes)
325
-
326
- ### Scenario: Validation failure — invalid email
327
- **Given** an admin user is on the Settings page
328
- **When** they enter "not-an-email" in the Contact Email field and click "Save Settings"
329
- **Then** the Contact Email field border turns red
330
- **And** an inline error appears below the field: "Please enter a valid email address"
331
- **And** the form is NOT submitted
332
- **And** focus moves to the Contact Email field
333
-
334
- Does this capture the behavior correctly? Anything missing or wrong?
335
- ```
336
-
337
- Use AskUserQuestion:
338
- - header: "Scenarios"
339
- - question: "Review the acceptance criteria scenarios above. Are they correct and complete?"
340
- - options:
341
- - "Looks good" Scenarios are accurate and complete
342
- - "Fix a scenario" — Something is wrong or missing in a scenario
343
- - "Add a scenario" — There's a case I haven't mentioned
344
- - "Too many" — Some scenarios should be removed or combined
345
-
346
- Loop until the user confirms all scenarios are correct.
347
-
348
- **CRITICAL: Scenario count check.**
349
- If more than 6-8 scenarios are needed, the story is likely too large:
350
- ```
351
- ! This story has {N} scenarios, which suggests it may be too large.
352
- Stories with more than 6-8 scenarios should usually be split.
353
- ```
354
-
355
- Use AskUserQuestion:
356
- - header: "Story size"
357
- - question: "This story has {N} acceptance criteria. Should we split it?"
358
- - options:
359
- - "Keep as-is" — The story is coherent and should not be split
360
- - "Split it" — Let's break this into smaller stories
361
-
362
- If "Split it": discuss the split, identify natural cut points, and restart
363
- questioning for the reduced-scope story.
364
-
365
- <!-- ── 4e: Decision gate ─────────────────────────────────────── -->
366
-
367
- When story specification feels complete:
368
-
369
- Use AskUserQuestion:
370
- - header: "Ready?"
371
- - question: "I have the full story spec: {N} acceptance criteria, size {estimate}. Ready to write the story document?"
372
- - options:
373
- - "Write story document" — Create the specification
374
- - "Keep exploring" — I want to add or change something
375
- - "Show summary" — Show me what you have before deciding
376
-
377
- If "Show summary":
378
- ```
379
- Story: {ID} — {Title}
380
- Feature: {Feature ID} {Feature Title}
381
-
382
- User Story:
383
- > As a [persona], I want [action], so that [benefit].
384
-
385
- Description: {2-4 sentences}
386
-
387
- Acceptance Criteria: {N} scenarios
388
- 1. {scenario name} {one-line summary}
389
- 2. {scenario name} — {one-line summary}
390
- ...
391
-
392
- Out of Scope: {M} items
393
- Size: {estimate}
394
- ```
395
- Return to decision gate.
396
-
397
- If "Keep exploring" — ask what they want to add or identify gaps.
398
- Loop until "Write story document" selected.
399
- </step>
400
-
401
- <!-- ══════════════════════════════════════════════════════════════════ -->
402
- <!-- STEP 5: WRITE STORY DOCUMENT (Pass 1) -->
403
- <!-- ══════════════════════════════════════════════════════════════════ -->
404
-
405
- <step name="write-story" order="5">
406
-
407
- Display:
408
- ```
409
- ┌──────────────────────────────────────────────────┐
410
- │ ACE > Plan Story > Writing Document (Pass 1) │
411
- └──────────────────────────────────────────────────┘
412
-
413
- i Writing story specification...
414
- Output: {STORY_FILE}
415
- ```
416
-
417
- Create directory structure:
418
- ```bash
419
- mkdir -p {INIT.paths.story_dir}
420
- ```
421
-
422
- Prepare the full story document following the story.xml template EXACTLY.
423
- Include ALL sections 1-8:
424
- - **Header**: Story ID, Title, Feature reference, Epic reference, Status=Refined,
425
- Size, Sprint=—, Link
426
- - **User Story**: As/I want/So that format
427
- - **Description**: 2-4 sentences of observable behavior and feature context
428
- - **Acceptance Criteria**: ALL Gherkin scenarios from questioning
429
- - **Out of Scope**: Explicit exclusions
430
- - **Dependencies**: Blocked By, Blocks, External
431
- - **Definition of Done**: Standard checklist + any story-specific items
432
- - **Relevant Wiki**: Placeholder — `&lt;!-- Pass 2. Populated by research-story-wiki. --&gt;`
433
- - **Technical Solution**: Placeholder `&lt;!-- Pass 5. Populated by research-technical-solution. --&gt;`
434
- - **Metadata**: Created date, Last refined date, Refinements count, Feature path
435
-
436
- Write the file using the Write tool to `{INIT.paths.story_file}`.
437
-
438
- **If RUN_MODE is REFINE:**
439
- Increment the metadata refinement count and update "Last refined" date.
440
- Preserve any existing Relevant Wiki or Technical Solution sections.
441
-
442
- Display:
443
- ```
444
- + Story specification written to {INIT.paths.story_file}
445
- Sections 1-8 complete. {N} acceptance criteria scenarios.
446
- ```
447
- </step>
448
-
449
- <!-- ══════════════════════════════════════════════════════════════════ -->
450
- <!-- STEP 6: REVIEW AND APPROVE (Pass 1) -->
451
- <!-- ══════════════════════════════════════════════════════════════════ -->
452
-
453
- <step name="review-pass1" order="6">
454
-
455
- Use AskUserQuestion:
456
- - header: "Story"
457
- - question: "Story specification written to `{INIT.paths.story_file}`. Review the file in your editor. Does it look right?"
458
- - options:
459
- - "Approve" — Looks good, proceed to research passes
460
- - "Adjust" I want to change some things
461
- - "Redo questioning"Let's go back and explore more
462
-
463
- **If "Adjust":**
464
- - Ask what needs changing
465
- - Apply edits using the Edit tool directly on `{INIT.paths.story_file}`
466
- - Present for review again. Loop until approved.
467
-
468
- **If "Redo questioning":**
469
- - Return to step 4 (deep-questioning)
470
- - Preserve FEATURE_CONTEXT, VISION, BACKLOG_CONTEXT
471
- - Hold previous answers as additional context
472
-
473
- **If "Approve":**
474
- Continue to step 7.
475
- </step>
476
-
477
- <!-- ══════════════════════════════════════════════════════════════════ -->
478
- <!-- STEP 7: DISPATCH RESEARCH PASSES (2-5) -->
479
- <!-- ══════════════════════════════════════════════════════════════════ -->
480
-
481
- <step name="dispatch-research" order="7">
482
-
483
- Display:
484
- ```
485
- ┌──────────────────────────────────────────────────┐
486
- │ ACE > Plan Story > Research Passes │
487
- └──────────────────────────────────────────────────┘
488
-
489
- i Story requirements complete. Dispatching research passes...
490
- ```
491
-
492
- <!-- ── 7a: Offer external analysis (Pass 3 — OPTIONAL) ──────── -->
493
-
494
- **If `EXTERNAL_CODEBASE` was provided as parameter:**
495
- Set `RUN_EXTERNAL = true`.
496
-
497
- **If `EXTERNAL_CODEBASE` was NOT provided:**
498
-
499
- Use AskUserQuestion:
500
- - header: "External"
501
- - question: "Does this story reference an external system or reference implementation you'd like to analyze?"
502
- - options:
503
- - "No external system" — Skip external analysis
504
- - "Yes, provide path" I have an external codebase to analyze
505
-
506
- If "Yes, provide path":
507
- Ask for the external-codebase path (and optionally external-docs).
508
- Set `EXTERNAL_CODEBASE` and `EXTERNAL_DOCS` from user response.
509
- Set `RUN_EXTERNAL = true`.
510
-
511
- If "No external system":
512
- Set `RUN_EXTERNAL = false`.
513
-
514
- <!-- ── 7b: Dispatch Pass 2 — Wiki Research ──────────────────── -->
515
-
516
- **If `has_wiki` is false:** Skip pass 2. Display:
517
- ```
518
- i No wiki found. Skipping pass 2 (wiki research).
519
- ```
520
-
521
- **If `has_wiki` is true:**
522
-
523
- Display:
524
- ```
525
- i Pass 2: Dispatching wiki research...
526
- Agent will update story file with Relevant Wiki section.
527
- ```
528
-
529
- **CRITICAL — Context Window Protection:**
530
- The agent writes to the story file and returns ONLY a ~10-line confirmation.
531
- This prevents agent output from inflating the main context window.
532
-
533
- **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
534
- After spawning the background agent, do NOT call TaskOutput to read its results.
535
- You will be automatically notified when the agent completes — IGNORE those notifications.
536
- The agent writes directly to the story file on disk. You do not need the return message.
537
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
538
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
539
- After the notification arrives, verify the file with `wc -l`, then READ the file
540
- directly from disk using the Read tool if needed. That is how you get the results.
541
-
542
- Spawn background agent:
543
- ```
544
- Agent(
545
- prompt="/ace:research-story-wiki story={INIT.paths.story_file}
546
-
547
- Execute the research-story-wiki workflow end-to-end.
548
- Write the Relevant Wiki section directly into the story file.
549
-
550
- **Return format ONLY this, nothing else:**
551
- DONE
552
- - Story: {story ID} — {story title}
553
- - Wiki refs: {count} total ({system_wide} system-wide + {subsystem} subsystem)
554
- - File updated: {story file path}",
555
- subagent_type="ace-wiki-mapper",
556
- model="{PO_MODEL}",
557
- run_in_background=true,
558
- description="Pass 2: Wiki research"
559
- )
560
- ```
561
-
562
- Store the agent task ID as `PASS2_TASK`.
563
-
564
- **After background notification arrives IGNORE it:**
565
-
566
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
567
- Just verify the file and read it directly from disk if needed.
568
-
569
- <!-- ── 7c: Dispatch Pass 3 External Analysis (OPTIONAL) ───── -->
570
-
571
- **If `RUN_EXTERNAL` is false:** Skip pass 3.
572
-
573
- **If `RUN_EXTERNAL` is true:**
574
-
575
- Display:
576
- ```
577
- i Pass 3: Dispatching external analysis...
578
- Agent will create external-analysis.md in story directory.
579
- ```
580
-
581
- **CRITICAL Context Window Protection:**
582
- The agent writes to a separate file and returns ONLY a ~10-line confirmation.
583
- This prevents agent output from inflating the main context window.
584
-
585
- **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
586
- After spawning the background agent, do NOT call TaskOutput to read its results.
587
- You will be automatically notified when the agent completes — IGNORE those notifications.
588
- The agent writes to `{INIT.paths.external_analysis_file}` on disk. You do not need the return message.
589
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
590
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
591
-
592
- Spawn background agent:
593
- ```
594
- Agent(
595
- prompt="/ace:research-external-solution story={INIT.paths.story_file} external-codebase={EXTERNAL_CODEBASE} {external-docs={EXTERNAL_DOCS} if provided}
596
-
597
- Execute the research-external-solution workflow end-to-end.
598
- Write the output to {INIT.paths.external_analysis_file}.
599
-
600
- **Return format ONLY this, nothing else:**
601
- DONE
602
- - Story: {story ID} {story title}
603
- - External files analyzed: {count}
604
- - Output: {external analysis file path}",
605
- subagent_type="ace-code-discovery-analyst",
606
- model="{PO_MODEL}",
607
- run_in_background=true,
608
- description="Pass 3: External analysis"
609
- )
610
- ```
611
-
612
- Store the agent task ID as `PASS3_TASK`.
613
-
614
- **After background notification arrives IGNORE it:**
615
-
616
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
617
- Just verify the file and read it directly from disk if needed.
618
-
619
- <!-- ── 7d: Wait for passes 2 (and 3 if running) before pass 4 ── -->
620
-
621
- Display:
622
- ```
623
- i Waiting for pass 2{" and pass 3" if RUN_EXTERNAL} to complete
624
- before dispatching integration analysis (pass 4)...
625
- ```
626
-
627
- **Wait for PASS2_TASK notification** (and PASS3_TASK if running).
628
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
629
- Just wait for the background notifications.
630
-
631
- After notifications arrive, verify the outputs exist:
632
- ```bash
633
- wc -l {INIT.paths.story_file}
634
- ```
635
- If RUN_EXTERNAL:
636
- ```bash
637
- wc -l {INIT.paths.external_analysis_file}
638
- ```
639
-
640
- Display:
641
- ```
642
- + Pass 2 complete. Story file updated with Relevant Wiki section.
643
- {+ Pass 3 complete. External analysis written. (if applicable)}
644
- ```
645
-
646
- <!-- ── 7d.1: Inject Library Documentation into Relevant Wiki ── -->
647
-
648
- **If `LIB_DOCS` is not null/empty:**
649
-
650
- Append a `### Library Documentation` subsection to the `## Relevant Wiki`
651
- section in the story file. This ensures passes 4-5 see these references.
652
-
653
- Read the story file, find the `## Relevant Wiki` section, and append
654
- the `### Library Documentation` subsection BEFORE the next `## ` heading
655
- (i.e., before `## Technical Solution`).
656
-
657
- Split `LIB_DOCS` by spaces. For each entry, determine if it's a weblink
658
- (starts with `http://` or `https://`) or a filepath, and format accordingly:
659
-
660
- ```markdown
661
- ### Library Documentation
662
-
663
- <!-- Provided via lib-docs parameter. These are external library/API docs
664
- that inform the technical solution design. Passes 4-5 MUST read/fetch
665
- these when designing the implementation. -->
666
-
667
- - `{entry}` Library/API documentation reference
668
- ```
669
-
670
- Use the Edit tool to insert this subsection into the story file.
671
-
672
- Display:
673
- ```
674
- + Library documentation ({count} entries) added to Relevant Wiki section.
675
- ```
676
-
677
- <!-- ── 7e: Dispatch Pass 4 Integration Analysis ───────────── -->
678
-
679
- Display:
680
- ```
681
- i Pass 4: Dispatching integration analysis...
682
- Agent will create integration-analysis.md in story directory.
683
- ```
684
-
685
- **CRITICAL Context Window Protection:**
686
- The agent writes to a separate file and returns ONLY a ~10-line confirmation.
687
- This prevents agent output from inflating the main context window.
688
-
689
- **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
690
- After spawning the background agent, do NOT call TaskOutput to read its results.
691
- You will be automatically notified when the agent completes — IGNORE those notifications.
692
- The agent writes to `{INIT.paths.integration_analysis_file}` on disk. You do not need the return message.
693
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
694
- every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
695
-
696
- Spawn background agent:
697
- ```
698
- Agent(
699
- prompt="/ace:research-integration-solution story={INIT.paths.story_file}
700
-
701
- Execute the research-integration-solution workflow end-to-end.
702
- Write the output to {INIT.paths.integration_analysis_file}.
703
- The story file now has the Relevant Wiki section (pass 2 complete).
704
- {If external analysis exists: The external-analysis.md file exists in the story directory.}
705
-
706
- **Return format — ONLY this, nothing else:**
707
- DONE
708
- - Story: {story ID} — {story title}
709
- - Integration points found: {count}
710
- - Output: {integration analysis file path}",
711
- subagent_type="ace-code-integration-analyst",
712
- model="{PO_MODEL}",
713
- run_in_background=true,
714
- description="Pass 4: Integration analysis"
715
- )
716
- ```
717
-
718
- Store the agent task ID as `PASS4_TASK`.
719
-
720
- **After background notification arrives — IGNORE it:**
721
-
722
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
723
- Just verify the file and read it directly from disk if needed.
724
-
725
- <!-- ── 7f: Wait for pass 4 before pass 5 ────────────────────── -->
726
-
727
- **Wait for PASS4_TASK notification.**
728
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
729
-
730
- After notification arrives, verify:
731
- ```bash
732
- wc -l {INIT.paths.integration_analysis_file}
733
- ```
734
-
735
- Display:
736
- ```
737
- + Pass 4 complete. Integration analysis written.
738
- ```
739
-
740
- <!-- ── 7g: Dispatch Pass 5 — Technical Solution ─────────────── -->
741
-
742
- Display:
743
- ```
744
- i Pass 5: Dispatching technical solution design...
745
- Agent will append Technical Solution to story file.
746
- ```
747
-
748
- **CRITICAL — Context Window Protection:**
749
- The agent writes directly into the story file and returns ONLY a ~10-line confirmation.
750
- This prevents agent output from inflating the main context window.
751
-
752
- **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
753
- After spawning the background agent, do NOT call TaskOutput to read its results.
754
- You will be automatically notified when the agent completes — IGNORE those notifications.
755
- The agent writes directly to the story file on disk. You do not need the return message.
756
- TaskOutput returns the agent's FULL internal transcript (every file read, every search,
757
- every tool call) calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
758
-
759
- Spawn background agent:
760
- ```
761
- Agent(
762
- prompt="/ace:research-technical-solution story={INIT.paths.story_file}
763
-
764
- Execute the research-technical-solution workflow end-to-end.
765
- The story file has the full requirements + Relevant Wiki section.
766
- {If LIB_DOCS provided: The Relevant Wiki section includes a '### Library Documentation' subsection with external library/API doc references — READ/FETCH these as primary design input.}
767
- The integration-analysis.md exists in the story directory.
768
- {If external analysis exists: The external-analysis.md exists in the story directory.}
769
- Append the Technical Solution section to the story file.
770
-
771
- **Return format — ONLY this, nothing else:**
772
- DONE
773
- - Story: {story ID} {story title}
774
- - Components designed: {count}
775
- - Sequence diagrams: {count}
776
- - Story file updated: {story file path}",
777
- subagent_type="ace-technical-application-architect",
778
- model="{PO_MODEL}",
779
- run_in_background=true,
780
- description="Pass 5: Technical solution"
781
- )
782
- ```
783
-
784
- Store the agent task ID as `PASS5_TASK`.
785
-
786
- **After background notification arrives — IGNORE it:**
787
-
788
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
789
- Just verify the file and read it directly from disk if needed.
790
-
791
- <!-- ── 7h: Wait for pass 5 ──────────────────────────────────── -->
792
-
793
- **Wait for PASS5_TASK notification.**
794
- Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
795
-
796
- After notification arrives, verify:
797
- ```bash
798
- wc -l {INIT.paths.story_file}
799
- ```
800
-
801
- Display:
802
- ```
803
- + Pass 5 complete. Technical solution appended to story file.
804
- ```
805
- </step>
806
-
807
- <!-- ══════════════════════════════════════════════════════════════════ -->
808
- <!-- STEP 8: STATE UPDATES -->
809
- <!-- ══════════════════════════════════════════════════════════════════ -->
810
-
811
- <step name="state-updates" order="8">
812
-
813
- <substep order="8.1" name="update-state-via-tools">
814
- ```bash
815
- node ~/.claude/agile-context-engineering/src/ace-tools.js story update-state \
816
- story={INIT.paths.story_file} \
817
- status=Refined
818
- ```
819
-
820
- Parse result for: `story_updated`, `feature_updated`, `backlog_updated`.
821
-
822
- ```
823
- + Story status updated to Refined
824
- {+ Feature file updated (if feature_updated)}
825
- {+ Product backlog updated (if backlog_updated)}
826
- ```
827
- </substep>
828
-
829
- Continue to step 9.
830
- </step>
831
-
832
- <!-- ══════════════════════════════════════════════════════════════════ -->
833
- <!-- STEP 9: GITHUB SYNC -->
834
- <!-- ══════════════════════════════════════════════════════════════════ -->
835
-
836
- <step name="github-sync" order="9">
837
-
838
- <variant condition="INIT.github_project.enabled is false OR INIT.has_gh_cli is false">
839
- ```
840
- — GitHub sync skipped (not configured or gh CLI unavailable).
841
- ```
842
- Continue to step 10.
843
- </variant>
844
-
845
- <variant condition="INIT.github_project.enabled is true AND INIT.has_gh_cli is true">
846
- Sync story and feature GitHub issues in a single call.
847
- This command prints status lines directly to the console (stderr)
848
- so the user ALWAYS sees whether each issue was updated or not.
849
-
850
- ```bash
851
- node ~/.claude/agile-context-engineering/src/ace-tools.js github sync-story \
852
- repo={INIT.github_project.repo} \
853
- story_file={INIT.paths.story_file} \
854
- feature_file={INIT.paths.feature_file} \
855
- owner={INIT.github_project.owner} \
856
- project={INIT.github_project.project_number}
857
- ```
858
-
859
- The command handles all cases:
860
- - Story/feature has no GitHub issue linked → prints skip message
861
- - Update succeeds prints success message with issue number
862
- - Update fails prints error message with details
863
-
864
- Continue to step 10.
865
- </variant>
866
- </step>
867
-
868
- <!-- ══════════════════════════════════════════════════════════════════ -->
869
- <!-- STEP 10: COMMIT -->
870
- <!-- ══════════════════════════════════════════════════════════════════ -->
871
-
872
- <step name="commit" order="10">
873
-
874
- **If `commit_docs` is false:** Skip commit.
875
-
876
- Stage all changed/created files:
877
- ```bash
878
- git add {INIT.paths.story_dir}/
879
- git add {INIT.paths.feature_file} .ace/artifacts/product/product-backlog.md
880
- ```
881
-
882
- Commit with descriptive message:
883
- - CREATE mode: `git commit -m "docs: plan story {Story ID} — {Story Title}"`
884
- - REFINE mode: `git commit -m "docs: refine story {Story ID} — {brief summary of changes}"`
885
-
886
- Display completion:
887
-
888
- ```
889
- ╔══════════════════════════════════════════════════╗
890
- ║ ACE > Story [Planned | Refined] ║
891
- ║ {Story ID} "{Story Title}" ║
892
- ╚══════════════════════════════════════════════════╝
893
-
894
- + Story specification complete. All passes finished.
895
-
896
- Artifacts:
897
- ────────
898
- Story file: {INIT.paths.story_file}
899
- {External analysis: {INIT.paths.external_analysis_file} (if created)}
900
- Integration analysis: {INIT.paths.integration_analysis_file}
901
-
902
- Summary:
903
- ────────
904
- Acceptance criteria: {N} scenarios
905
- Size: {estimate}
906
- Passes completed: {2-5 count}
907
-
908
- Next > /ace:execute-story story={INIT.paths.story_file}
909
- Execute the story implementation.
910
- > /ace:plan-story story={next story}
911
- Plan the next story in the feature.
912
- ```
913
- </step>
914
-
915
- </process>
916
-
917
- <success_criteria>
918
- - Init function executed (environment detected, story validated, paths computed)
919
- - Story seed loaded and parsed (title, description, images validated)
920
- - CREATE vs REFINE mode correctly determined
921
- - Feature context loaded (parent feature document, if available)
922
- - Deep questioning conducted with ZERO-ASSUMPTION mandate
923
- - Every acceptance criterion has EXACT trigger, precondition, outcome, data, error handling
924
- - No vague terms remain ("it works", "shows error", "updates data" — all must be specific)
925
- - All Gherkin scenarios follow Given/When/Then format correctly
926
- - Scenarios are independent — no scenario depends on another's state
927
- - Minimum coverage: happy path + edge case + error path
928
- - Story passes INVEST checklist
929
- - Story size is Fibonacci (1, 2, 3, 5, 8) — split if > 8 or > 6-8 scenarios
930
- - Story document written following story.xml template exactly (sections 1-8)
931
- - User reviewed and approved pass 1 output
932
- - Pass 2 (wiki research) dispatched as background agent, wrote to story file
933
- - Pass 3 (external analysis) offered/dispatched if external-codebase provided
934
- - Library documentation entries injected into Relevant Wiki section after pass 2 (if lib-docs provided)
935
- - Pass 4 (integration analysis) dispatched AFTER passes 2-3 complete
936
- - Pass 5 (technical solution) dispatched AFTER pass 4 complete
937
- - NO TaskOutput called on ANY background agent — context window stays clean
938
- - Each background agent wrote output directly to disk (story file or separate artifact)
939
- - Story status updated to Refined via ace-tools (story file, feature file, product backlog)
940
- - GitHub issue updated (if applicable)
941
- - All artifacts committed with descriptive message (story dir + feature file + backlog)
942
- </success_criteria>
943
-
944
- </workflow>
1
+ <workflow>
2
+
3
+ <purpose>
4
+ Orchestrate story specification: load a story seed (from file or GitHub issue),
5
+ absorb any existing description, conduct deep questioning to define CRYSTAL-CLEAR
6
+ acceptance criteria with ZERO ambiguity, write the story specification (pass 1),
7
+ then dispatch passes 2-5 as background agents that write their outputs directly
8
+ to files — keeping this orchestrator's context window clean.
9
+
10
+ Produces `.ace/artifacts/product/&lt;id-epic_name&gt;/&lt;id-feature_name&gt;/&lt;id-story_name&gt;/&lt;id-story_name&gt;.md`
11
+ — a complete story specification with INVEST-compliant user story, Gherkin acceptance
12
+ criteria, definition of done, scope boundaries, and relevant wiki references.
13
+
14
+ Additionally produces (via background agents):
15
+ - `external-analysis.md` in story directory (OPTIONAL — pass 3)
16
+ - `integration-analysis.md` in story directory (pass 4)
17
+ - Technical Solution section appended to story file (pass 5)
18
+
19
+ The orchestrator's context window contains ONLY story requirements information.
20
+ Passes 2-5 write to disk and return only completion confirmations.
21
+ The orchestrator MUST NOT call TaskOutput on any background agent.
22
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
23
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
24
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
25
+ </purpose>
26
+
27
+ <mandatory-context>
28
+ Read all supporting resource files listed in the skill before starting.
29
+ Also read any document or text passed as parameter ($ARGUMENTS).
30
+ </mandatory-context>
31
+
32
+ <process>
33
+
34
+ <!-- ══════════════════════════════════════════════════════════════════ -->
35
+ <!-- STEP 1: SETUP -->
36
+ <!-- ══════════════════════════════════════════════════════════════════ -->
37
+
38
+ <step name="setup" order="1">
39
+ **MANDATORY FIRST STEP — Use preprocessed environment data:**
40
+
41
+ The INIT JSON was already preprocessed by the skill's shell injection
42
+ and is available in the Environment Context section above the workflow.
43
+ Parse it directly do NOT re-run the init script.
44
+
45
+ INIT contains:
46
+ - `commit_docs`
47
+ - `has_git`, `has_gh_cli`, `github_project`
48
+ - `is_brownfield`, `is_greenfield`, `has_wiki`
49
+ - `has_product_vision`, `has_product_backlog`
50
+ - `story_source` (`file`, `github`, `text`, `new`), `story_valid`, `story_error`, `story_content`
51
+ - `story` (id, title, status, size), `feature` (id, title), `epic` (id, title)
52
+ - `user_story`, `description`, `acceptance_criteria_count`
53
+ - `paths.*` (story_dir, story_file, feature_dir, feature_file, etc.)
54
+ - `has_external_analysis`, `has_integration_analysis`, `has_feature_file`, `has_story_file`
55
+
56
+ Also extract from `$ARGUMENTS` (not in INIT):
57
+ - `external-codebase` (OPTIONAL): path or GitHub URL to external system
58
+ - `external-docs` (OPTIONAL): weblink or filepath to external docs
59
+ - `lib-docs` (OPTIONAL): space-separated weblinks and/or filepaths to library documentation
60
+
61
+ Store `EXTERNAL_CODEBASE`, `EXTERNAL_DOCS`, and `LIB_DOCS` from parsed arguments (may be null).
62
+
63
+ Display stage banner:
64
+
65
+ ```
66
+ ╔══════════════════════════════════════════════════╗
67
+ ║ ACE > Plan Story ║
68
+ ╚══════════════════════════════════════════════════╝
69
+ ```
70
+
71
+ <!-- ── Validate and determine mode ─────────────────────────── -->
72
+
73
+ **If `INIT.story_valid` is false AND `INIT.story_source` is not `new` and not `text`:**
74
+ Display error using `INIT.story_error` and exit:
75
+ ```
76
+ x {INIT.story_error}
77
+ Provide a valid story file path, GitHub issue, or use text= for a new story.
78
+ ```
79
+
80
+ **Determine `IS_NEW_STORY`:**
81
+ - `IS_NEW_STORY = true` if: `INIT.story_source` is `new` or `text`,
82
+ OR `INIT.story.id == null` OR `INIT.feature.id == null`
83
+ (file exists but has no ACE structure/feature reference — treat as new story with seed content)
84
+ - `IS_NEW_STORY = false` if: both story.id and feature.id are set (proper ACE story file)
85
+
86
+ If `IS_NEW_STORY = true`: set `STORY_CONTENT = INIT.story_content` (may be null for `new` mode).
87
+
88
+ <!-- ── Git init if needed ─────────────────────────────────────── -->
89
+
90
+ **If `has_git` is false:** Initialize git:
91
+ ```bash
92
+ git init
93
+ ```
94
+ </step>
95
+
96
+ <!-- ══════════════════════════════════════════════════════════════════ -->
97
+ <!-- STEP 2: BACKLOG CHECK AND PLACEMENT -->
98
+ <!-- ══════════════════════════════════════════════════════════════════ -->
99
+
100
+ <step name="backlog-check-placement" order="2">
101
+
102
+ Execute ONLY when `IS_NEW_STORY` is true.
103
+ If `IS_NEW_STORY` is false: skip entirely, continue to step 3.
104
+
105
+ Display:
106
+ ```
107
+ ┌──────────────────────────────────────────────────┐
108
+ │ ACE > Plan Story > Backlog Placement │
109
+ └──────────────────────────────────────────────────┘
110
+ ```
111
+
112
+ <!-- ── 2a: No backlog minimal context flow ─────────────────── -->
113
+
114
+ **If `has_product_backlog` is false:**
115
+
116
+ Display:
117
+ ```
118
+ ! No product backlog found. Proceeding without backlog integration.
119
+ ```
120
+
121
+ Use AskUserQuestion:
122
+ - header: "Story Context"
123
+ - question: "No product backlog found. How would you like to proceed?"
124
+ - options:
125
+ - "Provide epic & feature context" — I'll give the epic and feature details
126
+ - "Create as standalone" Save under uncategorized path
127
+
128
+ **If "Create as standalone":**
129
+ - Derive STORY_TITLE from STORY_CONTENT first line/heading, or ask with AskUserQuestion
130
+ - STORY_ID = S1
131
+ - Jump to 2f (compute paths with epic=uncategorized, feature=uncategorized)
132
+
133
+ **If "Provide epic & feature context":**
134
+ Ask user (two AskUserQuestion calls):
135
+ 1. "What is the Epic ID and Title?" (e.g., E1 — User Authentication)
136
+ 2. "What is the Feature ID and Title?" (e.g., F1 — OAuth2 Login)
137
+ Set TARGET_FEATURE from user answers. STORY_ID = S1. Jump to 2c.
138
+
139
+ <!-- ── 2b: Read backlog, identify feature ────────────────────── -->
140
+
141
+ **If `has_product_backlog` is true:**
142
+
143
+ Read `.ace/artifacts/product/product-backlog.md`.
144
+ Parse all features across all epics: ID, Title, Status, Epic ID, Epic Title.
145
+
146
+ **Determine STORY_TITLE:**
147
+ If STORY_CONTENT is not empty: extract from first heading (`# Title`) or first sentence.
148
+ If unclear: Use AskUserQuestion:
149
+ - header: "Story Title"
150
+ - question: "What is the title for this new story?"
151
+ (free-form text — accept any response as STORY_TITLE)
152
+
153
+ **Present feature list:**
154
+
155
+ Display features grouped by epic as a tree (same style as plan-feature):
156
+ ```
157
+ E1 User Authentication
158
+ ├── F1 OAuth2 Login Flow [Todo]
159
+ └── F2 Session Management [Refined]
160
+ E2 Data Export
161
+ └── F3 CSV Export [Todo]
162
+ ```
163
+
164
+ Use AskUserQuestion:
165
+ - header: "Feature Placement"
166
+ - question: "Which feature should '{STORY_TITLE}' belong to?"
167
+ - options: list all feature IDs + titles (up to 4 per page), plus "Create under a new feature"
168
+
169
+ **If "Create under a new feature":**
170
+ ```
171
+ ! Creating a new feature requires /ace:plan-feature first.
172
+ Run /ace:plan-feature to define the feature, then re-run /ace:plan-story.
173
+ ```
174
+ Exit workflow.
175
+
176
+ Set `TARGET_FEATURE = { id, title, epic_id, epic_title }` from user selection.
177
+
178
+ <!-- ── 2c: Compute feature file path ─────────────────────────── -->
179
+
180
+ ```bash
181
+ EPIC_SLUG=$(node ${CLAUDE_SKILL_DIR}/script.js generate-slug "{TARGET_FEATURE.epic_id}-{TARGET_FEATURE.epic_title}" --raw)
182
+ FEATURE_SLUG=$(node ${CLAUDE_SKILL_DIR}/script.js generate-slug "{TARGET_FEATURE.id}-{TARGET_FEATURE.title}" --raw)
183
+ ```
184
+
185
+ FEATURE_DIR = .ace/artifacts/product/{EPIC_SLUG}/{FEATURE_SLUG}
186
+ FEATURE_FILE = {FEATURE_DIR}/{FEATURE_SLUG}.md
187
+
188
+ Check if feature file exists:
189
+ ```bash
190
+ test -f {FEATURE_FILE} && echo "exists" || echo "missing"
191
+ ```
192
+ Set `HAS_FEATURE_FILE` = true/false.
193
+
194
+ <!-- ── 2d: Assign story ID and ordering ──────────────────────── -->
195
+
196
+ **Find the next story ID for this feature:**
197
+
198
+ Scan existing story subdirectories in FEATURE_DIR:
199
+ ```bash
200
+ ls {FEATURE_DIR}/ 2>/dev/null | grep -E '^(s|#)[0-9]'
201
+ ```
202
+
203
+ If HAS_FEATURE_FILE is true: also read the story breakdown table in FEATURE_FILE
204
+ to confirm the highest existing S[N] or #[N].
205
+
206
+ Assign `STORY_ID = S[N+1]` where N is the highest found. If none: `STORY_ID = S1`.
207
+
208
+ **Ask about ordering (only if feature has existing stories):**
209
+
210
+ If there are existing stories, use AskUserQuestion:
211
+ - header: "Story Order"
212
+ - question: "Where should '{STORY_TITLE}' appear in the feature's story breakdown?"
213
+ - options: (build from existing story list)
214
+ - "After {last story ID} — {last story title}" (default/most common)
215
+ - "After {S[N]} — {title}" for each existing story
216
+ - "At the beginning"
217
+
218
+ Set `INSERT_AFTER` = selected story ID, or "end" if no existing stories / last position chosen,
219
+ or "beginning" if first position chosen.
220
+
221
+ <!-- ── 2e: Ask about dependencies ────────────────────────────── -->
222
+
223
+ If there are existing stories in the feature:
224
+
225
+ Use AskUserQuestion:
226
+ - header: "Dependencies"
227
+ - question: "Does '{STORY_TITLE}' have dependencies with existing stories?"
228
+ - options:
229
+ - "None" No dependencies
230
+ - "Blocked by a story" — This story depends on another completing first
231
+ - "Blocks a story" — Another story must wait for this one
232
+ - "Both" — Mutual dependency
233
+
234
+ **If "Blocked by a story" or "Both":**
235
+ Use AskUserQuestion:
236
+ - header: "Blocked By"
237
+ - question: "Which story must complete before '{STORY_TITLE}'?"
238
+ - options: list existing story IDs + titles
239
+ Set `BLOCKED_BY = { id, title }`.
240
+
241
+ **If "Blocks a story" or "Both":**
242
+ Use AskUserQuestion:
243
+ - header: "Blocks"
244
+ - question: "Which story requires '{STORY_TITLE}' to complete first?"
245
+ - options: list existing story IDs + titles
246
+ Set `BLOCKS = { id, title }`.
247
+
248
+ Else: `BLOCKED_BY = null`, `BLOCKS = null`.
249
+
250
+ <!-- ── 2f: Compute final story paths ──────────────────────────── -->
251
+
252
+ ```bash
253
+ STORY_SLUG=$(node ${CLAUDE_SKILL_DIR}/script.js generate-slug "{STORY_ID}-{STORY_TITLE}" --raw)
254
+ ```
255
+
256
+ STORY_DIR = {FEATURE_DIR}/{STORY_SLUG}
257
+ STORY_FILE = {STORY_DIR}/{STORY_SLUG}.md
258
+
259
+ <!-- ── 2g: Create stub file ──────────────────────────────────── -->
260
+
261
+ ```bash
262
+ mkdir -p {STORY_DIR}
263
+ ```
264
+
265
+ Write stub file to `{STORY_FILE}`:
266
+
267
+ ```markdown
268
+ # {STORY_ID}: {STORY_TITLE}
269
+
270
+ **Feature**: {TARGET_FEATURE.id} {TARGET_FEATURE.title} | **Epic**: {TARGET_FEATURE.epic_id} {TARGET_FEATURE.epic_title}
271
+ **Status**: Todo | **Size**: | **Sprint**: | **Link**:
272
+
273
+ ## Description
274
+
275
+ {STORY_CONTENT if non-empty, otherwise empty section}
276
+
277
+ ## Dependencies
278
+
279
+ {If BLOCKED_BY set: - **Blocked By**: {BLOCKED_BY.id} — {BLOCKED_BY.title}}
280
+ {If BLOCKS set: - **Blocks**: {BLOCKS.id} {BLOCKS.title}}
281
+ {If neither: _No dependencies._}
282
+
283
+ ---
284
+ *Stub created by plan-story. Proceeding to formal specification.*
285
+ ```
286
+
287
+ Display:
288
+ ```
289
+ + Stub created: {STORY_FILE}
290
+ ```
291
+
292
+ <!-- ── 2h: Update feature file ────────────────────────────────── -->
293
+
294
+ If `HAS_FEATURE_FILE` is true:
295
+
296
+ Spawn a Task agent to update the feature file:
297
+
298
+ ```
299
+ Task(
300
+ prompt="Read `{FEATURE_FILE}`.
301
+
302
+ 1. Add a new row to the Story Breakdown table:
303
+ | {STORY_ID} | {STORY_TITLE} | | Todo | — | — |
304
+ Insert it: {after story {INSERT_AFTER} / at the beginning / at the end}.
305
+
306
+ 2. Add a story detail section after the existing story details:
307
+ ### {STORY_ID}: {STORY_TITLE}
308
+ {STORY_CONTENT or '(Description to be filled via plan-story.)'}
309
+
310
+ {If BLOCKS is set:
311
+ 3. Locate the Dependencies section of story {BLOCKS.id} and add:
312
+ - **Blocked By**: {STORY_ID} {STORY_TITLE}}
313
+
314
+ Maintain all table formatting pad ALL cells so | separators align vertically.
315
+ Use the Edit tool to modify in place.
316
+
317
+ **Return format ONLY this:**
318
+ DONE
319
+ - Feature: {Feature ID} — updated
320
+ - Story row: added at position {INSERT_AFTER}
321
+ - Dependency updates: {count}",
322
+ subagent_type="ace-product-owner",
323
+ model="{PO_MODEL}",
324
+ description="Add story to feature file"
325
+ )
326
+ ```
327
+
328
+ Display:
329
+ ```
330
+ + Feature file updated: {STORY_ID} added to story breakdown.
331
+ ```
332
+
333
+ <!-- ── 2i: GitHub sync (if enabled) ───────────────────────────── -->
334
+
335
+ **If `github_project.enabled` is false OR `has_gh_cli` is false:** Skip to 2j.
336
+
337
+ **If GitHub is enabled:**
338
+
339
+ Display:
340
+ ```
341
+ i GitHub enabledcreating story issue...
342
+ Repo: {github_project.repo} | Project: #{github_project.project_number}
343
+ ```
344
+
345
+ Determine parent feature's GitHub issue number:
346
+ If HAS_FEATURE_FILE is true: read FEATURE_FILE and extract `**Link**:` value.
347
+ Else: check backlog for the feature's Link column.
348
+ If feature has a GitHub link (e.g., `[#78](url)`): extract FEATURE_ISSUE_NUMBER.
349
+ If no link found: FEATURE_ISSUE_NUMBER = null (warn: "Feature has no GitHub issue — story will be created without a parent.").
350
+
351
+ Resolve project fields:
352
+ ```bash
353
+ GH_FIELDS=$(node "${CLAUDE_SKILL_DIR}/script.js" resolve-fields \
354
+ repo={github_project.repo} owner={github_project.owner} project={github_project.project_number})
355
+ ```
356
+
357
+ Parse: PROJECT_ID, STORY_TYPE_ID, STATUS_FIELD_ID, STATUS_OPTIONS, ESTIMATE_FIELD_ID.
358
+
359
+ Create story GitHub issue:
360
+ ```bash
361
+ STORY_RESULT=$(node "${CLAUDE_SKILL_DIR}/script.js" create-issue \
362
+ type=Story \
363
+ "title={STORY_TITLE}" \
364
+ body_file={STORY_FILE} \
365
+ repo={github_project.repo} \
366
+ owner={github_project.owner} \
367
+ project={github_project.project_number} \
368
+ project_id={PROJECT_ID} \
369
+ [type_id={STORY_TYPE_ID}] \
370
+ status_field_id={STATUS_FIELD_ID} \
371
+ status_option_id={STATUS_OPTIONS["Todo"]} \
372
+ [parent={FEATURE_ISSUE_NUMBER}])
373
+ ```
374
+
375
+ Parse response: `STORY_ISSUE_NUMBER`, `STORY_ISSUE_URL`.
376
+
377
+ **Rename directory and file to use GitHub issue number:**
378
+
379
+ ```bash
380
+ NEW_STORY_SLUG=$(node ${CLAUDE_SKILL_DIR}/script.js generate-slug "#{STORY_ISSUE_NUMBER}-{STORY_TITLE}" --raw)
381
+ mv {STORY_DIR} {FEATURE_DIR}/{NEW_STORY_SLUG}
382
+ ```
383
+
384
+ Update `STORY_DIR = {FEATURE_DIR}/{NEW_STORY_SLUG}`
385
+ Update `STORY_FILE = {STORY_DIR}/{NEW_STORY_SLUG}.md`
386
+
387
+ **Update stub file header** with GitHub link:
388
+ Edit `{STORY_FILE}`: change `**Link**: —` to `**Link**: [#{STORY_ISSUE_NUMBER}]({STORY_ISSUE_URL})`.
389
+
390
+ **Update feature file** Link column for this story:
391
+ Edit `{FEATURE_FILE}`: change the story row's Link cell from `—` to
392
+ `[#{STORY_ISSUE_NUMBER}]({STORY_ISSUE_URL})`.
393
+
394
+ Display:
395
+ ```
396
+ + Created GitHub story issue #{STORY_ISSUE_NUMBER}
397
+ Directory renamed: {STORY_DIR}
398
+ ```
399
+
400
+ <!-- ── 2j: Re-init with final story path ─────────────────────── -->
401
+
402
+ Re-run init to populate all INIT fields from the newly created story file:
403
+ ```bash
404
+ INIT=$(node ${CLAUDE_SKILL_DIR}/script.js init story={STORY_FILE})
405
+ ```
406
+
407
+ If `INIT.story_valid` is false: display error and exit.
408
+
409
+ Display:
410
+ ```
411
+ + Story ready for specification:
412
+ File: {STORY_FILE}
413
+ Feature: {TARGET_FEATURE.id} — {TARGET_FEATURE.title}
414
+ Story: {STORY_ID} {STORY_TITLE}
415
+ ```
416
+
417
+ </step>
418
+
419
+ <!-- ══════════════════════════════════════════════════════════════════ -->
420
+ <!-- STEP 3: LOAD STORY SEED -->
421
+ <!-- ══════════════════════════════════════════════════════════════════ -->
422
+
423
+ <step name="load-story-seed" order="3">
424
+
425
+ The story seed is the raw description of what needs to be built.
426
+ It may come from:
427
+ - A stub file created by `plan-feature` (has Description section)
428
+ - A GitHub issue with free-text description
429
+ - Any markdown file with story context
430
+
431
+ **Read the story content** (already available in `INIT.story_content`).
432
+ Parse and hold as `STORY_SEED`:
433
+ - Title (from header or first heading)
434
+ - Description (any free-text description of what needs to be done)
435
+ - Any existing AC scenarios (if the story was previously partially refined)
436
+ - Any images referenced (markdown `![](path)` or HTML `&lt;img src="path"&gt;`)
437
+
438
+ <!-- ── 2a: Image validation ──────────────────────────────────── -->
439
+
440
+ Extract ALL image references from the story content:
441
+ - Markdown: `![alt](path)`
442
+ - HTML: `&lt;img src="path"&gt;`
443
+
444
+ For EACH image reference, attempt to READ it using the Read tool.
445
+
446
+ **IF ANY IMAGE CANNOT BE READ:**
447
+ ```
448
+ x STOP: Cannot proceed — Referenced images are not accessible.
449
+
450
+ Image validation results:
451
+ - [image1.png] -> SUCCESS
452
+ - [image2.png] -> FAILED: File not found
453
+
454
+ Please provide correct paths or describe what each missing image contains.
455
+ ```
456
+ Wait for user response before proceeding.
457
+
458
+ <!-- ── 2b: Detect run mode ───────────────────────────────────── -->
459
+
460
+ **If `INIT.acceptance_criteria_count > 0`:**
461
+ The story has existing AC this is a REFINE run.
462
+ Set `RUN_MODE = REFINE`.
463
+
464
+ Use AskUserQuestion:
465
+ - header: "Story exists"
466
+ - question: "This story already has {INIT.acceptance_criteria_count} acceptance criteria scenarios. What would you like to do?"
467
+ - options:
468
+ - "Refine it" — Review and update the existing specification
469
+ - "Start fresh" Discard existing AC and rebuild from the description
470
+ - "Skip to research" — Keep current AC, skip to passes 2-5
471
+
472
+ If "Start fresh": set `RUN_MODE = CREATE`, clear existing AC from working copy.
473
+ If "Skip to research": jump directly to step 8 (dispatch passes 2-5).
474
+ If "Refine it": continue to step 4 with existing content as context.
475
+
476
+ **If `INIT.acceptance_criteria_count == 0`:**
477
+ Set `RUN_MODE = CREATE`. Continue to step 4.
478
+
479
+ Display:
480
+ ```
481
+ i Story loaded: {title}
482
+ Source: {file path or GitHub issue}
483
+ Mode: {CREATE | REFINE}
484
+ Description: {first 100 chars of description}...
485
+ ```
486
+ </step>
487
+
488
+ <!-- ══════════════════════════════════════════════════════════════════ -->
489
+ <!-- STEP 4: LOAD FOUNDATION CONTEXT -->
490
+ <!-- ══════════════════════════════════════════════════════════════════ -->
491
+
492
+ <step name="load-foundation" order="4">
493
+
494
+ **3a. Load parent feature document (if exists):**
495
+
496
+ If `INIT.has_feature_file` is true:
497
+ - Read the feature document at `INIT.paths.feature_file`
498
+ - Extract: Feature description, scope (includes/excludes), benefit hypothesis,
499
+ story breakdown (other stories and their scopes), acceptance criteria, technical context
500
+ - Hold as `FEATURE_CONTEXT`
501
+
502
+ If false: set `FEATURE_CONTEXT = null`
503
+
504
+ **3b. Load product vision (if exists):**
505
+
506
+ If `INIT.has_product_vision` is true:
507
+ - Read `.docs/product/product-vision.md`
508
+ - Extract personas, target audience, key objectives
509
+ - Hold as `VISION` (used to validate persona in user story statement)
510
+
511
+ If false: set `VISION = null`
512
+
513
+ **3c. Load product backlog (if exists):**
514
+
515
+ If `INIT.has_product_backlog` is true:
516
+ - Read `.ace/artifacts/product/product-backlog.md`
517
+ - Extract the parent epic's context and any related features
518
+ - Hold as `BACKLOG_CONTEXT`
519
+
520
+ If false: set `BACKLOG_CONTEXT = null`
521
+
522
+ Display loaded context:
523
+ ```
524
+ i Context loaded:
525
+ [+] Parent feature document ({lines} lines)
526
+ [+] Product vision (personas: {list})
527
+ [ ] Product backlog (not found)
528
+ ```
529
+ </step>
530
+
531
+ <!-- ══════════════════════════════════════════════════════════════════ -->
532
+ <!-- STEP 5: DEEP QUESTIONING -->
533
+ <!-- ══════════════════════════════════════════════════════════════════ -->
534
+
535
+ <step name="deep-questioning" order="5">
536
+ Follow the questioning guide from `questioning.xml`. You are a thinking partner,
537
+ not an interviewer.
538
+
539
+ Display:
540
+ ```
541
+ ┌──────────────────────────────────────────────────┐
542
+ │ ACE > Plan Story > Questioning │
543
+ └──────────────────────────────────────────────────┘
544
+ ```
545
+
546
+ <!-- ── 4a: Opening — present what you know ───────────────────── -->
547
+
548
+ Start by presenting your understanding of the story from the seed:
549
+
550
+ "Based on the story description and feature context, here's what I understand
551
+ this story delivers: {summary}. Let me ask some questions to make sure the
552
+ acceptance criteria are crystal clear."
553
+
554
+ If FEATURE_CONTEXT is available, reference the story's position within
555
+ the feature — what it builds on and what it enables.
556
+
557
+ <!-- ── 4b: ZERO-ASSUMPTION questioning ───────────────────────── -->
558
+
559
+ **CRITICAL MANDATE: ZERO ASSUMPTIONS**
560
+
561
+ Every acceptance criterion MUST be so explicit that an AI agent with NO prior
562
+ context can implement it correctly. This means:
563
+
564
+ **For EVERY behavior, probe until you have:**
565
+ 1. **Exact trigger** — What SPECIFIC user action or system event starts this?
566
+ - Bad: "When the user submits" Submit what? Where? How?
567
+ - Good: "When the user clicks the 'Save' button on the Settings page"
568
+
569
+ 2. **Exact preconditions** What state MUST exist before the trigger?
570
+ - Bad: "Given the user is logged in" → What kind of user? What permissions?
571
+ - Good: "Given a user with 'admin' role is authenticated and on the Dashboard page"
572
+
573
+ 3. **Exact expected outcome** — What OBSERVABLE result occurs?
574
+ - Bad: "Then it works" → How do you KNOW it works?
575
+ - Bad: "Then the data is saved" → Saved WHERE? What confirmation does the user see?
576
+ - Good: "Then a success toast appears with message 'Settings saved' and the page
577
+ reflects the updated value without requiring a refresh"
578
+
579
+ 4. **Exact data/values** — What SPECIFIC data is involved?
580
+ - Bad: "The form has fields" → Which fields? What types? What validation?
581
+ - Good: "The form contains: Name (text, required, max 100 chars), Email (email format,
582
+ required), Role (dropdown: Admin/Editor/Viewer, default: Viewer)"
583
+
584
+ 5. **Exact error handling** — What happens when things go wrong?
585
+ - Bad: "Show an error" What error? Where? What message?
586
+ - Good: "Display inline validation error below the Email field: 'Please enter a valid
587
+ email address' in red (#DC3545), field border turns red"
588
+
589
+ 6. **Exact edge cases** What happens at boundaries?
590
+ - What if the list is empty? What placeholder is shown?
591
+ - What if the input is at max length? What happens at max+1?
592
+ - What if the network request fails? Timeout? 403? 500?
593
+ - What if the user double-clicks? Navigates away mid-operation?
594
+
595
+ **QUESTIONING TECHNIQUES for extracting precision:**
596
+
597
+ - "You said [vague thing]. What does that actually look like on screen?"
598
+ - "Walk me through exactly what happens, step by step, from the user's perspective."
599
+ - "What does the user SEE when this succeeds? What EXACT message, where on the page?"
600
+ - "What if [edge case]? What should happen? What should the user see?"
601
+ - "You mentioned [behavior]. Is that a modal dialog, an inline message, a page redirect, or something else?"
602
+ - "When you say 'update', do you mean replace the entire record, merge specific fields, or append?"
603
+ - "What validation rules apply? Be specific: required/optional, min/max, format, allowed values."
604
+ - "How does the user know this worked? What visual feedback do they get?"
605
+
606
+ **USE AskUserQuestion for specific clarification:**
607
+
608
+ When the user gives a vague answer, present concrete interpretations:
609
+
610
+ ```
611
+ header: "Behavior"
612
+ question: "When the save fails due to network error, what should the user see?"
613
+ options:
614
+ - "Toast notification"Non-blocking message at top of page
615
+ - "Modal dialog" — Blocking popup requiring acknowledgment
616
+ - "Inline error" Error message below the form
617
+ - "Let me explain" Different approach
618
+ ```
619
+
620
+ <!-- ── 4c: Template-field coverage (background checklist) ────── -->
621
+
622
+ As you question, mentally track coverage against story.xml template sections:
623
+ - [ ] **User Story** As/I want/So that (persona must match vision if available)
624
+ - [ ] **Description** 2-4 sentences of observable user behavior and feature context
625
+ - [ ] **Acceptance Criteria** — ALL scenarios with EXACT Given/When/Then
626
+ - [ ] Happy path(s) — main success scenario(s)
627
+ - [ ] Edge cases boundary conditions, empty states, max limits
628
+ - [ ] Error paths validation failures, network errors, permission issues
629
+ - [ ] Each scenario: EXACT trigger, EXACT precondition, EXACT outcome
630
+ - [ ] **Out of Scope** — Things someone might assume are included but are NOT
631
+ - [ ] **Dependencies** Blocked by, Blocks, External
632
+ - [ ] **Definition of Done** — Any story-specific additions to the default checklist
633
+ - [ ] **Size** — Fibonacci estimate (1, 2, 3, 5, 8)
634
+
635
+ Don't walk through this as a checklist. Weave questions naturally.
636
+ When gaps remain after conversation feels complete, probe those areas.
637
+
638
+ <!-- ── 4d: AC Scenario crafting ──────────────────────────────── -->
639
+
640
+ Once you have enough context, draft the Gherkin scenarios:
641
+
642
+ Present each scenario and VALIDATE with the user:
643
+
644
+ ```
645
+ Here's what I have so far:
646
+
647
+ ### Scenario: Successful settings save
648
+ **Given** an admin user is on the Settings page with unsaved changes
649
+ **When** they click the "Save Settings" button
650
+ **Then** a success toast appears with message "Settings saved successfully"
651
+ **And** the updated values are reflected on the page without refresh
652
+ **And** the "Save Settings" button becomes disabled (no unsaved changes)
653
+
654
+ ### Scenario: Validation failure invalid email
655
+ **Given** an admin user is on the Settings page
656
+ **When** they enter "not-an-email" in the Contact Email field and click "Save Settings"
657
+ **Then** the Contact Email field border turns red
658
+ **And** an inline error appears below the field: "Please enter a valid email address"
659
+ **And** the form is NOT submitted
660
+ **And** focus moves to the Contact Email field
661
+
662
+ Does this capture the behavior correctly? Anything missing or wrong?
663
+ ```
664
+
665
+ Use AskUserQuestion:
666
+ - header: "Scenarios"
667
+ - question: "Review the acceptance criteria scenarios above. Are they correct and complete?"
668
+ - options:
669
+ - "Looks good" — Scenarios are accurate and complete
670
+ - "Fix a scenario" Something is wrong or missing in a scenario
671
+ - "Add a scenario" — There's a case I haven't mentioned
672
+ - "Too many" — Some scenarios should be removed or combined
673
+
674
+ Loop until the user confirms all scenarios are correct.
675
+
676
+ **CRITICAL: Scenario count check.**
677
+ If more than 6-8 scenarios are needed, the story is likely too large:
678
+ ```
679
+ ! This story has {N} scenarios, which suggests it may be too large.
680
+ Stories with more than 6-8 scenarios should usually be split.
681
+ ```
682
+
683
+ Use AskUserQuestion:
684
+ - header: "Story size"
685
+ - question: "This story has {N} acceptance criteria. Should we split it?"
686
+ - options:
687
+ - "Keep as-is" The story is coherent and should not be split
688
+ - "Split it" — Let's break this into smaller stories
689
+
690
+ If "Split it": discuss the split, identify natural cut points, and restart
691
+ questioning for the reduced-scope story.
692
+
693
+ <!-- ── 4e: Decision gate ─────────────────────────────────────── -->
694
+
695
+ When story specification feels complete:
696
+
697
+ Use AskUserQuestion:
698
+ - header: "Ready?"
699
+ - question: "I have the full story spec: {N} acceptance criteria, size {estimate}. Ready to write the story document?"
700
+ - options:
701
+ - "Write story document" — Create the specification
702
+ - "Keep exploring" — I want to add or change something
703
+ - "Show summary" Show me what you have before deciding
704
+
705
+ If "Show summary":
706
+ ```
707
+ Story: {ID} — {Title}
708
+ Feature: {Feature ID} — {Feature Title}
709
+
710
+ User Story:
711
+ > As a [persona], I want [action], so that [benefit].
712
+
713
+ Description: {2-4 sentences}
714
+
715
+ Acceptance Criteria: {N} scenarios
716
+ 1. {scenario name} — {one-line summary}
717
+ 2. {scenario name} — {one-line summary}
718
+ ...
719
+
720
+ Out of Scope: {M} items
721
+ Size: {estimate}
722
+ ```
723
+ Return to decision gate.
724
+
725
+ If "Keep exploring" ask what they want to add or identify gaps.
726
+ Loop until "Write story document" selected.
727
+ </step>
728
+
729
+ <!-- ══════════════════════════════════════════════════════════════════ -->
730
+ <!-- STEP 6: WRITE STORY DOCUMENT (Pass 1) -->
731
+ <!-- ══════════════════════════════════════════════════════════════════ -->
732
+
733
+ <step name="write-story" order="6">
734
+
735
+ Display:
736
+ ```
737
+ ┌──────────────────────────────────────────────────┐
738
+ │ ACE > Plan Story > Writing Document (Pass 1) │
739
+ └──────────────────────────────────────────────────┘
740
+
741
+ i Writing story specification...
742
+ Output: {STORY_FILE}
743
+ ```
744
+
745
+ Create directory structure:
746
+ ```bash
747
+ mkdir -p {INIT.paths.story_dir}
748
+ ```
749
+
750
+ Prepare the full story document following the story.xml template EXACTLY.
751
+ Include ALL sections 1-8:
752
+ - **Header**: Story ID, Title, Feature reference, Epic reference, Status=Refined,
753
+ Size, Sprint=—, Link
754
+ - **User Story**: As/I want/So that format
755
+ - **Description**: 2-4 sentences of observable behavior and feature context
756
+ - **Acceptance Criteria**: ALL Gherkin scenarios from questioning
757
+ - **Out of Scope**: Explicit exclusions
758
+ - **Dependencies**: Blocked By, Blocks, External
759
+ - **Definition of Done**: Standard checklist + any story-specific items
760
+ - **Relevant Wiki**: Placeholder — `&lt;!-- Pass 2. Populated by research-story-wiki. --&gt;`
761
+ - **Technical Solution**: Placeholder — `&lt;!-- Pass 5. Populated by research-technical-solution. --&gt;`
762
+ - **Metadata**: Created date, Last refined date, Refinements count, Feature path
763
+
764
+ Write the file using the Write tool to `{INIT.paths.story_file}`.
765
+
766
+ **If RUN_MODE is REFINE:**
767
+ Increment the metadata refinement count and update "Last refined" date.
768
+ Preserve any existing Relevant Wiki or Technical Solution sections.
769
+
770
+ Display:
771
+ ```
772
+ + Story specification written to {INIT.paths.story_file}
773
+ Sections 1-8 complete. {N} acceptance criteria scenarios.
774
+ ```
775
+ </step>
776
+
777
+ <!-- ══════════════════════════════════════════════════════════════════ -->
778
+ <!-- STEP 7: REVIEW AND APPROVE (Pass 1) -->
779
+ <!-- ══════════════════════════════════════════════════════════════════ -->
780
+
781
+ <step name="review-pass1" order="7">
782
+
783
+ Use AskUserQuestion:
784
+ - header: "Story"
785
+ - question: "Story specification written to `{INIT.paths.story_file}`. Review the file in your editor. Does it look right?"
786
+ - options:
787
+ - "Approve" — Looks good, proceed to research passes
788
+ - "Adjust" I want to change some things
789
+ - "Redo questioning" Let's go back and explore more
790
+
791
+ **If "Adjust":**
792
+ - Ask what needs changing
793
+ - Apply edits using the Edit tool directly on `{INIT.paths.story_file}`
794
+ - Present for review again. Loop until approved.
795
+
796
+ **If "Redo questioning":**
797
+ - Return to step 5 (deep-questioning)
798
+ - Preserve FEATURE_CONTEXT, VISION, BACKLOG_CONTEXT
799
+ - Hold previous answers as additional context
800
+
801
+ **If "Approve":**
802
+ Continue to step 8.
803
+ </step>
804
+
805
+ <!-- ══════════════════════════════════════════════════════════════════ -->
806
+ <!-- STEP 8: DISPATCH RESEARCH PASSES (2-5) -->
807
+ <!-- ══════════════════════════════════════════════════════════════════ -->
808
+
809
+ <step name="dispatch-research" order="8">
810
+
811
+ Display:
812
+ ```
813
+ ┌──────────────────────────────────────────────────┐
814
+ │ ACE > Plan Story > Research Passes │
815
+ └──────────────────────────────────────────────────┘
816
+
817
+ i Story requirements complete. Dispatching research passes...
818
+ ```
819
+
820
+ <!-- ── 8a: Offer external analysis (Pass 3 — OPTIONAL) ──────── -->
821
+
822
+ **If `EXTERNAL_CODEBASE` was provided as parameter:**
823
+ Set `RUN_EXTERNAL = true`.
824
+
825
+ **If `EXTERNAL_CODEBASE` was NOT provided:**
826
+
827
+ Use AskUserQuestion:
828
+ - header: "External"
829
+ - question: "Does this story reference an external system or reference implementation you'd like to analyze?"
830
+ - options:
831
+ - "No external system" — Skip external analysis
832
+ - "Yes, provide path" — I have an external codebase to analyze
833
+
834
+ If "Yes, provide path":
835
+ Ask for the external-codebase path (and optionally external-docs).
836
+ Set `EXTERNAL_CODEBASE` and `EXTERNAL_DOCS` from user response.
837
+ Set `RUN_EXTERNAL = true`.
838
+
839
+ If "No external system":
840
+ Set `RUN_EXTERNAL = false`.
841
+
842
+ <!-- ── 8b: Dispatch Pass 2 — Wiki Research ──────────────────── -->
843
+
844
+ **If `has_wiki` is false:** Skip pass 2. Display:
845
+ ```
846
+ i No wiki found. Skipping pass 2 (wiki research).
847
+ ```
848
+
849
+ **If `has_wiki` is true:**
850
+
851
+ Display:
852
+ ```
853
+ i Pass 2: Dispatching wiki research...
854
+ Agent will update story file with Relevant Wiki section.
855
+ ```
856
+
857
+ **CRITICAL — Context Window Protection:**
858
+ The agent writes to the story file and returns ONLY a ~10-line confirmation.
859
+ This prevents agent output from inflating the main context window.
860
+
861
+ **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
862
+ After spawning the background agent, do NOT call TaskOutput to read its results.
863
+ You will be automatically notified when the agent completes — IGNORE those notifications.
864
+ The agent writes directly to the story file on disk. You do not need the return message.
865
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
866
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
867
+ After the notification arrives, verify the file with `wc -l`, then READ the file
868
+ directly from disk using the Read tool if needed. That is how you get the results.
869
+
870
+ Spawn background agent:
871
+ ```
872
+ Agent(
873
+ prompt="/ace:research-story-wiki story={INIT.paths.story_file}
874
+
875
+ Execute the research-story-wiki workflow end-to-end.
876
+ Write the Relevant Wiki section directly into the story file.
877
+
878
+ **Return format — ONLY this, nothing else:**
879
+ DONE
880
+ - Story: {story ID} — {story title}
881
+ - Wiki refs: {count} total ({system_wide} system-wide + {subsystem} subsystem)
882
+ - File updated: {story file path}",
883
+ subagent_type="ace-wiki-mapper",
884
+ model="{PO_MODEL}",
885
+ run_in_background=true,
886
+ description="Pass 2: Wiki research"
887
+ )
888
+ ```
889
+
890
+ Store the agent task ID as `PASS2_TASK`.
891
+
892
+ **After background notification arrives — IGNORE it:**
893
+
894
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
895
+ Just verify the file and read it directly from disk if needed.
896
+
897
+ <!-- ── 8c: Dispatch Pass 3 — External Analysis (OPTIONAL) ───── -->
898
+
899
+ **If `RUN_EXTERNAL` is false:** Skip pass 3.
900
+
901
+ **If `RUN_EXTERNAL` is true:**
902
+
903
+ Display:
904
+ ```
905
+ i Pass 3: Dispatching external analysis...
906
+ Agent will create external-analysis.md in story directory.
907
+ ```
908
+
909
+ **CRITICAL Context Window Protection:**
910
+ The agent writes to a separate file and returns ONLY a ~10-line confirmation.
911
+ This prevents agent output from inflating the main context window.
912
+
913
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
914
+ After spawning the background agent, do NOT call TaskOutput to read its results.
915
+ You will be automatically notified when the agent completes — IGNORE those notifications.
916
+ The agent writes to `{INIT.paths.external_analysis_file}` on disk. You do not need the return message.
917
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
918
+ every tool call) calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
919
+
920
+ Spawn background agent:
921
+ ```
922
+ Agent(
923
+ prompt="/ace:research-external-solution story={INIT.paths.story_file} external-codebase={EXTERNAL_CODEBASE} {external-docs={EXTERNAL_DOCS} if provided}
924
+
925
+ Execute the research-external-solution workflow end-to-end.
926
+ Write the output to {INIT.paths.external_analysis_file}.
927
+
928
+ **Return format ONLY this, nothing else:**
929
+ DONE
930
+ - Story: {story ID} {story title}
931
+ - External files analyzed: {count}
932
+ - Output: {external analysis file path}",
933
+ subagent_type="ace-code-discovery-analyst",
934
+ model="{PO_MODEL}",
935
+ run_in_background=true,
936
+ description="Pass 3: External analysis"
937
+ )
938
+ ```
939
+
940
+ Store the agent task ID as `PASS3_TASK`.
941
+
942
+ **After background notification arrives — IGNORE it:**
943
+
944
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
945
+ Just verify the file and read it directly from disk if needed.
946
+
947
+ <!-- ── 8d: Wait for passes 2 (and 3 if running) before pass 4 ── -->
948
+
949
+ Display:
950
+ ```
951
+ i Waiting for pass 2{" and pass 3" if RUN_EXTERNAL} to complete
952
+ before dispatching integration analysis (pass 4)...
953
+ ```
954
+
955
+ **Wait for PASS2_TASK notification** (and PASS3_TASK if running).
956
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
957
+ Just wait for the background notifications.
958
+
959
+ After notifications arrive, verify the outputs exist:
960
+ ```bash
961
+ wc -l {INIT.paths.story_file}
962
+ ```
963
+ If RUN_EXTERNAL:
964
+ ```bash
965
+ wc -l {INIT.paths.external_analysis_file}
966
+ ```
967
+
968
+ Display:
969
+ ```
970
+ + Pass 2 complete. Story file updated with Relevant Wiki section.
971
+ {+ Pass 3 complete. External analysis written. (if applicable)}
972
+ ```
973
+
974
+ <!-- ── 8d.1: Inject Library Documentation into Relevant Wiki ── -->
975
+
976
+ **If `LIB_DOCS` is not null/empty:**
977
+
978
+ Append a `### Library Documentation` subsection to the `## Relevant Wiki`
979
+ section in the story file. This ensures passes 4-5 see these references.
980
+
981
+ Read the story file, find the `## Relevant Wiki` section, and append
982
+ the `### Library Documentation` subsection BEFORE the next `## ` heading
983
+ (i.e., before `## Technical Solution`).
984
+
985
+ Split `LIB_DOCS` by spaces. For each entry, determine if it's a weblink
986
+ (starts with `http://` or `https://`) or a filepath, and format accordingly:
987
+
988
+ ```markdown
989
+ ### Library Documentation
990
+
991
+ <!-- Provided via lib-docs parameter. These are external library/API docs
992
+ that inform the technical solution design. Passes 4-5 MUST read/fetch
993
+ these when designing the implementation. -->
994
+
995
+ - `{entry}` — Library/API documentation reference
996
+ ```
997
+
998
+ Use the Edit tool to insert this subsection into the story file.
999
+
1000
+ Display:
1001
+ ```
1002
+ + Library documentation ({count} entries) added to Relevant Wiki section.
1003
+ ```
1004
+
1005
+ <!-- ── 8e: Dispatch Pass 4 — Integration Analysis ───────────── -->
1006
+
1007
+ Display:
1008
+ ```
1009
+ i Pass 4: Dispatching integration analysis...
1010
+ Agent will create integration-analysis.md in story directory.
1011
+ ```
1012
+
1013
+ **CRITICAL — Context Window Protection:**
1014
+ The agent writes to a separate file and returns ONLY a ~10-line confirmation.
1015
+ This prevents agent output from inflating the main context window.
1016
+
1017
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
1018
+ After spawning the background agent, do NOT call TaskOutput to read its results.
1019
+ You will be automatically notified when the agent completes — IGNORE those notifications.
1020
+ The agent writes to `{INIT.paths.integration_analysis_file}` on disk. You do not need the return message.
1021
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
1022
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
1023
+
1024
+ Spawn background agent:
1025
+ ```
1026
+ Agent(
1027
+ prompt="/ace:research-integration-solution story={INIT.paths.story_file}
1028
+
1029
+ Execute the research-integration-solution workflow end-to-end.
1030
+ Write the output to {INIT.paths.integration_analysis_file}.
1031
+ The story file now has the Relevant Wiki section (pass 2 complete).
1032
+ {If external analysis exists: The external-analysis.md file exists in the story directory.}
1033
+
1034
+ **Return format — ONLY this, nothing else:**
1035
+ DONE
1036
+ - Story: {story ID} — {story title}
1037
+ - Integration points found: {count}
1038
+ - Output: {integration analysis file path}",
1039
+ subagent_type="ace-code-integration-analyst",
1040
+ model="{PO_MODEL}",
1041
+ run_in_background=true,
1042
+ description="Pass 4: Integration analysis"
1043
+ )
1044
+ ```
1045
+
1046
+ Store the agent task ID as `PASS4_TASK`.
1047
+
1048
+ **After background notification arrives — IGNORE it:**
1049
+
1050
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1051
+ Just verify the file and read it directly from disk if needed.
1052
+
1053
+ <!-- ── 8f: Wait for pass 4 before pass 5 ────────────────────── -->
1054
+
1055
+ **Wait for PASS4_TASK notification.**
1056
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1057
+
1058
+ After notification arrives, verify:
1059
+ ```bash
1060
+ wc -l {INIT.paths.integration_analysis_file}
1061
+ ```
1062
+
1063
+ Display:
1064
+ ```
1065
+ + Pass 4 complete. Integration analysis written.
1066
+ ```
1067
+
1068
+ <!-- ── 8g: Dispatch Pass 5 — Technical Solution ─────────────── -->
1069
+
1070
+ Display:
1071
+ ```
1072
+ i Pass 5: Dispatching technical solution design...
1073
+ Agent will append Technical Solution to story file.
1074
+ ```
1075
+
1076
+ **CRITICAL — Context Window Protection:**
1077
+ The agent writes directly into the story file and returns ONLY a ~10-line confirmation.
1078
+ This prevents agent output from inflating the main context window.
1079
+
1080
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
1081
+ After spawning the background agent, do NOT call TaskOutput to read its results.
1082
+ You will be automatically notified when the agent completes — IGNORE those notifications.
1083
+ The agent writes directly to the story file on disk. You do not need the return message.
1084
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
1085
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
1086
+
1087
+ Spawn background agent:
1088
+ ```
1089
+ Agent(
1090
+ prompt="/ace:research-technical-solution story={INIT.paths.story_file}
1091
+
1092
+ Execute the research-technical-solution workflow end-to-end.
1093
+ The story file has the full requirements + Relevant Wiki section.
1094
+ {If LIB_DOCS provided: The Relevant Wiki section includes a '### Library Documentation' subsection with external library/API doc references — READ/FETCH these as primary design input.}
1095
+ The integration-analysis.md exists in the story directory.
1096
+ {If external analysis exists: The external-analysis.md exists in the story directory.}
1097
+ Append the Technical Solution section to the story file.
1098
+
1099
+ **Return format — ONLY this, nothing else:**
1100
+ DONE
1101
+ - Story: {story ID} — {story title}
1102
+ - Components designed: {count}
1103
+ - Sequence diagrams: {count}
1104
+ - Story file updated: {story file path}",
1105
+ subagent_type="ace-technical-application-architect",
1106
+ model="{PO_MODEL}",
1107
+ run_in_background=true,
1108
+ description="Pass 5: Technical solution"
1109
+ )
1110
+ ```
1111
+
1112
+ Store the agent task ID as `PASS5_TASK`.
1113
+
1114
+ **After background notification arrives — IGNORE it:**
1115
+
1116
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1117
+ Just verify the file and read it directly from disk if needed.
1118
+
1119
+ <!-- ── 8h: Wait for pass 5 ──────────────────────────────────── -->
1120
+
1121
+ **Wait for PASS5_TASK notification.**
1122
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1123
+
1124
+ After notification arrives, verify:
1125
+ ```bash
1126
+ wc -l {INIT.paths.story_file}
1127
+ ```
1128
+
1129
+ Display:
1130
+ ```
1131
+ + Pass 5 complete. Technical solution appended to story file.
1132
+ ```
1133
+ </step>
1134
+
1135
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1136
+ <!-- STEP 9: STATE UPDATES -->
1137
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1138
+
1139
+ <step name="state-updates" order="9">
1140
+
1141
+ <substep order="9.1" name="update-state-via-tools">
1142
+ ```bash
1143
+ node ${CLAUDE_SKILL_DIR}/script.js update-state \
1144
+ story={INIT.paths.story_file} \
1145
+ status=Refined
1146
+ ```
1147
+
1148
+ Parse result for: `story_updated`, `feature_updated`, `backlog_updated`.
1149
+
1150
+ ```
1151
+ + Story status updated to Refined
1152
+ {+ Feature file updated (if feature_updated)}
1153
+ {+ Product backlog updated (if backlog_updated)}
1154
+ ```
1155
+ </substep>
1156
+
1157
+ Continue to step 10.
1158
+ </step>
1159
+
1160
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1161
+ <!-- STEP 10: GITHUB SYNC -->
1162
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1163
+
1164
+ <step name="github-sync" order="10">
1165
+
1166
+ <variant condition="INIT.github_project.enabled is false OR INIT.has_gh_cli is false">
1167
+ ```
1168
+ — GitHub sync skipped (not configured or gh CLI unavailable).
1169
+ ```
1170
+ Continue to step 11.
1171
+ </variant>
1172
+
1173
+ <variant condition="INIT.github_project.enabled is true AND INIT.has_gh_cli is true">
1174
+ Sync story and feature GitHub issues in a single call.
1175
+ This command prints status lines directly to the console (stderr)
1176
+ so the user ALWAYS sees whether each issue was updated or not.
1177
+
1178
+ ```bash
1179
+ node ${CLAUDE_SKILL_DIR}/script.js sync-github \
1180
+ repo={INIT.github_project.repo} \
1181
+ story_file={INIT.paths.story_file} \
1182
+ feature_file={INIT.paths.feature_file} \
1183
+ owner={INIT.github_project.owner} \
1184
+ project={INIT.github_project.project_number}
1185
+ ```
1186
+
1187
+ The command handles all cases:
1188
+ - Story/feature has no GitHub issue linked → prints skip message
1189
+ - Update succeeds → prints success message with issue number
1190
+ - Update fails → prints error message with details
1191
+
1192
+ Continue to step 11.
1193
+ </variant>
1194
+ </step>
1195
+
1196
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1197
+ <!-- STEP 11: COMMIT -->
1198
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1199
+
1200
+ <step name="commit" order="11">
1201
+
1202
+ **If `commit_docs` is false:** Skip commit.
1203
+
1204
+ Stage all changed/created files:
1205
+ ```bash
1206
+ git add {INIT.paths.story_dir}/
1207
+ git add {INIT.paths.feature_file} .ace/artifacts/product/product-backlog.md
1208
+ ```
1209
+
1210
+ Commit with descriptive message:
1211
+ - CREATE mode: `git commit -m "docs: plan story {Story ID} — {Story Title}"`
1212
+ - REFINE mode: `git commit -m "docs: refine story {Story ID} — {brief summary of changes}"`
1213
+
1214
+ Display completion:
1215
+
1216
+ ```
1217
+ ╔══════════════════════════════════════════════════╗
1218
+ ║ ACE > Story [Planned | Refined] ║
1219
+ ║ {Story ID} "{Story Title}" ║
1220
+ ╚══════════════════════════════════════════════════╝
1221
+
1222
+ + Story specification complete. All passes finished.
1223
+
1224
+ Artifacts:
1225
+ ────────
1226
+ Story file: {INIT.paths.story_file}
1227
+ {External analysis: {INIT.paths.external_analysis_file} (if created)}
1228
+ Integration analysis: {INIT.paths.integration_analysis_file}
1229
+
1230
+ Summary:
1231
+ ────────
1232
+ Acceptance criteria: {N} scenarios
1233
+ Size: {estimate}
1234
+ Passes completed: {2-5 count}
1235
+
1236
+ Next > /ace:execute-story story={INIT.paths.story_file}
1237
+ Execute the story implementation.
1238
+ > /ace:plan-story story={next story}
1239
+ Plan the next story in the feature.
1240
+ ```
1241
+ </step>
1242
+
1243
+ </process>
1244
+
1245
+ <success_criteria>
1246
+ - Init function executed (environment detected, story validated or env-only init for new stories)
1247
+ - IS_NEW_STORY correctly determined: true when no story param, story has no ACE structure, or file has no feature reference
1248
+ - Step 2 (backlog-check-placement) executed when IS_NEW_STORY is true:
1249
+ - Product backlog read and features presented for selection
1250
+ - Story title extracted from STORY_CONTENT or asked via AskUserQuestion
1251
+ - Feature placement confirmed (TARGET_FEATURE set)
1252
+ - Story ID assigned as next S[N] in the selected feature
1253
+ - Story ordering within feature confirmed (INSERT_AFTER set)
1254
+ - Dependencies asked and recorded (BLOCKED_BY, BLOCKS)
1255
+ - Story stub file created at correct ACE path with proper header (Feature/Epic/Status/Link)
1256
+ - Feature file updated: story row added to breakdown table, detail section appended, blocking story's Dependencies section updated if applicable
1257
+ - GitHub issue created (if enabled): issue linked as parent of feature issue, file header updated with link, directory and file renamed to #{issue_number}-{slug}
1258
+ - INIT re-run with final story file path; story_valid confirmed true
1259
+ - Step 2 skipped when IS_NEW_STORY is false (story is a proper ACE file with feature reference)
1260
+ - Story seed loaded and parsed (title, description, images validated)
1261
+ - CREATE vs REFINE mode correctly determined
1262
+ - Feature context loaded (parent feature document, if available)
1263
+ - Deep questioning conducted with ZERO-ASSUMPTION mandate
1264
+ - Every acceptance criterion has EXACT trigger, precondition, outcome, data, error handling
1265
+ - No vague terms remain ("it works", "shows error", "updates data" — all must be specific)
1266
+ - All Gherkin scenarios follow Given/When/Then format correctly
1267
+ - Scenarios are independent — no scenario depends on another's state
1268
+ - Minimum coverage: happy path + edge case + error path
1269
+ - Story passes INVEST checklist
1270
+ - Story size is Fibonacci (1, 2, 3, 5, 8) — split if > 8 or > 6-8 scenarios
1271
+ - Story document written following story.xml template exactly (sections 1-8)
1272
+ - User reviewed and approved pass 1 output
1273
+ - Pass 2 (wiki research) dispatched as background agent, wrote to story file
1274
+ - Pass 3 (external analysis) offered/dispatched if external-codebase provided
1275
+ - Library documentation entries injected into Relevant Wiki section after pass 2 (if lib-docs provided)
1276
+ - Pass 4 (integration analysis) dispatched AFTER passes 2-3 complete
1277
+ - Pass 5 (technical solution) dispatched AFTER pass 4 complete
1278
+ - NO TaskOutput called on ANY background agent — context window stays clean
1279
+ - Each background agent wrote output directly to disk (story file or separate artifact)
1280
+ - Story status updated to Refined via ace-tools (story file, feature file, product backlog)
1281
+ - GitHub issue synced (if applicable): updated with full story body and project status
1282
+ - All artifacts committed with descriptive message (story dir + feature file + backlog)
1283
+ </success_criteria>
1284
+
1285
+ </workflow>