gsd-pi 2.28.0-dev.e19bf89 → 2.29.0-dev.23d50d0

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 (285) hide show
  1. package/README.md +24 -17
  2. package/dist/cli.js +15 -9
  3. package/dist/headless.js +4 -0
  4. package/dist/resource-loader.js +80 -8
  5. package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
  6. package/dist/resources/extensions/gsd/auto-dashboard.ts +217 -65
  7. package/dist/resources/extensions/gsd/auto-dispatch.ts +2 -2
  8. package/dist/resources/extensions/gsd/auto-post-unit.ts +53 -6
  9. package/dist/resources/extensions/gsd/auto-prompts.ts +27 -14
  10. package/dist/resources/extensions/gsd/auto-recovery.ts +33 -23
  11. package/dist/resources/extensions/gsd/auto-start.ts +25 -10
  12. package/dist/resources/extensions/gsd/auto-verification.ts +41 -7
  13. package/dist/resources/extensions/gsd/auto-worktree-sync.ts +21 -6
  14. package/dist/resources/extensions/gsd/auto-worktree.ts +9 -0
  15. package/dist/resources/extensions/gsd/auto.ts +67 -22
  16. package/dist/resources/extensions/gsd/commands-handlers.ts +3 -11
  17. package/dist/resources/extensions/gsd/commands-logs.ts +536 -0
  18. package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +90 -47
  19. package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  20. package/dist/resources/extensions/gsd/commands.ts +75 -29
  21. package/dist/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  22. package/dist/resources/extensions/gsd/doctor-types.ts +13 -0
  23. package/dist/resources/extensions/gsd/doctor.ts +2 -6
  24. package/dist/resources/extensions/gsd/export.ts +28 -2
  25. package/dist/resources/extensions/gsd/gsd-db.ts +19 -0
  26. package/dist/resources/extensions/gsd/index.ts +2 -1
  27. package/dist/resources/extensions/gsd/json-persistence.ts +67 -0
  28. package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
  29. package/dist/resources/extensions/gsd/metrics.ts +17 -31
  30. package/dist/resources/extensions/gsd/paths.ts +17 -8
  31. package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
  32. package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
  33. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  34. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  35. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  36. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  37. package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  38. package/dist/resources/extensions/gsd/queue-order.ts +10 -11
  39. package/dist/resources/extensions/gsd/routing-history.ts +13 -17
  40. package/dist/resources/extensions/gsd/session-lock.ts +284 -0
  41. package/dist/resources/extensions/gsd/session-status-io.ts +23 -41
  42. package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  43. package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  44. package/dist/resources/extensions/gsd/tests/commands-logs.test.ts +241 -0
  45. package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  46. package/dist/resources/extensions/gsd/tests/gsd-inspect.test.ts +1 -1
  47. package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  48. package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  49. package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  50. package/dist/resources/extensions/gsd/tests/session-lock.test.ts +315 -0
  51. package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  52. package/dist/resources/extensions/gsd/tests/validate-milestone.test.ts +55 -0
  53. package/dist/resources/extensions/gsd/tests/verification-evidence.test.ts +26 -24
  54. package/dist/resources/extensions/gsd/tests/verification-gate.test.ts +136 -7
  55. package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  56. package/dist/resources/extensions/gsd/types.ts +3 -0
  57. package/dist/resources/extensions/gsd/unit-runtime.ts +16 -13
  58. package/dist/resources/extensions/gsd/verification-evidence.ts +2 -0
  59. package/dist/resources/extensions/gsd/verification-gate.ts +13 -2
  60. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  61. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  62. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  63. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  64. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  65. package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  66. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  67. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  68. package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  69. package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
  70. package/dist/resources/extensions/mcp-client/index.ts +459 -0
  71. package/dist/resources/extensions/remote-questions/discord-adapter.ts +9 -20
  72. package/dist/resources/extensions/remote-questions/http-client.ts +76 -0
  73. package/dist/resources/extensions/remote-questions/notify.ts +1 -2
  74. package/dist/resources/extensions/remote-questions/slack-adapter.ts +11 -18
  75. package/dist/resources/extensions/remote-questions/telegram-adapter.ts +8 -20
  76. package/dist/resources/extensions/remote-questions/types.ts +3 -0
  77. package/dist/resources/extensions/shared/mod.ts +3 -0
  78. package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
  79. package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  80. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  81. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  82. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  83. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  84. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  85. package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  86. package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  87. package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  88. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  89. package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  90. package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  91. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  92. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  93. package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  94. package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  95. package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  96. package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  97. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  98. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  99. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  100. package/dist/resources/skills/create-skill/SKILL.md +184 -0
  101. package/dist/resources/skills/create-skill/references/api-security.md +226 -0
  102. package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  103. package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
  104. package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
  105. package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
  106. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  107. package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  108. package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
  109. package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
  110. package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  111. package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
  112. package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
  113. package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  114. package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
  115. package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
  116. package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
  117. package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
  118. package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
  119. package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  120. package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  121. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  122. package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  123. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  124. package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  125. package/package.json +6 -3
  126. package/packages/native/dist/native.d.ts +2 -0
  127. package/packages/native/dist/native.js +19 -5
  128. package/packages/native/src/native.ts +23 -9
  129. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  130. package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
  131. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  132. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
  134. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  136. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  138. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  140. package/packages/pi-coding-agent/dist/core/system-prompt.js +10 -0
  141. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  145. package/packages/pi-coding-agent/package.json +1 -1
  146. package/packages/pi-coding-agent/scripts/copy-assets.cjs +39 -8
  147. package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
  148. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
  149. package/packages/pi-coding-agent/src/core/settings-manager.ts +11 -0
  150. package/packages/pi-coding-agent/src/core/system-prompt.ts +11 -0
  151. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -1
  152. package/packages/pi-tui/dist/autocomplete.d.ts +3 -0
  153. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  154. package/packages/pi-tui/dist/autocomplete.js +14 -0
  155. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  156. package/packages/pi-tui/src/autocomplete.ts +19 -1
  157. package/pkg/package.json +1 -1
  158. package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
  159. package/src/resources/extensions/gsd/auto-dashboard.ts +217 -65
  160. package/src/resources/extensions/gsd/auto-dispatch.ts +2 -2
  161. package/src/resources/extensions/gsd/auto-post-unit.ts +53 -6
  162. package/src/resources/extensions/gsd/auto-prompts.ts +27 -14
  163. package/src/resources/extensions/gsd/auto-recovery.ts +33 -23
  164. package/src/resources/extensions/gsd/auto-start.ts +25 -10
  165. package/src/resources/extensions/gsd/auto-verification.ts +41 -7
  166. package/src/resources/extensions/gsd/auto-worktree-sync.ts +21 -6
  167. package/src/resources/extensions/gsd/auto-worktree.ts +9 -0
  168. package/src/resources/extensions/gsd/auto.ts +67 -22
  169. package/src/resources/extensions/gsd/commands-handlers.ts +3 -11
  170. package/src/resources/extensions/gsd/commands-logs.ts +536 -0
  171. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +90 -47
  172. package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
  173. package/src/resources/extensions/gsd/commands.ts +75 -29
  174. package/src/resources/extensions/gsd/dashboard-overlay.ts +2 -1
  175. package/src/resources/extensions/gsd/doctor-types.ts +13 -0
  176. package/src/resources/extensions/gsd/doctor.ts +2 -6
  177. package/src/resources/extensions/gsd/export.ts +28 -2
  178. package/src/resources/extensions/gsd/gsd-db.ts +19 -0
  179. package/src/resources/extensions/gsd/index.ts +2 -1
  180. package/src/resources/extensions/gsd/json-persistence.ts +67 -0
  181. package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
  182. package/src/resources/extensions/gsd/metrics.ts +17 -31
  183. package/src/resources/extensions/gsd/paths.ts +17 -8
  184. package/src/resources/extensions/gsd/preferences-models.ts +7 -1
  185. package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
  186. package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
  187. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  188. package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
  189. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
  190. package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
  191. package/src/resources/extensions/gsd/queue-order.ts +10 -11
  192. package/src/resources/extensions/gsd/routing-history.ts +13 -17
  193. package/src/resources/extensions/gsd/session-lock.ts +284 -0
  194. package/src/resources/extensions/gsd/session-status-io.ts +23 -41
  195. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +1 -1
  196. package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +1 -1
  197. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +241 -0
  198. package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
  199. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +1 -1
  200. package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
  201. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +1 -1
  202. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
  203. package/src/resources/extensions/gsd/tests/session-lock.test.ts +315 -0
  204. package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
  205. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +55 -0
  206. package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +26 -24
  207. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +136 -7
  208. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
  209. package/src/resources/extensions/gsd/types.ts +3 -0
  210. package/src/resources/extensions/gsd/unit-runtime.ts +16 -13
  211. package/src/resources/extensions/gsd/verification-evidence.ts +2 -0
  212. package/src/resources/extensions/gsd/verification-gate.ts +13 -2
  213. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
  214. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
  215. package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
  216. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
  217. package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
  218. package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
  219. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
  220. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
  221. package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
  222. package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
  223. package/src/resources/extensions/mcp-client/index.ts +459 -0
  224. package/src/resources/extensions/remote-questions/discord-adapter.ts +9 -20
  225. package/src/resources/extensions/remote-questions/http-client.ts +76 -0
  226. package/src/resources/extensions/remote-questions/notify.ts +1 -2
  227. package/src/resources/extensions/remote-questions/slack-adapter.ts +11 -18
  228. package/src/resources/extensions/remote-questions/telegram-adapter.ts +8 -20
  229. package/src/resources/extensions/remote-questions/types.ts +3 -0
  230. package/src/resources/extensions/shared/mod.ts +3 -0
  231. package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
  232. package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
  233. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
  234. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
  235. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
  236. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
  237. package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
  238. package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
  239. package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
  240. package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
  241. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
  242. package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
  243. package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
  244. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
  245. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
  246. package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
  247. package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
  248. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
  249. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
  250. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
  251. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
  252. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
  253. package/src/resources/skills/create-skill/SKILL.md +184 -0
  254. package/src/resources/skills/create-skill/references/api-security.md +226 -0
  255. package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
  256. package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
  257. package/src/resources/skills/create-skill/references/core-principles.md +437 -0
  258. package/src/resources/skills/create-skill/references/executable-code.md +175 -0
  259. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
  260. package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
  261. package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
  262. package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
  263. package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
  264. package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
  265. package/src/resources/skills/create-skill/references/using-templates.md +112 -0
  266. package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
  267. package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
  268. package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
  269. package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
  270. package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
  271. package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
  272. package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
  273. package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
  274. package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
  275. package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
  276. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
  277. package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
  278. package/dist/resources/extensions/gsd/preferences-hooks.ts +0 -10
  279. package/dist/resources/extensions/mcporter/index.ts +0 -525
  280. package/dist/resources/extensions/shared/progress-widget.ts +0 -282
  281. package/dist/resources/extensions/shared/thinking-widget.ts +0 -107
  282. package/src/resources/extensions/gsd/preferences-hooks.ts +0 -10
  283. package/src/resources/extensions/mcporter/index.ts +0 -525
  284. package/src/resources/extensions/shared/progress-widget.ts +0 -282
  285. package/src/resources/extensions/shared/thinking-widget.ts +0 -107
@@ -0,0 +1,430 @@
1
+ /**
2
+ * Mechanical Completion — deterministic post-verification artifact generation.
3
+ *
4
+ * Pure functions that aggregate task-level outputs into slice/milestone summaries,
5
+ * UAT stubs, roadmap checkbox updates, and validation reports. Zero orchestration
6
+ * dependencies — operates on filesystem paths and parsed structures only.
7
+ *
8
+ * ADR-003: replaces LLM-driven complete-slice and validate-milestone units with
9
+ * mechanical aggregation when the data is sufficient.
10
+ */
11
+
12
+ import { readFileSync, existsSync, readdirSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { atomicWriteSync } from "./atomic-write.js";
15
+ import { loadFile, parseSummary } from "./files.js";
16
+ import { extractMarkdownSection } from "./auto-prompts.js";
17
+ import {
18
+ resolveTaskFiles,
19
+ resolveTaskJsonFiles,
20
+ resolveTasksDir,
21
+ resolveSliceFile,
22
+ resolveSlicePath,
23
+ resolveMilestoneFile,
24
+ resolveMilestonePath,
25
+ resolveGsdRootFile,
26
+ } from "./paths.js";
27
+ import type { Summary, SummaryFrontmatter } from "./types.js";
28
+ import type { EvidenceJSON } from "./verification-evidence.js";
29
+
30
+ // ─── Slice Completion ────────────────────────────────────────────────────────
31
+
32
+ /**
33
+ * Mechanically complete a slice by aggregating task summaries into:
34
+ * - S##-SUMMARY.md (aggregated frontmatter + task one-liners)
35
+ * - S##-UAT.md (extracted from plan Verification section)
36
+ * - Roadmap checkbox [x] update
37
+ *
38
+ * Returns true if completion succeeded, false if data is insufficient
39
+ * (serves as quality gate — caller falls back to LLM completion).
40
+ */
41
+ export async function mechanicalSliceCompletion(
42
+ base: string, mid: string, sid: string,
43
+ ): Promise<boolean> {
44
+ const tDir = resolveTasksDir(base, mid, sid);
45
+ if (!tDir) return false;
46
+
47
+ // Read all task summaries
48
+ const summaryFiles = resolveTaskFiles(tDir, "SUMMARY");
49
+ if (summaryFiles.length === 0) return false;
50
+
51
+ const taskSummaries: Array<{ taskId: string; summary: Summary }> = [];
52
+ for (const file of summaryFiles) {
53
+ const content = readFileSync(join(tDir, file), "utf-8");
54
+ if (!content.trim()) continue;
55
+ const summary = parseSummary(content);
56
+ const taskId = file.match(/^(T\d+)/)?.[1] ?? file;
57
+ taskSummaries.push({ taskId, summary });
58
+ }
59
+
60
+ if (taskSummaries.length === 0) return false;
61
+
62
+ // Quality gate: multi-task slices need substantive summaries
63
+ if (taskSummaries.length > 1) {
64
+ const totalContent = taskSummaries
65
+ .map(ts => ts.summary.whatHappened || ts.summary.oneLiner || "")
66
+ .join("");
67
+ if (totalContent.length < 200) return false;
68
+ }
69
+
70
+ // Aggregate frontmatter
71
+ const aggregated = aggregateFrontmatter(taskSummaries.map(ts => ts.summary.frontmatter));
72
+
73
+ // Build SUMMARY.md
74
+ const summaryLines: string[] = [
75
+ "---",
76
+ `id: ${sid}`,
77
+ `parent: ${mid}`,
78
+ `milestone: ${mid}`,
79
+ ];
80
+ if (aggregated.provides.length > 0)
81
+ summaryLines.push(`provides:\n${aggregated.provides.map(p => ` - ${p}`).join("\n")}`);
82
+ if (aggregated.key_files.length > 0)
83
+ summaryLines.push(`key_files:\n${aggregated.key_files.map(f => ` - ${f}`).join("\n")}`);
84
+ if (aggregated.key_decisions.length > 0)
85
+ summaryLines.push(`key_decisions:\n${aggregated.key_decisions.map(d => ` - ${d}`).join("\n")}`);
86
+ if (aggregated.patterns_established.length > 0)
87
+ summaryLines.push(`patterns_established:\n${aggregated.patterns_established.map(p => ` - ${p}`).join("\n")}`);
88
+ if (aggregated.affects.length > 0)
89
+ summaryLines.push(`affects:\n${aggregated.affects.map(a => ` - ${a}`).join("\n")}`);
90
+ if (aggregated.observability_surfaces.length > 0)
91
+ summaryLines.push(`observability_surfaces:\n${aggregated.observability_surfaces.map(o => ` - ${o}`).join("\n")}`);
92
+ const allPassed = taskSummaries.every(ts => ts.summary.frontmatter.verification_result === "passed");
93
+ summaryLines.push(`verification_result: ${allPassed ? "passed" : "mixed"}`);
94
+ summaryLines.push(`completed_at: ${new Date().toISOString()}`);
95
+ summaryLines.push("---");
96
+ summaryLines.push("");
97
+ summaryLines.push(`# ${sid}: Slice Summary`);
98
+ summaryLines.push("");
99
+
100
+ // Task one-liners
101
+ for (const { taskId, summary } of taskSummaries) {
102
+ const line = summary.oneLiner || summary.title || taskId;
103
+ summaryLines.push(`- **${taskId}**: ${line}`);
104
+ }
105
+ summaryLines.push("");
106
+
107
+ const sDir = resolveSlicePath(base, mid, sid);
108
+ if (!sDir) return false;
109
+
110
+ const summaryPath = join(sDir, `${sid}-SUMMARY.md`);
111
+ atomicWriteSync(summaryPath, summaryLines.join("\n"));
112
+ process.stderr.write(`gsd-mechanical: wrote ${summaryPath}\n`);
113
+
114
+ // Build UAT.md from plan's Verification section
115
+ const planPath = resolveSliceFile(base, mid, sid, "PLAN");
116
+ if (planPath) {
117
+ const planContent = readFileSync(planPath, "utf-8");
118
+ const verification = extractMarkdownSection(planContent, "Verification");
119
+ if (verification) {
120
+ const uatContent = [
121
+ "---",
122
+ `id: ${sid}`,
123
+ `parent: ${mid}`,
124
+ "type: artifact-driven",
125
+ "---",
126
+ "",
127
+ `# ${sid}: UAT`,
128
+ "",
129
+ verification,
130
+ "",
131
+ ].join("\n");
132
+ const uatPath = join(sDir, `${sid}-UAT.md`);
133
+ atomicWriteSync(uatPath, uatContent);
134
+ process.stderr.write(`gsd-mechanical: wrote ${uatPath}\n`);
135
+ }
136
+ }
137
+
138
+ // Mark slice [x] in ROADMAP
139
+ await markSliceInRoadmap(base, mid, sid);
140
+
141
+ // Append new decisions if any
142
+ await appendNewDecisions(base, taskSummaries.map(ts => ts.summary));
143
+
144
+ // Update requirements if all passed
145
+ if (allPassed) {
146
+ await mechanicalRequirementsUpdate(base, mid, sid, taskSummaries.map(ts => ts.summary));
147
+ }
148
+
149
+ return true;
150
+ }
151
+
152
+ // ─── Requirements Update ─────────────────────────────────────────────────────
153
+
154
+ /**
155
+ * Conservative requirements update: mark requirements Validated only if
156
+ * all tasks' verification passed.
157
+ */
158
+ export async function mechanicalRequirementsUpdate(
159
+ _base: string, _mid: string, _sid: string, _taskSummaries: Summary[],
160
+ ): Promise<void> {
161
+ // Conservative: requirements validation requires human or LLM judgment
162
+ // about whether the requirement is truly met. Mechanical completion only
163
+ // marks the slice done — requirement status updates are left to the
164
+ // existing validation pipeline.
165
+ }
166
+
167
+ // ─── Decision Aggregation ────────────────────────────────────────────────────
168
+
169
+ /**
170
+ * Collect key_decisions from task summaries, deduplicate against existing
171
+ * DECISIONS.md, and append new ones.
172
+ */
173
+ export async function appendNewDecisions(
174
+ base: string, taskSummaries: Summary[],
175
+ ): Promise<void> {
176
+ const allDecisions = taskSummaries.flatMap(s => s.frontmatter.key_decisions);
177
+ if (allDecisions.length === 0) return;
178
+
179
+ const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
180
+ const existing = existsSync(decisionsPath)
181
+ ? readFileSync(decisionsPath, "utf-8")
182
+ : "";
183
+
184
+ // Deduplicate — skip decisions whose text already appears in the file
185
+ const newDecisions = allDecisions.filter(d =>
186
+ d.trim() && !existing.includes(d.trim()),
187
+ );
188
+ if (newDecisions.length === 0) return;
189
+
190
+ const entries = newDecisions
191
+ .map(d => `- ${d} _(auto-aggregated from task summaries)_`)
192
+ .join("\n");
193
+
194
+ const updated = existing.trimEnd() + "\n\n### Auto-aggregated Decisions\n\n" + entries + "\n";
195
+ atomicWriteSync(decisionsPath, updated);
196
+ process.stderr.write(`gsd-mechanical: appended ${newDecisions.length} decision(s) to DECISIONS.md\n`);
197
+ }
198
+
199
+ // ─── Milestone Verification ──────────────────────────────────────────────────
200
+
201
+ export interface MilestoneVerificationResult {
202
+ verdict: "passed" | "failed" | "mixed";
203
+ checks: EvidenceJSON[];
204
+ uatResults: string[];
205
+ markdown: string;
206
+ }
207
+
208
+ /**
209
+ * Aggregate T##-VERIFY.json files and S##-UAT-RESULT.md files across all
210
+ * slices in a milestone to produce VALIDATION.md.
211
+ */
212
+ export async function aggregateMilestoneVerification(
213
+ base: string, mid: string,
214
+ ): Promise<MilestoneVerificationResult> {
215
+ const mDir = resolveMilestonePath(base, mid);
216
+ if (!mDir) return { verdict: "failed", checks: [], uatResults: [], markdown: "" };
217
+
218
+ const allChecks: EvidenceJSON[] = [];
219
+ const allUatResults: string[] = [];
220
+
221
+ // Scan all slices
222
+ const slicesDir = join(mDir, "slices");
223
+ if (!existsSync(slicesDir)) return { verdict: "failed", checks: [], uatResults: [], markdown: "" };
224
+
225
+ const sliceDirs = readdirSyncSafe(slicesDir).filter(name => /^S\d+/i.test(name)).sort();
226
+
227
+ for (const sliceName of sliceDirs) {
228
+ const sid = sliceName.match(/^(S\d+)/i)?.[1] ?? sliceName;
229
+ const tDir = resolveTasksDir(base, mid, sid);
230
+ if (tDir) {
231
+ const verifyFiles = resolveTaskJsonFiles(tDir, "VERIFY");
232
+ for (const vf of verifyFiles) {
233
+ try {
234
+ const content = readFileSync(join(tDir, vf), "utf-8");
235
+ const evidence = JSON.parse(content) as EvidenceJSON;
236
+ allChecks.push(evidence);
237
+ } catch {
238
+ // Skip malformed JSON
239
+ }
240
+ }
241
+ }
242
+
243
+ // Check for UAT result
244
+ const uatResultPath = resolveSliceFile(base, mid, sid, "UAT-RESULT");
245
+ if (uatResultPath) {
246
+ try {
247
+ const uatContent = readFileSync(uatResultPath, "utf-8");
248
+ allUatResults.push(`### ${sid}\n\n${uatContent}`);
249
+ } catch {
250
+ // Non-fatal
251
+ }
252
+ }
253
+ }
254
+
255
+ // Determine verdict
256
+ const allPassed = allChecks.length > 0 && allChecks.every(c => c.passed);
257
+ const anyFailed = allChecks.some(c => !c.passed);
258
+ const verdict: "passed" | "failed" | "mixed" = allPassed
259
+ ? "passed"
260
+ : anyFailed
261
+ ? (allChecks.some(c => c.passed) ? "mixed" : "failed")
262
+ : "passed"; // No checks = vacuously passed
263
+
264
+ // Build VALIDATION.md
265
+ const mdLines: string[] = [
266
+ "---",
267
+ `milestone: ${mid}`,
268
+ `verdict: ${verdict}`,
269
+ "remediation_round: 0",
270
+ `validated_at: ${new Date().toISOString()}`,
271
+ "---",
272
+ "",
273
+ `# ${mid}: Milestone Validation`,
274
+ "",
275
+ `**Verdict:** ${verdict}`,
276
+ "",
277
+ "## Verification Results",
278
+ "",
279
+ ];
280
+
281
+ if (allChecks.length === 0) {
282
+ mdLines.push("_No verification evidence found._");
283
+ } else {
284
+ mdLines.push("| Task | Passed | Checks | Failed |");
285
+ mdLines.push("|------|--------|--------|--------|");
286
+ for (const check of allChecks) {
287
+ const failedCount = check.checks.filter(c => c.verdict === "fail").length;
288
+ mdLines.push(
289
+ `| ${check.taskId} | ${check.passed ? "yes" : "no"} | ${check.checks.length} | ${failedCount} |`,
290
+ );
291
+ }
292
+ }
293
+
294
+ if (allUatResults.length > 0) {
295
+ mdLines.push("");
296
+ mdLines.push("## UAT Results");
297
+ mdLines.push("");
298
+ mdLines.push(...allUatResults);
299
+ }
300
+
301
+ mdLines.push("");
302
+
303
+ const markdown = mdLines.join("\n");
304
+
305
+ // Write VALIDATION.md
306
+ const validationPath = join(mDir, `${mid}-VALIDATION.md`);
307
+ atomicWriteSync(validationPath, markdown);
308
+ process.stderr.write(`gsd-mechanical: wrote ${validationPath}\n`);
309
+
310
+ return { verdict, checks: allChecks, uatResults: allUatResults, markdown };
311
+ }
312
+
313
+ // ─── Milestone Summary ──────────────────────────────────────────────────────
314
+
315
+ /**
316
+ * Read all S##-SUMMARY.md files and produce M##-SUMMARY.md.
317
+ */
318
+ export async function generateMilestoneSummary(
319
+ base: string, mid: string,
320
+ ): Promise<string> {
321
+ const mDir = resolveMilestonePath(base, mid);
322
+ if (!mDir) return "";
323
+
324
+ const slicesDir = join(mDir, "slices");
325
+ if (!existsSync(slicesDir)) return "";
326
+
327
+ const sliceDirs = readdirSyncSafe(slicesDir).filter(name => /^S\d+/i.test(name)).sort();
328
+
329
+ const aggregatedProvides: string[] = [];
330
+ const aggregatedKeyFiles: string[] = [];
331
+ const aggregatedKeyDecisions: string[] = [];
332
+ const aggregatedPatterns: string[] = [];
333
+ const sliceOneLinerList: string[] = [];
334
+
335
+ for (const sliceName of sliceDirs) {
336
+ const sid = sliceName.match(/^(S\d+)/i)?.[1] ?? sliceName;
337
+ const summaryPath = resolveSliceFile(base, mid, sid, "SUMMARY");
338
+ if (!summaryPath) continue;
339
+
340
+ try {
341
+ const content = readFileSync(summaryPath, "utf-8");
342
+ const summary = parseSummary(content);
343
+ aggregatedProvides.push(...summary.frontmatter.provides);
344
+ aggregatedKeyFiles.push(...summary.frontmatter.key_files);
345
+ aggregatedKeyDecisions.push(...summary.frontmatter.key_decisions);
346
+ aggregatedPatterns.push(...summary.frontmatter.patterns_established);
347
+ sliceOneLinerList.push(`- **${sid}**: ${summary.oneLiner || summary.title || sid}`);
348
+ } catch {
349
+ sliceOneLinerList.push(`- **${sid}**: _(summary unavailable)_`);
350
+ }
351
+ }
352
+
353
+ const mdLines: string[] = [
354
+ "---",
355
+ `id: ${mid}`,
356
+ ];
357
+ if (dedup(aggregatedProvides).length > 0)
358
+ mdLines.push(`provides:\n${dedup(aggregatedProvides).map(p => ` - ${p}`).join("\n")}`);
359
+ if (dedup(aggregatedKeyFiles).length > 0)
360
+ mdLines.push(`key_files:\n${dedup(aggregatedKeyFiles).map(f => ` - ${f}`).join("\n")}`);
361
+ if (dedup(aggregatedKeyDecisions).length > 0)
362
+ mdLines.push(`key_decisions:\n${dedup(aggregatedKeyDecisions).map(d => ` - ${d}`).join("\n")}`);
363
+ if (dedup(aggregatedPatterns).length > 0)
364
+ mdLines.push(`patterns_established:\n${dedup(aggregatedPatterns).map(p => ` - ${p}`).join("\n")}`);
365
+ mdLines.push(`completed_at: ${new Date().toISOString()}`);
366
+ mdLines.push("---");
367
+ mdLines.push("");
368
+ mdLines.push(`# ${mid}: Milestone Summary`);
369
+ mdLines.push("");
370
+ mdLines.push("## Slices");
371
+ mdLines.push("");
372
+ mdLines.push(...sliceOneLinerList);
373
+ mdLines.push("");
374
+
375
+ const content = mdLines.join("\n");
376
+
377
+ // Write M##-SUMMARY.md
378
+ const summaryPath = join(mDir, `${mid}-SUMMARY.md`);
379
+ atomicWriteSync(summaryPath, content);
380
+ process.stderr.write(`gsd-mechanical: wrote ${summaryPath}\n`);
381
+
382
+ return content;
383
+ }
384
+
385
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
386
+
387
+ function aggregateFrontmatter(fms: SummaryFrontmatter[]): {
388
+ provides: string[];
389
+ key_files: string[];
390
+ key_decisions: string[];
391
+ patterns_established: string[];
392
+ affects: string[];
393
+ observability_surfaces: string[];
394
+ } {
395
+ return {
396
+ provides: dedup(fms.flatMap(f => f.provides)),
397
+ key_files: dedup(fms.flatMap(f => f.key_files)),
398
+ key_decisions: dedup(fms.flatMap(f => f.key_decisions)),
399
+ patterns_established: dedup(fms.flatMap(f => f.patterns_established)),
400
+ affects: dedup(fms.flatMap(f => f.affects)),
401
+ observability_surfaces: dedup(fms.flatMap(f => f.observability_surfaces)),
402
+ };
403
+ }
404
+
405
+ function dedup(arr: string[]): string[] {
406
+ return [...new Set(arr.filter(s => s.trim()))];
407
+ }
408
+
409
+ async function markSliceInRoadmap(base: string, mid: string, sid: string): Promise<void> {
410
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
411
+ if (!roadmapPath) return;
412
+ const content = await loadFile(roadmapPath);
413
+ if (!content) return;
414
+ const updated = content.replace(
415
+ new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${sid}:`, "m"),
416
+ `$1[x] **${sid}:`,
417
+ );
418
+ if (updated !== content) {
419
+ atomicWriteSync(roadmapPath, updated);
420
+ process.stderr.write(`gsd-mechanical: marked ${sid} done in ROADMAP\n`);
421
+ }
422
+ }
423
+
424
+ function readdirSyncSafe(dir: string): string[] {
425
+ try {
426
+ return readdirSync(dir);
427
+ } catch {
428
+ return [];
429
+ }
430
+ }
@@ -13,11 +13,11 @@
13
13
  * 4. On crash recovery or fresh start, the ledger is loaded from disk
14
14
  */
15
15
 
16
- import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
17
16
  import { join } from "node:path";
18
17
  import type { ExtensionContext } from "@gsd/pi-coding-agent";
19
18
  import { gsdRoot } from "./paths.js";
20
19
  import { getAndClearSkills } from "./skill-telemetry.js";
20
+ import { loadJsonFile, loadJsonFileOrNull, saveJsonFile } from "./json-persistence.js";
21
21
 
22
22
  // Re-export from shared — canonical implementation lives in format-utils.
23
23
  export { formatTokenCount } from "../shared/mod.js";
@@ -502,45 +502,31 @@ function metricsPath(base: string): string {
502
502
  return join(gsdRoot(base), "metrics.json");
503
503
  }
504
504
 
505
+ function isMetricsLedger(data: unknown): data is MetricsLedger {
506
+ return (
507
+ typeof data === "object" &&
508
+ data !== null &&
509
+ (data as MetricsLedger).version === 1 &&
510
+ Array.isArray((data as MetricsLedger).units)
511
+ );
512
+ }
513
+
514
+ function defaultLedger(): MetricsLedger {
515
+ return { version: 1, projectStartedAt: Date.now(), units: [] };
516
+ }
517
+
505
518
  /**
506
519
  * Load ledger from disk without initializing in-memory state.
507
520
  * Used by history/export commands outside of auto-mode.
508
521
  */
509
522
  export function loadLedgerFromDisk(base: string): MetricsLedger | null {
510
- try {
511
- const raw = readFileSync(metricsPath(base), "utf-8");
512
- const parsed = JSON.parse(raw);
513
- if (parsed.version === 1 && Array.isArray(parsed.units)) {
514
- return parsed as MetricsLedger;
515
- }
516
- } catch {
517
- // File doesn't exist or is corrupt
518
- }
519
- return null;
523
+ return loadJsonFileOrNull(metricsPath(base), isMetricsLedger);
520
524
  }
521
525
 
522
526
  function loadLedger(base: string): MetricsLedger {
523
- try {
524
- const raw = readFileSync(metricsPath(base), "utf-8");
525
- const parsed = JSON.parse(raw);
526
- if (parsed.version === 1 && Array.isArray(parsed.units)) {
527
- return parsed as MetricsLedger;
528
- }
529
- } catch {
530
- // File doesn't exist or is corrupt — start fresh
531
- }
532
- return {
533
- version: 1,
534
- projectStartedAt: Date.now(),
535
- units: [],
536
- };
527
+ return loadJsonFile(metricsPath(base), isMetricsLedger, defaultLedger);
537
528
  }
538
529
 
539
530
  function saveLedger(base: string, data: MetricsLedger): void {
540
- try {
541
- mkdirSync(gsdRoot(base), { recursive: true });
542
- writeFileSync(metricsPath(base), JSON.stringify(data, null, 2) + "\n", "utf-8");
543
- } catch {
544
- // Don't let metrics failures break auto-mode
545
- }
531
+ saveJsonFile(metricsPath(base), data);
546
532
  }
@@ -137,14 +137,6 @@ export function clearPathCache(): void {
137
137
 
138
138
  // ─── Name Builders ─────────────────────────────────────────────────────────
139
139
 
140
- /**
141
- * Build a directory name from an ID.
142
- * ("M001") → "M001"
143
- */
144
- export function buildDirName(id: string): string {
145
- return id;
146
- }
147
-
148
140
  /**
149
141
  * Build a milestone-level file name.
150
142
  * ("M001", "CONTEXT") → "M001-CONTEXT.md"
@@ -244,6 +236,23 @@ export function resolveTaskFiles(tasksDir: string, suffix: string): string[] {
244
236
  }
245
237
  }
246
238
 
239
+ /**
240
+ * Find all task JSON files matching a pattern in a tasks directory.
241
+ * Returns sorted file names matching T##-SUFFIX.json or legacy T##-*-SUFFIX.json
242
+ */
243
+ export function resolveTaskJsonFiles(tasksDir: string, suffix: string): string[] {
244
+ if (!existsSync(tasksDir)) return [];
245
+ try {
246
+ const currentPattern = new RegExp(`^T\\d+-${suffix}\\.json$`, "i");
247
+ const legacyPattern = new RegExp(`^T\\d+-.*-${suffix}\\.json$`, "i");
248
+ return cachedReaddir(tasksDir)
249
+ .filter(f => currentPattern.test(f) || legacyPattern.test(f))
250
+ .sort();
251
+ } catch {
252
+ return [];
253
+ }
254
+ }
255
+
247
256
  // ─── Full Path Builders ────────────────────────────────────────────────────
248
257
 
249
258
  export const GSD_ROOT_FILES = {
@@ -254,13 +254,19 @@ export function resolveProfileDefaults(profile: TokenProfile): Partial<GSDPrefer
254
254
  subagent: "claude-sonnet-4-5-20250514",
255
255
  },
256
256
  phases: {
257
+ skip_research: true,
258
+ skip_reassess: true,
257
259
  skip_slice_research: true,
258
260
  },
259
261
  };
260
262
  case "quality":
261
263
  return {
262
264
  models: {},
263
- phases: {},
265
+ phases: {
266
+ skip_research: true,
267
+ skip_slice_research: true,
268
+ skip_reassess: true,
269
+ },
264
270
  };
265
271
  }
266
272
  }
@@ -172,9 +172,10 @@ export function validatePreferences(preferences: GSDPreferences): {
172
172
  if (p.skip_reassess !== undefined) validatedPhases.skip_reassess = !!p.skip_reassess;
173
173
  if (p.skip_slice_research !== undefined) validatedPhases.skip_slice_research = !!p.skip_slice_research;
174
174
  if (p.skip_milestone_validation !== undefined) validatedPhases.skip_milestone_validation = !!p.skip_milestone_validation;
175
+ if (p.reassess_after_slice !== undefined) validatedPhases.reassess_after_slice = !!p.reassess_after_slice;
175
176
  if ((p as any).require_slice_discussion !== undefined) (validatedPhases as any).require_slice_discussion = !!(p as any).require_slice_discussion;
176
177
  // Warn on unknown phase keys
177
- const knownPhaseKeys = new Set(["skip_research", "skip_reassess", "skip_slice_research", "skip_milestone_validation", "require_slice_discussion"]);
178
+ const knownPhaseKeys = new Set(["skip_research", "skip_reassess", "skip_slice_research", "skip_milestone_validation", "reassess_after_slice", "require_slice_discussion"]);
178
179
  for (const key of Object.keys(p)) {
179
180
  if (!knownPhaseKeys.has(key)) {
180
181
  warnings.push(`unknown phases key "${key}" — ignored`);
@@ -16,13 +16,15 @@ Summarize your understanding of the specification concretely:
16
16
  - Scope estimate (how many milestones × slices)
17
17
  - Any ambiguities or gaps you notice
18
18
 
19
- ### Step 2: Investigate
19
+ ### Step 2: Investigate (brief)
20
20
 
21
- Scout the codebase to understand what already exists:
21
+ Quickly scout the codebase to understand what already exists — spend no more than 5-6 tool calls here:
22
22
  - `ls` the project root and key directories
23
23
  - Search for relevant existing code, patterns, dependencies
24
24
  - Check library docs if needed (`resolve_library` / `get_library_docs`)
25
25
 
26
+ Then move on to writing artifacts. Do not explore exhaustively — the research phase will do deeper investigation later.
27
+
26
28
  ### Step 3: Make Decisions
27
29
 
28
30
  For any ambiguities or gaps in the specification:
@@ -91,7 +91,7 @@ Before moving to the wrap-up gate, verify you have covered:
91
91
  - options: "Yes, you got it (Recommended)", "Not quite — let me clarify"
92
92
  - **The question ID must contain `depth_verification`** (e.g. `depth_verification_confirm`) — this enables the write-gate downstream.
93
93
 
94
- **If `{{structuredQuestionsAvailable}}` is `false`:** ask in plain text: "Did I capture that correctly? Anything I missed?" Wait for confirmation before proceeding.
94
+ **If `{{structuredQuestionsAvailable}}` is `false`:** ask in plain text: "Did I capture that correctly? If not, tell me what I missed." Wait for confirmation before proceeding.
95
95
 
96
96
  If they clarify, absorb the correction and re-verify.
97
97
 
@@ -12,9 +12,33 @@ All relevant context has been preloaded below — start working immediately with
12
12
 
13
13
  ## Your Role in the Pipeline
14
14
 
15
- A **researcher agent** already explored the codebase and documented findings in the milestone research doc (inlined above, if present). It identified key files, technology choices, constraints, and risks. **Trust the research.** Your job is strategic decomposition turning findings into an ordered set of demoable slices — not re-exploration. Don't read code files the research already summarized unless something is ambiguous or missing.
15
+ You are the first deep look at this milestone. You have full tool access explore the codebase, look up docs, investigate technology choices. Your job is to understand the landscape and then strategically decompose the work into demoable slices.
16
16
 
17
- After you finish, each slice goes through its own research → plan → execute cycle. Slice researchers dive deeper into the specific area. Slice planners decompose into tasks. Executors build each task. Your roadmap sets the strategic frame for all of them.
17
+ After you finish, each slice goes through its own plan → execute cycle. Slice planners decompose into tasks. Executors build each task. Your roadmap sets the strategic frame for all of them.
18
+
19
+ ### Explore First, Then Decompose
20
+
21
+ Before decomposing, build your understanding:
22
+
23
+ 1. **Codebase exploration.** For small/familiar codebases, use `rg`, `find`, and targeted reads. For large or unfamiliar codebases, use `scout` to build a broad map efficiently before diving in.
24
+ 2. **Library docs.** Use `resolve_library` / `get_library_docs` for unfamiliar libraries — skip this for libraries already used in the codebase.
25
+ 3. **Skill Discovery ({{skillDiscoveryMode}}):**{{skillDiscoveryInstructions}}
26
+ 4. **Requirements analysis.** If `.gsd/REQUIREMENTS.md` exists, research against it. Identify which Active requirements are table stakes, likely omissions, overbuilt risks, or domain-standard behaviors.
27
+
28
+ ### Strategic Questions to Answer
29
+
30
+ - What should be proven first?
31
+ - What existing patterns should be reused?
32
+ - What boundary contracts matter?
33
+ - What constraints does the existing codebase impose?
34
+ - Are there known failure modes that should shape slice ordering?
35
+ - If requirements exist: what table stakes, expected behaviors, continuity expectations, launchability expectations, or failure-visibility expectations are missing, optional, or clearly out of scope?
36
+
37
+ ### Source Files
38
+
39
+ {{sourceFilePaths}}
40
+
41
+ If milestone research exists (inlined above), trust those findings and skip redundant exploration. If findings are significant and no research file exists yet, write `{{researchOutputPath}}`.
18
42
 
19
43
  Narrate your decomposition reasoning — why you're grouping work this way, what risks are driving the order, what verification strategy you're choosing and why. Use complete sentences rather than planner shorthand or fragmentary notes.
20
44
 
@@ -18,7 +18,21 @@ Pay particular attention to **Forward Intelligence** sections — they contain h
18
18
 
19
19
  ## Your Role in the Pipeline
20
20
 
21
- A **researcher agent** already explored the codebase and documented findings in the slice research doc (inlined above, if present). It identified key files, build order, constraints, and verification approach. **Trust the research.** Your job is decomposition — turning findings into executable tasks — not re-exploration. Don't read code files the research already summarized unless something is ambiguous or missing from its findings.
21
+ You have full tool access. Before decomposing, explore the relevant code to ground your plan in reality.
22
+
23
+ ### Verify Roadmap Assumptions
24
+
25
+ Check prior slice summaries (inlined above as dependency summaries, if present). If prior slices discovered constraints, changed approaches, or flagged fragility, adjust your plan accordingly. The roadmap description may be stale — verify it against the current codebase state.
26
+
27
+ ### Explore Slice Scope
28
+
29
+ Read the code files relevant to this slice. Confirm the roadmap's description of what exists, what needs to change, and what boundaries apply. Use `rg`, `find`, and targeted reads.
30
+
31
+ ### Source Files
32
+
33
+ {{sourceFilePaths}}
34
+
35
+ If slice research exists (inlined above), trust those findings and skip redundant exploration.
22
36
 
23
37
  After you finish, **executor agents** implement each task in isolated fresh context windows. They see only their task plan, the slice plan excerpt (goal/demo/verification), and compressed summaries of prior tasks. They do not see the research doc, the roadmap, or REQUIREMENTS.md. Everything an executor needs must be in the task plan itself — file paths, specific steps, expected inputs and outputs.
24
38