maestro-flow 0.3.12 → 0.3.13

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 (235) hide show
  1. package/.claude/CLAUDE.md +7 -0
  2. package/.claude/agents/workflow-analyzer.md +0 -1
  3. package/.claude/agents/workflow-collab-planner.md +0 -1
  4. package/.claude/agents/workflow-debugger.md +0 -1
  5. package/.claude/agents/workflow-integration-checker.md +2 -2
  6. package/.claude/agents/workflow-nyquist-auditor.md +0 -1
  7. package/.claude/agents/workflow-phase-researcher.md +2 -2
  8. package/.claude/agents/workflow-plan-checker.md +1 -1
  9. package/.claude/agents/workflow-planner.md +1 -2
  10. package/.claude/agents/workflow-roadmapper.md +1 -1
  11. package/.claude/agents/workflow-verifier.md +0 -1
  12. package/.claude/commands/learn-retro.md +2 -2
  13. package/.claude/commands/learn-second-opinion.md +2 -2
  14. package/.claude/commands/maestro-analyze.md +10 -2
  15. package/.claude/commands/maestro-brainstorm.md +1 -1
  16. package/.claude/commands/maestro-execute.md +21 -4
  17. package/.claude/commands/maestro-milestone-complete.md +14 -0
  18. package/.claude/commands/maestro-plan.md +12 -6
  19. package/.claude/commands/maestro-roadmap.md +1 -1
  20. package/.claude/commands/maestro-ui-design.md +7 -7
  21. package/.claude/commands/maestro-update.md +176 -0
  22. package/.claude/commands/maestro-verify.md +18 -3
  23. package/.claude/commands/manage-codebase-rebuild.md +0 -1
  24. package/.claude/commands/manage-harvest.md +1 -1
  25. package/.claude/commands/manage-learn.md +5 -5
  26. package/.claude/commands/manage-memory-capture.md +4 -4
  27. package/.claude/commands/manage-memory.md +1 -1
  28. package/.claude/commands/manage-wiki.md +62 -0
  29. package/.claude/commands/quality-business-test.md +2 -2
  30. package/.claude/commands/quality-debug.md +53 -7
  31. package/.claude/commands/quality-retrospective.md +5 -5
  32. package/.claude/commands/quality-review.md +39 -7
  33. package/.claude/commands/quality-sync.md +1 -1
  34. package/.claude/commands/quality-test-gen.md +1 -1
  35. package/.claude/commands/quality-test.md +45 -12
  36. package/.claude/commands/spec-remove.md +51 -0
  37. package/.claude/commands/spec-setup.md +1 -3
  38. package/.claude/commands/wiki-connect.md +9 -5
  39. package/.claude/commands/wiki-digest.md +6 -3
  40. package/.codex/skills/maestro/SKILL.md +2 -2
  41. package/.codex/skills/maestro-analyze/SKILL.md +4 -4
  42. package/.codex/skills/maestro-brainstorm/SKILL.md +4 -4
  43. package/.codex/skills/maestro-coordinate/SKILL.md +2 -2
  44. package/.codex/skills/maestro-execute/SKILL.md +15 -5
  45. package/.codex/skills/maestro-init/SKILL.md +1 -1
  46. package/.codex/skills/maestro-milestone-complete/SKILL.md +18 -1
  47. package/.codex/skills/maestro-plan/SKILL.md +6 -6
  48. package/.codex/skills/maestro-roadmap/SKILL.md +3 -4
  49. package/.codex/skills/maestro-spec-generate/SKILL.md +2 -2
  50. package/.codex/skills/maestro-ui-design/SKILL.md +6 -6
  51. package/.codex/skills/maestro-verify/SKILL.md +20 -11
  52. package/.codex/skills/manage-codebase-rebuild/SKILL.md +4 -4
  53. package/.codex/skills/manage-harvest/SKILL.md +10 -1
  54. package/.codex/skills/manage-issue-discover/SKILL.md +3 -3
  55. package/.codex/skills/manage-learn/SKILL.md +3 -2
  56. package/.codex/skills/manage-memory/SKILL.md +3 -3
  57. package/.codex/skills/manage-memory-capture/SKILL.md +8 -14
  58. package/.codex/skills/manage-status/SKILL.md +9 -4
  59. package/.codex/skills/manage-wiki/SKILL.md +55 -0
  60. package/.codex/skills/quality-business-test/SKILL.md +8 -6
  61. package/.codex/skills/quality-debug/SKILL.md +22 -9
  62. package/.codex/skills/quality-integration-test/SKILL.md +11 -7
  63. package/.codex/skills/quality-retrospective/SKILL.md +45 -26
  64. package/.codex/skills/quality-review/SKILL.md +10 -7
  65. package/.codex/skills/quality-test/SKILL.md +9 -4
  66. package/.codex/skills/quality-test-gen/SKILL.md +13 -9
  67. package/.codex/skills/spec-add/SKILL.md +11 -3
  68. package/.codex/skills/spec-load/SKILL.md +7 -0
  69. package/.codex/skills/spec-map/SKILL.md +2 -2
  70. package/.codex/skills/spec-remove/SKILL.md +101 -0
  71. package/.codex/skills/spec-setup/SKILL.md +4 -8
  72. package/.codex/skills/wiki-connect/SKILL.md +6 -5
  73. package/.codex/skills/wiki-digest/SKILL.md +2 -2
  74. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.d.ts +9 -0
  75. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +109 -9
  76. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
  77. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js +49 -0
  78. package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.test.js.map +1 -1
  79. package/dashboard/dist-server/dashboard/src/server/routes/index.js +5 -4
  80. package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
  81. package/dashboard/dist-server/dashboard/src/server/routes/specs.d.ts +5 -13
  82. package/dashboard/dist-server/dashboard/src/server/routes/specs.js +97 -155
  83. package/dashboard/dist-server/dashboard/src/server/routes/specs.js.map +1 -1
  84. package/dashboard/dist-server/dashboard/src/server/routes/wiki.d.ts +11 -1
  85. package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js +27 -6
  86. package/dashboard/dist-server/dashboard/src/server/routes/wiki.integration.test.js.map +1 -1
  87. package/dashboard/dist-server/dashboard/src/server/routes/wiki.js +25 -7
  88. package/dashboard/dist-server/dashboard/src/server/routes/wiki.js.map +1 -1
  89. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js +8 -0
  90. package/dashboard/dist-server/dashboard/src/server/wiki/graph-analysis.js.map +1 -1
  91. package/dashboard/dist-server/dashboard/src/server/wiki/search.js +1 -0
  92. package/dashboard/dist-server/dashboard/src/server/wiki/search.js.map +1 -1
  93. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.d.ts +29 -0
  94. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js +148 -0
  95. package/dashboard/dist-server/dashboard/src/server/wiki/spec-entry-parser.js.map +1 -0
  96. package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js +4 -2
  97. package/dashboard/dist-server/dashboard/src/server/wiki/stress.test.js.map +1 -1
  98. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js +8 -2
  99. package/dashboard/dist-server/dashboard/src/server/wiki/virtual-wiki-adapters.js.map +1 -1
  100. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.d.ts +5 -0
  101. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js +80 -38
  102. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.js.map +1 -1
  103. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js +8 -6
  104. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-indexer.test.js.map +1 -1
  105. package/dashboard/dist-server/dashboard/src/server/wiki/wiki-types.d.ts +40 -5
  106. package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js +21 -23
  107. package/dashboard/dist-server/dashboard/src/server/wiki/writer-stress.test.js.map +1 -1
  108. package/dashboard/dist-server/dashboard/src/server/wiki/writer.d.ts +33 -3
  109. package/dashboard/dist-server/dashboard/src/server/wiki/writer.js +184 -12
  110. package/dashboard/dist-server/dashboard/src/server/wiki/writer.js.map +1 -1
  111. package/dashboard/dist-server/src/commands/delegate.js +26 -0
  112. package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
  113. package/dashboard/dist-server/src/coordinator/graph-types.d.ts +11 -1
  114. package/dashboard/dist-server/src/coordinator/graph-walker.js +29 -2
  115. package/dashboard/dist-server/src/coordinator/graph-walker.js.map +1 -1
  116. package/dashboard/dist-server/src/coordinator/prompt-assembler.js +3 -2
  117. package/dashboard/dist-server/src/coordinator/prompt-assembler.js.map +1 -1
  118. package/dashboard/dist-server/src/hooks/constants.d.ts +29 -60
  119. package/dashboard/dist-server/src/hooks/constants.js +105 -82
  120. package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
  121. package/dashboard/dist-server/src/types/index.d.ts +2 -1
  122. package/dist/src/commands/delegate.d.ts.map +1 -1
  123. package/dist/src/commands/delegate.js +26 -0
  124. package/dist/src/commands/delegate.js.map +1 -1
  125. package/dist/src/commands/hooks.d.ts +2 -4
  126. package/dist/src/commands/hooks.d.ts.map +1 -1
  127. package/dist/src/commands/hooks.js +4 -7
  128. package/dist/src/commands/hooks.js.map +1 -1
  129. package/dist/src/commands/install-ui/InstallConfirm.d.ts +2 -3
  130. package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
  131. package/dist/src/commands/install-ui/InstallConfirm.js +1 -1
  132. package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
  133. package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
  134. package/dist/src/commands/install-ui/InstallExecution.js +1 -2
  135. package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
  136. package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
  137. package/dist/src/commands/install-ui/InstallFlow.js +5 -7
  138. package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
  139. package/dist/src/commands/install-ui/StatuslineConfig.d.ts +3 -6
  140. package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
  141. package/dist/src/commands/install-ui/StatuslineConfig.js +21 -17
  142. package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
  143. package/dist/src/commands/update.d.ts.map +1 -1
  144. package/dist/src/commands/update.js +95 -0
  145. package/dist/src/commands/update.js.map +1 -1
  146. package/dist/src/commands/wiki.d.ts.map +1 -1
  147. package/dist/src/commands/wiki.js +75 -11
  148. package/dist/src/commands/wiki.js.map +1 -1
  149. package/dist/src/coordinator/graph-types.d.ts +11 -1
  150. package/dist/src/coordinator/graph-types.d.ts.map +1 -1
  151. package/dist/src/coordinator/graph-walker.d.ts.map +1 -1
  152. package/dist/src/coordinator/graph-walker.js +29 -2
  153. package/dist/src/coordinator/graph-walker.js.map +1 -1
  154. package/dist/src/coordinator/prompt-assembler.d.ts.map +1 -1
  155. package/dist/src/coordinator/prompt-assembler.js +3 -2
  156. package/dist/src/coordinator/prompt-assembler.js.map +1 -1
  157. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +4 -1
  158. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -1
  159. package/dist/src/hooks/__tests__/statusline-visual-test.js +55 -174
  160. package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -1
  161. package/dist/src/hooks/constants.d.ts +29 -60
  162. package/dist/src/hooks/constants.d.ts.map +1 -1
  163. package/dist/src/hooks/constants.js +105 -82
  164. package/dist/src/hooks/constants.js.map +1 -1
  165. package/dist/src/hooks/skill-context.d.ts.map +1 -1
  166. package/dist/src/hooks/skill-context.js +54 -6
  167. package/dist/src/hooks/skill-context.js.map +1 -1
  168. package/dist/src/hooks/statusline.d.ts +11 -8
  169. package/dist/src/hooks/statusline.d.ts.map +1 -1
  170. package/dist/src/hooks/statusline.js +284 -182
  171. package/dist/src/hooks/statusline.js.map +1 -1
  172. package/dist/src/hooks/workspace.d.ts.map +1 -1
  173. package/dist/src/hooks/workspace.js +2 -1
  174. package/dist/src/hooks/workspace.js.map +1 -1
  175. package/dist/src/migrations/_template.d.ts +12 -0
  176. package/dist/src/migrations/_template.d.ts.map +1 -0
  177. package/dist/src/migrations/_template.js +55 -0
  178. package/dist/src/migrations/_template.js.map +1 -0
  179. package/dist/src/migrations/index.d.ts +14 -0
  180. package/dist/src/migrations/index.d.ts.map +1 -0
  181. package/dist/src/migrations/index.js +20 -0
  182. package/dist/src/migrations/index.js.map +1 -0
  183. package/dist/src/migrations/run.d.ts +12 -0
  184. package/dist/src/migrations/run.d.ts.map +1 -0
  185. package/dist/src/migrations/run.js +119 -0
  186. package/dist/src/migrations/run.js.map +1 -0
  187. package/dist/src/migrations/v1-to-v2.d.ts +10 -0
  188. package/dist/src/migrations/v1-to-v2.d.ts.map +1 -0
  189. package/dist/src/migrations/v1-to-v2.js +71 -0
  190. package/dist/src/migrations/v1-to-v2.js.map +1 -0
  191. package/dist/src/tools/team-activity.d.ts.map +1 -1
  192. package/dist/src/tools/team-activity.js +22 -0
  193. package/dist/src/tools/team-activity.js.map +1 -1
  194. package/dist/src/tools/transition-recorder.d.ts +2 -17
  195. package/dist/src/tools/transition-recorder.d.ts.map +1 -1
  196. package/dist/src/tools/transition-recorder.js +6 -3
  197. package/dist/src/tools/transition-recorder.js.map +1 -1
  198. package/dist/src/types/index.d.ts +2 -1
  199. package/dist/src/types/index.d.ts.map +1 -1
  200. package/dist/src/utils/migration-registry.d.ts +65 -0
  201. package/dist/src/utils/migration-registry.d.ts.map +1 -0
  202. package/dist/src/utils/migration-registry.js +117 -0
  203. package/dist/src/utils/migration-registry.js.map +1 -0
  204. package/dist/src/utils/state-schema.d.ts +153 -0
  205. package/dist/src/utils/state-schema.d.ts.map +1 -0
  206. package/dist/src/utils/state-schema.js +329 -0
  207. package/dist/src/utils/state-schema.js.map +1 -0
  208. package/package.json +1 -1
  209. package/templates/state.json +17 -39
  210. package/workflows/brainstorm.md +3 -3
  211. package/workflows/codebase-rebuild.md +2 -12
  212. package/workflows/debug.md +7 -8
  213. package/workflows/execute.md +18 -4
  214. package/workflows/fork.md +37 -86
  215. package/workflows/init.md +1 -4
  216. package/workflows/integration-test.md +4 -5
  217. package/workflows/issue.md +3 -9
  218. package/workflows/learn.md +20 -19
  219. package/workflows/maestro.codex.md +8 -1
  220. package/workflows/maestro.md +12 -3
  221. package/workflows/memory.md +26 -71
  222. package/workflows/merge.md +45 -107
  223. package/workflows/milestone-complete.md +24 -7
  224. package/workflows/retrospective.md +77 -109
  225. package/workflows/review.md +5 -12
  226. package/workflows/specs-remove.md +115 -0
  227. package/workflows/specs-setup.md +10 -32
  228. package/workflows/status.md +291 -290
  229. package/workflows/sync.md +5 -5
  230. package/workflows/test.md +4 -5
  231. package/workflows/ui-style.md +3 -4
  232. package/workflows/verify.md +2 -2
  233. package/workflows/wiki-connect.md +188 -0
  234. package/workflows/wiki-digest.md +221 -0
  235. package/workflows/wiki-manage.md +204 -0
@@ -106,28 +106,15 @@ incompletePhases = []
106
106
  // Read worktree state for artifact registry check
107
107
  Read {target.path}/.workflow/state.json → wtState (if exists)
108
108
  wtArtifacts = wtState?.artifacts ?? []
109
- useArtifactRegistry = wtArtifacts.length > 0
110
-
111
- IF useArtifactRegistry:
112
- // Check phase completeness via artifact registry
113
- for (phaseNum of target.owned_phases):
114
- execArtifacts = wtArtifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
115
- IF execArtifacts.some(a => a.status === 'completed'):
116
- completedPhases.push({ phase: phaseNum })
117
- ELSE:
118
- status = execArtifacts.length > 0 ? execArtifacts[0].status : 'no_execute_artifact'
119
- incompletePhases.push({ phase: phaseNum, status })
120
- ELSE:
121
- // Legacy: check phases/ directory
122
- for (phaseNum of target.owned_phases):
123
- NN = String(phaseNum).padStart(2, '0')
124
- Glob: {target.path}/.workflow/phases/{NN}-*/index.json
125
- Read → wtIndex
126
109
 
127
- IF wtIndex.status === "completed":
128
- completedPhases.push({ phase: phaseNum, index: wtIndex })
129
- ELSE:
130
- incompletePhases.push({ phase: phaseNum, status: wtIndex.status })
110
+ // Check phase completeness via artifact registry
111
+ for (phaseNum of target.owned_phases):
112
+ execArtifacts = wtArtifacts.filter(a => a.type === 'execute' && a.phase === phaseNum)
113
+ IF execArtifacts.some(a => a.status === 'completed'):
114
+ completedPhases.push({ phase: phaseNum })
115
+ ELSE:
116
+ status = execArtifacts.length > 0 ? execArtifacts[0].status : 'no_execute_artifact'
117
+ incompletePhases.push({ phase: phaseNum, status })
131
118
 
132
119
  IF incompletePhases.length > 0 AND NOT force:
133
120
  WARN W002: "M{target.milestone_num} ({target.milestone}) has incomplete phases:"
@@ -199,88 +186,42 @@ Display "Syncing workflow artifacts for M{target.milestone_num} ({target.milesto
199
186
 
200
187
  Read .workflow/state.json → mainState
201
188
 
202
- IF useArtifactRegistry:
203
- // 7a: Copy scratch dirs from worktree to main
204
- Read {target.path}/.workflow/state.json wtState
205
- wtArtifacts = wtState?.artifacts ?? []
206
- milestoneArtifacts = wtArtifacts.filter(a =>
207
- a.path && (a.milestone === target.milestone || target.owned_phases.includes(a.phase))
208
- )
209
- for (art of milestoneArtifacts):
210
- srcDir = target.path + "/.workflow/" + art.path
211
- dstDir = ".workflow/" + art.path
212
- IF directory_exists(srcDir):
213
- Bash("mkdir -p {dstDir} && cp -r {srcDir}/* {dstDir}/")
214
-
215
- // 7b: Merge artifact registries
216
- mainArtifacts = mainState.artifacts ?? []
217
- existingIds = new Set(mainArtifacts.map(a => a.id))
218
- for (art of wtArtifacts):
219
- IF existingIds.has(art.id):
220
- // Update existing artifact status
221
- idx = mainArtifacts.findIndex(a => a.id === art.id)
222
- mainArtifacts[idx] = art
223
- ELSE:
224
- mainArtifacts.push(art)
225
- mainState.artifacts = mainArtifacts
226
-
227
- // Record merge in transition history
228
- mainState.transition_history = mainState.transition_history ?? []
229
- mainState.transition_history.push({
230
- milestone_num: target.milestone_num,
231
- milestone: target.milestone,
232
- action: "worktree_merge",
233
- completed_at: getUtc8ISOString(),
234
- branch: target.branch,
235
- phases: target.owned_phases
236
- })
237
-
238
- ELSE:
239
- // Legacy: copy phase directories from worktree to main
240
- // 7a: Copy all owned phase directories
241
- for (phaseNum of target.owned_phases):
242
- NN = String(phaseNum).padStart(2, '0')
243
- Glob: {target.path}/.workflow/phases/{NN}-*/
244
- phaseDir = matched directory name
245
-
246
- srcDir = target.path + "/.workflow/phases/" + phaseDir + "/"
247
- dstDir = ".workflow/phases/" + phaseDir + "/"
248
-
249
- Bash("cp -r {srcDir}* {dstDir}")
250
-
251
- // 7b: Update phase summaries
252
- for (phaseNum of target.owned_phases):
253
- NN = String(phaseNum).padStart(2, '0')
254
- Glob: .workflow/phases/{NN}-*/index.json
255
- Read → phaseIndex
256
-
257
- IF phaseIndex.status === "completed":
258
- mainState.phases_summary.completed += 1
259
- mainState.phases_summary.pending -= 1
260
- IF mainState.phases_summary.pending < 0:
261
- mainState.phases_summary.pending = 0
262
-
263
- mainState.transition_history = mainState.transition_history ?? []
264
- mainState.transition_history.push({
265
- milestone_num: target.milestone_num,
266
- milestone: target.milestone,
267
- phase: phaseNum,
268
- action: "worktree_merge",
269
- completed_at: phaseIndex.completed_at ?? getUtc8ISOString(),
270
- branch: target.branch
271
- })
272
- ELSE IF phaseIndex.status !== "forked":
273
- mainState.phases_summary.in_progress += 1
274
- mainState.phases_summary.pending -= 1
275
- IF mainState.phases_summary.pending < 0:
276
- mainState.phases_summary.pending = 0
277
-
278
- phaseIndex.updated_at = getUtc8ISOString()
279
- Write .workflow/phases/{NN}-{slug}/index.json: phaseIndex
280
-
281
- // Merge accumulated context from worktree (both paths)
282
- IF NOT useArtifactRegistry:
283
- Read target.path + "/.workflow/state.json" → wtState (if exists)
189
+ // 7a: Copy scratch dirs from worktree to main
190
+ Read {target.path}/.workflow/state.json wtState
191
+ wtArtifacts = wtState?.artifacts ?? []
192
+ milestoneArtifacts = wtArtifacts.filter(a =>
193
+ a.path && (a.milestone === target.milestone || target.owned_phases.includes(a.phase))
194
+ )
195
+ for (art of milestoneArtifacts):
196
+ srcDir = target.path + "/.workflow/" + art.path
197
+ dstDir = ".workflow/" + art.path
198
+ IF directory_exists(srcDir):
199
+ Bash("mkdir -p {dstDir} && cp -r {srcDir}/* {dstDir}/")
200
+
201
+ // 7b: Merge artifact registries
202
+ mainArtifacts = mainState.artifacts ?? []
203
+ existingIds = new Set(mainArtifacts.map(a => a.id))
204
+ for (art of wtArtifacts):
205
+ IF existingIds.has(art.id):
206
+ // Update existing artifact status
207
+ idx = mainArtifacts.findIndex(a => a.id === art.id)
208
+ mainArtifacts[idx] = art
209
+ ELSE:
210
+ mainArtifacts.push(art)
211
+ mainState.artifacts = mainArtifacts
212
+
213
+ // Record merge in transition history
214
+ mainState.transition_history = mainState.transition_history ?? []
215
+ mainState.transition_history.push({
216
+ milestone_num: target.milestone_num,
217
+ milestone: target.milestone,
218
+ action: "worktree_merge",
219
+ completed_at: getUtc8ISOString(),
220
+ branch: target.branch,
221
+ phases: target.owned_phases
222
+ })
223
+
224
+ // Merge accumulated context from worktree
284
225
  IF wtState?.accumulated_context:
285
226
  for (decision of (wtState.accumulated_context.key_decisions ?? [])):
286
227
  IF NOT mainState.accumulated_context.key_decisions.includes(decision):
@@ -294,10 +235,7 @@ Write .workflow/state.json: mainState
294
235
  // 7c: Update roadmap.md (mark completed phases)
295
236
  Read .workflow/roadmap.md → roadmap
296
237
  for (phaseNum of target.owned_phases):
297
- IF useArtifactRegistry:
298
- isCompleted = completedPhases.some(p => p.phase === phaseNum)
299
- ELSE:
300
- Read phase index → isCompleted = (status === "completed")
238
+ isCompleted = completedPhases.some(p => p.phase === phaseNum)
301
239
  IF isCompleted:
302
240
  Append " ✅ COMPLETED" to phase title line in roadmap
303
241
  Write .workflow/roadmap.md: roadmap
@@ -66,24 +66,41 @@ Check existing entries to avoid duplicates when appending in Step 3.
66
66
  - Extract patterns discovered
67
67
  - Extract pitfalls encountered
68
68
 
69
- 2. Aggregate learnings and append to `.workflow/specs/learnings.md`:
69
+ 2. Aggregate learnings and append to `.workflow/specs/learnings.md` using `<spec-entry>` closed-tag format:
70
70
  ```
71
71
  For each strategy adjustment:
72
- ### [YYYY-MM-DD HH:mm] decision: {summary}
72
+ <spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
73
+
74
+ ### {summary}
75
+
73
76
  {content}
74
- Milestone: {milestone} | Source: milestone-complete
77
+ Milestone: {milestone}
78
+
79
+ </spec-entry>
75
80
 
76
81
  For each pattern:
77
- ### [YYYY-MM-DD HH:mm] pattern: {summary}
82
+ <spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
83
+
84
+ ### {summary}
85
+
78
86
  {content}
79
- Milestone: {milestone} | Source: milestone-complete
87
+ Milestone: {milestone}
88
+
89
+ </spec-entry>
80
90
 
81
91
  For each pitfall:
82
- ### [YYYY-MM-DD HH:mm] bug: {summary}
92
+ <spec-entry category="learning" keywords="{auto-extracted}" date="{YYYY-MM-DD}" source="milestone-complete">
93
+
94
+ ### {summary}
95
+
83
96
  {content}
84
- Milestone: {milestone} | Source: milestone-complete
97
+ Milestone: {milestone}
98
+
99
+ </spec-entry>
85
100
  ```
86
101
 
102
+ **Keyword extraction**: Extract 3-5 domain-specific terms from the content (same rules as `spec-add`).
103
+
87
104
  ---
88
105
 
89
106
  ## Step 4: Update State
@@ -9,7 +9,7 @@ This is a **post-execution analysis** workflow. It reads only — until the rout
9
9
  ## Prerequisites
10
10
 
11
11
  - `.workflow/` initialized (`.workflow/state.json` exists)
12
- - At least one completed phase (via artifact registry in state.json, or legacy `.workflow/phases/{NN}-{slug}/`)
12
+ - At least one completed phase (via artifact registry in state.json)
13
13
  - Target phase has been executed (has `.task/` and `.summaries/`)
14
14
  - `maestro delegate` available (used for the four lens analyses via Agent calls)
15
15
 
@@ -64,43 +64,24 @@ candidates = []
64
64
 
65
65
  Read .workflow/state.json → state
66
66
  artifacts = state.artifacts ?? []
67
- useArtifactRegistry = artifacts.length > 0
68
-
69
- IF useArtifactRegistry:
70
- // Resolve completed phases from artifact registry
71
- phaseNums = [...new Set(artifacts.map(a => a.phase).filter(Boolean))]
72
- FOR each phaseNum in phaseNums:
73
- execArt = artifacts.find(a => a.type === 'execute' && a.phase === phaseNum && a.status === 'completed')
74
- IF execArt:
75
- scratchDir = ".workflow/" + execArt.path
76
- has_retro = file exists at "{scratchDir}/retrospective.json"
77
- candidates.push({
78
- number: phaseNum,
79
- slug: execArt.slug ?? "phase-" + phaseNum,
80
- title: execArt.title ?? execArt.slug ?? "Phase " + phaseNum,
81
- completed_at: execArt.completed_at,
82
- has_retro: has_retro,
83
- phase_dir: scratchDir,
84
- gaps: 0,
85
- review_verdict: "—"
86
- })
87
- ELSE:
88
- // Legacy: scan phases/ directory
89
- FOR each .workflow/phases/{NN}-{slug}/index.json:
90
- Read index.json
91
- IF index.json.status == "completed":
92
- phase_dir = ".workflow/phases/{NN}-{slug}"
93
- has_retro = file exists at "{phase_dir}/retrospective.json"
94
- candidates.push({
95
- number: NN,
96
- slug: slug,
97
- title: index.json.title or slug,
98
- completed_at: index.json.completed_at,
99
- has_retro: has_retro,
100
- phase_dir: phase_dir,
101
- gaps: index.json.verification?.gaps?.length or 0,
102
- review_verdict: index.json.review?.verdict or "—"
103
- })
67
+
68
+ // Resolve completed phases from artifact registry
69
+ phaseNums = [...new Set(artifacts.map(a => a.phase).filter(Boolean))]
70
+ FOR each phaseNum in phaseNums:
71
+ execArt = artifacts.find(a => a.type === 'execute' && a.phase === phaseNum && a.status === 'completed')
72
+ IF execArt:
73
+ artifact_dir = ".workflow/" + execArt.path
74
+ has_retro = file exists at "{artifact_dir}/retrospective.json"
75
+ candidates.push({
76
+ number: phaseNum,
77
+ slug: execArt.slug ?? "phase-" + phaseNum,
78
+ title: execArt.title ?? execArt.slug ?? "Phase " + phaseNum,
79
+ completed_at: execArt.completed_at,
80
+ has_retro: has_retro,
81
+ phase_dir: artifact_dir,
82
+ gaps: 0,
83
+ review_verdict: "—"
84
+ })
104
85
  ```
105
86
 
106
87
  ### Display backlog
@@ -130,7 +111,7 @@ ELSE:
130
111
 
131
112
  If overwriting existing retrospective.json:
132
113
  ```
133
- mkdir -p "{candidate.phase_dir}/.history"
114
+ mkdir -p "{candidate.phase_dir}/.history" // phase_dir is artifact_dir from registry
134
115
  TIMESTAMP = format(now(), "YYYY-MM-DDTHH-mm-ss")
135
116
  mv "{candidate.phase_dir}/retrospective.json" "{candidate.phase_dir}/.history/retrospective-{TIMESTAMP}.json"
136
117
  mv "{candidate.phase_dir}/retrospective.md" "{candidate.phase_dir}/.history/retrospective-{TIMESTAMP}.md"
@@ -143,20 +124,20 @@ mv "{candidate.phase_dir}/retrospective.md" "{candidate.phase_dir}/.history/re
143
124
  For each selected phase (using `candidate.phase_dir` resolved in Stage 2), build the in-memory artifacts bundle:
144
125
 
145
126
  ```
146
- phase_dir = candidate.phase_dir // already resolved: scratch path (artifact registry) or legacy phases/ path
127
+ phase_dir = candidate.phase_dir // already resolved from artifact registry (e.g. .workflow/scratch/plan-auth-2026-04-20)
147
128
 
148
129
  artifacts = {
149
130
  phase_num: NN,
150
131
  phase_slug: slug,
151
- phase_dir: phase_dir,
152
- index: read "{phase_dir}/index.json" or null,
132
+ artifact_dir: artifact_dir,
133
+ index: read "{artifact_dir}/index.json" or null,
153
134
  state: read .workflow/state.json,
154
- plan: read "{phase_dir}/plan.json" or null,
155
- verification: read "{phase_dir}/verification.json" or null,
156
- review: read "{phase_dir}/review.json" or null,
157
- uat: read "{phase_dir}/uat.md" or null,
158
- task_summaries: read all "{phase_dir}/.summaries/TASK-*-summary.md",
159
- task_jsons: read all "{phase_dir}/.task/TASK-*.json",
135
+ plan: read "{artifact_dir}/plan.json" or null,
136
+ verification: read "{artifact_dir}/verification.json" or null,
137
+ review: read "{artifact_dir}/review.json" or null,
138
+ uat: read "{artifact_dir}/uat.md" or null,
139
+ task_summaries: read all "{artifact_dir}/.summaries/TASK-*-summary.md",
140
+ task_jsons: read all "{artifact_dir}/.task/TASK-*.json",
160
141
  phase_issues: filter ".workflow/issues/issues.jsonl" + ".workflow/issues/issue-history.jsonl"
161
142
  where issue.phase_ref == phase_slug or issue.phase_ref == NN,
162
143
  prior_retro: null
@@ -164,12 +145,9 @@ artifacts = {
164
145
 
165
146
  // Resolve --compare target
166
147
  IF --compare M:
167
- IF useArtifactRegistry:
168
- compareArt = state.artifacts.find(a => a.type === 'execute' && a.phase === M)
169
- IF compareArt:
170
- artifacts.prior_retro = read ".workflow/" + compareArt.path + "/retrospective.json"
171
- ELSE:
172
- artifacts.prior_retro = read .workflow/phases/{MM}-*/retrospective.json
148
+ compareArt = state.artifacts.find(a => a.type === 'execute' && a.phase === M)
149
+ IF compareArt:
150
+ artifacts.prior_retro = read ".workflow/" + compareArt.path + "/retrospective.json"
173
151
  }
174
152
  ```
175
153
 
@@ -245,12 +223,12 @@ the project's spec / note / issue stores.
245
223
  - Completed at: {index.completed_at}
246
224
 
247
225
  ## Artifacts (read these from disk)
248
- - Plan: {phase_dir}/plan.json
249
- - Verification: {phase_dir}/verification.json
250
- - Review: {phase_dir}/review.json
251
- - UAT notes: {phase_dir}/uat.md
252
- - Task summaries: {phase_dir}/.summaries/
253
- - Task JSONs: {phase_dir}/.task/
226
+ - Plan: {artifact_dir}/plan.json
227
+ - Verification: {artifact_dir}/verification.json
228
+ - Review: {artifact_dir}/review.json
229
+ - UAT notes: {artifact_dir}/uat.md
230
+ - Task summaries: {artifact_dir}/.summaries/
231
+ - Task JSONs: {artifact_dir}/.task/
254
232
  - Phase issues: .workflow/issues/issues.jsonl (filter phase_ref == "{phase_slug}")
255
233
  - Project state: .workflow/state.json (decisions, deferred)
256
234
 
@@ -287,7 +265,7 @@ Return ONLY a single JSON object, no prose, matching this schema:
287
265
  "title": "Short imperative title",
288
266
  "summary": "1–3 sentences a future planner can act on",
289
267
  "confidence": "high|medium|low",
290
- "evidence_refs": ["{phase_dir}/verification.json#gaps[2]", "..."],
268
+ "evidence_refs": ["{artifact_dir}/verification.json#gaps[2]", "..."],
291
269
  "routed_to": "spec|note|issue|none",
292
270
  "tags": ["..."]
293
271
  }
@@ -463,8 +441,8 @@ retrospective = {
463
441
 
464
442
  Write both files (phase_dir already resolved in Stage 2):
465
443
  ```
466
- Write "{phase_dir}/retrospective.json"
467
- Write "{phase_dir}/retrospective.md"
444
+ Write "{artifact_dir}/retrospective.json"
445
+ Write "{artifact_dir}/retrospective.md"
468
446
  ```
469
447
 
470
448
  ---
@@ -493,46 +471,31 @@ Accept all? [Y/n/i for individual]
493
471
 
494
472
  #### Target: spec
495
473
 
496
- Write a stub spec file directly. Do NOT invoke `spec-generate` (heavyweight 7-phase pipeline).
474
+ Route spec-routed insights as `<spec-entry>` entries into the appropriate category file. Map insight type to category:
475
+ - `pattern` / `convention` → `coding`
476
+ - `adr-candidate` / architecture → `arch`
477
+ - quality-related → `quality`
497
478
 
498
479
  ```
499
- mkdir -p ".workflow/specs"
500
- slug = slugify(insight.title)
501
- spec_file = ".workflow/specs/SPEC-retro-{phase_num}-{INS_id}-{slug}.md"
502
-
503
- Write spec_file:
504
- ---
505
- status: draft
506
- type: pattern | convention | adr-candidate
507
- source: retrospective
508
- source_phase: {NN}
509
- source_insight: {INS_id}
510
- created_at: {now ISO}
511
- tags: {insight.tags}
512
- confidence: {insight.confidence}
513
- ---
514
-
515
- # {insight.title}
480
+ category = map_insight_to_category(insight.type)
481
+ target_file = category_to_file(category) # e.g., coding → coding-conventions.md
516
482
 
517
- ## Context
483
+ keywords = extract_keywords(insight.title + insight.summary) # 3-5 domain-specific terms
518
484
 
519
- Extracted from phase {NN} ({phase_slug}) retrospective by the {lens} lens.
520
- This stub captures a reusable {category} surfaced during execution; expand it
521
- into a full spec via `/maestro-spec-generate` if it warrants project-wide adoption.
485
+ Append to .workflow/specs/{target_file}:
486
+ <spec-entry category="{category}" keywords="{keywords}" date="{YYYY-MM-DD}" source="retrospective">
522
487
 
523
- ## Pattern / Convention
488
+ ### {insight.title}
524
489
 
525
- {insight.summary}
490
+ {insight.summary}
526
491
 
527
- ## Evidence
492
+ **Evidence:** {FOR ref in evidence_refs:} `{ref}` {END FOR}
493
+ **Phase:** {NN} ({phase_slug}) | **Lens:** {lens} | **Insight:** {INS_id} | **Confidence:** {insight.confidence}
528
494
 
529
- {FOR ref in evidence_refs:} - `{ref}`{END FOR}
530
-
531
- ## Open Questions
495
+ </spec-entry>
496
+ ```
532
497
 
533
- - Is this pattern already documented elsewhere?
534
- - Should existing code be migrated to this pattern, or is it forward-only?
535
- - What is the failure mode if this pattern is violated?
498
+ If the target file does not exist, create it with category frontmatter first (same as `spec-add` on-demand creation).
536
499
 
537
500
  ## Routing trail
538
501
 
@@ -541,7 +504,7 @@ into a full spec via `/maestro-spec-generate` if it warrants project-wide adopti
541
504
  - Insight: {INS_id}
542
505
  - Confidence: {confidence}
543
506
 
544
- insight.routed_id = "SPEC-retro-{phase_num}-{INS_id}-{slug}.md"
507
+ insight.routed_id = "{category_file}#INS-{INS_id}" # e.g., coding-conventions.md#INS-a1b2c3d4
545
508
  ```
546
509
 
547
510
  #### Target: note
@@ -561,7 +524,7 @@ Capture the returned TIP-{id} from the skill output.
561
524
  insight.routed_id = "TIP-{captured_id}"
562
525
  ```
563
526
 
564
- If the skill call cannot be intercepted to capture the ID, fall back to writing the tip file directly using the schema in `workflows/memory.md` Part B Step 3 (Tip mode), and update `memory-index.json` per Step 4.
527
+ If the skill call cannot be intercepted to capture the ID, fall back to writing the tip file directly using the schema in `workflows/memory.md` Part B Step 3 (Tip mode), and update `wiki-index.json` per Step 4.
565
528
 
566
529
  #### Target: issue
567
530
 
@@ -706,19 +669,24 @@ Write .workflow/learning/learning-index.json
706
669
 
707
670
  ### Backward-compat append to specs/learnings.md
708
671
 
709
- Append learnings to `.workflow/specs/learnings.md` (shared with milestone-complete's learning extraction). Append a one-line summary per insight:
672
+ Append learnings to `.workflow/specs/learnings.md` (shared with milestone-complete's learning extraction) using `<spec-entry>` closed-tag format:
710
673
 
711
674
  ```
712
675
  IF .workflow/specs/learnings.md exists:
713
676
  FOR each insight:
714
- Append under "## Entries":
715
- ### [{YYYY-MM-DD HH:mm}] {category}: {title}
677
+ keywords = extract_keywords(insight.title + insight.summary) # 3-5 domain-specific terms
678
+ Append:
679
+ <spec-entry category="learning" keywords="{keywords}" date="{YYYY-MM-DD}" source="retrospective">
680
+
681
+ ### {title}
716
682
 
717
683
  {summary}
718
- Phase: {NN} | Source: retrospective | Insight: {INS_id} | Lens: {lens}
684
+ Phase: {NN} | Lens: {lens} | Insight: {INS_id}
685
+
686
+ </spec-entry>
719
687
  ```
720
688
 
721
- If the file does not exist, create it with a `## Entries` header.
689
+ If the file does not exist, create it with category frontmatter and a `## Entries` header.
722
690
 
723
691
  ---
724
692
 
@@ -733,14 +701,14 @@ Lenses run: {lenses joined by ", "}
733
701
  Insights: {count}
734
702
 
735
703
  Routing summary:
736
- Specs drafted: {N} → .workflow/specs/SPEC-retro-*
704
+ Spec entries: {N} → .workflow/specs/{category-file}.md
737
705
  Notes saved: {N} → .workflow/memory/TIP-*
738
706
  Issues opened: {N} → .workflow/issues/issues.jsonl
739
707
  Lessons logged: {N} → .workflow/learning/lessons.jsonl
740
708
 
741
709
  Files:
742
- {phase_dir}/retrospective.md
743
- {phase_dir}/retrospective.json
710
+ {artifact_dir}/retrospective.md
711
+ {artifact_dir}/retrospective.json
744
712
 
745
713
  Next steps (suggested):
746
714
  Skill({ skill: "manage-status" }) — Review project state
@@ -809,12 +777,12 @@ Total issues: {sum}
809
777
  "summary": "Refresh-on-use prevents replay attacks. Implemented in src/auth/refresh.ts; should become a project-wide convention.",
810
778
  "confidence": "high",
811
779
  "evidence_refs": [
812
- ".workflow/phases/01-auth/verification.json#gaps[2]",
813
- ".workflow/phases/01-auth/.summaries/TASK-005-summary.md:42"
780
+ ".workflow/scratch/plan-auth-2026-04-15/verification.json#gaps[2]",
781
+ ".workflow/scratch/plan-auth-2026-04-15/.summaries/TASK-005-summary.md:42"
814
782
  ],
815
783
  "tags": ["auth", "jwt", "security"],
816
784
  "routed_to": "spec",
817
- "routed_id": "SPEC-retro-1-INS-a1b2c3d4-jwt-refresh-rotation.md"
785
+ "routed_id": "coding-conventions.md#INS-a1b2c3d4"
818
786
  }
819
787
  ],
820
788
  "routing_recommendations": [
@@ -829,7 +797,7 @@ Total issues: {sum}
829
797
  One JSON object per line:
830
798
 
831
799
  ```json
832
- {"id":"INS-a1b2c3d4","phase":1,"phase_slug":"01-auth","lens":"technical","category":"pattern","title":"JWT refresh tokens must rotate on every use","summary":"...","confidence":"high","tags":["auth","jwt","security"],"evidence_refs":["..."],"routed_to":"spec","routed_id":"SPEC-retro-1-INS-a1b2c3d4-jwt-refresh-rotation.md","source":"retrospective","captured_at":"2026-04-11T10:00:00Z"}
800
+ {"id":"INS-a1b2c3d4","phase":1,"phase_slug":"01-auth","lens":"technical","category":"pattern","title":"JWT refresh tokens must rotate on every use","summary":"...","confidence":"high","tags":["auth","jwt","security"],"evidence_refs":["..."],"routed_to":"spec","routed_id":"coding-conventions.md#INS-a1b2c3d4","source":"retrospective","captured_at":"2026-04-11T10:00:00Z"}
833
801
  ```
834
802
 
835
803
  ### learning-index.json
@@ -850,7 +818,7 @@ One JSON object per line:
850
818
  "phase_slug": "01-auth",
851
819
  "confidence": "high",
852
820
  "routed_to": "spec",
853
- "routed_id": "SPEC-retro-1-INS-a1b2c3d4-jwt-refresh-rotation.md"
821
+ "routed_id": "coding-conventions.md#INS-a1b2c3d4"
854
822
  }
855
823
  ],
856
824
  "_metadata": {
@@ -18,18 +18,11 @@ Input: <phase> argument (number or slug)
18
18
 
19
19
  Read .workflow/state.json → state
20
20
  artifacts = state.artifacts ?? []
21
- useArtifactRegistry = artifacts.length > 0
22
21
 
23
- IF useArtifactRegistry:
24
- IF number: art = artifacts.find(a => a.type === 'execute' && a.phase === number)
25
- IF slug: art = artifacts.find(a => a.type === 'execute' && a.slug?.includes(slug))
26
- IF art: PHASE_DIR = ".workflow/" + art.path
27
- ELSE: ERROR "Phase not found in artifact registry"
28
- ELSE:
29
- // Legacy: resolve from phases/ directory
30
- IF number: find .workflow/phases/{NN}-*/index.json
31
- IF slug: find .workflow/phases/*-{slug}/index.json
32
- PHASE_DIR = resolved path
22
+ IF number: art = artifacts.find(a => a.type === 'execute' && a.phase === number)
23
+ IF slug: art = artifacts.find(a => a.type === 'execute' && a.slug?.includes(slug))
24
+ IF art: PHASE_DIR = ".workflow/" + art.path
25
+ ELSE: ERROR "Phase not found in artifact registry"
33
26
 
34
27
  Validate execution has occurred (tasks_completed > 0 or .task/ exists)
35
28
  ```
@@ -587,7 +580,7 @@ Verdict: {PASS | WARN | BLOCK}
587
580
  Issues Created: {count}
588
581
 
589
582
  Files:
590
- {phase_dir}/review.json
583
+ {artifact_dir}/review.json
591
584
 
592
585
  Next steps:
593
586
  {suggested_next_command}