gsd-pi 2.81.0-dev.72a81bdf3 → 2.82.0-dev.20138ae42

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 (463) hide show
  1. package/README.md +50 -31
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  5. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  7. package/dist/resources/extensions/cmux/index.js +5 -0
  8. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  9. package/dist/resources/extensions/gsd/auto/loop.js +5 -5
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
  11. package/dist/resources/extensions/gsd/auto/phases.js +30 -1
  12. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +233 -127
  17. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  18. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  19. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  20. package/dist/resources/extensions/gsd/auto-verification.js +28 -22
  21. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  22. package/dist/resources/extensions/gsd/auto.js +158 -55
  23. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +25 -6
  24. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
  26. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  27. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  28. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -2
  29. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  30. package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
  31. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -1
  32. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  33. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  34. package/dist/resources/extensions/gsd/context-store.js +112 -0
  35. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  36. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  37. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  38. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  40. package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
  41. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  42. package/dist/resources/extensions/gsd/doctor.js +2 -28
  43. package/dist/resources/extensions/gsd/export-html.js +27 -425
  44. package/dist/resources/extensions/gsd/git-service.js +39 -1
  45. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  46. package/dist/resources/extensions/gsd/guided-flow.js +93 -111
  47. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  48. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  49. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  50. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  51. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  52. package/dist/resources/extensions/gsd/markdown-renderer.js +6 -1
  53. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  54. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  55. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  56. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  57. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  58. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  59. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  60. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  61. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  62. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  63. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  64. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  65. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  66. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  67. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  68. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  71. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  73. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  75. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  76. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  77. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  79. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  80. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  81. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  82. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  83. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  84. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  85. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  86. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  87. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  88. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  89. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  90. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  91. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  92. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  93. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  94. package/dist/resources/extensions/gsd/validation.js +23 -1
  95. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  96. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  97. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  98. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  99. package/dist/resources/extensions/shared/html-shell.js +388 -0
  100. package/dist/resources/extensions/subagent/index.js +448 -78
  101. package/dist/resources/extensions/subagent/launch.js +77 -0
  102. package/dist/resources/extensions/subagent/run-store.js +148 -0
  103. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  104. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  105. package/dist/resources/extensions/visual-brief/index.js +5 -0
  106. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  107. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  108. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  109. package/dist/web/standalone/.next/BUILD_ID +1 -1
  110. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  111. package/dist/web/standalone/.next/build-manifest.json +3 -3
  112. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  113. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  114. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  124. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  134. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/index.html +1 -1
  136. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  137. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  139. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  141. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  142. package/dist/web/standalone/.next/server/app/page.js +2 -2
  143. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  146. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  147. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  151. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  152. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  153. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  154. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  155. package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
  156. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  157. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-9a4db269f9ed63ad.js} +1 -1
  158. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  159. package/package.json +6 -5
  160. package/packages/contracts/dist/rpc.test.js +7 -0
  161. package/packages/contracts/dist/rpc.test.js.map +1 -1
  162. package/packages/contracts/dist/workflow.d.ts +21 -0
  163. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  164. package/packages/contracts/dist/workflow.js +24 -0
  165. package/packages/contracts/dist/workflow.js.map +1 -1
  166. package/packages/contracts/src/rpc.test.ts +8 -0
  167. package/packages/contracts/src/workflow.ts +24 -0
  168. package/packages/daemon/package.json +2 -2
  169. package/packages/mcp-server/README.md +14 -3
  170. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  171. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  172. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  173. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  174. package/packages/mcp-server/package.json +2 -2
  175. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  176. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  177. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  178. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  179. package/packages/native/package.json +1 -1
  180. package/packages/native/tsconfig.json +2 -1
  181. package/packages/native/tsconfig.tsbuildinfo +1 -1
  182. package/packages/pi-agent-core/package.json +1 -1
  183. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  184. package/packages/pi-ai/dist/index.d.ts +2 -2
  185. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  186. package/packages/pi-ai/dist/index.js +1 -1
  187. package/packages/pi-ai/dist/index.js.map +1 -1
  188. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  189. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  190. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  191. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  192. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  193. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  194. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  195. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  196. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  197. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  198. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  199. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  200. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  201. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  202. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  203. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  204. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  205. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  206. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  207. package/packages/pi-ai/package.json +1 -1
  208. package/packages/pi-ai/src/index.ts +7 -2
  209. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  210. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  211. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  212. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  213. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  214. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  215. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  216. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  218. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  220. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  222. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  228. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  229. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  230. package/packages/pi-coding-agent/package.json +1 -1
  231. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  232. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  233. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  234. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  235. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  236. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  237. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  238. package/packages/pi-tui/dist/tui.js +5 -0
  239. package/packages/pi-tui/dist/tui.js.map +1 -1
  240. package/packages/pi-tui/package.json +1 -1
  241. package/packages/pi-tui/src/tui.ts +6 -0
  242. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  243. package/packages/rpc-client/package.json +1 -1
  244. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  245. package/pkg/package.json +1 -1
  246. package/src/resources/GSD-WORKFLOW.md +10 -1
  247. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  248. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  249. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  250. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  251. package/src/resources/extensions/cmux/index.ts +6 -0
  252. package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
  253. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  254. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  255. package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
  256. package/src/resources/extensions/gsd/auto/phases.ts +36 -1
  257. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  258. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  259. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  260. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  261. package/src/resources/extensions/gsd/auto-post-unit.ts +266 -139
  262. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  263. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  264. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  265. package/src/resources/extensions/gsd/auto-verification.ts +36 -34
  266. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  267. package/src/resources/extensions/gsd/auto.ts +167 -53
  268. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +33 -6
  269. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  270. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
  271. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  272. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  273. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -3
  274. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  275. package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
  276. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -1
  277. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  278. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  279. package/src/resources/extensions/gsd/context-store.ts +120 -1
  280. package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
  281. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  282. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  283. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  284. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  285. package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
  286. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  287. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  288. package/src/resources/extensions/gsd/doctor.ts +2 -27
  289. package/src/resources/extensions/gsd/export-html.ts +27 -427
  290. package/src/resources/extensions/gsd/git-service.ts +45 -1
  291. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  292. package/src/resources/extensions/gsd/guided-flow.ts +126 -128
  293. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  294. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  295. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  296. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  297. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  298. package/src/resources/extensions/gsd/markdown-renderer.ts +6 -1
  299. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  300. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  301. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  302. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  303. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  304. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  305. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  306. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  307. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  308. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  309. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  310. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  311. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  312. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  313. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  314. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  315. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  316. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  317. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  318. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  319. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  320. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  321. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  322. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  323. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  324. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  325. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  326. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  327. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  328. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  329. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  330. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  331. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  332. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  333. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  334. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  335. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  336. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +129 -0
  337. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
  338. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +12 -11
  339. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  340. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  341. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  342. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  343. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  344. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  345. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  346. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  347. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  348. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  349. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  350. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  351. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  352. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  353. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  354. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  355. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  356. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  357. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  358. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  359. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  360. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  361. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  362. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  363. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  364. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  365. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  366. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  367. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  368. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  369. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  370. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  371. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  372. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  373. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  374. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  375. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  376. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  377. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  378. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  379. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  380. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  381. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  382. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  383. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  384. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  385. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  386. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  387. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  388. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  389. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  390. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  391. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  392. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  393. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  394. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  395. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  398. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  399. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  400. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  401. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  402. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  403. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  404. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  405. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +20 -1
  406. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  407. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
  408. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  409. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  410. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  411. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  412. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  413. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  414. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  415. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  416. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +86 -7
  417. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  418. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  419. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
  420. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  421. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  422. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  423. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  424. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  425. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  426. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  427. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  428. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  429. package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
  430. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  431. package/src/resources/extensions/gsd/types.ts +1 -1
  432. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  433. package/src/resources/extensions/gsd/validation.ts +23 -1
  434. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  435. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  436. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  437. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  438. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  439. package/src/resources/extensions/shared/html-shell.ts +412 -0
  440. package/src/resources/extensions/subagent/index.ts +567 -103
  441. package/src/resources/extensions/subagent/launch.ts +131 -0
  442. package/src/resources/extensions/subagent/run-store.ts +218 -0
  443. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  444. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  445. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  446. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  447. package/src/resources/extensions/visual-brief/index.ts +8 -0
  448. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  449. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  450. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  451. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  452. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  453. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  454. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  455. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  456. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  457. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  458. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  459. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  460. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  461. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  462. /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_ssgManifest.js +0 -0
@@ -23,7 +23,7 @@ An override was issued by the user that changes a fundamental decision or approa
23
23
  - For DECISIONS.md: append a new decision entry documenting the override and why. Do NOT delete prior decisions — mark them as superseded with a note.
24
24
  - For slice plans (S##-PLAN.md): update Goal, Demo, and Verification sections if affected. Update Files Likely Touched if the override changes scope. Do NOT modify completed task entries.
25
25
  - For REQUIREMENTS.md: update requirement descriptions if the override changes what "done" means, but do not remove requirements.
26
- - For PROJECT.md: update if the override changes project-level facts.
26
+ - For PROJECT.md: do not edit the projection directly. If the override changes project-level facts, persist the revised Project content through `gsd_summary_save` with `artifact_type: "PROJECT"` so the DB remains authoritative.
27
27
  - Milestone context files are reference only — do not modify them.
28
28
  4. Mark all active overrides as resolved: change `**Scope:** active` to `**Scope:** resolved` in `{{overridesPath}}`
29
29
  5. Do not commit manually — the system auto-commits your changes after this unit completes.
@@ -27,7 +27,7 @@ GSD ships with bundled skills. When the task matches, load the relevant skill fi
27
27
 
28
28
  - Never ask the user to do work the agent can execute or verify itself.
29
29
  - Use the lightest sufficient tool first.
30
- - Read before edit.
30
+ - Read before edit or overwrite. Before any write that creates or replaces a file, verify the target path and read relevant existing files, templates, callers, or surrounding code. For truly new files, confirm the path does not already exist.
31
31
  - Reproduce before fix when possible.
32
32
  - Work is not done until the relevant verification has passed.
33
33
  - **Never fabricate, simulate, or role-play user responses.** Never generate markers like `[User]`, `[Human]`, `User:`, or similar; never emit `<user_message>`, `<assistant_message>`, or similar as user input. Treat `<conversation_history>` as read-only context. Ask one question round (1-3 questions), then stop and wait for the user's actual response. If `ask_user_questions` is available, its result is the only valid structured user input for that round. If it cancels, fails, or returns nothing, never use earlier chat as confirmation for the current gate; ask in plain chat and stop.
@@ -102,7 +102,7 @@ Templates are in `{{templatesDir}}`.
102
102
 
103
103
  **File reading:** Use `read` for file inspection. Never use `cat`, `head`, `tail`, or `sed -n` to view contents. Use `read` with `offset`/`limit` for slicing. `bash` is for searching (`rg`, `grep`, `find`) and commands, not displaying files.
104
104
 
105
- **File editing:** Always `read` before `edit`; exact text match is required. Use `write` only for new files or complete rewrites.
105
+ **File editing:** Always `read` before `edit` or overwrite. Before `write`, confirm whether the path exists; if it does, `read` it first and preserve intentional existing content. Use `write` only for new files or complete rewrites.
106
106
 
107
107
  **Code navigation:** Use `lsp` for definition, type_definition, implementation, references, calls, hover, signature, symbols, rename, code_actions, format, and diagnostics. Do not `grep` symbol definitions or shell out to formatters when `lsp` can do it. After code edits, run `lsp diagnostics`.
108
108
 
@@ -0,0 +1,185 @@
1
+ // GSD-2 — ADR-005 Phase 3b: surface ProviderSwitchReport from pi-ai.
2
+ //
3
+ // pi-ai builds a ProviderSwitchReport on every cross-provider transform but
4
+ // only logs it to stderr when GSD_VERBOSE=1. This module installs a
5
+ // single-subscriber observer that surfaces non-empty reports through GSD's
6
+ // three usual telemetry surfaces:
7
+ //
8
+ // 1. UOK audit event (category model-policy, type provider-switch) — only
9
+ // when an auto trace is active.
10
+ // 2. Persistent notification (.gsd/notifications.jsonl, severity warning) —
11
+ // whenever the GSD basePath is known, so users see the loss in the
12
+ // dashboard / status surface without GSD_VERBOSE.
13
+ // 3. In-memory counter, exposed via getProviderSwitchStats() so any
14
+ // caller (dashboard, doctor, tests) can read the rollup.
15
+
16
+ import { setProviderSwitchObserver, type ProviderSwitchReport } from "@gsd/pi-ai";
17
+
18
+ import { autoSession } from "./auto-runtime-state.js";
19
+ import { appendNotification } from "./notification-store.js";
20
+ import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
21
+
22
+ /** Rollup of cross-provider context transformations, grouped by trace. */
23
+ export interface ProviderSwitchStats {
24
+ /** Total non-empty reports observed since process start (or last reset). */
25
+ totalSwitches: number;
26
+ /** Sum of every counted transformation across all reports. */
27
+ totals: {
28
+ thinkingBlocksDropped: number;
29
+ thinkingBlocksDowngraded: number;
30
+ toolCallIdsRemapped: number;
31
+ syntheticToolResultsInserted: number;
32
+ thoughtSignaturesDropped: number;
33
+ };
34
+ /** Per-trace breakdown. Key "interactive" covers reports outside auto-mode. */
35
+ byTrace: Record<string, TraceSwitchStats>;
36
+ /** The most recent non-empty report, if any. */
37
+ lastReport: ProviderSwitchReport | null;
38
+ /** ISO timestamp of the most recent non-empty report, if any. */
39
+ lastAt: string | null;
40
+ }
41
+
42
+ export interface TraceSwitchStats {
43
+ switches: number;
44
+ lastReport: ProviderSwitchReport;
45
+ lastAt: string;
46
+ }
47
+
48
+ const INTERACTIVE_TRACE_KEY = "interactive";
49
+
50
+ interface MutableTraceStats {
51
+ switches: number;
52
+ lastReport: ProviderSwitchReport;
53
+ lastAt: string;
54
+ }
55
+
56
+ let installed = false;
57
+ let totalSwitches = 0;
58
+ const totals = {
59
+ thinkingBlocksDropped: 0,
60
+ thinkingBlocksDowngraded: 0,
61
+ toolCallIdsRemapped: 0,
62
+ syntheticToolResultsInserted: 0,
63
+ thoughtSignaturesDropped: 0,
64
+ };
65
+ const byTrace = new Map<string, MutableTraceStats>();
66
+ let lastReport: ProviderSwitchReport | null = null;
67
+ let lastAt: string | null = null;
68
+
69
+ /** Format a one-line summary suitable for a notification message. */
70
+ function summarize(report: ProviderSwitchReport): string {
71
+ const parts: string[] = [];
72
+ if (report.thinkingBlocksDropped > 0) parts.push(`${report.thinkingBlocksDropped} thinking dropped`);
73
+ if (report.thinkingBlocksDowngraded > 0) parts.push(`${report.thinkingBlocksDowngraded} thinking downgraded`);
74
+ if (report.toolCallIdsRemapped > 0) parts.push(`${report.toolCallIdsRemapped} tool ids remapped`);
75
+ if (report.syntheticToolResultsInserted > 0) parts.push(`${report.syntheticToolResultsInserted} synthetic tool results`);
76
+ if (report.thoughtSignaturesDropped > 0) parts.push(`${report.thoughtSignaturesDropped} thought signatures dropped`);
77
+ return `Provider switch ${report.fromApi} → ${report.toApi}: ${parts.join(", ")}`;
78
+ }
79
+
80
+ function recordReport(report: ProviderSwitchReport): void {
81
+ const now = new Date().toISOString();
82
+ totalSwitches += 1;
83
+ totals.thinkingBlocksDropped += report.thinkingBlocksDropped;
84
+ totals.thinkingBlocksDowngraded += report.thinkingBlocksDowngraded;
85
+ totals.toolCallIdsRemapped += report.toolCallIdsRemapped;
86
+ totals.syntheticToolResultsInserted += report.syntheticToolResultsInserted;
87
+ totals.thoughtSignaturesDropped += report.thoughtSignaturesDropped;
88
+ lastReport = report;
89
+ lastAt = now;
90
+
91
+ const traceKey = autoSession.currentTraceId ?? INTERACTIVE_TRACE_KEY;
92
+ const existing = byTrace.get(traceKey);
93
+ if (existing) {
94
+ existing.switches += 1;
95
+ existing.lastReport = report;
96
+ existing.lastAt = now;
97
+ } else {
98
+ byTrace.set(traceKey, { switches: 1, lastReport: report, lastAt: now });
99
+ }
100
+ }
101
+
102
+ function emitAudit(report: ProviderSwitchReport): void {
103
+ const traceId = autoSession.currentTraceId;
104
+ const basePath = autoSession.basePath;
105
+ if (!traceId || !basePath) return;
106
+ try {
107
+ emitUokAuditEvent(
108
+ basePath,
109
+ buildAuditEnvelope({
110
+ traceId,
111
+ category: "model-policy",
112
+ type: "provider-switch",
113
+ payload: {
114
+ fromApi: report.fromApi,
115
+ toApi: report.toApi,
116
+ thinkingBlocksDropped: report.thinkingBlocksDropped,
117
+ thinkingBlocksDowngraded: report.thinkingBlocksDowngraded,
118
+ toolCallIdsRemapped: report.toolCallIdsRemapped,
119
+ syntheticToolResultsInserted: report.syntheticToolResultsInserted,
120
+ thoughtSignaturesDropped: report.thoughtSignaturesDropped,
121
+ },
122
+ }),
123
+ );
124
+ } catch {
125
+ // Audit emission is best-effort. Counter + notification still fire.
126
+ }
127
+ }
128
+
129
+ function emitNotification(report: ProviderSwitchReport): void {
130
+ try {
131
+ appendNotification(summarize(report), "warning", "workflow-logger");
132
+ } catch {
133
+ // Notification persistence is best-effort.
134
+ }
135
+ }
136
+
137
+ function handleReport(report: ProviderSwitchReport): void {
138
+ recordReport(report);
139
+ emitAudit(report);
140
+ emitNotification(report);
141
+ }
142
+
143
+ /**
144
+ * Install the pi-ai observer. Idempotent — calling more than once is a no-op
145
+ * after the first install.
146
+ */
147
+ export function installProviderSwitchObserver(): void {
148
+ if (installed) return;
149
+ setProviderSwitchObserver(handleReport);
150
+ installed = true;
151
+ }
152
+
153
+ /** Uninstall the observer. Intended for tests. */
154
+ export function uninstallProviderSwitchObserver(): void {
155
+ setProviderSwitchObserver(undefined);
156
+ installed = false;
157
+ }
158
+
159
+ /** Read-only snapshot of the in-memory rollup. */
160
+ export function getProviderSwitchStats(): ProviderSwitchStats {
161
+ const trace: Record<string, TraceSwitchStats> = {};
162
+ for (const [key, value] of byTrace) {
163
+ trace[key] = { switches: value.switches, lastReport: { ...value.lastReport }, lastAt: value.lastAt };
164
+ }
165
+ return {
166
+ totalSwitches,
167
+ totals: { ...totals },
168
+ byTrace: trace,
169
+ lastReport: lastReport ? { ...lastReport } : null,
170
+ lastAt,
171
+ };
172
+ }
173
+
174
+ /** Reset the in-memory rollup. Intended for tests. */
175
+ export function _resetProviderSwitchStats(): void {
176
+ totalSwitches = 0;
177
+ totals.thinkingBlocksDropped = 0;
178
+ totals.thinkingBlocksDowngraded = 0;
179
+ totals.toolCallIdsRemapped = 0;
180
+ totals.syntheticToolResultsInserted = 0;
181
+ totals.thoughtSignaturesDropped = 0;
182
+ byTrace.clear();
183
+ lastReport = null;
184
+ lastAt = null;
185
+ }
@@ -0,0 +1,77 @@
1
+ // GSD-2 — Smart entry routing decisions.
2
+ // Pure route selection for /gsd guided wizard choices.
3
+
4
+ export type SmartEntryIsolationMode = "worktree" | "branch" | "none";
5
+
6
+ export type ActiveTaskChoice =
7
+ | "execute"
8
+ | "auto"
9
+ | "status"
10
+ | "milestone_actions";
11
+
12
+ export type ActiveTaskRoute =
13
+ | {
14
+ kind: "auto-bootstrap";
15
+ verboseMode: false;
16
+ options?: {
17
+ step?: true;
18
+ milestoneLock?: string;
19
+ };
20
+ }
21
+ | {
22
+ kind: "guided-dispatch";
23
+ unitType: "execute-task";
24
+ }
25
+ | {
26
+ kind: "status";
27
+ }
28
+ | {
29
+ kind: "milestone-actions";
30
+ };
31
+
32
+ export function resolveGuidedExecuteLaunchMode(
33
+ isolationMode: SmartEntryIsolationMode,
34
+ ): "auto-step" | "guided-dispatch" {
35
+ return isolationMode === "worktree" ? "auto-step" : "guided-dispatch";
36
+ }
37
+
38
+ export function resolveActiveTaskChoiceRoute(input: {
39
+ choice: ActiveTaskChoice;
40
+ isolationMode: SmartEntryIsolationMode;
41
+ milestoneId: string;
42
+ }): ActiveTaskRoute {
43
+ if (input.choice === "auto") {
44
+ return {
45
+ kind: "auto-bootstrap",
46
+ verboseMode: false,
47
+ };
48
+ }
49
+
50
+ if (input.choice === "execute") {
51
+ if (resolveGuidedExecuteLaunchMode(input.isolationMode) === "auto-step") {
52
+ return {
53
+ kind: "auto-bootstrap",
54
+ verboseMode: false,
55
+ options: {
56
+ step: true,
57
+ milestoneLock: input.milestoneId,
58
+ },
59
+ };
60
+ }
61
+
62
+ return {
63
+ kind: "guided-dispatch",
64
+ unitType: "execute-task",
65
+ };
66
+ }
67
+
68
+ if (input.choice === "status") {
69
+ return { kind: "status" };
70
+ }
71
+
72
+ if (input.choice === "milestone_actions") {
73
+ return { kind: "milestone-actions" };
74
+ }
75
+
76
+ throw new Error(`Invalid ActiveTaskChoice: ${input.choice}`);
77
+ }
@@ -23,6 +23,7 @@ import {
23
23
  } from "../../native-git-bridge.js";
24
24
  import type { GSDState } from "../../types.js";
25
25
  import { logError, logWarning } from "../../workflow-logger.js";
26
+ import { isGsdWorktreePath } from "../../worktree-root.js";
26
27
  import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
27
28
 
28
29
  export type MergeReconcileResult = "clean" | "reconciled" | "blocked";
@@ -46,7 +47,13 @@ function resolveGitDir(basePath: string): string {
46
47
  return isAbsolute(gitDir) ? gitDir : resolve(basePath, gitDir);
47
48
  }
48
49
  } catch (err) {
49
- logWarning("recovery", `gitdir resolution failed: ${getErrorMessage(err)}`);
50
+ const message = getErrorMessage(err);
51
+ logWarning("recovery", `gitdir resolution failed: ${message}`);
52
+ if (isGsdWorktreePath(basePath)) {
53
+ throw new Error(
54
+ `Worktree integrity failure: ${basePath} is not a valid git worktree (git rev-parse failed: ${message.split("\n")[0]}). Repair or recreate the worktree before retrying.`,
55
+ );
56
+ }
50
57
  }
51
58
 
52
59
  return join(basePath, ".git");
@@ -1,14 +1,13 @@
1
1
  // Project/App: GSD-2
2
2
  // File Purpose: ADR-017 unregistered-milestone drift handler. Detects
3
3
  // milestones whose on-disk directory has meaningful content (ROADMAP/
4
- // CONTEXT/SUMMARY) but no DB row, then runs the markdown importer to
5
- // reconcile. PROJECT.md is the human-facing index the importer's source
6
- // of truth is the .gsd/milestones/ directory tree.
4
+ // CONTEXT/SUMMARY) but no DB row, then fails closed with an explicit recovery
5
+ // instruction. Markdown hierarchy import is reserved for operator-controlled
6
+ // migration/recovery commands, not automatic runtime reconciliation.
7
7
 
8
8
  import { existsSync } from "node:fs";
9
9
 
10
10
  import { getMilestone, isDbAvailable } from "../../gsd-db.js";
11
- import { migrateHierarchyToDb } from "../../md-importer.js";
12
11
  import { findMilestoneIds } from "../../milestone-ids.js";
13
12
  import { resolveMilestoneFile } from "../../paths.js";
14
13
  import type { GSDState } from "../../types.js";
@@ -46,20 +45,18 @@ export function detectUnregisteredMilestoneDrift(
46
45
  }
47
46
 
48
47
  /**
49
- * Repair: invoke the markdown importer. migrateHierarchyToDb walks the same
50
- * findMilestoneIds list the detector uses and INSERTs OR IGNOREs every
51
- * missing milestone (and its slices/tasks) idempotent under cap=2 retry.
52
- *
53
- * Note: even though we receive one record at a time, the importer is a
54
- * project-wide operation. Repeated invocation across multiple drift records
55
- * in the same pass is wasteful but safe; a future optimization could
56
- * coalesce by checking whether the importer has already run this pass.
48
+ * Repair intentionally fails closed. The project-root DB is authoritative at
49
+ * runtime; markdown-only milestones must be imported through an explicit
50
+ * migration/recovery command so operators opt into changing canonical state.
57
51
  */
58
52
  export function repairUnregisteredMilestone(
59
- _record: UnregisteredMilestoneDrift,
60
- ctx: DriftContext,
53
+ record: UnregisteredMilestoneDrift,
54
+ _ctx: DriftContext,
61
55
  ): void {
62
- migrateHierarchyToDb(ctx.basePath);
56
+ throw new Error(
57
+ `Milestone ${record.milestoneId} exists only as markdown projection. ` +
58
+ "Runtime reconciliation will not import markdown into the authoritative DB; run explicit GSD recovery/migration if this markdown should repopulate the database.",
59
+ );
63
60
  }
64
61
 
65
62
  export const unregisteredMilestoneHandler: DriftHandler<UnregisteredMilestoneDrift> = {
@@ -1,8 +1,8 @@
1
1
  // Project/App: GSD-2
2
2
  // File Purpose: ADR-017 roadmap-divergence drift handler. Detects mismatches
3
- // between ROADMAP.md (parsed slice sequence + depends declarations) and the
4
- // DB slice rows for that milestone, then reconciles via the markdown
5
- // importer plus an explicit junction-table sync.
3
+ // between ROADMAP.md (parsed slice sequence, depends declarations, and
4
+ // checkboxes) and the DB slice rows for that milestone, then re-renders the
5
+ // ROADMAP projection from the authoritative DB rows.
6
6
 
7
7
  import { existsSync, readFileSync } from "node:fs";
8
8
 
@@ -10,12 +10,12 @@ import {
10
10
  getMilestone,
11
11
  getMilestoneSlices,
12
12
  isDbAvailable,
13
- syncSliceDependencies,
14
13
  } from "../../gsd-db.js";
15
- import { migrateHierarchyToDb } from "../../md-importer.js";
14
+ import { renderRoadmapFromDb } from "../../markdown-renderer.js";
16
15
  import { findMilestoneIds } from "../../milestone-ids.js";
17
16
  import { parseRoadmap } from "../../parsers-legacy.js";
18
17
  import { resolveMilestoneFile } from "../../paths.js";
18
+ import { isClosedStatus } from "../../status-guards.js";
19
19
  import type { GSDState } from "../../types.js";
20
20
  import type { DriftContext, DriftHandler, DriftRecord } from "../types.js";
21
21
 
@@ -46,14 +46,20 @@ function milestoneHasDivergence(
46
46
 
47
47
  const dbSlices = getMilestoneSlices(milestoneId);
48
48
  const dbSliceMap = new Map(dbSlices.map((s) => [s.id, s]));
49
+ const roadmapSliceIds = new Set<string>();
49
50
 
50
51
  for (let i = 0; i < roadmap.slices.length; i++) {
51
52
  const roadmapSlice = roadmap.slices[i]!;
53
+ roadmapSliceIds.add(roadmapSlice.id);
52
54
  const expectedSequence = i + 1;
53
55
  const dbSlice = dbSliceMap.get(roadmapSlice.id);
54
56
  if (!dbSlice) return true; // Roadmap has a slice the DB doesn't.
55
57
  if (dbSlice.sequence !== expectedSequence) return true;
56
58
  if (!arraysEqual(dbSlice.depends, roadmapSlice.depends)) return true;
59
+ if (isClosedStatus(dbSlice.status) !== roadmapSlice.done) return true;
60
+ }
61
+ for (const dbSlice of dbSlices) {
62
+ if (!roadmapSliceIds.has(dbSlice.id)) return true;
57
63
  }
58
64
  return false;
59
65
  }
@@ -77,29 +83,15 @@ export function detectRoadmapDivergenceDrift(
77
83
  }
78
84
 
79
85
  /**
80
- * Repair a milestone's roadmap divergence:
81
- * 1. migrateHierarchyToDb upserts slice rows (sequence + depends JSON
82
- * update via ON CONFLICT DO UPDATE).
83
- * 2. syncSliceDependencies updates the junction table per slice — the
84
- * importer only writes the JSON column, not the relational view.
86
+ * Repair a milestone's roadmap divergence by regenerating the projection from
87
+ * DB rows. ROADMAP.md is a projection; runtime reconciliation must not import
88
+ * slice presence, sequence, dependencies, or checkbox state from markdown.
85
89
  */
86
- export function repairRoadmapDivergence(
90
+ export async function repairRoadmapDivergence(
87
91
  record: RoadmapDivergenceDrift,
88
92
  ctx: DriftContext,
89
- ): void {
90
- migrateHierarchyToDb(ctx.basePath);
91
-
92
- const roadmapPath = resolveMilestoneFile(ctx.basePath, record.milestoneId, "ROADMAP");
93
- if (!roadmapPath || !existsSync(roadmapPath)) return;
94
-
95
- try {
96
- const roadmap = parseRoadmap(readFileSync(roadmapPath, "utf-8"));
97
- for (const slice of roadmap.slices) {
98
- syncSliceDependencies(record.milestoneId, slice.id, slice.depends);
99
- }
100
- } catch {
101
- /* parse failure: detector will fire again next pass */
102
- }
93
+ ): Promise<void> {
94
+ await renderRoadmapFromDb(ctx.basePath, record.milestoneId);
103
95
  }
104
96
 
105
97
  export const roadmapDivergenceHandler: DriftHandler<RoadmapDivergenceDrift> = {
@@ -25,3 +25,8 @@ export function isDeferredStatus(status: string): boolean {
25
25
  export function isInactiveStatus(status: string): boolean {
26
26
  return isClosedStatus(status) || isDeferredStatus(status);
27
27
  }
28
+
29
+ /** Returns true when a prior milestone should not block dispatch ordering. */
30
+ export function isSkippedForDispatch(status: string): boolean {
31
+ return isClosedStatus(status) || status === "parked" || isDeferredStatus(status);
32
+ }
@@ -1,7 +1,7 @@
1
1
  # Project Knowledge
2
2
 
3
- Append-only register of project-specific rules, patterns, and lessons learned.
4
- Agents read this before every unit. Add entries when you discover something worth remembering.
3
+ Project-specific rules plus projected patterns and lessons learned.
4
+ Rules are maintained in this file. Patterns and lessons are persisted to the memories table and rendered here on the next session-start projection.
5
5
 
6
6
  ## Rules
7
7
 
@@ -99,11 +99,11 @@
99
99
  - "Improve UI"
100
100
 
101
101
  Each task should usually include:
102
- - Why: why this task exists / what part of the slice it closes
103
- - Files: the main files likely touched
104
- - Do: concrete implementation steps and important constraints
105
- - Verify: the command, test, or runtime check that proves it worked
106
- - Done when: a measurable acceptance condition
102
+ - description: why this task exists, concrete steps, and done-when acceptance
103
+ - files: JSON array of likely touched paths
104
+ - verify: the command, test, or runtime check that proves it worked
105
+ - inputs: JSON array of existing paths or prior task outputs this task consumes
106
+ - expectedOutput: JSON array of paths this task creates or overwrites
107
107
 
108
108
  Keep the checkbox line format exactly:
109
109
  - [ ] **T01: Title** `est:30m`
@@ -131,10 +131,13 @@
131
131
 
132
132
  Verify field rules:
133
133
  - MUST be a mechanically executable command: `npm test`, `grep -q "pattern" file`, `test -f path`
134
+ - MUST NOT use shell pipes, redirects, semicolons, backticks, command substitution, or output trimming
134
135
  - For content/document tasks: verify file existence, section count, YAML validity, or word count
135
136
  NOT exact phrasing, specific formulas, or "zero TBD" aspirational criteria
136
137
  - If no command can verify the output, write: "Manual review — file exists and is non-empty"
138
+ - BAD: `python3 -m pytest tests/ -q --tb=short 2>&1 | tail -5`
137
139
  - BAD: "Sections 3.1 and 3.2 exist with exact formulas. Zero TBD/TODO."
140
+ - GOOD: `python3 -m pytest tests/ -q --tb=short`
138
141
  - GOOD: `grep -c "^## " doc.md` returns >= 4 (4+ sections), `! grep -q "TBD\|TODO" doc.md`
139
142
 
140
143
  Integration closure rule:
@@ -72,7 +72,8 @@ skills_used:
72
72
  <!-- Every input MUST be a backtick-wrapped file path. These paths are machine-parsed to
73
73
  derive task dependencies — vague descriptions without paths break dependency detection.
74
74
  For the first task in a slice with no prior task outputs, list the existing source files
75
- this task reads or modifies. -->
75
+ this task reads or modifies.
76
+ Tool field: inputs must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
76
77
 
77
78
  - `{{filePath}}` — {{whatThisTaskNeedsFromPriorWork}}
78
79
 
@@ -82,6 +83,7 @@ skills_used:
82
83
  or modifies. These paths are machine-parsed to derive task dependencies.
83
84
  This task should produce a real increment toward making the slice goal/demo true. A full
84
85
  slice plan should not be able to mark every task complete while the claimed slice behavior
85
- still does not work at the stated proof level. -->
86
+ still does not work at the stated proof level.
87
+ Tool field: expectedOutput must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
86
88
 
87
89
  - `{{filePath}}` — {{whatThisTaskCreatesOrModifies}}
@@ -13,6 +13,7 @@ import {
13
13
  formatWidgetTokens,
14
14
  estimateTimeRemaining,
15
15
  extractUatSliceId,
16
+ buildPhaseHandoffOutcome,
16
17
  updateProgressWidget,
17
18
  setAutoOutcomeWidget,
18
19
  getRoadmapSlicesSync,
@@ -255,6 +256,76 @@ test("setAutoOutcomeWidget renders a durable next-action handoff", () => {
255
256
  assert.match(output, /\/gsd auto/);
256
257
  });
257
258
 
259
+ test("buildPhaseHandoffOutcome summarizes the last phase result", () => {
260
+ const snapshot = buildPhaseHandoffOutcome({
261
+ unitType: "plan-slice",
262
+ unitId: "M005/S01",
263
+ agentEndMessages: [
264
+ { message: { role: "assistant", content: "Planned S01 with category-aware filtering and validation steps." } },
265
+ ],
266
+ });
267
+
268
+ assert.equal(snapshot.status, "complete");
269
+ assert.equal(snapshot.title, "PLAN complete");
270
+ assert.match(snapshot.detail ?? "", /category-aware filtering/);
271
+ assert.equal(snapshot.unitLabel, "planning M005/S01");
272
+ assert.match(snapshot.nextAction, /next phase/);
273
+ });
274
+
275
+ test("buildPhaseHandoffOutcome ignores non-assistant trailing messages", () => {
276
+ const snapshot = buildPhaseHandoffOutcome({
277
+ unitType: "plan-slice",
278
+ unitId: "M005/S01",
279
+ agentEndMessages: [
280
+ { message: { role: "assistant", content: "Assistant summary to hand off." } },
281
+ { role: "tool", content: "Tool output should not be shown." },
282
+ { role: "user", content: "User follow-up should not be shown." },
283
+ ],
284
+ });
285
+
286
+ assert.match(snapshot.detail ?? "", /Assistant summary/);
287
+ assert.doesNotMatch(snapshot.detail ?? "", /Tool output/);
288
+ assert.doesNotMatch(snapshot.detail ?? "", /User follow-up/);
289
+ });
290
+
291
+ test("updateProgressWidget preserves the phase handoff during session switching", () => {
292
+ const calls: Array<[string, unknown]> = [];
293
+ updateProgressWidget(
294
+ {
295
+ hasUI: true,
296
+ ui: {
297
+ setWidget(key: string, factory: unknown) {
298
+ calls.push([key, factory]);
299
+ },
300
+ setHeader() {},
301
+ setStatus() {},
302
+ },
303
+ } as any,
304
+ "execute-task",
305
+ "M005/S01/T01",
306
+ {
307
+ phase: "executing",
308
+ activeSlice: { id: "S01", title: "Filter chip bar" },
309
+ activeTask: { id: "T01", title: "Add category filter" },
310
+ } as any,
311
+ {
312
+ getAutoStartTime: () => Date.now(),
313
+ isStepMode: () => false,
314
+ getCmdCtx: () => null,
315
+ getBasePath: () => "",
316
+ isVerbose: () => false,
317
+ isSessionSwitching: () => true,
318
+ getCurrentDispatchedModelId: () => null,
319
+ },
320
+ );
321
+
322
+ assert.ok(calls.some(([key]) => key === "gsd-progress"));
323
+ assert.ok(
324
+ !calls.some(([key, value]) => key === "gsd-outcome" && value === undefined),
325
+ "handoff widget should stay visible until the next progress frame renders",
326
+ );
327
+ });
328
+
258
329
  test("shouldRenderRoadmapProgress hides pre-roadmap zero-slice progress", () => {
259
330
  assert.equal(shouldRenderRoadmapProgress(null), false);
260
331
  assert.equal(shouldRenderRoadmapProgress({ done: 0, total: 0, activeSliceTasks: null } as any), false);