maestro-flow 0.3.9 → 0.3.11

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 (281) hide show
  1. package/.claude/agents/workflow-collab-planner.md +1 -1
  2. package/.claude/agents/workflow-executor.md +1 -1
  3. package/.claude/agents/workflow-plan-checker.md +1 -1
  4. package/.claude/agents/workflow-planner.md +1 -1
  5. package/.claude/commands/learn-decompose.md +176 -176
  6. package/.claude/commands/learn-follow.md +167 -167
  7. package/.claude/commands/learn-retro.md +1 -1
  8. package/.claude/commands/maestro-analyze.md +46 -3
  9. package/.claude/commands/maestro-coordinate.md +1 -3
  10. package/.claude/commands/maestro-execute.md +14 -0
  11. package/.claude/commands/maestro-plan.md +16 -0
  12. package/.claude/commands/manage-harvest.md +131 -131
  13. package/.claude/commands/manage-issue-discover.md +2 -2
  14. package/.claude/commands/manage-issue.md +5 -5
  15. package/.claude/commands/spec-add.md +67 -56
  16. package/.claude/commands/spec-load.md +66 -64
  17. package/.claude/commands/spec-setup.md +5 -9
  18. package/.codex/skills/learn-decompose/SKILL.md +119 -0
  19. package/.codex/skills/learn-follow/SKILL.md +83 -0
  20. package/.codex/skills/learn-investigate/SKILL.md +83 -0
  21. package/.codex/skills/learn-retro/SKILL.md +83 -0
  22. package/.codex/skills/learn-second-opinion/SKILL.md +86 -0
  23. package/.codex/skills/maestro/SKILL.md +335 -0
  24. package/.codex/skills/maestro-analyze/SKILL.md +84 -75
  25. package/.codex/skills/maestro-brainstorm/SKILL.md +452 -463
  26. package/.codex/skills/maestro-chain/SKILL.md +233 -0
  27. package/.codex/skills/maestro-coordinate/SKILL.md +167 -278
  28. package/.codex/skills/maestro-execute/SKILL.md +435 -438
  29. package/.codex/skills/maestro-fork/SKILL.md +68 -0
  30. package/.codex/skills/maestro-init/SKILL.md +171 -167
  31. package/.codex/skills/maestro-learn/SKILL.md +80 -0
  32. package/.codex/skills/maestro-link-coordinate/SKILL.md +224 -220
  33. package/.codex/skills/maestro-merge/SKILL.md +62 -0
  34. package/.codex/skills/maestro-milestone-audit/SKILL.md +108 -103
  35. package/.codex/skills/maestro-milestone-complete/SKILL.md +155 -149
  36. package/.codex/skills/maestro-milestone-release/SKILL.md +70 -0
  37. package/.codex/skills/maestro-overlay/SKILL.md +188 -185
  38. package/.codex/skills/maestro-plan/SKILL.md +66 -69
  39. package/.codex/skills/maestro-quick/SKILL.md +26 -23
  40. package/.codex/skills/maestro-roadmap/SKILL.md +65 -73
  41. package/.codex/skills/maestro-spec-generate/SKILL.md +66 -74
  42. package/.codex/skills/maestro-ui-design/SKILL.md +34 -31
  43. package/.codex/skills/maestro-verify/SKILL.md +556 -566
  44. package/.codex/skills/manage-codebase-rebuild/SKILL.md +397 -405
  45. package/.codex/skills/manage-codebase-refresh/SKILL.md +93 -82
  46. package/.codex/skills/manage-harvest/SKILL.md +82 -0
  47. package/.codex/skills/manage-issue/SKILL.md +80 -65
  48. package/.codex/skills/manage-issue-discover/SKILL.md +491 -503
  49. package/.codex/skills/manage-learn/SKILL.md +190 -186
  50. package/.codex/skills/manage-memory/SKILL.md +95 -72
  51. package/.codex/skills/manage-memory-capture/SKILL.md +99 -86
  52. package/.codex/skills/manage-status/SKILL.md +102 -89
  53. package/.codex/skills/quality-business-test/SKILL.md +228 -223
  54. package/.codex/skills/quality-debug/SKILL.md +54 -66
  55. package/.codex/skills/quality-integration-test/SKILL.md +532 -544
  56. package/.codex/skills/quality-refactor/SKILL.md +197 -191
  57. package/.codex/skills/quality-retrospective/SKILL.md +512 -505
  58. package/.codex/skills/quality-review/SKILL.md +93 -105
  59. package/.codex/skills/quality-sync/SKILL.md +101 -89
  60. package/.codex/skills/quality-test/SKILL.md +202 -198
  61. package/.codex/skills/quality-test-gen/SKILL.md +93 -104
  62. package/.codex/skills/spec-add/SKILL.md +58 -39
  63. package/.codex/skills/spec-load/SKILL.md +45 -40
  64. package/.codex/skills/spec-map/SKILL.md +180 -182
  65. package/.codex/skills/spec-setup/SKILL.md +94 -76
  66. package/.codex/skills/team-coordinate/SKILL.md +346 -357
  67. package/.codex/skills/team-executor/SKILL.md +70 -112
  68. package/.codex/skills/team-lifecycle-v4/SKILL.md +311 -299
  69. package/.codex/skills/team-quality-assurance/SKILL.md +234 -227
  70. package/.codex/skills/team-review/SKILL.md +232 -225
  71. package/.codex/skills/team-tech-debt/SKILL.md +78 -100
  72. package/.codex/skills/team-testing/SKILL.md +242 -235
  73. package/.codex/skills/wiki-connect/SKILL.md +75 -0
  74. package/.codex/skills/wiki-digest/SKILL.md +87 -0
  75. package/README.md +14 -11
  76. package/README.zh-CN.md +14 -11
  77. package/chains/issue-lifecycle.json +13 -13
  78. package/chains/singles/issue-analyze.json +3 -3
  79. package/chains/singles/issue-execute.json +3 -3
  80. package/chains/singles/issue-plan.json +3 -3
  81. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js +2 -2
  82. package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js.map +1 -1
  83. package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js +3 -3
  84. package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js.map +1 -1
  85. package/dashboard/dist-server/dashboard/src/server/routes/issues.js +34 -0
  86. package/dashboard/dist-server/dashboard/src/server/routes/issues.js.map +1 -1
  87. package/dashboard/dist-server/dashboard/src/server/routes/specs.d.ts +1 -1
  88. package/dashboard/dist-server/dashboard/src/server/routes/specs.js +75 -30
  89. package/dashboard/dist-server/dashboard/src/server/routes/specs.js.map +1 -1
  90. package/dashboard/dist-server/dashboard/src/server/state/event-bus.d.ts +5 -0
  91. package/dashboard/dist-server/dashboard/src/server/state/event-bus.js +5 -0
  92. package/dashboard/dist-server/dashboard/src/server/state/event-bus.js.map +1 -1
  93. package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js +2 -3
  94. package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js.map +1 -1
  95. package/dashboard/dist-server/dashboard/src/shared/constants.js +5 -0
  96. package/dashboard/dist-server/dashboard/src/shared/constants.js.map +1 -1
  97. package/dashboard/dist-server/dashboard/src/shared/issue-types.d.ts +5 -0
  98. package/dashboard/dist-server/dashboard/src/shared/issue-types.js.map +1 -1
  99. package/dashboard/dist-server/dashboard/src/shared/normalize-task.d.ts +2 -0
  100. package/dashboard/dist-server/dashboard/src/shared/normalize-task.js +75 -0
  101. package/dashboard/dist-server/dashboard/src/shared/normalize-task.js.map +1 -0
  102. package/dashboard/dist-server/dashboard/src/shared/team-types.d.ts +21 -0
  103. package/dashboard/dist-server/dashboard/src/shared/team-types.js.map +1 -1
  104. package/dashboard/dist-server/dashboard/src/shared/types.d.ts +3 -2
  105. package/dashboard/dist-server/dashboard/src/shared/ws-protocol.d.ts +1 -1
  106. package/dashboard/dist-server/dashboard/src/shared/ws-protocol.js.map +1 -1
  107. package/dashboard/dist-server/src/hooks/constants.d.ts +92 -12
  108. package/dashboard/dist-server/src/hooks/constants.js +151 -16
  109. package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
  110. package/dashboard/dist-server/src/types/index.d.ts +5 -0
  111. package/dist/src/commands/collab.d.ts +1 -34
  112. package/dist/src/commands/collab.d.ts.map +1 -1
  113. package/dist/src/commands/collab.js +8 -76
  114. package/dist/src/commands/collab.js.map +1 -1
  115. package/dist/src/commands/hooks.d.ts +5 -1
  116. package/dist/src/commands/hooks.d.ts.map +1 -1
  117. package/dist/src/commands/hooks.js +115 -10
  118. package/dist/src/commands/hooks.js.map +1 -1
  119. package/dist/src/commands/install-ui/InstallConfirm.d.ts +3 -1
  120. package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
  121. package/dist/src/commands/install-ui/InstallConfirm.js +3 -1
  122. package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
  123. package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
  124. package/dist/src/commands/install-ui/InstallExecution.js +5 -1
  125. package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
  126. package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
  127. package/dist/src/commands/install-ui/InstallFlow.js +7 -3
  128. package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
  129. package/dist/src/commands/install-ui/StatuslineConfig.d.ts +6 -1
  130. package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
  131. package/dist/src/commands/install-ui/StatuslineConfig.js +27 -5
  132. package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
  133. package/dist/src/commands/spec.d.ts.map +1 -1
  134. package/dist/src/commands/spec.js +7 -2
  135. package/dist/src/commands/spec.js.map +1 -1
  136. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +7 -0
  137. package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -0
  138. package/dist/src/hooks/__tests__/statusline-visual-test.js +236 -0
  139. package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -0
  140. package/dist/src/hooks/constants.d.ts +92 -12
  141. package/dist/src/hooks/constants.d.ts.map +1 -1
  142. package/dist/src/hooks/constants.js +151 -16
  143. package/dist/src/hooks/constants.js.map +1 -1
  144. package/dist/src/hooks/guards/index.d.ts +2 -0
  145. package/dist/src/hooks/guards/index.d.ts.map +1 -1
  146. package/dist/src/hooks/guards/index.js +2 -0
  147. package/dist/src/hooks/guards/index.js.map +1 -1
  148. package/dist/src/hooks/guards/preflight-guard.d.ts +29 -0
  149. package/dist/src/hooks/guards/preflight-guard.d.ts.map +1 -0
  150. package/dist/src/hooks/guards/preflight-guard.js +95 -0
  151. package/dist/src/hooks/guards/preflight-guard.js.map +1 -0
  152. package/dist/src/hooks/guards/spec-validator.d.ts +25 -0
  153. package/dist/src/hooks/guards/spec-validator.d.ts.map +1 -0
  154. package/dist/src/hooks/guards/spec-validator.js +66 -0
  155. package/dist/src/hooks/guards/spec-validator.js.map +1 -0
  156. package/dist/src/hooks/index.d.ts +1 -0
  157. package/dist/src/hooks/index.d.ts.map +1 -1
  158. package/dist/src/hooks/index.js +1 -0
  159. package/dist/src/hooks/index.js.map +1 -1
  160. package/dist/src/hooks/keyword-spec-injector.d.ts +21 -0
  161. package/dist/src/hooks/keyword-spec-injector.d.ts.map +1 -0
  162. package/dist/src/hooks/keyword-spec-injector.js +96 -0
  163. package/dist/src/hooks/keyword-spec-injector.js.map +1 -0
  164. package/dist/src/hooks/plugins/spec-injection-plugin.d.ts +2 -1
  165. package/dist/src/hooks/plugins/spec-injection-plugin.d.ts.map +1 -1
  166. package/dist/src/hooks/plugins/spec-injection-plugin.js +21 -12
  167. package/dist/src/hooks/plugins/spec-injection-plugin.js.map +1 -1
  168. package/dist/src/hooks/preflight-core.d.ts +37 -0
  169. package/dist/src/hooks/preflight-core.d.ts.map +1 -0
  170. package/dist/src/hooks/preflight-core.js +86 -0
  171. package/dist/src/hooks/preflight-core.js.map +1 -0
  172. package/dist/src/hooks/spec-bridge.d.ts +40 -0
  173. package/dist/src/hooks/spec-bridge.d.ts.map +1 -0
  174. package/dist/src/hooks/spec-bridge.js +97 -0
  175. package/dist/src/hooks/spec-bridge.js.map +1 -0
  176. package/dist/src/hooks/spec-injector.d.ts.map +1 -1
  177. package/dist/src/hooks/spec-injector.js +18 -12
  178. package/dist/src/hooks/spec-injector.js.map +1 -1
  179. package/dist/src/hooks/statusline.d.ts +8 -17
  180. package/dist/src/hooks/statusline.d.ts.map +1 -1
  181. package/dist/src/hooks/statusline.js +269 -112
  182. package/dist/src/hooks/statusline.js.map +1 -1
  183. package/dist/src/i18n/locales/en.d.ts.map +1 -1
  184. package/dist/src/i18n/locales/en.js +5 -0
  185. package/dist/src/i18n/locales/en.js.map +1 -1
  186. package/dist/src/i18n/locales/zh.d.ts.map +1 -1
  187. package/dist/src/i18n/locales/zh.js +5 -0
  188. package/dist/src/i18n/locales/zh.js.map +1 -1
  189. package/dist/src/i18n/types.d.ts +5 -0
  190. package/dist/src/i18n/types.d.ts.map +1 -1
  191. package/dist/src/team/phase-orchestrator.d.ts +52 -0
  192. package/dist/src/team/phase-orchestrator.d.ts.map +1 -0
  193. package/dist/src/team/phase-orchestrator.js +165 -0
  194. package/dist/src/team/phase-orchestrator.js.map +1 -0
  195. package/dist/src/team/phase-types.d.ts +51 -0
  196. package/dist/src/team/phase-types.d.ts.map +1 -0
  197. package/dist/src/team/phase-types.js +41 -0
  198. package/dist/src/team/phase-types.js.map +1 -0
  199. package/dist/src/tools/collab-adapter.d.ts +17 -0
  200. package/dist/src/tools/collab-adapter.d.ts.map +1 -1
  201. package/dist/src/tools/collab-adapter.js +138 -0
  202. package/dist/src/tools/collab-adapter.js.map +1 -1
  203. package/dist/src/tools/index.d.ts.map +1 -1
  204. package/dist/src/tools/index.js +6 -0
  205. package/dist/src/tools/index.js.map +1 -1
  206. package/dist/src/tools/merge-validator.d.ts +24 -0
  207. package/dist/src/tools/merge-validator.d.ts.map +1 -0
  208. package/dist/src/tools/merge-validator.js +220 -0
  209. package/dist/src/tools/merge-validator.js.map +1 -0
  210. package/dist/src/tools/spec-entry-parser.d.ts +56 -0
  211. package/dist/src/tools/spec-entry-parser.d.ts.map +1 -0
  212. package/dist/src/tools/spec-entry-parser.js +196 -0
  213. package/dist/src/tools/spec-entry-parser.js.map +1 -0
  214. package/dist/src/tools/spec-init.d.ts.map +1 -1
  215. package/dist/src/tools/spec-init.js +66 -92
  216. package/dist/src/tools/spec-init.js.map +1 -1
  217. package/dist/src/tools/spec-keyword-index.d.ts +30 -0
  218. package/dist/src/tools/spec-keyword-index.d.ts.map +1 -0
  219. package/dist/src/tools/spec-keyword-index.js +101 -0
  220. package/dist/src/tools/spec-keyword-index.js.map +1 -0
  221. package/dist/src/tools/spec-loader.d.ts +3 -3
  222. package/dist/src/tools/spec-loader.d.ts.map +1 -1
  223. package/dist/src/tools/spec-loader.js +49 -23
  224. package/dist/src/tools/spec-loader.js.map +1 -1
  225. package/dist/src/tools/team-agents.d.ts +27 -0
  226. package/dist/src/tools/team-agents.d.ts.map +1 -0
  227. package/dist/src/tools/team-agents.js +362 -0
  228. package/dist/src/tools/team-agents.js.map +1 -0
  229. package/dist/src/tools/team-mailbox.d.ts +40 -0
  230. package/dist/src/tools/team-mailbox.d.ts.map +1 -0
  231. package/dist/src/tools/team-mailbox.js +384 -0
  232. package/dist/src/tools/team-mailbox.js.map +1 -0
  233. package/dist/src/tools/team-msg.d.ts +17 -8
  234. package/dist/src/tools/team-msg.d.ts.map +1 -1
  235. package/dist/src/tools/team-msg.js +110 -13
  236. package/dist/src/tools/team-msg.js.map +1 -1
  237. package/dist/src/tools/team-tasks-mcp.d.ts +27 -0
  238. package/dist/src/tools/team-tasks-mcp.d.ts.map +1 -0
  239. package/dist/src/tools/team-tasks-mcp.js +408 -0
  240. package/dist/src/tools/team-tasks-mcp.js.map +1 -0
  241. package/dist/src/types/index.d.ts +5 -0
  242. package/dist/src/types/index.d.ts.map +1 -1
  243. package/package.json +2 -1
  244. package/templates/cli/prompts/workflow-skill-conflict-patterns.txt +3 -3
  245. package/templates/cli/prompts/workflow-skill-lessons-learned.txt +3 -3
  246. package/templates/search-tools.md +1 -1
  247. package/workflows/analyze.md +816 -816
  248. package/workflows/brainstorm.md +471 -471
  249. package/workflows/cli-tools-usage.md +44 -27
  250. package/workflows/codebase-rebuild.md +332 -332
  251. package/workflows/codebase-refresh.md +240 -240
  252. package/workflows/delegate-usage.md +3 -3
  253. package/workflows/execute.md +1 -1
  254. package/workflows/harvest.md +420 -420
  255. package/workflows/integration-test.md +343 -343
  256. package/workflows/issue-analyze.md +6 -2
  257. package/workflows/issue-discover.md +414 -414
  258. package/workflows/issue-execute.md +6 -3
  259. package/workflows/issue-plan.md +5 -2
  260. package/workflows/maestro-coordinate.codex.md +281 -470
  261. package/workflows/maestro-coordinate.md +14 -14
  262. package/workflows/maestro-link-coordinate.md +2 -2
  263. package/workflows/maestro.codex.md +710 -0
  264. package/workflows/maestro.md +10 -11
  265. package/workflows/map.md +111 -111
  266. package/workflows/milestone-complete.md +176 -176
  267. package/workflows/plan.md +1 -1
  268. package/workflows/quick.md +497 -497
  269. package/workflows/refactor.md +300 -300
  270. package/workflows/retrospective.md +1 -1
  271. package/workflows/roadmap.md +335 -335
  272. package/workflows/spec-generate.md +640 -640
  273. package/workflows/specs-add.md +46 -81
  274. package/workflows/specs-load.md +15 -17
  275. package/workflows/specs-setup.md +40 -161
  276. package/.claude/commands/manage-issue-analyze.md +0 -62
  277. package/.claude/commands/manage-issue-execute.md +0 -73
  278. package/.claude/commands/manage-issue-plan.md +0 -62
  279. package/.codex/skills/manage-issue-analyze/SKILL.md +0 -207
  280. package/.codex/skills/manage-issue-execute/SKILL.md +0 -200
  281. package/.codex/skills/manage-issue-plan/SKILL.md +0 -186
@@ -1,420 +1,420 @@
1
- # Harvest Workflow
2
-
3
- Extract knowledge from workflow artifacts and route into wiki / spec / issue stores.
4
-
5
- Unlike `retrospective.md` which is phase-scoped and post-execution, harvest operates on **any workflow session artifact** — analysis results, brainstorm outputs, debug sessions, lite-plan/fix results, scratchpad notes, and completed workflow sessions.
6
-
7
- ---
8
-
9
- ## Prerequisites
10
-
11
- - `.workflow/` initialized (`.workflow/state.json` exists)
12
- - At least one artifact source present (analysis, brainstorm, debug, lite-plan, lite-fix, scratchpad, or active session)
13
- - For wiki routing: `maestro wiki` CLI available
14
-
15
- ---
16
-
17
- ## Argument Shape
18
-
19
- ```
20
- /manage-harvest → scan all sources, interactive selection
21
- /manage-harvest <session-id> → harvest specific session (ANL-*, WFS-*, etc.)
22
- /manage-harvest <path> → harvest from explicit directory or file
23
- /manage-harvest --recent 7 → harvest from artifacts updated in last 7 days
24
- /manage-harvest --source analysis → harvest only from analysis sessions
25
- /manage-harvest <target> --to wiki → force all findings to wiki
26
- /manage-harvest <target> --to spec → force all findings to spec
27
- /manage-harvest <target> --to issue → force all findings to issue
28
- /manage-harvest <target> --to auto → auto-classify routing (default)
29
- /manage-harvest <target> --dry-run → preview without writing
30
- ```
31
-
32
- | Flag | Effect |
33
- |------|--------|
34
- | `--to <target>` | Force routing target: `wiki`, `spec`, `issue`, `auto` (default: auto) |
35
- | `--source <type>` | Filter by source type: `analysis`, `brainstorm`, `debug`, `lite-plan`, `lite-fix`, `scratchpad`, `session`, `all` |
36
- | `--recent N` | Only scan artifacts updated within last N days (default: 30) |
37
- | `--dry-run` | Preview extracted items without writing to any store |
38
- | `-y` / `--yes` | Skip confirmation prompts, accept all routing |
39
- | `--min-confidence N` | Minimum extraction confidence 0.0-1.0 (default: 0.5) |
40
-
41
- ---
42
-
43
- ## Stage 1: parse_input
44
-
45
- ```
46
- 1. Verify .workflow/ exists; else error E001.
47
- 2. Tokenize $ARGUMENTS:
48
- - First non-flag token: session ID, path, or empty (scan mode)
49
- - Flags: --to, --source, --recent, --dry-run, -y, --min-confidence
50
- 3. Build:
51
- mode = "scan" | "session" | "path"
52
- target_filter = "auto" | "wiki" | "spec" | "issue"
53
- source_filter = "all" | specific source type
54
- recent_days = 30 (or --recent value)
55
- dry_run = false
56
- auto_yes = false
57
- min_confidence = 0.5
58
- 4. Validate --to value. Unknown target → error E002.
59
- 5. Validate --source value. Unknown source → error E003.
60
- ```
61
-
62
- ---
63
-
64
- ## Stage 2: discover_artifacts
65
-
66
- Scan `.workflow/` for harvestable artifacts. Each source type has a known structure:
67
-
68
- ### Source Registry
69
-
70
- | Source Type | Scan Path | Key Files | ID Pattern |
71
- |-------------|-----------|-----------|------------|
72
- | `analysis` | `.workflow/.analysis/ANL-*/` | `conclusions.json`, `*.md` | `ANL-*` |
73
- | `brainstorm` | `.workflow/scratch/brainstorm-*/` | `guidance-specification.md`, `brainstorm-*.md` | directory name |
74
- | `lite-plan` | `.workflow/.lite-plan/*/` | `plan.json`, `plan-overview.md` | directory name |
75
- | `lite-fix` | `.workflow/.lite-fix/*/` | `fix-plan.json` | directory name |
76
- | `debug` | `.workflow/.debug/*/` | `debug-log.md`, `hypothesis-*.md` | directory name |
77
- | `scratchpad` | `.workflow/.scratchpad/` | `*.md`, `*.json` | filename |
78
- | `session` | `.workflow/active/WFS-*/` | `workflow-session.json` | `WFS-*` |
79
- | `learning` | `.workflow/learning/` | `lessons.jsonl`, `digest-*.md`, `*.md` | filename |
80
-
81
- ```
82
- candidates = []
83
- FOR each source_type in source_registry:
84
- IF source_filter != "all" AND source_filter != source_type: SKIP
85
- Glob for directories/files matching scan_path
86
- FOR each match:
87
- stat = file modification time
88
- IF stat.mtime < (now - recent_days): SKIP
89
- Read key files, extract:
90
- - session_id or directory name
91
- - title (from JSON title field or markdown H1)
92
- - created_at / updated_at
93
- - summary (first paragraph or JSON summary field)
94
- - file_count (number of artifact files)
95
- candidates.push({ source_type, id, path, title, updated_at, summary, file_count })
96
- ```
97
-
98
- ### Display candidates
99
-
100
- ```
101
- === HARVESTABLE ARTIFACTS ===
102
-
103
- # Source ID Title Updated Files
104
- ─ ────────── ──────────────────── ─────────────────────── ──────────── ─────
105
- 1 analysis ANL-auth-20260410 Auth vulnerability scan 2026-04-10 4
106
- 2 brainstorm brainstorm-cache Cache strategy options 2026-04-08 3
107
- 3 lite-fix rate-limit-20260405 Rate limiter edge case 2026-04-05 2
108
- 4 debug debug-memory-leak Memory leak in worker 2026-04-03 5
109
-
110
- Found: 4 artifacts (filtered by: last 30 days)
111
- ```
112
-
113
- ### Selection logic
114
-
115
- | Mode | Action |
116
- |------|--------|
117
- | `scan`, 0 candidates | Print "No harvestable artifacts found", exit 0 |
118
- | `scan`, ≥1 candidates | AskUserQuestion: select one, multiple (comma-separated), or "all" |
119
- | `session` | Find matching session ID in candidates; error E004 if not found |
120
- | `path` | Validate path exists; auto-detect source type from structure |
121
-
122
- ---
123
-
124
- ## Stage 3: load_and_extract (per selected artifact)
125
-
126
- For each selected artifact, load all files and extract knowledge fragments.
127
-
128
- ### 3a. Load artifact content
129
-
130
- Read all relevant files in the artifact directory. Build a content bundle:
131
-
132
- ```
133
- bundle = {
134
- source_type: "analysis" | "brainstorm" | ...,
135
- id: session_id,
136
- path: artifact_directory,
137
- files: [{ name, content, type: "json"|"md" }],
138
- metadata: extracted from key files (conclusions.json, plan.json, etc.)
139
- }
140
- ```
141
-
142
- ### 3b. Extract knowledge fragments
143
-
144
- Parse content to identify discrete knowledge items. Each source type has specific extraction patterns:
145
-
146
- **Analysis (`conclusions.json` + markdown):**
147
- - `findings[]` → each finding is a fragment
148
- - `recommendations[]` → each recommendation is a fragment
149
- - `risks[]` → each risk is a fragment
150
- - Markdown sections with `## ` headings → section-level fragments
151
-
152
- **Brainstorm (`guidance-specification.md` + notes):**
153
- - `## Options` or `## Approaches` → each option is a fragment
154
- - `## Decision` or `## Recommendation` → decision fragment
155
- - `## Trade-offs` → trade-off fragments
156
- - Action items (lines starting with `- [ ]` or `TODO`) → task fragments
157
-
158
- **Lite-plan (`plan.json`):**
159
- - `tasks[]` → each with rationale → decision fragments
160
- - `dependencies[]` → architectural constraint fragments
161
- - `risks[]` → risk fragments
162
-
163
- **Lite-fix (`fix-plan.json`):**
164
- - `root_cause` → bug fragment
165
- - `fix_strategy` → pattern fragment
166
- - `verification` → test/validation fragment
167
-
168
- **Debug (`debug-log.md`, `hypothesis-*.md`):**
169
- - Final diagnosis → bug fragment
170
- - Verified hypothesis → pattern/lesson fragment
171
- - Rejected hypotheses with reasoning → lesson fragment
172
-
173
- **Scratchpad (*.md):**
174
- - Markdown sections → generic fragments
175
- - Code blocks with explanations → pattern fragments
176
-
177
- **Session (`workflow-session.json`):**
178
- - `completed_tasks[].summary` → pattern/decision fragments
179
- - `key_decisions[]` → decision fragments
180
- - `deferred_items[]` → issue fragments
181
-
182
- **Learning (`lessons.jsonl`):**
183
- - Each lesson line → lesson fragment (check if already routed to wiki/spec/issue)
184
-
185
- Each fragment gets:
186
- ```
187
- fragment = {
188
- id: "HRV-{8 hex}" from hash(source_id + content_hash),
189
- source_type: ...,
190
- source_id: ...,
191
- title: extracted or inferred,
192
- content: raw text,
193
- tags: extracted from context,
194
- category: "finding" | "decision" | "pattern" | "bug" | "risk" | "task" | "lesson" | "recommendation",
195
- confidence: 0.0-1.0 (based on specificity and actionability)
196
- }
197
- ```
198
-
199
- Filter by `--min-confidence`.
200
-
201
- ---
202
-
203
- ## Stage 4: classify_routing
204
-
205
- For each fragment, determine the best routing target (unless `--to` forces a specific target).
206
-
207
- ### Classification Rules
208
-
209
- | Category | Default Target | Rationale |
210
- |----------|---------------|-----------|
211
- | `finding` | wiki (note) | Observations go to knowledge graph |
212
- | `decision` | wiki (spec) or spec (decision) | Architectural decisions → spec ADR or wiki spec entry |
213
- | `pattern` | spec (pattern) | Reusable code patterns → coding conventions |
214
- | `bug` | issue or spec (bug) | Active bugs → issue; fixed bugs → spec learnings |
215
- | `risk` | issue | Unmitigated risks → trackable issues |
216
- | `task` | issue | Unfinished work → trackable issues |
217
- | `lesson` | wiki (lesson) | Generalizable insights → wiki knowledge |
218
- | `recommendation` | wiki (note) or issue | Actionable recommendations → issue; informational → wiki |
219
-
220
- ### Override with `--to`
221
-
222
- If `--to wiki`: all fragments → wiki entries
223
- If `--to spec`: all fragments → spec entries
224
- If `--to issue`: all fragments → issue entries
225
- If `--to auto`: use classification rules above
226
-
227
- ### Build routing plan
228
-
229
- ```
230
- routing_plan = {
231
- wiki: [{ fragment, wiki_type, slug, title, tags, body }],
232
- spec: [{ fragment, spec_type, content }],
233
- issue: [{ fragment, title, severity, description }]
234
- }
235
- ```
236
-
237
- ---
238
-
239
- ## Stage 5: preview_and_confirm
240
-
241
- Display the routing plan:
242
-
243
- ```
244
- === HARVEST PLAN ===
245
- Source: ANL-auth-20260410 (analysis)
246
- Fragments extracted: 8 (filtered from 12 by confidence ≥ 0.5)
247
-
248
- → Wiki (3 entries):
249
- [note] "SQL injection vector in user input" tags: security, sql
250
- [lesson] "Parameterized queries prevent injection" tags: security, pattern
251
- [spec] "Auth token rotation policy" tags: auth, security
252
-
253
- → Spec (2 entries):
254
- [pattern] "Always use parameterized queries for user input"
255
- [decision] "JWT refresh tokens over session cookies"
256
-
257
- → Issue (3 entries):
258
- [high] "Unvalidated redirect in OAuth callback"
259
- [medium] "Missing rate limit on token refresh endpoint"
260
- [low] "Inconsistent error messages leak internal state"
261
-
262
- Total: 3 wiki + 2 spec + 3 issue = 8 routed items
263
- ```
264
-
265
- If `--dry-run`: display and exit.
266
- If NOT `--dry-run` AND NOT `-y`:
267
- AskUserQuestion: "Apply this routing plan? (yes/edit/skip)" with options.
268
- - `edit`: re-display with per-item accept/reject
269
- - `skip`: exit without writing
270
-
271
- ---
272
-
273
- ## Stage 6: route_outputs
274
-
275
- Execute the routing plan. Each target uses existing infrastructure:
276
-
277
- ### 6a. Wiki routing
278
-
279
- For each wiki item:
280
- ```bash
281
- maestro wiki create --type <wiki_type> --slug harvest-<source_type>-<short_id> \
282
- --title "<title>" --tags "<tags>" --body "<body>"
283
- ```
284
-
285
- Wiki types mapping:
286
- - `note` → `--type note`
287
- - `lesson` → `--type lesson`
288
- - `spec` → `--type spec`
289
-
290
- If `maestro wiki create` fails, fall back to writing `.workflow/harvest/wiki-pending-{id}.md` with frontmatter.
291
-
292
- ### 6b. Spec routing
293
-
294
- For each spec item, use the same mechanism as `quality-retrospective` Stage 6:
295
-
296
- ```
297
- Skill({ skill: "spec-add", args: "<spec_type> <content>" })
298
- ```
299
-
300
- Where `spec_type` maps from fragment category:
301
- - `pattern` → `pattern`
302
- - `decision` → `decision`
303
- - `bug` → `bug`
304
- - `lesson` → `rule` (if it prescribes a rule)
305
-
306
- ### 6c. Issue routing
307
-
308
- For each issue item, append to `.workflow/issues/issues.jsonl` using the canonical schema from `workflows/issue.md`:
309
-
310
- ```json
311
- {
312
- "id": "ISS-{YYYYMMDD}-{NNN}",
313
- "title": "<title>",
314
- "description": "<description>",
315
- "severity": "<high|medium|low>",
316
- "status": "open",
317
- "source": "harvest",
318
- "source_ref": "<source_id>",
319
- "tags": [],
320
- "created_at": "<ISO timestamp>",
321
- "issue_history": [{ "action": "created", "timestamp": "<ISO>", "by": "harvest", "detail": "Extracted from <source_type> <source_id>" }]
322
- }
323
- ```
324
-
325
- ### 6d. Track harvest provenance
326
-
327
- For each routed item, record in `.workflow/harvest/harvest-log.jsonl`:
328
-
329
- ```json
330
- {
331
- "fragment_id": "HRV-...",
332
- "source_type": "analysis",
333
- "source_id": "ANL-auth-20260410",
334
- "routed_to": "wiki|spec|issue",
335
- "target_id": "note-harvest-analysis-abc123|ISS-20260413-001|...",
336
- "timestamp": "<ISO>",
337
- "title": "<title>",
338
- "confidence": 0.85
339
- }
340
- ```
341
-
342
- This log prevents duplicate harvesting in future runs.
343
-
344
- ---
345
-
346
- ## Stage 7: dedup_check
347
-
348
- Before writing any item in Stage 6, check for duplicates:
349
-
350
- 1. **harvest-log.jsonl**: Has this fragment_id already been routed?
351
- 2. **Wiki**: `maestro wiki search "<title>"` — does a similar entry exist?
352
- 3. **Issues**: Search `issues.jsonl` for matching title/description
353
- 4. **Specs**: Search `learnings.md` for similar content
354
-
355
- If duplicate found:
356
- - Skip with `[SKIP-DUP]` marker
357
- - Log to harvest report
358
-
359
- ---
360
-
361
- ## Stage 8: report
362
-
363
- Write `.workflow/harvest/harvest-report-{date}.md`:
364
-
365
- ```markdown
366
- # Harvest Report — {date}
367
-
368
- ## Source
369
- - Type: {source_type}
370
- - ID: {source_id}
371
- - Path: {path}
372
-
373
- ## Extraction Summary
374
- - Fragments found: {total}
375
- - Filtered by confidence: {filtered_count}
376
- - Duplicates skipped: {dup_count}
377
-
378
- ## Routing Results
379
-
380
- ### Wiki ({N} entries)
381
- | # | Type | Slug | Title | Status |
382
- |---|------|------|-------|--------|
383
- | 1 | note | harvest-analysis-abc | SQL injection vector | CREATED |
384
- | 2 | lesson | harvest-analysis-def | Parameterized queries | CREATED |
385
-
386
- ### Spec ({N} entries)
387
- | # | Type | Content (truncated) | Status |
388
- |---|------|---------------------|--------|
389
- | 1 | pattern | Always use parameterized queries... | ADDED |
390
-
391
- ### Issue ({N} entries)
392
- | # | Severity | Title | ID | Status |
393
- |---|----------|-------|-----|--------|
394
- | 1 | high | Unvalidated redirect in OAuth... | ISS-20260413-001 | CREATED |
395
-
396
- ## Skipped
397
- | Fragment | Reason |
398
- |----------|--------|
399
- | HRV-abc123 | Duplicate: existing wiki entry note-sql-injection |
400
- ```
401
-
402
- Display summary:
403
-
404
- ```
405
- === HARVEST COMPLETE ===
406
- Source: ANL-auth-20260410 (analysis)
407
-
408
- Wiki: 3 created, 0 skipped
409
- Spec: 2 added, 0 skipped
410
- Issue: 3 created, 1 skipped (dup)
411
-
412
- Report: .workflow/harvest/harvest-report-2026-04-13.md
413
- Log: .workflow/harvest/harvest-log.jsonl
414
-
415
- Next:
416
- → Review wiki entries: maestro wiki list --type note
417
- → Triage issues: Skill({ skill: "manage-issue", args: "list --source harvest" })
418
- → Connect wiki graph: Skill({ skill: "wiki-connect", args: "--fix" })
419
- → View specs: Skill({ skill: "spec-load", args: "--category general" })
420
- ```
1
+ # Harvest Workflow
2
+
3
+ Extract knowledge from workflow artifacts and route into wiki / spec / issue stores.
4
+
5
+ Unlike `retrospective.md` which is phase-scoped and post-execution, harvest operates on **any workflow session artifact** — analysis results, brainstorm outputs, debug sessions, lite-plan/fix results, scratchpad notes, and completed workflow sessions.
6
+
7
+ ---
8
+
9
+ ## Prerequisites
10
+
11
+ - `.workflow/` initialized (`.workflow/state.json` exists)
12
+ - At least one artifact source present (analysis, brainstorm, debug, lite-plan, lite-fix, scratchpad, or active session)
13
+ - For wiki routing: `maestro wiki` CLI available
14
+
15
+ ---
16
+
17
+ ## Argument Shape
18
+
19
+ ```
20
+ /manage-harvest → scan all sources, interactive selection
21
+ /manage-harvest <session-id> → harvest specific session (ANL-*, WFS-*, etc.)
22
+ /manage-harvest <path> → harvest from explicit directory or file
23
+ /manage-harvest --recent 7 → harvest from artifacts updated in last 7 days
24
+ /manage-harvest --source analysis → harvest only from analysis sessions
25
+ /manage-harvest <target> --to wiki → force all findings to wiki
26
+ /manage-harvest <target> --to spec → force all findings to spec
27
+ /manage-harvest <target> --to issue → force all findings to issue
28
+ /manage-harvest <target> --to auto → auto-classify routing (default)
29
+ /manage-harvest <target> --dry-run → preview without writing
30
+ ```
31
+
32
+ | Flag | Effect |
33
+ |------|--------|
34
+ | `--to <target>` | Force routing target: `wiki`, `spec`, `issue`, `auto` (default: auto) |
35
+ | `--source <type>` | Filter by source type: `analysis`, `brainstorm`, `debug`, `lite-plan`, `lite-fix`, `scratchpad`, `session`, `all` |
36
+ | `--recent N` | Only scan artifacts updated within last N days (default: 30) |
37
+ | `--dry-run` | Preview extracted items without writing to any store |
38
+ | `-y` / `--yes` | Skip confirmation prompts, accept all routing |
39
+ | `--min-confidence N` | Minimum extraction confidence 0.0-1.0 (default: 0.5) |
40
+
41
+ ---
42
+
43
+ ## Stage 1: parse_input
44
+
45
+ ```
46
+ 1. Verify .workflow/ exists; else error E001.
47
+ 2. Tokenize $ARGUMENTS:
48
+ - First non-flag token: session ID, path, or empty (scan mode)
49
+ - Flags: --to, --source, --recent, --dry-run, -y, --min-confidence
50
+ 3. Build:
51
+ mode = "scan" | "session" | "path"
52
+ target_filter = "auto" | "wiki" | "spec" | "issue"
53
+ source_filter = "all" | specific source type
54
+ recent_days = 30 (or --recent value)
55
+ dry_run = false
56
+ auto_yes = false
57
+ min_confidence = 0.5
58
+ 4. Validate --to value. Unknown target → error E002.
59
+ 5. Validate --source value. Unknown source → error E003.
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Stage 2: discover_artifacts
65
+
66
+ Scan `.workflow/` for harvestable artifacts. Each source type has a known structure:
67
+
68
+ ### Source Registry
69
+
70
+ | Source Type | Scan Path | Key Files | ID Pattern |
71
+ |-------------|-----------|-----------|------------|
72
+ | `analysis` | `.workflow/.analysis/ANL-*/` | `conclusions.json`, `*.md` | `ANL-*` |
73
+ | `brainstorm` | `.workflow/scratch/brainstorm-*/` | `guidance-specification.md`, `brainstorm-*.md` | directory name |
74
+ | `lite-plan` | `.workflow/.lite-plan/*/` | `plan.json`, `plan-overview.md` | directory name |
75
+ | `lite-fix` | `.workflow/.lite-fix/*/` | `fix-plan.json` | directory name |
76
+ | `debug` | `.workflow/.debug/*/` | `debug-log.md`, `hypothesis-*.md` | directory name |
77
+ | `scratchpad` | `.workflow/.scratchpad/` | `*.md`, `*.json` | filename |
78
+ | `session` | `.workflow/active/WFS-*/` | `workflow-session.json` | `WFS-*` |
79
+ | `learning` | `.workflow/learning/` | `lessons.jsonl`, `digest-*.md`, `*.md` | filename |
80
+
81
+ ```
82
+ candidates = []
83
+ FOR each source_type in source_registry:
84
+ IF source_filter != "all" AND source_filter != source_type: SKIP
85
+ Glob for directories/files matching scan_path
86
+ FOR each match:
87
+ stat = file modification time
88
+ IF stat.mtime < (now - recent_days): SKIP
89
+ Read key files, extract:
90
+ - session_id or directory name
91
+ - title (from JSON title field or markdown H1)
92
+ - created_at / updated_at
93
+ - summary (first paragraph or JSON summary field)
94
+ - file_count (number of artifact files)
95
+ candidates.push({ source_type, id, path, title, updated_at, summary, file_count })
96
+ ```
97
+
98
+ ### Display candidates
99
+
100
+ ```
101
+ === HARVESTABLE ARTIFACTS ===
102
+
103
+ # Source ID Title Updated Files
104
+ ─ ────────── ──────────────────── ─────────────────────── ──────────── ─────
105
+ 1 analysis ANL-auth-20260410 Auth vulnerability scan 2026-04-10 4
106
+ 2 brainstorm brainstorm-cache Cache strategy options 2026-04-08 3
107
+ 3 lite-fix rate-limit-20260405 Rate limiter edge case 2026-04-05 2
108
+ 4 debug debug-memory-leak Memory leak in worker 2026-04-03 5
109
+
110
+ Found: 4 artifacts (filtered by: last 30 days)
111
+ ```
112
+
113
+ ### Selection logic
114
+
115
+ | Mode | Action |
116
+ |------|--------|
117
+ | `scan`, 0 candidates | Print "No harvestable artifacts found", exit 0 |
118
+ | `scan`, ≥1 candidates | AskUserQuestion: select one, multiple (comma-separated), or "all" |
119
+ | `session` | Find matching session ID in candidates; error E004 if not found |
120
+ | `path` | Validate path exists; auto-detect source type from structure |
121
+
122
+ ---
123
+
124
+ ## Stage 3: load_and_extract (per selected artifact)
125
+
126
+ For each selected artifact, load all files and extract knowledge fragments.
127
+
128
+ ### 3a. Load artifact content
129
+
130
+ Read all relevant files in the artifact directory. Build a content bundle:
131
+
132
+ ```
133
+ bundle = {
134
+ source_type: "analysis" | "brainstorm" | ...,
135
+ id: session_id,
136
+ path: artifact_directory,
137
+ files: [{ name, content, type: "json"|"md" }],
138
+ metadata: extracted from key files (conclusions.json, plan.json, etc.)
139
+ }
140
+ ```
141
+
142
+ ### 3b. Extract knowledge fragments
143
+
144
+ Parse content to identify discrete knowledge items. Each source type has specific extraction patterns:
145
+
146
+ **Analysis (`conclusions.json` + markdown):**
147
+ - `findings[]` → each finding is a fragment
148
+ - `recommendations[]` → each recommendation is a fragment
149
+ - `risks[]` → each risk is a fragment
150
+ - Markdown sections with `## ` headings → section-level fragments
151
+
152
+ **Brainstorm (`guidance-specification.md` + notes):**
153
+ - `## Options` or `## Approaches` → each option is a fragment
154
+ - `## Decision` or `## Recommendation` → decision fragment
155
+ - `## Trade-offs` → trade-off fragments
156
+ - Action items (lines starting with `- [ ]` or `TODO`) → task fragments
157
+
158
+ **Lite-plan (`plan.json`):**
159
+ - `tasks[]` → each with rationale → decision fragments
160
+ - `dependencies[]` → architectural constraint fragments
161
+ - `risks[]` → risk fragments
162
+
163
+ **Lite-fix (`fix-plan.json`):**
164
+ - `root_cause` → bug fragment
165
+ - `fix_strategy` → pattern fragment
166
+ - `verification` → test/validation fragment
167
+
168
+ **Debug (`debug-log.md`, `hypothesis-*.md`):**
169
+ - Final diagnosis → bug fragment
170
+ - Verified hypothesis → pattern/lesson fragment
171
+ - Rejected hypotheses with reasoning → lesson fragment
172
+
173
+ **Scratchpad (*.md):**
174
+ - Markdown sections → generic fragments
175
+ - Code blocks with explanations → pattern fragments
176
+
177
+ **Session (`workflow-session.json`):**
178
+ - `completed_tasks[].summary` → pattern/decision fragments
179
+ - `key_decisions[]` → decision fragments
180
+ - `deferred_items[]` → issue fragments
181
+
182
+ **Learning (`lessons.jsonl`):**
183
+ - Each lesson line → lesson fragment (check if already routed to wiki/spec/issue)
184
+
185
+ Each fragment gets:
186
+ ```
187
+ fragment = {
188
+ id: "HRV-{8 hex}" from hash(source_id + content_hash),
189
+ source_type: ...,
190
+ source_id: ...,
191
+ title: extracted or inferred,
192
+ content: raw text,
193
+ tags: extracted from context,
194
+ category: "finding" | "decision" | "pattern" | "bug" | "risk" | "task" | "lesson" | "recommendation",
195
+ confidence: 0.0-1.0 (based on specificity and actionability)
196
+ }
197
+ ```
198
+
199
+ Filter by `--min-confidence`.
200
+
201
+ ---
202
+
203
+ ## Stage 4: classify_routing
204
+
205
+ For each fragment, determine the best routing target (unless `--to` forces a specific target).
206
+
207
+ ### Classification Rules
208
+
209
+ | Category | Default Target | Rationale |
210
+ |----------|---------------|-----------|
211
+ | `finding` | wiki (note) | Observations go to knowledge graph |
212
+ | `decision` | wiki (spec) or spec (decision) | Architectural decisions → spec ADR or wiki spec entry |
213
+ | `pattern` | spec (pattern) | Reusable code patterns → coding conventions |
214
+ | `bug` | issue or spec (bug) | Active bugs → issue; fixed bugs → spec learnings |
215
+ | `risk` | issue | Unmitigated risks → trackable issues |
216
+ | `task` | issue | Unfinished work → trackable issues |
217
+ | `lesson` | wiki (lesson) | Generalizable insights → wiki knowledge |
218
+ | `recommendation` | wiki (note) or issue | Actionable recommendations → issue; informational → wiki |
219
+
220
+ ### Override with `--to`
221
+
222
+ If `--to wiki`: all fragments → wiki entries
223
+ If `--to spec`: all fragments → spec entries
224
+ If `--to issue`: all fragments → issue entries
225
+ If `--to auto`: use classification rules above
226
+
227
+ ### Build routing plan
228
+
229
+ ```
230
+ routing_plan = {
231
+ wiki: [{ fragment, wiki_type, slug, title, tags, body }],
232
+ spec: [{ fragment, spec_type, content }],
233
+ issue: [{ fragment, title, severity, description }]
234
+ }
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Stage 5: preview_and_confirm
240
+
241
+ Display the routing plan:
242
+
243
+ ```
244
+ === HARVEST PLAN ===
245
+ Source: ANL-auth-20260410 (analysis)
246
+ Fragments extracted: 8 (filtered from 12 by confidence ≥ 0.5)
247
+
248
+ → Wiki (3 entries):
249
+ [note] "SQL injection vector in user input" tags: security, sql
250
+ [lesson] "Parameterized queries prevent injection" tags: security, pattern
251
+ [spec] "Auth token rotation policy" tags: auth, security
252
+
253
+ → Spec (2 entries):
254
+ [pattern] "Always use parameterized queries for user input"
255
+ [decision] "JWT refresh tokens over session cookies"
256
+
257
+ → Issue (3 entries):
258
+ [high] "Unvalidated redirect in OAuth callback"
259
+ [medium] "Missing rate limit on token refresh endpoint"
260
+ [low] "Inconsistent error messages leak internal state"
261
+
262
+ Total: 3 wiki + 2 spec + 3 issue = 8 routed items
263
+ ```
264
+
265
+ If `--dry-run`: display and exit.
266
+ If NOT `--dry-run` AND NOT `-y`:
267
+ AskUserQuestion: "Apply this routing plan? (yes/edit/skip)" with options.
268
+ - `edit`: re-display with per-item accept/reject
269
+ - `skip`: exit without writing
270
+
271
+ ---
272
+
273
+ ## Stage 6: route_outputs
274
+
275
+ Execute the routing plan. Each target uses existing infrastructure:
276
+
277
+ ### 6a. Wiki routing
278
+
279
+ For each wiki item:
280
+ ```bash
281
+ maestro wiki create --type <wiki_type> --slug harvest-<source_type>-<short_id> \
282
+ --title "<title>" --tags "<tags>" --body "<body>"
283
+ ```
284
+
285
+ Wiki types mapping:
286
+ - `note` → `--type note`
287
+ - `lesson` → `--type lesson`
288
+ - `spec` → `--type spec`
289
+
290
+ If `maestro wiki create` fails, fall back to writing `.workflow/harvest/wiki-pending-{id}.md` with frontmatter.
291
+
292
+ ### 6b. Spec routing
293
+
294
+ For each spec item, use the same mechanism as `quality-retrospective` Stage 6:
295
+
296
+ ```
297
+ Skill({ skill: "spec-add", args: "<spec_type> <content>" })
298
+ ```
299
+
300
+ Where `spec_type` maps from fragment category:
301
+ - `pattern` → `pattern`
302
+ - `decision` → `decision`
303
+ - `bug` → `bug`
304
+ - `lesson` → `rule` (if it prescribes a rule)
305
+
306
+ ### 6c. Issue routing
307
+
308
+ For each issue item, append to `.workflow/issues/issues.jsonl` using the canonical schema from `workflows/issue.md`:
309
+
310
+ ```json
311
+ {
312
+ "id": "ISS-{YYYYMMDD}-{NNN}",
313
+ "title": "<title>",
314
+ "description": "<description>",
315
+ "severity": "<high|medium|low>",
316
+ "status": "open",
317
+ "source": "harvest",
318
+ "source_ref": "<source_id>",
319
+ "tags": [],
320
+ "created_at": "<ISO timestamp>",
321
+ "issue_history": [{ "action": "created", "timestamp": "<ISO>", "by": "harvest", "detail": "Extracted from <source_type> <source_id>" }]
322
+ }
323
+ ```
324
+
325
+ ### 6d. Track harvest provenance
326
+
327
+ For each routed item, record in `.workflow/harvest/harvest-log.jsonl`:
328
+
329
+ ```json
330
+ {
331
+ "fragment_id": "HRV-...",
332
+ "source_type": "analysis",
333
+ "source_id": "ANL-auth-20260410",
334
+ "routed_to": "wiki|spec|issue",
335
+ "target_id": "note-harvest-analysis-abc123|ISS-20260413-001|...",
336
+ "timestamp": "<ISO>",
337
+ "title": "<title>",
338
+ "confidence": 0.85
339
+ }
340
+ ```
341
+
342
+ This log prevents duplicate harvesting in future runs.
343
+
344
+ ---
345
+
346
+ ## Stage 7: dedup_check
347
+
348
+ Before writing any item in Stage 6, check for duplicates:
349
+
350
+ 1. **harvest-log.jsonl**: Has this fragment_id already been routed?
351
+ 2. **Wiki**: `maestro wiki search "<title>"` — does a similar entry exist?
352
+ 3. **Issues**: Search `issues.jsonl` for matching title/description
353
+ 4. **Specs**: Search `learnings.md` for similar content
354
+
355
+ If duplicate found:
356
+ - Skip with `[SKIP-DUP]` marker
357
+ - Log to harvest report
358
+
359
+ ---
360
+
361
+ ## Stage 8: report
362
+
363
+ Write `.workflow/harvest/harvest-report-{date}.md`:
364
+
365
+ ```markdown
366
+ # Harvest Report — {date}
367
+
368
+ ## Source
369
+ - Type: {source_type}
370
+ - ID: {source_id}
371
+ - Path: {path}
372
+
373
+ ## Extraction Summary
374
+ - Fragments found: {total}
375
+ - Filtered by confidence: {filtered_count}
376
+ - Duplicates skipped: {dup_count}
377
+
378
+ ## Routing Results
379
+
380
+ ### Wiki ({N} entries)
381
+ | # | Type | Slug | Title | Status |
382
+ |---|------|------|-------|--------|
383
+ | 1 | note | harvest-analysis-abc | SQL injection vector | CREATED |
384
+ | 2 | lesson | harvest-analysis-def | Parameterized queries | CREATED |
385
+
386
+ ### Spec ({N} entries)
387
+ | # | Type | Content (truncated) | Status |
388
+ |---|------|---------------------|--------|
389
+ | 1 | pattern | Always use parameterized queries... | ADDED |
390
+
391
+ ### Issue ({N} entries)
392
+ | # | Severity | Title | ID | Status |
393
+ |---|----------|-------|-----|--------|
394
+ | 1 | high | Unvalidated redirect in OAuth... | ISS-20260413-001 | CREATED |
395
+
396
+ ## Skipped
397
+ | Fragment | Reason |
398
+ |----------|--------|
399
+ | HRV-abc123 | Duplicate: existing wiki entry note-sql-injection |
400
+ ```
401
+
402
+ Display summary:
403
+
404
+ ```
405
+ === HARVEST COMPLETE ===
406
+ Source: ANL-auth-20260410 (analysis)
407
+
408
+ Wiki: 3 created, 0 skipped
409
+ Spec: 2 added, 0 skipped
410
+ Issue: 3 created, 1 skipped (dup)
411
+
412
+ Report: .workflow/harvest/harvest-report-2026-04-13.md
413
+ Log: .workflow/harvest/harvest-log.jsonl
414
+
415
+ Next:
416
+ → Review wiki entries: maestro wiki list --type note
417
+ → Triage issues: Skill({ skill: "manage-issue", args: "list --source harvest" })
418
+ → Connect wiki graph: Skill({ skill: "wiki-connect", args: "--fix" })
419
+ → View specs: Skill({ skill: "spec-load", args: "--category learning" })
420
+ ```