gsd-pi 2.73.1-dev.d987996 → 2.74.0-dev.0306a2e

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 (535) hide show
  1. package/dist/cli-web-branch.d.ts +4 -3
  2. package/dist/cli-web-branch.js +10 -7
  3. package/dist/cli.js +184 -206
  4. package/dist/headless-query.js +4 -1
  5. package/dist/help-text.js +23 -0
  6. package/dist/logo.d.ts +1 -1
  7. package/dist/logo.js +1 -1
  8. package/dist/onboarding.js +59 -53
  9. package/dist/resource-loader.js +2 -2
  10. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
  11. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  12. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  13. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  14. package/dist/resources/extensions/gsd/auto/phases.js +173 -13
  15. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +22 -4
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +105 -16
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +254 -15
  19. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  20. package/dist/resources/extensions/gsd/auto-start.js +23 -6
  21. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
  22. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  23. package/dist/resources/extensions/gsd/auto-verification.js +186 -3
  24. package/dist/resources/extensions/gsd/auto.js +65 -12
  25. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
  26. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  30. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  31. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  32. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  33. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  34. package/dist/resources/extensions/gsd/commands-handlers.js +8 -2
  35. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  36. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  38. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  39. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  40. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  41. package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  42. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  43. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  44. package/dist/resources/extensions/gsd/git-service.js +49 -1
  45. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  46. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  47. package/dist/resources/extensions/gsd/guided-flow.js +23 -0
  48. package/dist/resources/extensions/gsd/index.js +15 -2
  49. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  50. package/dist/resources/extensions/gsd/journal.js +27 -0
  51. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  52. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  53. package/dist/resources/extensions/gsd/metrics.js +19 -0
  54. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  55. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  56. package/dist/resources/extensions/gsd/notification-widget.js +2 -2
  57. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  58. package/dist/resources/extensions/gsd/preferences-models.js +63 -3
  59. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  60. package/dist/resources/extensions/gsd/preferences-validation.js +130 -2
  61. package/dist/resources/extensions/gsd/preferences.js +26 -0
  62. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  63. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  64. package/dist/resources/extensions/gsd/state.js +66 -15
  65. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  66. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  67. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  68. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  69. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  70. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  71. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  72. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  73. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  74. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  75. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  76. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  77. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  78. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  79. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  80. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  81. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  82. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  83. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  84. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  85. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  86. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  87. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  88. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  89. package/dist/update-check.d.ts +1 -0
  90. package/dist/update-check.js +13 -5
  91. package/dist/update-cmd.js +4 -3
  92. package/dist/web/standalone/.next/BUILD_ID +1 -1
  93. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  94. package/dist/web/standalone/.next/build-manifest.json +2 -2
  95. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/index.html +1 -1
  118. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  125. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  126. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  128. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  129. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  130. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  131. package/package.json +3 -3
  132. package/packages/daemon/package.json +2 -2
  133. package/packages/mcp-server/dist/index.d.ts +3 -0
  134. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  135. package/packages/mcp-server/dist/index.js +3 -0
  136. package/packages/mcp-server/dist/index.js.map +1 -1
  137. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  138. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  139. package/packages/mcp-server/dist/readers/graph.js +655 -0
  140. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  141. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  142. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  143. package/packages/mcp-server/dist/readers/index.js +1 -0
  144. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  145. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  146. package/packages/mcp-server/dist/server.js +65 -0
  147. package/packages/mcp-server/dist/server.js.map +1 -1
  148. package/packages/mcp-server/package.json +2 -2
  149. package/packages/mcp-server/src/index.ts +15 -0
  150. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  151. package/packages/mcp-server/src/readers/graph.ts +855 -0
  152. package/packages/mcp-server/src/readers/index.ts +12 -0
  153. package/packages/mcp-server/src/server.ts +83 -0
  154. package/packages/mcp-server/tsconfig.json +1 -0
  155. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  156. package/packages/native/package.json +2 -2
  157. package/packages/native/tsconfig.tsbuildinfo +1 -0
  158. package/packages/pi-agent-core/package.json +1 -1
  159. package/packages/pi-agent-core/tsconfig.json +1 -0
  160. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  161. package/packages/pi-ai/dist/index.d.ts +2 -9
  162. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  163. package/packages/pi-ai/dist/index.js +2 -9
  164. package/packages/pi-ai/dist/index.js.map +1 -1
  165. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  166. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  167. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  168. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  169. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  170. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  172. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  174. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  176. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  177. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  178. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  179. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  180. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  181. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  182. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  183. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  184. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  185. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  186. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  187. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  188. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  189. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  190. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  191. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  192. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  193. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  194. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  195. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  196. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  197. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  198. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  199. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  200. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  201. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  202. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  203. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  204. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  205. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  206. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  207. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  208. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  209. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  210. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  212. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  213. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  214. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  215. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  216. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  217. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  218. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  219. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  220. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  221. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  222. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  223. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  224. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  225. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  226. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  227. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  228. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  229. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  230. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  231. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  232. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  233. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  234. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  235. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  236. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  237. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  238. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  239. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  240. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  241. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  242. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  243. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  244. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  245. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  246. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  247. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  248. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  249. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  250. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  251. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  252. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  253. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  254. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  255. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  256. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  257. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  258. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  259. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  260. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  261. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  262. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  263. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  264. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  265. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  266. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  267. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  268. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  269. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  270. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  271. package/packages/pi-ai/dist/models/index.js +80 -0
  272. package/packages/pi-ai/dist/models/index.js.map +1 -0
  273. package/packages/pi-ai/dist/models.d.ts +1 -36
  274. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  275. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  276. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  277. package/packages/pi-ai/dist/models.js +3 -112
  278. package/packages/pi-ai/dist/models.js.map +1 -1
  279. package/packages/pi-ai/dist/models.test.js +6 -5
  280. package/packages/pi-ai/dist/models.test.js.map +1 -1
  281. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  282. package/packages/pi-ai/dist/utils/overflow.js +12 -0
  283. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  284. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
  285. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
  286. package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
  287. package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
  288. package/packages/pi-ai/package.json +1 -1
  289. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  290. package/packages/pi-ai/src/index.ts +5 -9
  291. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  292. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  293. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  294. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  295. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  296. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  297. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  298. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  299. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  300. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  301. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  302. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  303. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  304. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  305. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  306. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  307. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  308. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  309. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  310. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  311. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  312. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  313. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  314. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  315. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  316. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  317. package/packages/pi-ai/src/models/index.ts +106 -0
  318. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  319. package/packages/pi-ai/src/models.test.ts +6 -5
  320. package/packages/pi-ai/src/models.ts +3 -153
  321. package/packages/pi-ai/src/utils/overflow.ts +14 -1
  322. package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
  323. package/packages/pi-ai/tsconfig.json +1 -0
  324. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  325. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +721 -8
  326. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
  328. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
  330. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
  332. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  334. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  335. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  336. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  337. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  339. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +12 -2
  341. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +65 -28
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -1
  345. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +9 -3
  347. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
  351. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
  352. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +305 -20
  354. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  356. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  357. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  358. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  359. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +13 -0
  360. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +59 -6
  362. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  363. package/packages/pi-coding-agent/package.json +1 -1
  364. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +884 -8
  365. package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
  366. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -0
  367. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  368. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  369. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +78 -32
  370. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
  371. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
  372. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +381 -39
  373. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  374. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +79 -6
  375. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  376. package/packages/pi-coding-agent/tsconfig.json +3 -2
  377. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  378. package/packages/pi-tui/dist/__tests__/tui.test.js +60 -1
  379. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  380. package/packages/pi-tui/dist/tui.d.ts +8 -0
  381. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  382. package/packages/pi-tui/dist/tui.js +32 -3
  383. package/packages/pi-tui/dist/tui.js.map +1 -1
  384. package/packages/pi-tui/package.json +1 -1
  385. package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
  386. package/packages/pi-tui/src/tui.ts +31 -3
  387. package/packages/pi-tui/tsconfig.json +1 -0
  388. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  389. package/packages/rpc-client/package.json +1 -1
  390. package/packages/rpc-client/tsconfig.json +1 -0
  391. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  392. package/pkg/package.json +1 -1
  393. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
  394. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
  395. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  396. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  397. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  398. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  399. package/src/resources/extensions/gsd/auto/phases.ts +213 -13
  400. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  401. package/src/resources/extensions/gsd/auto-dispatch.ts +26 -10
  402. package/src/resources/extensions/gsd/auto-model-selection.ts +151 -16
  403. package/src/resources/extensions/gsd/auto-post-unit.ts +278 -16
  404. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  405. package/src/resources/extensions/gsd/auto-start.ts +30 -6
  406. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
  407. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  408. package/src/resources/extensions/gsd/auto-verification.ts +225 -3
  409. package/src/resources/extensions/gsd/auto.ts +72 -16
  410. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
  411. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -2
  412. package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
  413. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  414. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  415. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  416. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  417. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  418. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  419. package/src/resources/extensions/gsd/commands-handlers.ts +8 -2
  420. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  421. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  422. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  423. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  424. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  425. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  426. package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  427. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  428. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  429. package/src/resources/extensions/gsd/git-service.ts +68 -0
  430. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  431. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  432. package/src/resources/extensions/gsd/guided-flow.ts +32 -0
  433. package/src/resources/extensions/gsd/index.ts +18 -2
  434. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  435. package/src/resources/extensions/gsd/journal.ts +30 -0
  436. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  437. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  438. package/src/resources/extensions/gsd/metrics.ts +26 -0
  439. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  440. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  441. package/src/resources/extensions/gsd/notification-widget.ts +2 -2
  442. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  443. package/src/resources/extensions/gsd/preferences-models.ts +61 -3
  444. package/src/resources/extensions/gsd/preferences-types.ts +44 -0
  445. package/src/resources/extensions/gsd/preferences-validation.ts +130 -2
  446. package/src/resources/extensions/gsd/preferences.ts +28 -0
  447. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  448. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  449. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  450. package/src/resources/extensions/gsd/state.ts +80 -17
  451. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  452. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +9 -5
  453. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  454. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
  455. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  456. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
  457. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  458. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  459. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  460. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  461. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  462. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  463. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  464. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  465. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +142 -0
  466. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  467. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  468. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +42 -0
  469. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
  470. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
  471. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
  472. package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
  473. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  474. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  475. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +137 -1
  476. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  477. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  478. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  479. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  480. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
  481. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  482. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  483. package/src/resources/extensions/gsd/tests/model-isolation.test.ts +91 -2
  484. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  485. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  486. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  487. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  488. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -0
  489. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  490. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  491. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -7
  492. package/src/resources/extensions/gsd/tests/token-profile.test.ts +9 -6
  493. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  494. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  495. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  496. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  497. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  498. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  499. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  500. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  501. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  502. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  503. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +179 -0
  504. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  505. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  506. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  507. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  508. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  509. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  510. package/src/resources/extensions/gsd/types.ts +14 -1
  511. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  512. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  513. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  514. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  515. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  516. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  517. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  518. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  519. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  520. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  521. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  522. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  523. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  524. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  525. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  526. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  527. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  528. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  529. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  530. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  531. package/packages/pi-ai/dist/models.generated.js +0 -14343
  532. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  533. package/packages/pi-ai/src/models.generated.ts +0 -14345
  534. /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → tqdo0yKKYz6fJXQnIgbdx}/_buildManifest.js +0 -0
  535. /package/dist/web/standalone/.next/static/{cGmbVq2su4f9tMpgIkG8u → tqdo0yKKYz6fJXQnIgbdx}/_ssgManifest.js +0 -0
@@ -19,7 +19,7 @@ import { invalidateAllCaches } from "./cache.js";
19
19
  import { rebuildState } from "./doctor.js";
20
20
  import { parseUnitId } from "./unit-id.js";
21
21
  import { closeoutUnit } from "./auto-unit-closeout.js";
22
- import { autoCommitCurrentBranch, } from "./worktree.js";
22
+ import { runTurnGitAction, } from "./git-service.js";
23
23
  import { verifyExpectedArtifact, resolveExpectedArtifactPath, writeBlockerPlaceholder, diagnoseExpectedArtifact, } from "./auto-recovery.js";
24
24
  import { regenerateIfMissing } from "./workflow-projections.js";
25
25
  import { syncStateToProjectRoot } from "./auto-worktree.js";
@@ -42,6 +42,9 @@ import { getSliceTasks } from "./gsd-db.js";
42
42
  import { runPreExecutionChecks } from "./pre-execution-checks.js";
43
43
  import { writePreExecutionEvidence } from "./verification-evidence.js";
44
44
  import { ensureCodebaseMapFresh } from "./codebase-generator.js";
45
+ import { resolveUokFlags } from "./uok/flags.js";
46
+ import { UokGateRunner } from "./uok/gate-runner.js";
47
+ import { writeTurnGitTransaction } from "./uok/gitops.js";
45
48
  /** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
46
49
  const MAX_VERIFICATION_RETRIES = 3;
47
50
  /** Enqueue a sidecar item (hook, triage, or quick-task) for the main loop to
@@ -67,9 +70,11 @@ const LIFECYCLE_ONLY_UNITS = new Set([
67
70
  "replan-slice", "complete-slice", "run-uat",
68
71
  "reassess-roadmap", "rewrite-docs",
69
72
  ]);
73
+ import { describeNextUnit, } from "./auto-dashboard.js";
70
74
  import { existsSync, unlinkSync } from "node:fs";
71
75
  import { join } from "node:path";
72
76
  import { _resetHasChangesCache } from "./native-git-bridge.js";
77
+ import { autoCommitCurrentBranch } from "./worktree.js";
73
78
  /**
74
79
  * Detect summary files written directly to disk without the LLM calling
75
80
  * the completion tool. A "rogue" file is one that exists on disk but has
@@ -179,6 +184,66 @@ export function detectRogueFileWrites(unitType, unitId, basePath) {
179
184
  }
180
185
  return rogues;
181
186
  }
187
+ export const STEP_COMPLETE_FALLBACK_MESSAGE = "Step complete. Run /clear, then /gsd to continue (or /gsd auto to run continuously).";
188
+ export function buildStepCompleteMessage(nextState) {
189
+ if (nextState.phase === "complete") {
190
+ return "Step complete — milestone finished. Run /gsd status to review, or start the next milestone.";
191
+ }
192
+ const next = describeNextUnit(nextState);
193
+ return `Step complete. Next: ${next.label}\n`
194
+ + `Run /clear, then /gsd to continue (or /gsd auto to run continuously).`;
195
+ }
196
+ export async function autoCommitUnit(basePath, unitType, unitId, ctx) {
197
+ try {
198
+ let taskContext;
199
+ if (unitType === "execute-task") {
200
+ const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
201
+ if (mid && sid && tid) {
202
+ const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
203
+ if (summaryPath) {
204
+ try {
205
+ const summaryContent = await loadFile(summaryPath);
206
+ if (summaryContent) {
207
+ const summary = parseSummary(summaryContent);
208
+ let ghIssueNumber;
209
+ try {
210
+ const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
211
+ ghIssueNumber = getTaskIssueNumberForCommit(basePath, mid, sid, tid) ?? undefined;
212
+ }
213
+ catch (err) {
214
+ logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
215
+ }
216
+ taskContext = {
217
+ taskId: `${sid}/${tid}`,
218
+ taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
219
+ oneLiner: summary.oneLiner || undefined,
220
+ keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
221
+ issueNumber: ghIssueNumber,
222
+ };
223
+ }
224
+ }
225
+ catch (e) {
226
+ debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
227
+ }
228
+ }
229
+ }
230
+ }
231
+ _resetHasChangesCache();
232
+ if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
233
+ return null;
234
+ }
235
+ const commitMsg = autoCommitCurrentBranch(basePath, unitType, unitId, taskContext);
236
+ if (commitMsg) {
237
+ ctx?.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
238
+ }
239
+ return commitMsg;
240
+ }
241
+ catch (e) {
242
+ debugLog("postUnit", { phase: "auto-commit", error: String(e) });
243
+ ctx?.ui.notify(`Auto-commit failed: ${String(e).split("\n")[0]}`, "warning");
244
+ return null;
245
+ }
246
+ }
182
247
  /**
183
248
  * Pre-verification processing: parallel worker signal check, cache invalidation,
184
249
  * auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
@@ -211,12 +276,19 @@ export async function postUnitPreVerification(pctx, opts) {
211
276
  if (!opts?.skipSettleDelay) {
212
277
  await new Promise(r => setTimeout(r, 100));
213
278
  }
214
- // Auto-commit
279
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
280
+ const uokFlags = resolveUokFlags(prefs);
281
+ // Turn-level git action (commit | snapshot | status-only)
215
282
  if (s.currentUnit) {
216
283
  const unit = s.currentUnit;
284
+ const turnAction = uokFlags.gitops ? uokFlags.gitopsTurnAction : "commit";
285
+ const traceId = s.currentTraceId ?? `turn:${unit.startedAt}`;
286
+ const turnId = s.currentTurnId ?? `${unit.type}/${unit.id}/${unit.startedAt}`;
287
+ s.lastGitActionFailure = null;
288
+ s.lastGitActionStatus = null;
217
289
  try {
218
290
  let taskContext;
219
- if (s.currentUnit.type === "execute-task") {
291
+ if (turnAction === "commit" && s.currentUnit.type === "execute-task") {
220
292
  const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
221
293
  if (mid && sid && tid) {
222
294
  const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
@@ -256,19 +328,101 @@ export async function postUnitPreVerification(pctx, opts) {
256
328
  // code files only in the working tree where they are destroyed by
257
329
  // `git worktree remove --force` during teardown.
258
330
  _resetHasChangesCache();
259
- // Skip auto-commit for lifecycle-only units (#2553) — they only touch
260
- // `.gsd/` internal state files. Those files are picked up by the next
261
- // actual task commit via smartStage().
262
- if (!LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type)) {
263
- const commitMsg = autoCommitCurrentBranch(s.basePath, s.currentUnit.type, s.currentUnit.id, taskContext);
264
- if (commitMsg) {
265
- ctx.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
331
+ const skipLifecycleCommit = turnAction === "commit" && LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type);
332
+ if (skipLifecycleCommit) {
333
+ debugLog("postUnit", {
334
+ phase: "git-action-skipped",
335
+ reason: "lifecycle-only-unit",
336
+ unitType: s.currentUnit.type,
337
+ unitId: s.currentUnit.id,
338
+ });
339
+ }
340
+ else {
341
+ const gitResult = runTurnGitAction({
342
+ basePath: s.basePath,
343
+ action: turnAction,
344
+ unitType: s.currentUnit.type,
345
+ unitId: s.currentUnit.id,
346
+ taskContext,
347
+ });
348
+ if (uokFlags.gitops) {
349
+ writeTurnGitTransaction({
350
+ basePath: s.basePath,
351
+ traceId,
352
+ turnId,
353
+ unitType: unit.type,
354
+ unitId: unit.id,
355
+ stage: "publish",
356
+ action: turnAction,
357
+ push: uokFlags.gitopsTurnPush,
358
+ status: gitResult.status,
359
+ error: gitResult.error,
360
+ metadata: {
361
+ dirty: gitResult.dirty,
362
+ commitMessage: gitResult.commitMessage,
363
+ snapshotLabel: gitResult.snapshotLabel,
364
+ },
365
+ });
366
+ }
367
+ if (gitResult.status === "failed") {
368
+ s.lastGitActionFailure = gitResult.error ?? `git ${turnAction} failed`;
369
+ s.lastGitActionStatus = "failed";
370
+ if (uokFlags.gitops && uokFlags.gates) {
371
+ const parsed = parseUnitId(unit.id);
372
+ const gateRunner = new UokGateRunner();
373
+ gateRunner.register({
374
+ id: "closeout-git-action",
375
+ type: "closeout",
376
+ execute: async () => ({
377
+ outcome: "fail",
378
+ failureClass: "git",
379
+ rationale: `turn git action "${turnAction}" failed`,
380
+ findings: gitResult.error ?? "unknown git failure",
381
+ }),
382
+ });
383
+ await gateRunner.run("closeout-git-action", {
384
+ basePath: s.basePath,
385
+ traceId,
386
+ turnId,
387
+ milestoneId: parsed.milestone ?? undefined,
388
+ sliceId: parsed.slice ?? undefined,
389
+ taskId: parsed.task ?? undefined,
390
+ unitType: unit.type,
391
+ unitId: unit.id,
392
+ });
393
+ }
394
+ const failureMsg = `Git ${turnAction} failed: ${(gitResult.error ?? "unknown error").split("\n")[0]}`;
395
+ if (uokFlags.gitops) {
396
+ ctx.ui.notify(failureMsg, "error");
397
+ await pauseAuto(ctx, pi);
398
+ return "dispatched";
399
+ }
400
+ ctx.ui.notify(failureMsg, "warning");
401
+ debugLog("postUnit", {
402
+ phase: "git-action-failed-nonblocking",
403
+ action: turnAction,
404
+ error: gitResult.error ?? "unknown error",
405
+ });
406
+ }
407
+ s.lastGitActionStatus = "ok";
408
+ if (turnAction === "commit" && gitResult.commitMessage) {
409
+ ctx.ui.notify(`Committed: ${gitResult.commitMessage.split("\n")[0]}`, "info");
410
+ }
411
+ else if (turnAction === "snapshot" && gitResult.snapshotLabel) {
412
+ ctx.ui.notify(`Snapshot recorded: ${gitResult.snapshotLabel}`, "info");
266
413
  }
267
414
  }
268
415
  }
269
416
  catch (e) {
270
- debugLog("postUnit", { phase: "auto-commit", error: String(e) });
271
- ctx.ui.notify(`Auto-commit failed: ${String(e).split("\n")[0]}`, "warning");
417
+ const message = e instanceof Error ? e.message : String(e);
418
+ s.lastGitActionFailure = message;
419
+ s.lastGitActionStatus = "failed";
420
+ debugLog("postUnit", { phase: "git-action", error: message, action: turnAction });
421
+ ctx.ui.notify(`Git ${turnAction} failed: ${message.split("\n")[0]}`, uokFlags.gitops ? "error" : "warning");
422
+ if (uokFlags.gitops) {
423
+ await pauseAuto(ctx, pi);
424
+ return "dispatched";
425
+ }
272
426
  }
273
427
  // GitHub sync (non-blocking, opt-in)
274
428
  await runSafely("postUnit", "github-sync", async () => {
@@ -509,6 +663,26 @@ export async function postUnitPreVerification(pctx, opts) {
509
663
  const attempt = (s.verificationRetryCount.get(retryKey) ?? 0) + 1;
510
664
  s.verificationRetryCount.set(retryKey, attempt);
511
665
  if (attempt > MAX_VERIFICATION_RETRIES) {
666
+ // #4175: For complete-milestone, a blocker placeholder is harmful —
667
+ // the stub SUMMARY has no recovery value (milestone is terminal),
668
+ // it does not update DB status (so deriveState never advances),
669
+ // and it fools stopAuto's presence check into merging a milestone
670
+ // that was never legitimately completed. Pause auto-mode with a
671
+ // clear single failure signal and preserve the worktree branch.
672
+ if (s.currentUnit.type === "complete-milestone") {
673
+ debugLog("postUnit", {
674
+ phase: "artifact-verify-pause-complete-milestone",
675
+ unitType: s.currentUnit.type,
676
+ unitId: s.currentUnit.id,
677
+ attempt,
678
+ maxRetries: MAX_VERIFICATION_RETRIES,
679
+ });
680
+ s.verificationRetryCount.delete(retryKey);
681
+ s.pendingVerificationRetry = null;
682
+ ctx.ui.notify(`Milestone ${s.currentUnit.id} verification failed after ${MAX_VERIFICATION_RETRIES} retries — worktree branch preserved. Re-run /gsd auto once blockers are resolved.`, "error");
683
+ await pauseAuto(ctx, pi);
684
+ return "dispatched";
685
+ }
512
686
  // Retries exhausted — write a blocker placeholder so the pipeline
513
687
  // can advance past this stuck unit (#2653).
514
688
  debugLog("postUnit", {
@@ -684,11 +858,13 @@ export async function postUnitPostVerification(pctx) {
684
858
  // ── Pre-execution checks (after plan-slice completes) ──
685
859
  if (s.currentUnit &&
686
860
  s.currentUnit.type === "plan-slice") {
861
+ const currentUnit = s.currentUnit;
687
862
  let preExecPauseNeeded = false;
688
863
  await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
864
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
865
+ const uokFlags = resolveUokFlags(prefs);
689
866
  try {
690
867
  // Check preferences — respect enhanced_verification and enhanced_verification_pre
691
- const prefs = loadEffectiveGSDPreferences()?.preferences;
692
868
  const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
693
869
  const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
694
870
  if (!enhancedEnabled || !preEnabled) {
@@ -700,7 +876,7 @@ export async function postUnitPostVerification(pctx) {
700
876
  return;
701
877
  }
702
878
  // Parse the unit ID to get milestone/slice IDs
703
- const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
879
+ const { milestone: mid, slice: sid } = parseUnitId(currentUnit.id);
704
880
  if (!mid || !sid) {
705
881
  debugLog("postUnitPostVerification", {
706
882
  phase: "pre-execution-checks",
@@ -719,6 +895,7 @@ export async function postUnitPostVerification(pctx) {
719
895
  });
720
896
  return;
721
897
  }
898
+ const strictMode = prefs?.enhanced_verification_strict === true;
722
899
  // Run pre-execution checks
723
900
  const result = await runPreExecutionChecks(tasks, s.basePath);
724
901
  // Log summary to stderr in existing verification output format
@@ -734,6 +911,35 @@ export async function postUnitPostVerification(pctx) {
734
911
  if (slicePath) {
735
912
  writePreExecutionEvidence(result, slicePath, mid, sid);
736
913
  }
914
+ if (uokFlags.gates) {
915
+ const failedChecks = result.checks
916
+ .filter((check) => !check.passed)
917
+ .map((check) => `[${check.category}] ${check.target}: ${check.message}`);
918
+ const warnEscalated = result.status === "warn" && strictMode;
919
+ const blockingFailure = result.status === "fail" || warnEscalated;
920
+ const gateRunner = new UokGateRunner();
921
+ gateRunner.register({
922
+ id: "pre-execution-checks",
923
+ type: "input",
924
+ execute: async () => ({
925
+ outcome: blockingFailure ? "fail" : "pass",
926
+ failureClass: result.status === "fail" ? "input" : warnEscalated ? "policy" : "none",
927
+ rationale: blockingFailure
928
+ ? `pre-execution checks ${result.status}${warnEscalated ? " (strict)" : ""}`
929
+ : "pre-execution checks passed",
930
+ findings: failedChecks.join("\n"),
931
+ }),
932
+ });
933
+ await gateRunner.run("pre-execution-checks", {
934
+ basePath: s.basePath,
935
+ traceId: `pre-execution:${currentUnit.id}`,
936
+ turnId: currentUnit.id,
937
+ milestoneId: mid,
938
+ sliceId: sid,
939
+ unitType: currentUnit.type,
940
+ unitId: currentUnit.id,
941
+ });
942
+ }
737
943
  // Notify UI
738
944
  if (result.status === "fail") {
739
945
  const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
@@ -764,6 +970,29 @@ export async function postUnitPostVerification(pctx) {
764
970
  });
765
971
  logError("engine", `gsd-pre-exec: Pre-execution checks threw an error: ${errorMessage}`);
766
972
  ctx.ui.notify(`Pre-execution checks error: ${errorMessage} — pausing for human review`, "error");
973
+ if (uokFlags.gates && s.currentUnit) {
974
+ const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
975
+ const gateRunner = new UokGateRunner();
976
+ gateRunner.register({
977
+ id: "pre-execution-checks",
978
+ type: "input",
979
+ execute: async () => ({
980
+ outcome: "manual-attention",
981
+ failureClass: "manual-attention",
982
+ rationale: "pre-execution checks threw before completion",
983
+ findings: errorMessage,
984
+ }),
985
+ });
986
+ await gateRunner.run("pre-execution-checks", {
987
+ basePath: s.basePath,
988
+ traceId: `pre-execution:${s.currentUnit.id}`,
989
+ turnId: s.currentUnit.id,
990
+ milestoneId: mid ?? undefined,
991
+ sliceId: sid ?? undefined,
992
+ unitType: s.currentUnit.type,
993
+ unitId: s.currentUnit.id,
994
+ });
995
+ }
767
996
  preExecPauseNeeded = true;
768
997
  }
769
998
  });
@@ -836,8 +1065,18 @@ export async function postUnitPostVerification(pctx) {
836
1065
  debugLog("postUnit", { phase: "quick-task-dispatch", error: String(e) });
837
1066
  }
838
1067
  }
839
- // Step mode → show wizard instead of dispatch
1068
+ // Step mode → show wizard instead of dispatch.
1069
+ // Without this notify(), /gsd in step mode finishes a unit and silently
1070
+ // exits the loop, leaving the user with no hint to /clear and /gsd again.
840
1071
  if (s.stepMode) {
1072
+ try {
1073
+ const nextState = await deriveState(s.basePath);
1074
+ ctx.ui.notify(buildStepCompleteMessage(nextState), "info");
1075
+ }
1076
+ catch (e) {
1077
+ debugLog("postUnit", { phase: "step-wizard-notify", error: String(e) });
1078
+ ctx.ui.notify(STEP_COMPLETE_FALLBACK_MESSAGE, "info");
1079
+ }
841
1080
  return "step-wizard";
842
1081
  }
843
1082
  return "continue";
@@ -20,6 +20,7 @@ import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
20
20
  import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
21
21
  import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
22
22
  import { logWarning } from "./workflow-logger.js";
23
+ import { inlineGraphSubgraph } from "./graph-context.js";
23
24
  // ─── Preamble Cap ─────────────────────────────────────────────────────────────
24
25
  const MAX_PREAMBLE_CHARS = 30_000;
25
26
  function capPreamble(preamble) {
@@ -1040,6 +1041,10 @@ export async function buildResearchSlicePrompt(mid, _midTitle, sid, sTitle, base
1040
1041
  const knowledgeInlineRS = await inlineKnowledgeScoped(base, keywords);
1041
1042
  if (knowledgeInlineRS)
1042
1043
  inlined.push(knowledgeInlineRS);
1044
+ // Knowledge graph: subgraph for this slice (graceful — skipped if no graph.json)
1045
+ const graphBlockRS = await inlineGraphSubgraph(base, `${sid} ${sTitle}`, { budget: 3000 });
1046
+ if (graphBlockRS)
1047
+ inlined.push(graphBlockRS);
1043
1048
  inlined.push(inlineTemplate("research", "Research"));
1044
1049
  const depContent = await inlineDependencySummaries(mid, sid, base);
1045
1050
  const activeOverrides = await loadActiveOverrides(base);
@@ -1111,6 +1116,10 @@ export async function buildPlanSlicePrompt(mid, _midTitle, sid, sTitle, base, le
1111
1116
  const knowledgeInlinePS = await inlineKnowledgeScoped(base, keywordsPS);
1112
1117
  if (knowledgeInlinePS)
1113
1118
  inlined.push(knowledgeInlinePS);
1119
+ // Knowledge graph: subgraph for this slice (graceful — skipped if no graph.json)
1120
+ const graphBlockPS = await inlineGraphSubgraph(base, `${sid} ${sTitle}`, { budget: 3000 });
1121
+ if (graphBlockPS)
1122
+ inlined.push(graphBlockPS);
1114
1123
  inlined.push(inlineTemplate("plan", "Slice Plan"));
1115
1124
  if (inlineLevel === "full") {
1116
1125
  inlined.push(inlineTemplate("task-plan", "Task Plan"));
@@ -1194,12 +1203,15 @@ export async function buildExecuteTaskPrompt(mid, sid, sTitle, tid, tTitle, base
1194
1203
  : null;
1195
1204
  // Only include if it has content (not a "not found" result)
1196
1205
  const knowledgeContent = knowledgeInlineET && !knowledgeInlineET.includes("not found") ? knowledgeInlineET : null;
1206
+ // Knowledge graph: tight subgraph for this task (graceful — skipped if no graph.json)
1207
+ const graphBlockET = await inlineGraphSubgraph(base, `${tid} ${tTitle}`, { budget: 2000 });
1197
1208
  const inlinedTemplates = inlineLevel === "minimal"
1198
1209
  ? inlineTemplate("task-summary", "Task Summary")
1199
1210
  : [
1200
1211
  inlineTemplate("task-summary", "Task Summary"),
1201
1212
  inlineTemplate("decisions", "Decisions"),
1202
1213
  ...(knowledgeContent ? [knowledgeContent] : []),
1214
+ ...(graphBlockET ? [graphBlockET] : []),
1203
1215
  ].join("\n\n---\n\n");
1204
1216
  const taskSummaryPath = join(base, `${relSlicePath(base, mid, sid)}/tasks/${tid}-SUMMARY.md`);
1205
1217
  const activeOverrides = await loadActiveOverrides(base);
@@ -38,7 +38,7 @@ import { existsSync, mkdirSync, readdirSync, rmSync, statSync, unlinkSync, } fro
38
38
  import { join } from "node:path";
39
39
  import { sep as pathSep } from "node:path";
40
40
  import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
41
- import { resolveDefaultSessionModel, resolveDynamicRoutingConfig } from "./preferences-models.js";
41
+ import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
42
42
  import { getSessionModelOverride } from "./session-model-override.js";
43
43
  /**
44
44
  * Bootstrap a fresh auto-mode session. Handles everything from git init
@@ -195,8 +195,18 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
195
195
  //
196
196
  // This preserves #3517 defaults while honoring explicit runtime model
197
197
  // selection for subsequent /gsd runs in the same session.
198
+ //
199
+ // Exception (#4122): when the session provider is a custom provider declared
200
+ // in ~/.gsd/agent/models.json (Ollama, vLLM, OpenAI-compatible proxy, etc.),
201
+ // PREFERENCES.md is skipped entirely. PREFERENCES.md cannot reference custom
202
+ // providers, so honoring it would silently reroute auto-mode to a built-in
203
+ // provider the user is not logged into and surface as "Not logged in · Please
204
+ // run /login" before pausing and resetting to claude-code/claude-sonnet-4-6.
198
205
  const manualSessionOverride = getSessionModelOverride(ctx.sessionManager.getSessionId());
199
- const preferredModel = resolveDefaultSessionModel(ctx.model?.provider);
206
+ const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
207
+ const preferredModel = sessionProviderIsCustom
208
+ ? null
209
+ : resolveDefaultSessionModel(ctx.model?.provider);
200
210
  // Validate the preferred model against the live registry + provider auth so
201
211
  // an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
202
212
  // start-model snapshot. Without this, every subsequent unit would try to
@@ -622,6 +632,9 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
622
632
  }
623
633
  ctx.ui.setStatus("gsd-auto", s.stepMode ? "next" : "auto");
624
634
  ctx.ui.setFooter(hideFooter);
635
+ // Hide gsd-health during AUTO — gsd-progress is the single source of truth
636
+ // for last-commit / cost / health signal while auto is running.
637
+ ctx.ui.setWidget("gsd-health", undefined);
625
638
  const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
626
639
  const pendingCount = (state.registry ?? []).filter((m) => m.status !== "complete" && m.status !== "parked").length;
627
640
  const scopeMsg = pendingCount > 1
@@ -636,12 +649,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
636
649
  const startModelLabel = s.autoModeStartModel
637
650
  ? `${s.autoModeStartModel.provider}/${s.autoModeStartModel.id}`
638
651
  : ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : "default";
639
- // Flat-rate providers (e.g. GitHub Copilot, claude-code) suppress routing
640
- // at dispatch time (#3453) reflect that in the banner.
641
- const { isFlatRateProvider } = await import("./auto-model-selection.js");
652
+ // Flat-rate providers (e.g. GitHub Copilot, claude-code, user-declared
653
+ // subscription proxies, externalCli CLIs) suppress routing at dispatch
654
+ // time (#3453) reflect that in the banner. Thread the same
655
+ // FlatRateContext used by selectAndApplyModel so user-declared
656
+ // flat-rate providers and externalCli auto-detection are respected.
657
+ const { isFlatRateProvider, buildFlatRateContext } = await import("./auto-model-selection.js");
658
+ const bannerPrefs = loadEffectiveGSDPreferences()?.preferences;
642
659
  const effectiveProvider = s.autoModeStartModel?.provider ?? ctx.model?.provider;
643
660
  const effectivelyEnabled = routingConfig.enabled
644
- && !(effectiveProvider && isFlatRateProvider(effectiveProvider));
661
+ && !(effectiveProvider && isFlatRateProvider(effectiveProvider, buildFlatRateContext(effectiveProvider, ctx, bannerPrefs)));
645
662
  // The actual ceiling may come from tier_models.heavy, not the start model.
646
663
  const effectiveCeiling = (routingConfig.enabled && routingConfig.tier_models?.heavy)
647
664
  ? routingConfig.tier_models.heavy
@@ -156,6 +156,19 @@ export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rct
156
156
  ctx.ui.notify(`${reason === "idle" ? "Idle" : "Timeout"} recovery: steering ${unitType} ${unitId} to produce ${expected} (attempt ${attemptNumber}, session ${recoveryAttempts + 1}/${maxRecoveryAttempts}).`, "warning");
157
157
  return "recovered";
158
158
  }
159
+ // #4175: For complete-milestone, never write a blocker placeholder — a stub
160
+ // SUMMARY has no recovery value (milestone is terminal), it does not update
161
+ // DB status, and downstream merge paths can treat the stub as a legitimate
162
+ // completion signal. Pause instead so the worktree branch is preserved.
163
+ if (unitType === "complete-milestone") {
164
+ writeUnitRuntimeRecord(basePath, unitType, unitId, currentUnitStartedAt, {
165
+ phase: "paused",
166
+ recoveryAttempts: recoveryAttempts + 1,
167
+ lastRecoveryReason: reason,
168
+ });
169
+ ctx.ui.notify(`Milestone ${unitId} ${reason}-recovery exhausted ${maxRecoveryAttempts} attempt(s) — worktree branch preserved. Re-run /gsd auto once blockers are resolved.`, "error");
170
+ return "paused";
171
+ }
159
172
  // Retries exhausted — write a blocker placeholder and advance the pipeline
160
173
  // instead of silently stalling.
161
174
  const placeholder = writeBlockerPlaceholder(unitType, unitId, basePath, `${reason} recovery exhausted ${maxRecoveryAttempts} attempts without producing the artifact.`);
@@ -6,6 +6,7 @@
6
6
  import { snapshotUnitMetrics } from "./metrics.js";
7
7
  import { saveActivityLog } from "./activity-log.js";
8
8
  import { logWarning } from "./workflow-logger.js";
9
+ import { writeTurnGitTransaction } from "./uok/gitops.js";
9
10
  /**
10
11
  * Snapshot metrics, save activity log, and fire-and-forget memory extraction
11
12
  * for a completed unit. Returns the activity log file path (if any).
@@ -28,5 +29,22 @@ export async function closeoutUnit(ctx, basePath, unitType, unitId, startedAt, o
28
29
  logWarning("engine", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
29
30
  }
30
31
  }
32
+ if (opts?.traceId && opts.turnId && opts.gitAction && opts.gitStatus) {
33
+ writeTurnGitTransaction({
34
+ basePath,
35
+ traceId: opts.traceId,
36
+ turnId: opts.turnId,
37
+ unitType,
38
+ unitId,
39
+ stage: "record",
40
+ action: opts.gitAction,
41
+ push: opts.gitPush === true,
42
+ status: opts.gitStatus,
43
+ error: opts.gitError,
44
+ metadata: {
45
+ activityFile,
46
+ },
47
+ });
48
+ }
31
49
  return activityFile ?? undefined;
32
50
  }