agile-context-engineering 0.3.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +10 -0
  3. package/CHANGELOG.md +7 -1
  4. package/LICENSE +51 -51
  5. package/README.md +330 -318
  6. package/agents/ace-code-discovery-analyst.md +245 -245
  7. package/agents/ace-code-integration-analyst.md +248 -248
  8. package/agents/ace-code-reviewer.md +375 -375
  9. package/agents/ace-product-owner.md +365 -361
  10. package/agents/ace-project-researcher.md +606 -606
  11. package/agents/ace-research-synthesizer.md +228 -228
  12. package/agents/ace-technical-application-architect.md +315 -315
  13. package/agents/ace-wiki-mapper.md +449 -445
  14. package/bin/install.js +605 -195
  15. package/hooks/ace-check-update.js +71 -62
  16. package/hooks/ace-statusline.js +107 -89
  17. package/hooks/hooks.json +14 -0
  18. package/package.json +7 -5
  19. package/shared/lib/ace-core.js +361 -0
  20. package/shared/lib/ace-core.test.js +308 -0
  21. package/shared/lib/ace-github.js +753 -0
  22. package/shared/lib/ace-story.js +400 -0
  23. package/shared/lib/ace-story.test.js +250 -0
  24. package/{agile-context-engineering → shared}/utils/questioning.xml +110 -110
  25. package/{agile-context-engineering → shared}/utils/ui-formatting.md +299 -299
  26. package/{commands/ace/execute-story.md → skills/execute-story/SKILL.md} +116 -138
  27. package/skills/execute-story/script.js +291 -0
  28. package/skills/execute-story/script.test.js +261 -0
  29. package/{agile-context-engineering/templates/product/story.xml → skills/execute-story/story-template.xml} +451 -451
  30. package/skills/execute-story/walkthrough-template.xml +255 -0
  31. package/{agile-context-engineering/workflows/execute-story.xml → skills/execute-story/workflow.xml} +1221 -1219
  32. package/skills/help/SKILL.md +71 -0
  33. package/skills/help/script.js +315 -0
  34. package/skills/help/script.test.js +183 -0
  35. package/{agile-context-engineering/workflows/help.xml → skills/help/workflow.xml} +544 -533
  36. package/{commands/ace/init-coding-standards.md → skills/init-coding-standards/SKILL.md} +91 -83
  37. package/{agile-context-engineering/templates/wiki/coding-standards.xml → skills/init-coding-standards/coding-standards-template.xml} +531 -531
  38. package/skills/init-coding-standards/script.js +50 -0
  39. package/skills/init-coding-standards/script.test.js +70 -0
  40. package/{agile-context-engineering/workflows/init-coding-standards.xml → skills/init-coding-standards/workflow.xml} +381 -386
  41. package/skills/map-cross-cutting/SKILL.md +126 -0
  42. package/{agile-context-engineering/templates/wiki → skills/map-cross-cutting}/system-cross-cutting.xml +197 -197
  43. package/skills/map-cross-cutting/workflow.xml +330 -0
  44. package/skills/map-guide/SKILL.md +126 -0
  45. package/{agile-context-engineering/templates/wiki → skills/map-guide}/guide.xml +137 -137
  46. package/skills/map-guide/workflow.xml +320 -0
  47. package/skills/map-pattern/SKILL.md +125 -0
  48. package/{agile-context-engineering/templates/wiki → skills/map-pattern}/pattern.xml +159 -159
  49. package/skills/map-pattern/workflow.xml +331 -0
  50. package/{commands/ace/map-story.md → skills/map-story/SKILL.md} +180 -165
  51. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/decizions.xml +115 -115
  52. package/skills/map-story/templates/guide.xml +137 -0
  53. package/skills/map-story/templates/pattern.xml +159 -0
  54. package/skills/map-story/templates/system-cross-cutting.xml +197 -0
  55. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/system.xml +381 -381
  56. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/tech-debt-index.xml +125 -125
  57. package/{agile-context-engineering/templates/wiki → skills/map-story/templates}/walkthrough.xml +255 -255
  58. package/{agile-context-engineering/workflows/map-story.xml → skills/map-story/workflow.xml} +1046 -1046
  59. package/{commands/ace/map-subsystem.md → skills/map-subsystem/SKILL.md} +155 -140
  60. package/skills/map-subsystem/script.js +51 -0
  61. package/skills/map-subsystem/script.test.js +68 -0
  62. package/skills/map-subsystem/templates/decizions.xml +115 -0
  63. package/skills/map-subsystem/templates/guide.xml +137 -0
  64. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/module-discovery.xml +174 -174
  65. package/skills/map-subsystem/templates/pattern.xml +159 -0
  66. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-architecture.xml +343 -343
  67. package/{agile-context-engineering/templates/wiki → skills/map-subsystem/templates}/subsystem-structure.xml +234 -234
  68. package/skills/map-subsystem/templates/system-cross-cutting.xml +197 -0
  69. package/skills/map-subsystem/templates/system.xml +381 -0
  70. package/skills/map-subsystem/templates/walkthrough.xml +255 -0
  71. package/{agile-context-engineering/workflows/map-subsystem.xml → skills/map-subsystem/workflow.xml} +1173 -1178
  72. package/skills/map-sys-doc/SKILL.md +125 -0
  73. package/skills/map-sys-doc/system.xml +381 -0
  74. package/skills/map-sys-doc/workflow.xml +336 -0
  75. package/{commands/ace/map-system.md → skills/map-system/SKILL.md} +103 -92
  76. package/skills/map-system/script.js +75 -0
  77. package/skills/map-system/script.test.js +73 -0
  78. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-architecture.xml +254 -254
  79. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/system-structure.xml +177 -177
  80. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/testing-framework.xml +283 -283
  81. package/{agile-context-engineering/templates/wiki → skills/map-system/templates}/wiki-readme.xml +296 -296
  82. package/{agile-context-engineering/workflows/map-system.xml → skills/map-system/workflow.xml} +667 -672
  83. package/{commands/ace/map-walkthrough.md → skills/map-walkthrough/SKILL.md} +140 -127
  84. package/skills/map-walkthrough/walkthrough.xml +255 -0
  85. package/{agile-context-engineering/workflows/map-walkthrough.xml → skills/map-walkthrough/workflow.xml} +457 -457
  86. package/{commands/ace/plan-backlog.md → skills/plan-backlog/SKILL.md} +93 -83
  87. package/{agile-context-engineering/templates/product/product-backlog.xml → skills/plan-backlog/product-backlog-template.xml} +231 -231
  88. package/skills/plan-backlog/script.js +121 -0
  89. package/skills/plan-backlog/script.test.js +83 -0
  90. package/{agile-context-engineering/workflows/plan-backlog.xml → skills/plan-backlog/workflow.xml} +1348 -1356
  91. package/{commands/ace/plan-feature.md → skills/plan-feature/SKILL.md} +99 -89
  92. package/{agile-context-engineering/templates/product/feature.xml → skills/plan-feature/feature-template.xml} +361 -361
  93. package/skills/plan-feature/script.js +131 -0
  94. package/skills/plan-feature/script.test.js +80 -0
  95. package/{agile-context-engineering/workflows/plan-feature.xml → skills/plan-feature/workflow.xml} +1487 -1495
  96. package/{commands/ace/plan-product-vision.md → skills/plan-product-vision/SKILL.md} +91 -81
  97. package/{agile-context-engineering/templates/product/product-vision.xml → skills/plan-product-vision/product-vision-template.xml} +227 -227
  98. package/skills/plan-product-vision/script.js +51 -0
  99. package/skills/plan-product-vision/script.test.js +69 -0
  100. package/{agile-context-engineering/workflows/plan-product-vision.xml → skills/plan-product-vision/workflow.xml} +337 -342
  101. package/{commands/ace/plan-story.md → skills/plan-story/SKILL.md} +139 -159
  102. package/skills/plan-story/script.js +295 -0
  103. package/skills/plan-story/script.test.js +240 -0
  104. package/skills/plan-story/story-template.xml +458 -0
  105. package/{agile-context-engineering/workflows/plan-story.xml → skills/plan-story/workflow.xml} +1301 -944
  106. package/{commands/ace/research-external-solution.md → skills/research-external-solution/SKILL.md} +120 -138
  107. package/{agile-context-engineering/templates/product/external-solution.xml → skills/research-external-solution/external-solution-template.xml} +832 -832
  108. package/skills/research-external-solution/script.js +229 -0
  109. package/skills/research-external-solution/script.test.js +134 -0
  110. package/{agile-context-engineering/workflows/research-external-solution.xml → skills/research-external-solution/workflow.xml} +657 -659
  111. package/{commands/ace/research-integration-solution.md → skills/research-integration-solution/SKILL.md} +121 -135
  112. package/{agile-context-engineering/templates/product/story-integration-solution.xml → skills/research-integration-solution/integration-solution-template.xml} +1015 -1015
  113. package/skills/research-integration-solution/script.js +223 -0
  114. package/skills/research-integration-solution/script.test.js +134 -0
  115. package/{agile-context-engineering/workflows/research-integration-solution.xml → skills/research-integration-solution/workflow.xml} +711 -713
  116. package/{commands/ace/research-story-wiki.md → skills/research-story-wiki/SKILL.md} +101 -116
  117. package/skills/research-story-wiki/script.js +223 -0
  118. package/skills/research-story-wiki/script.test.js +138 -0
  119. package/{agile-context-engineering/templates/product/story-wiki.xml → skills/research-story-wiki/story-wiki-template.xml} +194 -194
  120. package/{agile-context-engineering/workflows/research-story-wiki.xml → skills/research-story-wiki/workflow.xml} +473 -475
  121. package/{commands/ace/research-technical-solution.md → skills/research-technical-solution/SKILL.md} +131 -147
  122. package/skills/research-technical-solution/script.js +223 -0
  123. package/skills/research-technical-solution/script.test.js +134 -0
  124. package/{agile-context-engineering/templates/product/story-technical-solution.xml → skills/research-technical-solution/technical-solution-template.xml} +1025 -1025
  125. package/{agile-context-engineering/workflows/research-technical-solution.xml → skills/research-technical-solution/workflow.xml} +761 -763
  126. package/{commands/ace/review-story.md → skills/review-story/SKILL.md} +99 -109
  127. package/skills/review-story/script.js +249 -0
  128. package/skills/review-story/script.test.js +169 -0
  129. package/skills/review-story/story-template.xml +451 -0
  130. package/{agile-context-engineering/workflows/review-story.xml → skills/review-story/workflow.xml} +279 -281
  131. package/{commands/ace/update.md → skills/update/SKILL.md} +65 -56
  132. package/{agile-context-engineering/workflows/update.xml → skills/update/workflow.xml} +33 -18
  133. package/agile-context-engineering/src/ace-tools.js +0 -2881
  134. package/agile-context-engineering/src/ace-tools.test.js +0 -1089
  135. package/agile-context-engineering/templates/_command.md +0 -54
  136. package/agile-context-engineering/templates/_workflow.xml +0 -17
  137. package/agile-context-engineering/templates/config.json +0 -0
  138. package/agile-context-engineering/templates/product/integration-solution.xml +0 -0
  139. package/commands/ace/help.md +0 -93
@@ -1,944 +1,1301 @@
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
+ All supporting resource files are auto-loaded in the skill prompt above. Do NOT re-read them.
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
+ **YOU (the product owner) DO NOT WRITE passes 2-5 yourself.**
812
+ Your job in this step is ONLY to dispatch background agents and wait for them.
813
+ You MUST NOT write the `## Relevant Wiki` section — the wiki-mapper agent does that.
814
+ You MUST NOT write the `## Technical Solution` section — the technical-architect agent does that.
815
+ You MUST NOT create any files not specified below (no wiki-research.md, no notes.md).
816
+ If you skip a dispatch or write these sections yourself, the workflow has FAILED.
817
+
818
+ Display:
819
+ ```
820
+ ┌──────────────────────────────────────────────────┐
821
+ │ ACE > Plan Story > Research Passes │
822
+ └──────────────────────────────────────────────────┘
823
+
824
+ i Story requirements complete. Dispatching research passes...
825
+ ```
826
+
827
+ <!-- ── 8a: Offer external analysis (Pass 3 — OPTIONAL) ──────── -->
828
+
829
+ **If `EXTERNAL_CODEBASE` was provided as parameter:**
830
+ Set `RUN_EXTERNAL = true`.
831
+
832
+ **If `EXTERNAL_CODEBASE` was NOT provided:**
833
+
834
+ Use AskUserQuestion:
835
+ - header: "External"
836
+ - question: "Does this story reference an external system or reference implementation you'd like to analyze?"
837
+ - options:
838
+ - "No external system" Skip external analysis
839
+ - "Yes, provide path" — I have an external codebase to analyze
840
+
841
+ If "Yes, provide path":
842
+ Ask for the external-codebase path (and optionally external-docs).
843
+ Set `EXTERNAL_CODEBASE` and `EXTERNAL_DOCS` from user response.
844
+ Set `RUN_EXTERNAL = true`.
845
+
846
+ If "No external system":
847
+ Set `RUN_EXTERNAL = false`.
848
+
849
+ <!-- ── 8b: Dispatch Pass 2 — Wiki Research ──────────────────── -->
850
+
851
+ **If `has_wiki` is false:** Skip pass 2. Display:
852
+ ```
853
+ i No wiki found. Skipping pass 2 (wiki research).
854
+ ```
855
+
856
+ **If `has_wiki` is true:**
857
+
858
+ Display:
859
+ ```
860
+ i Pass 2: Dispatching wiki research...
861
+ Agent will update story file with Relevant Wiki section.
862
+ ```
863
+
864
+ **CRITICAL Context Window Protection:**
865
+ The agent writes to the story file and returns ONLY a ~10-line confirmation.
866
+ This prevents agent output from inflating the main context window.
867
+
868
+ **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
869
+ After spawning the background agent, do NOT call TaskOutput to read its results.
870
+ You will be automatically notified when the agent completes — IGNORE those notifications.
871
+ The agent writes directly to the story file on disk. You do not need the return message.
872
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
873
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
874
+ After the notification arrives, verify the file with `wc -l`, then READ the file
875
+ directly from disk using the Read tool if needed. That is how you get the results.
876
+
877
+ Spawn background agent:
878
+ ```
879
+ Agent(
880
+ prompt="/ace:research-story-wiki story={INIT.paths.story_file}
881
+
882
+ Execute the research-story-wiki workflow end-to-end.
883
+ Write the Relevant Wiki section directly into the story file.
884
+
885
+ **Return format — ONLY this, nothing else:**
886
+ DONE
887
+ - Story: {story ID} — {story title}
888
+ - Wiki refs: {count} total ({system_wide} system-wide + {subsystem} subsystem)
889
+ - File updated: {story file path}",
890
+ subagent_type="ace-wiki-mapper",
891
+ model="{PO_MODEL}",
892
+ run_in_background=true,
893
+ description="Pass 2: Wiki research"
894
+ )
895
+ ```
896
+
897
+ Store the agent task ID as `PASS2_TASK`.
898
+
899
+ **After background notification arrives — IGNORE it:**
900
+
901
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
902
+ Just verify the file and read it directly from disk if needed.
903
+
904
+ <!-- ── 8c: Dispatch Pass 3 — External Analysis (OPTIONAL) ───── -->
905
+
906
+ **If `RUN_EXTERNAL` is false:** Skip pass 3.
907
+
908
+ **If `RUN_EXTERNAL` is true:**
909
+
910
+ Display:
911
+ ```
912
+ i Pass 3: Dispatching external analysis...
913
+ Agent will create external-analysis.md in story directory.
914
+ ```
915
+
916
+ **CRITICAL — Context Window Protection:**
917
+ The agent writes to a separate file and returns ONLY a ~10-line confirmation.
918
+ This prevents agent output from inflating the main context window.
919
+
920
+ **CRITICAL Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
921
+ After spawning the background agent, do NOT call TaskOutput to read its results.
922
+ You will be automatically notified when the agent completes — IGNORE those notifications.
923
+ The agent writes to `{INIT.paths.external_analysis_file}` on disk. You do not need the return message.
924
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
925
+ every tool call) calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
926
+
927
+ Spawn background agent:
928
+ ```
929
+ Agent(
930
+ prompt="/ace:research-external-solution story={INIT.paths.story_file} external-codebase={EXTERNAL_CODEBASE} {external-docs={EXTERNAL_DOCS} if provided}
931
+
932
+ Execute the research-external-solution workflow end-to-end.
933
+ Write the output to {INIT.paths.external_analysis_file}.
934
+
935
+ **Return format ONLY this, nothing else:**
936
+ DONE
937
+ - Story: {story ID}{story title}
938
+ - External files analyzed: {count}
939
+ - Output: {external analysis file path}",
940
+ subagent_type="ace-code-discovery-analyst",
941
+ model="{PO_MODEL}",
942
+ run_in_background=true,
943
+ description="Pass 3: External analysis"
944
+ )
945
+ ```
946
+
947
+ Store the agent task ID as `PASS3_TASK`.
948
+
949
+ **After background notification arrives — IGNORE it:**
950
+
951
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
952
+ Just verify the file and read it directly from disk if needed.
953
+
954
+ <!-- ── 8d: Wait for passes 2 (and 3 if running) before pass 4 ── -->
955
+
956
+ Display:
957
+ ```
958
+ i Waiting for pass 2{" and pass 3" if RUN_EXTERNAL} to complete
959
+ before dispatching integration analysis (pass 4)...
960
+ ```
961
+
962
+ **Wait for PASS2_TASK notification** (and PASS3_TASK if running).
963
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
964
+ Just wait for the background notifications.
965
+
966
+ After notifications arrive, verify the outputs exist:
967
+ ```bash
968
+ wc -l {INIT.paths.story_file}
969
+ ```
970
+ If RUN_EXTERNAL:
971
+ ```bash
972
+ wc -l {INIT.paths.external_analysis_file}
973
+ ```
974
+
975
+ Display:
976
+ ```
977
+ + Pass 2 complete. Story file updated with Relevant Wiki section.
978
+ {+ Pass 3 complete. External analysis written. (if applicable)}
979
+ ```
980
+
981
+ <!-- ── 8d.1: Inject Library Documentation into Relevant Wiki ── -->
982
+
983
+ **If `LIB_DOCS` is not null/empty:**
984
+
985
+ Append a `### Library Documentation` subsection to the `## Relevant Wiki`
986
+ section in the story file. This ensures passes 4-5 see these references.
987
+
988
+ Read the story file, find the `## Relevant Wiki` section, and append
989
+ the `### Library Documentation` subsection BEFORE the next `## ` heading
990
+ (i.e., before `## Technical Solution`).
991
+
992
+ Split `LIB_DOCS` by spaces. For each entry, determine if it's a weblink
993
+ (starts with `http://` or `https://`) or a filepath, and format accordingly:
994
+
995
+ ```markdown
996
+ ### Library Documentation
997
+
998
+ <!-- Provided via lib-docs parameter. These are external library/API docs
999
+ that inform the technical solution design. Passes 4-5 MUST read/fetch
1000
+ these when designing the implementation. -->
1001
+
1002
+ - `{entry}` — Library/API documentation reference
1003
+ ```
1004
+
1005
+ Use the Edit tool to insert this subsection into the story file.
1006
+
1007
+ Display:
1008
+ ```
1009
+ + Library documentation ({count} entries) added to Relevant Wiki section.
1010
+ ```
1011
+
1012
+ <!-- ── 8e: Dispatch Pass 4 — Integration Analysis ───────────── -->
1013
+
1014
+ Display:
1015
+ ```
1016
+ i Pass 4: Dispatching integration analysis...
1017
+ Agent will create integration-analysis.md in story directory.
1018
+ ```
1019
+
1020
+ **CRITICAL — Context Window Protection:**
1021
+ The agent writes to a separate file and returns ONLY a ~10-line confirmation.
1022
+ This prevents agent output from inflating the main context window.
1023
+
1024
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
1025
+ After spawning the background agent, do NOT call TaskOutput to read its results.
1026
+ You will be automatically notified when the agent completes — IGNORE those notifications.
1027
+ The agent writes to `{INIT.paths.integration_analysis_file}` on disk. You do not need the return message.
1028
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
1029
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
1030
+
1031
+ Spawn background agent:
1032
+ ```
1033
+ Agent(
1034
+ prompt="/ace:research-integration-solution story={INIT.paths.story_file}
1035
+
1036
+ Execute the research-integration-solution workflow end-to-end.
1037
+ Write the output to {INIT.paths.integration_analysis_file}.
1038
+ The story file now has the Relevant Wiki section (pass 2 complete).
1039
+ {If external analysis exists: The external-analysis.md file exists in the story directory.}
1040
+
1041
+ **Return format — ONLY this, nothing else:**
1042
+ DONE
1043
+ - Story: {story ID} — {story title}
1044
+ - Integration points found: {count}
1045
+ - Output: {integration analysis file path}",
1046
+ subagent_type="ace-code-integration-analyst",
1047
+ model="{PO_MODEL}",
1048
+ run_in_background=true,
1049
+ description="Pass 4: Integration analysis"
1050
+ )
1051
+ ```
1052
+
1053
+ Store the agent task ID as `PASS4_TASK`.
1054
+
1055
+ **After background notification arrives — IGNORE it:**
1056
+
1057
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1058
+ Just verify the file and read it directly from disk if needed.
1059
+
1060
+ <!-- ── 8f: Wait for pass 4 before pass 5 ────────────────────── -->
1061
+
1062
+ **Wait for PASS4_TASK notification.**
1063
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1064
+
1065
+ After notification arrives, verify:
1066
+ ```bash
1067
+ wc -l {INIT.paths.integration_analysis_file}
1068
+ ```
1069
+
1070
+ Display:
1071
+ ```
1072
+ + Pass 4 complete. Integration analysis written.
1073
+ ```
1074
+
1075
+ <!-- ── 8g: Dispatch Pass 5 — Technical Solution ─────────────── -->
1076
+
1077
+ Display:
1078
+ ```
1079
+ i Pass 5: Dispatching technical solution design...
1080
+ Agent will append Technical Solution to story file.
1081
+ ```
1082
+
1083
+ **CRITICAL — Context Window Protection:**
1084
+ The agent writes directly into the story file and returns ONLY a ~10-line confirmation.
1085
+ This prevents agent output from inflating the main context window.
1086
+
1087
+ **CRITICAL — Do NOT call TaskOutput. NEVER. UNDER NO CIRCUMSTANCES.**
1088
+ After spawning the background agent, do NOT call TaskOutput to read its results.
1089
+ You will be automatically notified when the agent completes — IGNORE those notifications.
1090
+ The agent writes directly to the story file on disk. You do not need the return message.
1091
+ TaskOutput returns the agent's FULL internal transcript (every file read, every search,
1092
+ every tool call) — calling it will inflate the context window by 10-20%. THIS IS FORBIDDEN.
1093
+
1094
+ Spawn background agent:
1095
+ ```
1096
+ Agent(
1097
+ prompt="/ace:research-technical-solution story={INIT.paths.story_file}
1098
+
1099
+ Execute the research-technical-solution workflow end-to-end.
1100
+ The story file has the full requirements + Relevant Wiki section.
1101
+ {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.}
1102
+ The integration-analysis.md exists in the story directory.
1103
+ {If external analysis exists: The external-analysis.md exists in the story directory.}
1104
+ Append the Technical Solution section to the story file.
1105
+
1106
+ **Return format — ONLY this, nothing else:**
1107
+ DONE
1108
+ - Story: {story ID} — {story title}
1109
+ - Components designed: {count}
1110
+ - Sequence diagrams: {count}
1111
+ - Story file updated: {story file path}",
1112
+ subagent_type="ace-technical-application-architect",
1113
+ model="{PO_MODEL}",
1114
+ run_in_background=true,
1115
+ description="Pass 5: Technical solution"
1116
+ )
1117
+ ```
1118
+
1119
+ Store the agent task ID as `PASS5_TASK`.
1120
+
1121
+ **After background notification arrives — IGNORE it:**
1122
+
1123
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1124
+ Just verify the file and read it directly from disk if needed.
1125
+
1126
+ <!-- ── 8h: Wait for pass 5 ──────────────────────────────────── -->
1127
+
1128
+ **Wait for PASS5_TASK notification.**
1129
+ Do NOT call TaskOutput. Do NOT call TaskOutput. Do NOT call TaskOutput.
1130
+
1131
+ After notification arrives, verify:
1132
+ ```bash
1133
+ wc -l {INIT.paths.story_file}
1134
+ ```
1135
+
1136
+ Display:
1137
+ ```
1138
+ + Pass 5 complete. Technical solution appended to story file.
1139
+ ```
1140
+
1141
+ <!-- ── 8i: Verification — confirm all passes ran ────────────── -->
1142
+
1143
+ Read the story file and verify it contains BOTH:
1144
+ 1. A `## Relevant Wiki` section with actual wiki references (not just a placeholder)
1145
+ 2. A `## Technical Solution` section with actual technical design (not just a placeholder or reference to another file)
1146
+
1147
+ If either section is missing or still a placeholder, the pass dispatch FAILED.
1148
+ Display an error and re-dispatch the missing pass(es).
1149
+ </step>
1150
+
1151
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1152
+ <!-- STEP 9: STATE UPDATES -->
1153
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1154
+
1155
+ <step name="state-updates" order="9">
1156
+
1157
+ <substep order="9.1" name="update-state-via-tools">
1158
+ ```bash
1159
+ node ${CLAUDE_SKILL_DIR}/script.js update-state \
1160
+ story={INIT.paths.story_file} \
1161
+ status=Refined
1162
+ ```
1163
+
1164
+ Parse result for: `story_updated`, `feature_updated`, `backlog_updated`.
1165
+
1166
+ ```
1167
+ + Story status updated to Refined
1168
+ {+ Feature file updated (if feature_updated)}
1169
+ {+ Product backlog updated (if backlog_updated)}
1170
+ ```
1171
+ </substep>
1172
+
1173
+ Continue to step 10.
1174
+ </step>
1175
+
1176
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1177
+ <!-- STEP 10: GITHUB SYNC -->
1178
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1179
+
1180
+ <step name="github-sync" order="10">
1181
+
1182
+ <variant condition="INIT.github_project.enabled is false OR INIT.has_gh_cli is false">
1183
+ ```
1184
+ — GitHub sync skipped (not configured or gh CLI unavailable).
1185
+ ```
1186
+ Continue to step 11.
1187
+ </variant>
1188
+
1189
+ <variant condition="INIT.github_project.enabled is true AND INIT.has_gh_cli is true">
1190
+ Sync story and feature GitHub issues in a single call.
1191
+ This command prints status lines directly to the console (stderr)
1192
+ so the user ALWAYS sees whether each issue was updated or not.
1193
+
1194
+ ```bash
1195
+ node ${CLAUDE_SKILL_DIR}/script.js sync-github \
1196
+ repo={INIT.github_project.repo} \
1197
+ story_file={INIT.paths.story_file} \
1198
+ feature_file={INIT.paths.feature_file} \
1199
+ owner={INIT.github_project.owner} \
1200
+ project={INIT.github_project.project_number}
1201
+ ```
1202
+
1203
+ The command handles all cases:
1204
+ - Story/feature has no GitHub issue linked → prints skip message
1205
+ - Update succeeds → prints success message with issue number
1206
+ - Update fails → prints error message with details
1207
+
1208
+ Continue to step 11.
1209
+ </variant>
1210
+ </step>
1211
+
1212
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1213
+ <!-- STEP 11: COMMIT -->
1214
+ <!-- ══════════════════════════════════════════════════════════════════ -->
1215
+
1216
+ <step name="commit" order="11">
1217
+
1218
+ **If `commit_docs` is false:** Skip commit.
1219
+
1220
+ Stage all changed/created files:
1221
+ ```bash
1222
+ git add {INIT.paths.story_dir}/
1223
+ git add {INIT.paths.feature_file} .ace/artifacts/product/product-backlog.md
1224
+ ```
1225
+
1226
+ Commit with descriptive message:
1227
+ - CREATE mode: `git commit -m "docs: plan story {Story ID} — {Story Title}"`
1228
+ - REFINE mode: `git commit -m "docs: refine story {Story ID} — {brief summary of changes}"`
1229
+
1230
+ Display completion:
1231
+
1232
+ ```
1233
+ ╔══════════════════════════════════════════════════╗
1234
+ ║ ACE > Story [Planned | Refined] ║
1235
+ ║ {Story ID} "{Story Title}" ║
1236
+ ╚══════════════════════════════════════════════════╝
1237
+
1238
+ + Story specification complete. All passes finished.
1239
+
1240
+ Artifacts:
1241
+ ────────
1242
+ Story file: {INIT.paths.story_file}
1243
+ {External analysis: {INIT.paths.external_analysis_file} (if created)}
1244
+ Integration analysis: {INIT.paths.integration_analysis_file}
1245
+
1246
+ Summary:
1247
+ ────────
1248
+ Acceptance criteria: {N} scenarios
1249
+ Size: {estimate}
1250
+ Passes completed: {2-5 count}
1251
+
1252
+ Next > /ace:execute-story story={INIT.paths.story_file}
1253
+ Execute the story implementation.
1254
+ > /ace:plan-story story={next story}
1255
+ Plan the next story in the feature.
1256
+ ```
1257
+ </step>
1258
+
1259
+ </process>
1260
+
1261
+ <success_criteria>
1262
+ - Init function executed (environment detected, story validated or env-only init for new stories)
1263
+ - IS_NEW_STORY correctly determined: true when no story param, story has no ACE structure, or file has no feature reference
1264
+ - Step 2 (backlog-check-placement) executed when IS_NEW_STORY is true:
1265
+ - Product backlog read and features presented for selection
1266
+ - Story title extracted from STORY_CONTENT or asked via AskUserQuestion
1267
+ - Feature placement confirmed (TARGET_FEATURE set)
1268
+ - Story ID assigned as next S[N] in the selected feature
1269
+ - Story ordering within feature confirmed (INSERT_AFTER set)
1270
+ - Dependencies asked and recorded (BLOCKED_BY, BLOCKS)
1271
+ - Story stub file created at correct ACE path with proper header (Feature/Epic/Status/Link)
1272
+ - Feature file updated: story row added to breakdown table, detail section appended, blocking story's Dependencies section updated if applicable
1273
+ - 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}
1274
+ - INIT re-run with final story file path; story_valid confirmed true
1275
+ - Step 2 skipped when IS_NEW_STORY is false (story is a proper ACE file with feature reference)
1276
+ - Story seed loaded and parsed (title, description, images validated)
1277
+ - CREATE vs REFINE mode correctly determined
1278
+ - Feature context loaded (parent feature document, if available)
1279
+ - Deep questioning conducted with ZERO-ASSUMPTION mandate
1280
+ - Every acceptance criterion has EXACT trigger, precondition, outcome, data, error handling
1281
+ - No vague terms remain ("it works", "shows error", "updates data" — all must be specific)
1282
+ - All Gherkin scenarios follow Given/When/Then format correctly
1283
+ - Scenarios are independent — no scenario depends on another's state
1284
+ - Minimum coverage: happy path + edge case + error path
1285
+ - Story passes INVEST checklist
1286
+ - Story size is Fibonacci (1, 2, 3, 5, 8) — split if > 8 or > 6-8 scenarios
1287
+ - Story document written following story.xml template exactly (sections 1-8)
1288
+ - User reviewed and approved pass 1 output
1289
+ - Pass 2 (wiki research) dispatched as background agent, wrote to story file
1290
+ - Pass 3 (external analysis) offered/dispatched if external-codebase provided
1291
+ - Library documentation entries injected into Relevant Wiki section after pass 2 (if lib-docs provided)
1292
+ - Pass 4 (integration analysis) dispatched AFTER passes 2-3 complete
1293
+ - Pass 5 (technical solution) dispatched AFTER pass 4 complete
1294
+ - NO TaskOutput called on ANY background agent — context window stays clean
1295
+ - Each background agent wrote output directly to disk (story file or separate artifact)
1296
+ - Story status updated to Refined via ace-tools (story file, feature file, product backlog)
1297
+ - GitHub issue synced (if applicable): updated with full story body and project status
1298
+ - All artifacts committed with descriptive message (story dir + feature file + backlog)
1299
+ </success_criteria>
1300
+
1301
+ </workflow>