gsd-pi 2.74.0-dev.2b524c3 → 2.74.0-dev.658744a

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 (506) hide show
  1. package/dist/cli.js +85 -0
  2. package/dist/headless-query.js +4 -1
  3. package/dist/help-text.js +23 -0
  4. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  5. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  6. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  7. package/dist/resources/extensions/gsd/auto/phases.js +209 -10
  8. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
  10. package/dist/resources/extensions/gsd/auto-model-selection.js +54 -8
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +220 -17
  12. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
  14. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  15. package/dist/resources/extensions/gsd/auto-verification.js +100 -2
  16. package/dist/resources/extensions/gsd/auto-worktree.js +2 -0
  17. package/dist/resources/extensions/gsd/auto.js +36 -4
  18. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -3
  19. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
  20. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
  21. package/dist/resources/extensions/gsd/cache.js +16 -5
  22. package/dist/resources/extensions/gsd/commands/catalog.js +31 -1
  23. package/dist/resources/extensions/gsd/commands/handlers/core.js +5 -1
  24. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  26. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  27. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  28. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  29. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  30. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  31. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  32. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +51 -4
  33. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  34. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  35. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +16 -1
  37. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  38. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  39. package/dist/resources/extensions/gsd/git-service.js +49 -1
  40. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  41. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  42. package/dist/resources/extensions/gsd/guided-flow.js +31 -6
  43. package/dist/resources/extensions/gsd/index.js +15 -2
  44. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  45. package/dist/resources/extensions/gsd/journal.js +27 -0
  46. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  47. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  48. package/dist/resources/extensions/gsd/metrics.js +19 -0
  49. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  50. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  51. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  52. package/dist/resources/extensions/gsd/preferences-models.js +20 -3
  53. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  54. package/dist/resources/extensions/gsd/preferences-validation.js +118 -2
  55. package/dist/resources/extensions/gsd/preferences.js +31 -0
  56. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  57. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  58. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  59. package/dist/resources/extensions/gsd/state.js +5 -1
  60. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  61. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  62. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  63. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  64. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  65. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  66. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  67. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  68. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  69. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  70. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  71. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  72. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  73. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  74. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  75. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  76. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  77. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  78. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  79. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  80. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  81. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  82. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  83. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  86. package/dist/web/standalone/.next/build-manifest.json +2 -2
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  117. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/package.json +3 -2
  124. package/packages/daemon/package.json +2 -2
  125. package/packages/mcp-server/dist/index.d.ts +3 -0
  126. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  127. package/packages/mcp-server/dist/index.js +3 -0
  128. package/packages/mcp-server/dist/index.js.map +1 -1
  129. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  130. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  131. package/packages/mcp-server/dist/readers/graph.js +655 -0
  132. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  133. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  134. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  135. package/packages/mcp-server/dist/readers/index.js +1 -0
  136. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  137. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  138. package/packages/mcp-server/dist/server.js +65 -0
  139. package/packages/mcp-server/dist/server.js.map +1 -1
  140. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  141. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  142. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  143. package/packages/mcp-server/package.json +2 -2
  144. package/packages/mcp-server/src/index.ts +15 -0
  145. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  146. package/packages/mcp-server/src/readers/graph.ts +855 -0
  147. package/packages/mcp-server/src/readers/index.ts +12 -0
  148. package/packages/mcp-server/src/server.ts +83 -0
  149. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  150. package/packages/mcp-server/tsconfig.json +1 -0
  151. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  152. package/packages/native/package.json +2 -2
  153. package/packages/native/tsconfig.tsbuildinfo +1 -0
  154. package/packages/pi-agent-core/package.json +1 -1
  155. package/packages/pi-agent-core/tsconfig.json +1 -0
  156. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  157. package/packages/pi-ai/dist/index.d.ts +1 -9
  158. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  159. package/packages/pi-ai/dist/index.js +1 -9
  160. package/packages/pi-ai/dist/index.js.map +1 -1
  161. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  162. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  163. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  164. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  165. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  166. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  167. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  168. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  169. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  170. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  172. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  174. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  176. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  177. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  178. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  179. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  180. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  181. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  182. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  183. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  184. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  185. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  186. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  187. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  188. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  189. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  190. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  191. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  192. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  193. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  194. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  195. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  196. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  197. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  198. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  199. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  200. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  201. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  202. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  203. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  204. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  205. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  206. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  207. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  208. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  209. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  210. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  212. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  213. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  214. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  215. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  216. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  217. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  218. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  219. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  220. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  221. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  222. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  223. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  224. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  225. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  226. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  227. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  228. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  229. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  230. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  231. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  232. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  233. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  234. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  235. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  236. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  237. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  238. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  239. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  240. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  241. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  242. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  243. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  244. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  245. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  246. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  247. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  248. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  249. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  250. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  251. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  252. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  253. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  254. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  255. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  256. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  257. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  258. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  259. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  260. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  261. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  262. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  263. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  264. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  265. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  266. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  267. package/packages/pi-ai/dist/models/index.js +80 -0
  268. package/packages/pi-ai/dist/models/index.js.map +1 -0
  269. package/packages/pi-ai/dist/models.d.ts +1 -36
  270. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  271. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  272. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  273. package/packages/pi-ai/dist/models.js +3 -112
  274. package/packages/pi-ai/dist/models.js.map +1 -1
  275. package/packages/pi-ai/dist/models.test.js +6 -5
  276. package/packages/pi-ai/dist/models.test.js.map +1 -1
  277. package/packages/pi-ai/package.json +1 -1
  278. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  279. package/packages/pi-ai/src/index.ts +1 -9
  280. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  281. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  282. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  283. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  284. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  285. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  286. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  287. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  288. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  289. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  290. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  291. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  292. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  293. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  294. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  295. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  296. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  297. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  298. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  299. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  300. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  301. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  302. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  303. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  304. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  305. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  306. package/packages/pi-ai/src/models/index.ts +106 -0
  307. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  308. package/packages/pi-ai/src/models.test.ts +6 -5
  309. package/packages/pi-ai/src/models.ts +3 -153
  310. package/packages/pi-ai/tsconfig.json +1 -0
  311. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  312. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  314. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
  316. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  318. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  319. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  320. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  321. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  323. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  337. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  340. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
  343. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  346. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  347. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  348. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  349. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  350. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  351. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  352. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  353. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
  354. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  355. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  356. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  357. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  358. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  360. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  361. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
  362. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  363. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  364. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  365. package/packages/pi-coding-agent/tsconfig.json +3 -2
  366. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  367. package/packages/pi-tui/package.json +1 -1
  368. package/packages/pi-tui/tsconfig.json +1 -0
  369. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  370. package/packages/rpc-client/package.json +1 -1
  371. package/packages/rpc-client/tsconfig.json +1 -0
  372. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  373. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  374. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  375. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  376. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  377. package/src/resources/extensions/gsd/auto/phases.ts +261 -10
  378. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  379. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
  380. package/src/resources/extensions/gsd/auto-model-selection.ts +69 -8
  381. package/src/resources/extensions/gsd/auto-post-unit.ts +238 -18
  382. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  383. package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
  384. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  385. package/src/resources/extensions/gsd/auto-verification.ts +129 -2
  386. package/src/resources/extensions/gsd/auto-worktree.ts +1 -0
  387. package/src/resources/extensions/gsd/auto.ts +41 -2
  388. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +5 -3
  389. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
  390. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
  391. package/src/resources/extensions/gsd/cache.ts +16 -5
  392. package/src/resources/extensions/gsd/commands/catalog.ts +31 -1
  393. package/src/resources/extensions/gsd/commands/handlers/core.ts +5 -1
  394. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  395. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  396. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  397. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  398. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  399. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  400. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  401. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  402. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +58 -4
  403. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  404. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  405. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  406. package/src/resources/extensions/gsd/docs/preferences-reference.md +16 -1
  407. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  408. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  409. package/src/resources/extensions/gsd/git-service.ts +68 -0
  410. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  411. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  412. package/src/resources/extensions/gsd/guided-flow.ts +36 -2
  413. package/src/resources/extensions/gsd/index.ts +18 -2
  414. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  415. package/src/resources/extensions/gsd/journal.ts +30 -0
  416. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  417. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  418. package/src/resources/extensions/gsd/metrics.ts +26 -0
  419. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  420. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  421. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  422. package/src/resources/extensions/gsd/preferences-models.ts +20 -3
  423. package/src/resources/extensions/gsd/preferences-types.ts +38 -0
  424. package/src/resources/extensions/gsd/preferences-validation.ts +117 -2
  425. package/src/resources/extensions/gsd/preferences.ts +34 -0
  426. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  427. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  428. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  429. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  430. package/src/resources/extensions/gsd/state.ts +9 -2
  431. package/src/resources/extensions/gsd/templates/PREFERENCES.md +19 -0
  432. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  433. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
  434. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  436. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  437. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +117 -0
  438. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  439. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  440. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  441. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  442. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  443. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  444. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  445. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  446. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  447. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  448. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  449. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  450. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  451. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  452. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  453. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +71 -4
  454. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  455. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  456. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  457. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  458. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  459. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  460. package/src/resources/extensions/gsd/tests/preferences.test.ts +145 -0
  461. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +57 -2
  462. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  463. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  464. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  465. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  466. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  467. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  468. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  469. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  470. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  471. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  472. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  473. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  474. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  475. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  476. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  477. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  478. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  479. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  480. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  481. package/src/resources/extensions/gsd/types.ts +14 -1
  482. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  483. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  484. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  485. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  486. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  487. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  488. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  489. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  490. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  491. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  492. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  493. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  494. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  495. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  496. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  497. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  498. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  499. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  500. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  501. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  502. package/packages/pi-ai/dist/models.generated.js +0 -14343
  503. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  504. package/packages/pi-ai/src/models.generated.ts +0 -14345
  505. /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → Es_JWCfFZjIvYZShmjyye}/_buildManifest.js +0 -0
  506. /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → Es_JWCfFZjIvYZShmjyye}/_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
@@ -71,6 +74,7 @@ import { describeNextUnit, } from "./auto-dashboard.js";
71
74
  import { existsSync, unlinkSync } from "node:fs";
72
75
  import { join } from "node:path";
73
76
  import { _resetHasChangesCache } from "./native-git-bridge.js";
77
+ import { autoCommitCurrentBranch } from "./worktree.js";
74
78
  /**
75
79
  * Detect summary files written directly to disk without the LLM calling
76
80
  * the completion tool. A "rogue" file is one that exists on disk but has
@@ -189,6 +193,57 @@ export function buildStepCompleteMessage(nextState) {
189
193
  return `Step complete. Next: ${next.label}\n`
190
194
  + `Run /clear, then /gsd to continue (or /gsd auto to run continuously).`;
191
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
+ }
192
247
  /**
193
248
  * Pre-verification processing: parallel worker signal check, cache invalidation,
194
249
  * auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
@@ -221,12 +276,19 @@ export async function postUnitPreVerification(pctx, opts) {
221
276
  if (!opts?.skipSettleDelay) {
222
277
  await new Promise(r => setTimeout(r, 100));
223
278
  }
224
- // Auto-commit
279
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
280
+ const uokFlags = resolveUokFlags(prefs);
281
+ // Turn-level git action (commit | snapshot | status-only)
225
282
  if (s.currentUnit) {
226
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;
227
289
  try {
228
290
  let taskContext;
229
- if (s.currentUnit.type === "execute-task") {
291
+ if (turnAction === "commit" && s.currentUnit.type === "execute-task") {
230
292
  const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
231
293
  if (mid && sid && tid) {
232
294
  const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
@@ -266,19 +328,101 @@ export async function postUnitPreVerification(pctx, opts) {
266
328
  // code files only in the working tree where they are destroyed by
267
329
  // `git worktree remove --force` during teardown.
268
330
  _resetHasChangesCache();
269
- // Skip auto-commit for lifecycle-only units (#2553) — they only touch
270
- // `.gsd/` internal state files. Those files are picked up by the next
271
- // actual task commit via smartStage().
272
- if (!LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type)) {
273
- const commitMsg = autoCommitCurrentBranch(s.basePath, s.currentUnit.type, s.currentUnit.id, taskContext);
274
- if (commitMsg) {
275
- 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");
276
413
  }
277
414
  }
278
415
  }
279
416
  catch (e) {
280
- debugLog("postUnit", { phase: "auto-commit", error: String(e) });
281
- 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
+ }
282
426
  }
283
427
  // GitHub sync (non-blocking, opt-in)
284
428
  await runSafely("postUnit", "github-sync", async () => {
@@ -714,11 +858,13 @@ export async function postUnitPostVerification(pctx) {
714
858
  // ── Pre-execution checks (after plan-slice completes) ──
715
859
  if (s.currentUnit &&
716
860
  s.currentUnit.type === "plan-slice") {
861
+ const currentUnit = s.currentUnit;
717
862
  let preExecPauseNeeded = false;
718
863
  await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
864
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
865
+ const uokFlags = resolveUokFlags(prefs);
719
866
  try {
720
867
  // Check preferences — respect enhanced_verification and enhanced_verification_pre
721
- const prefs = loadEffectiveGSDPreferences()?.preferences;
722
868
  const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
723
869
  const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
724
870
  if (!enhancedEnabled || !preEnabled) {
@@ -730,7 +876,7 @@ export async function postUnitPostVerification(pctx) {
730
876
  return;
731
877
  }
732
878
  // Parse the unit ID to get milestone/slice IDs
733
- const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
879
+ const { milestone: mid, slice: sid } = parseUnitId(currentUnit.id);
734
880
  if (!mid || !sid) {
735
881
  debugLog("postUnitPostVerification", {
736
882
  phase: "pre-execution-checks",
@@ -749,6 +895,7 @@ export async function postUnitPostVerification(pctx) {
749
895
  });
750
896
  return;
751
897
  }
898
+ const strictMode = prefs?.enhanced_verification_strict === true;
752
899
  // Run pre-execution checks
753
900
  const result = await runPreExecutionChecks(tasks, s.basePath);
754
901
  // Log summary to stderr in existing verification output format
@@ -764,10 +911,43 @@ export async function postUnitPostVerification(pctx) {
764
911
  if (slicePath) {
765
912
  writePreExecutionEvidence(result, slicePath, mid, sid);
766
913
  }
767
- // Notify UI
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
+ }
943
+ // Notify UI — surface actionable details (#4259)
768
944
  if (result.status === "fail") {
769
- const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
770
- ctx.ui.notify(`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`, "error");
945
+ const blockingChecks = result.checks.filter(c => !c.passed && c.blocking);
946
+ const blockingCount = blockingChecks.length;
947
+ const details = blockingChecks.slice(0, 3).map(c => ` \u2022 ${c.message}`).join("\n");
948
+ const suffix = blockingChecks.length > 3 ? `\n \u2022 ...and ${blockingChecks.length - 3} more` : "";
949
+ const evidenceNote = `\nSee ${sid}-PRE-EXEC-VERIFY.json for full details.`;
950
+ ctx.ui.notify(`Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found\n${details}${suffix}${evidenceNote}`, "error");
771
951
  preExecPauseNeeded = true;
772
952
  }
773
953
  else if (result.status === "warn") {
@@ -794,6 +974,29 @@ export async function postUnitPostVerification(pctx) {
794
974
  });
795
975
  logError("engine", `gsd-pre-exec: Pre-execution checks threw an error: ${errorMessage}`);
796
976
  ctx.ui.notify(`Pre-execution checks error: ${errorMessage} — pausing for human review`, "error");
977
+ if (uokFlags.gates && s.currentUnit) {
978
+ const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
979
+ const gateRunner = new UokGateRunner();
980
+ gateRunner.register({
981
+ id: "pre-execution-checks",
982
+ type: "input",
983
+ execute: async () => ({
984
+ outcome: "manual-attention",
985
+ failureClass: "manual-attention",
986
+ rationale: "pre-execution checks threw before completion",
987
+ findings: errorMessage,
988
+ }),
989
+ });
990
+ await gateRunner.run("pre-execution-checks", {
991
+ basePath: s.basePath,
992
+ traceId: `pre-execution:${s.currentUnit.id}`,
993
+ turnId: s.currentUnit.id,
994
+ milestoneId: mid ?? undefined,
995
+ sliceId: sid ?? undefined,
996
+ unitType: s.currentUnit.type,
997
+ unitId: s.currentUnit.id,
998
+ });
999
+ }
797
1000
  preExecPauseNeeded = true;
798
1001
  }
799
1002
  });
@@ -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);
@@ -215,20 +215,28 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
215
215
  const absPath = resolveExpectedArtifactPath(unitType, unitId, base);
216
216
  // For unit types with no verifiable artifact (null path), the parent directory
217
217
  // is missing on disk — treat as stale completion state so the key gets evicted (#313).
218
- if (!absPath)
218
+ if (!absPath) {
219
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: resolveExpectedArtifactPath returned null (parent dir missing)`);
219
220
  return false;
220
- if (!existsSync(absPath))
221
+ }
222
+ if (!existsSync(absPath)) {
223
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: existsSync false for ${absPath}`);
221
224
  return false;
225
+ }
222
226
  if (unitType === "validate-milestone") {
223
227
  const validationContent = readFileSync(absPath, "utf-8");
224
- if (!isValidationTerminal(validationContent))
228
+ if (!isValidationTerminal(validationContent)) {
229
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: validation not terminal (len=${validationContent.length}) at ${absPath}`);
225
230
  return false;
231
+ }
226
232
  }
227
233
  if (unitType === "plan-milestone") {
228
234
  try {
229
235
  const roadmap = parseLegacyRoadmap(readFileSync(absPath, "utf-8"));
230
- if (roadmap.slices.length === 0)
236
+ if (roadmap.slices.length === 0) {
237
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: roadmap has zero slices at ${absPath}`);
231
238
  return false;
239
+ }
232
240
  }
233
241
  catch (err) {
234
242
  logWarning("recovery", `plan-milestone roadmap verification failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -245,8 +253,10 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
245
253
  // Accept checkbox-style (- [x] **T01: ...) or heading-style (### T01 -- / ### T01: / ### T01 —)
246
254
  const hasCheckboxTask = /^- \[[xX ]\] \*\*T\d+:/m.test(planContent);
247
255
  const hasHeadingTask = /^#{2,4}\s+T\d+\s*(?:--|—|:)/m.test(planContent);
248
- if (!hasCheckboxTask && !hasHeadingTask)
256
+ if (!hasCheckboxTask && !hasHeadingTask) {
257
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: plan has no task checkbox/heading (len=${planContent.length}) at ${absPath}`);
249
258
  return false;
259
+ }
250
260
  }
251
261
  // execute-task: DB status is authoritative. Fall back to checked-checkbox
252
262
  // detection when the DB is unavailable (unmigrated projects).
@@ -306,11 +316,15 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
306
316
  }
307
317
  if (taskIds && taskIds.length > 0) {
308
318
  const tasksDir = resolveTasksDir(base, mid, sid);
309
- if (tasksDir) {
310
- for (const tid of taskIds) {
311
- const taskPlanFile = join(tasksDir, `${tid}-PLAN.md`);
312
- if (!existsSync(taskPlanFile))
313
- return false;
319
+ if (!tasksDir) {
320
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: resolveTasksDir returned null for ${mid}/${sid}`);
321
+ return false;
322
+ }
323
+ for (const tid of taskIds) {
324
+ const taskPlanFile = join(tasksDir, `${tid}-PLAN.md`);
325
+ if (!existsSync(taskPlanFile)) {
326
+ logWarning("recovery", `verify-fail ${unitType} ${unitId}: task plan missing ${taskPlanFile}`);
327
+ return false;
314
328
  }
315
329
  }
316
330
  }
@@ -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
  }
@@ -24,6 +24,8 @@ import { writeVerificationJSON } from "./verification-evidence.js";
24
24
  import { logWarning } from "./workflow-logger.js";
25
25
  import { runPostExecutionChecks } from "./post-execution-checks.js";
26
26
  import { join } from "node:path";
27
+ import { resolveUokFlags } from "./uok/flags.js";
28
+ import { UokGateRunner } from "./uok/gate-runner.js";
27
29
  function isInfraVerificationFailure(stderr) {
28
30
  return /\b(ENOENT|ENOTFOUND|ETIMEDOUT|ECONNRESET|EAI_AGAIN|spawn\s+\S+\s+ENOENT|command not found)\b/i.test(stderr);
29
31
  }
@@ -43,6 +45,31 @@ function isInfraVerificationFailure(stderr) {
43
45
  */
44
46
  async function runValidateMilestonePostCheck(vctx, pauseAuto) {
45
47
  const { s, ctx, pi } = vctx;
48
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
49
+ const uokFlags = resolveUokFlags(prefs);
50
+ const persistMilestoneValidationGate = async (outcome, failureClass, rationale, findings = "", milestoneId) => {
51
+ if (!uokFlags.gates || !s.currentUnit)
52
+ return;
53
+ const gateRunner = new UokGateRunner();
54
+ gateRunner.register({
55
+ id: "milestone-validation-post-check",
56
+ type: "verification",
57
+ execute: async () => ({
58
+ outcome,
59
+ failureClass,
60
+ rationale,
61
+ findings,
62
+ }),
63
+ });
64
+ await gateRunner.run("milestone-validation-post-check", {
65
+ basePath: s.basePath,
66
+ traceId: `validation-post-check:${s.currentUnit.id}`,
67
+ turnId: s.currentUnit.id,
68
+ milestoneId,
69
+ unitType: s.currentUnit.type,
70
+ unitId: s.currentUnit.id,
71
+ });
72
+ };
46
73
  if (!s.currentUnit)
47
74
  return "continue";
48
75
  const { milestone: mid } = parseUnitId(s.currentUnit.id);
@@ -55,17 +82,22 @@ async function runValidateMilestonePostCheck(vctx, pauseAuto) {
55
82
  if (!validationContent)
56
83
  return "continue";
57
84
  const verdict = extractVerdict(validationContent);
58
- if (verdict !== "needs-remediation")
85
+ if (verdict !== "needs-remediation") {
86
+ await persistMilestoneValidationGate("pass", "none", `milestone validation verdict is ${verdict}; no remediation loop risk`, "", mid);
59
87
  return "continue";
88
+ }
60
89
  const incompleteSliceCount = await countIncompleteSlices(s.basePath, mid);
61
90
  // If any non-closed slices exist, the agent successfully queued remediation
62
91
  // work — proceed normally. The state machine will execute those slices and
63
92
  // re-validate per the #3596/#3670 fix.
64
- if (incompleteSliceCount > 0)
93
+ if (incompleteSliceCount > 0) {
94
+ await persistMilestoneValidationGate("pass", "none", `remediation slices present (${incompleteSliceCount}); validation can continue`, "", mid);
65
95
  return "continue";
96
+ }
66
97
  ctx.ui.notify(`Milestone ${mid} validation returned verdict=needs-remediation but no remediation slices were added. Pausing for human review.`, "error");
67
98
  process.stderr.write(`validate-milestone: pausing — verdict=needs-remediation with no incomplete slices for ${mid}. ` +
68
99
  `The agent must call gsd_reassess_roadmap to add remediation slices before re-validation.\n`);
100
+ await persistMilestoneValidationGate("manual-attention", "manual-attention", "needs-remediation verdict without queued remediation slices", `No incomplete slices found for ${mid} while verdict=needs-remediation`, mid);
69
101
  await pauseAuto(ctx, pi);
70
102
  return "pause";
71
103
  }
@@ -122,6 +154,7 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
122
154
  try {
123
155
  const effectivePrefs = loadEffectiveGSDPreferences();
124
156
  const prefs = effectivePrefs?.preferences;
157
+ const uokFlags = resolveUokFlags(prefs);
125
158
  // Read task plan verify field
126
159
  const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
127
160
  let taskPlanVerify;
@@ -153,6 +186,35 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
153
186
  process.stderr.write(` [${w.severity}] ${w.name}: ${w.title}\n`);
154
187
  }
155
188
  }
189
+ if (uokFlags.gates) {
190
+ const gateRunner = new UokGateRunner();
191
+ gateRunner.register({
192
+ id: "verification-gate",
193
+ type: "verification",
194
+ execute: async () => ({
195
+ outcome: result.passed ? "pass" : "fail",
196
+ failureClass: result.runtimeErrors?.some((e) => e.blocking)
197
+ ? "execution"
198
+ : "verification",
199
+ rationale: result.passed
200
+ ? "verification checks passed"
201
+ : "verification checks failed",
202
+ findings: result.passed
203
+ ? ""
204
+ : formatFailureContext(result),
205
+ }),
206
+ });
207
+ await gateRunner.run("verification-gate", {
208
+ basePath: s.basePath,
209
+ traceId: `verification:${s.currentUnit.id}`,
210
+ turnId: s.currentUnit.id,
211
+ milestoneId: mid ?? undefined,
212
+ sliceId: sid ?? undefined,
213
+ taskId: tid ?? undefined,
214
+ unitType: s.currentUnit.type,
215
+ unitId: s.currentUnit.id,
216
+ });
217
+ }
156
218
  // Auto-fix retry preferences
157
219
  const autoFixEnabled = prefs?.verification_auto_fix !== false;
158
220
  const maxRetries = typeof prefs?.verification_max_retries === "number"
@@ -253,6 +315,42 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
253
315
  : "⚠";
254
316
  process.stderr.write(`gsd-post-exec: ${checkEmoji} [${check.category}] ${check.target}: ${check.message}\n`);
255
317
  }
318
+ if (uokFlags.gates) {
319
+ const strictMode = prefs?.enhanced_verification_strict === true;
320
+ const warnEscalated = postExecResult.status === "warn" && strictMode;
321
+ const blockingFailure = postExecResult.status === "fail" || warnEscalated;
322
+ const findings = postExecResult.checks
323
+ .filter((check) => !check.passed)
324
+ .map((check) => `[${check.category}] ${check.target}: ${check.message}`)
325
+ .join("\n");
326
+ const gateRunner = new UokGateRunner();
327
+ gateRunner.register({
328
+ id: "post-execution-checks",
329
+ type: "artifact",
330
+ execute: async () => ({
331
+ outcome: blockingFailure ? "fail" : "pass",
332
+ failureClass: postExecResult.status === "fail"
333
+ ? "artifact"
334
+ : warnEscalated
335
+ ? "policy"
336
+ : "none",
337
+ rationale: blockingFailure
338
+ ? `post-execution checks ${postExecResult.status}${warnEscalated ? " (strict)" : ""}`
339
+ : "post-execution checks passed",
340
+ findings,
341
+ }),
342
+ });
343
+ await gateRunner.run("post-execution-checks", {
344
+ basePath: s.basePath,
345
+ traceId: `verification:${s.currentUnit.id}`,
346
+ turnId: s.currentUnit.id,
347
+ milestoneId: mid,
348
+ sliceId: sid,
349
+ taskId: tid,
350
+ unitType: s.currentUnit.type,
351
+ unitId: s.currentUnit.id,
352
+ });
353
+ }
256
354
  // Check for blocking failures
257
355
  if (postExecResult.status === "fail") {
258
356
  postExecBlockingFailure = true;
@@ -54,6 +54,8 @@ function isSamePath(a, b) {
54
54
  return realpathSync(a) === realpathSync(b);
55
55
  }
56
56
  catch (e) {
57
+ if (e.code === "ENOENT")
58
+ return false;
57
59
  logWarning("worktree", `isSamePath failed: ${e.message}`);
58
60
  return false;
59
61
  }