@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 1.2.0-dev.fb12b103

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 (520) hide show
  1. package/dist/cli-style.d.ts +17 -0
  2. package/dist/cli-style.js +28 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/headless-events.d.ts +4 -2
  5. package/dist/headless-events.js +7 -29
  6. package/dist/models-resolver.d.ts +3 -13
  7. package/dist/models-resolver.js +3 -22
  8. package/dist/resource-loader.js +2 -14
  9. package/dist/resources/.managed-resources-content-hash +1 -1
  10. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  11. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  12. package/dist/resources/extensions/async-jobs/index.js +65 -0
  13. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  14. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  15. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  16. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  17. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  18. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  19. package/dist/resources/extensions/bg-shell/utilities.js +5 -2
  20. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  21. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  22. package/dist/resources/extensions/browser-tools/index.js +69 -12
  23. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  24. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
  25. package/dist/resources/extensions/gsd/auto/orchestrator.js +40 -9
  26. package/dist/resources/extensions/gsd/auto/phases.js +6 -1
  27. package/dist/resources/extensions/gsd/auto-dispatch.js +12 -1
  28. package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +19 -8
  30. package/dist/resources/extensions/gsd/auto-prompts.js +15 -10
  31. package/dist/resources/extensions/gsd/auto-start.js +21 -21
  32. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  33. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +7 -16
  34. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  35. package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
  36. package/dist/resources/extensions/gsd/auto.js +8 -20
  37. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
  38. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +151 -20
  41. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +30 -4
  42. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  43. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  44. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  45. package/dist/resources/extensions/gsd/captures.js +5 -15
  46. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  47. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  48. package/dist/resources/extensions/gsd/constants.js +0 -2
  49. package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
  50. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  51. package/dist/resources/extensions/gsd/db/queries.js +372 -0
  52. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  53. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  54. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  55. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  56. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  57. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  58. package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
  59. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  60. package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
  61. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  62. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  63. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  64. package/dist/resources/extensions/gsd/git-service.js +1 -0
  65. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  66. package/dist/resources/extensions/gsd/gsd-db.js +171 -2048
  67. package/dist/resources/extensions/gsd/guidance.js +98 -0
  68. package/dist/resources/extensions/gsd/guided-flow.js +51 -5
  69. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  70. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  71. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  72. package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
  73. package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
  74. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  75. package/dist/resources/extensions/gsd/model-router.js +3 -0
  76. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  77. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  78. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  79. package/dist/resources/extensions/gsd/paths.js +37 -24
  80. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  81. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  82. package/dist/resources/extensions/gsd/preferences.js +14 -0
  83. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  86. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  87. package/dist/resources/extensions/gsd/prompts/run-uat.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  89. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  90. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  91. package/dist/resources/extensions/gsd/publication.js +87 -0
  92. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  93. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  94. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  95. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  96. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  97. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  98. package/dist/resources/extensions/gsd/state.js +1 -20
  99. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  100. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  101. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
  103. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
  105. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
  106. package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
  107. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  108. package/dist/resources/extensions/gsd/uat-policy.js +2 -1
  109. package/dist/resources/extensions/gsd/undo.js +8 -7
  110. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  111. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  112. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  113. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  114. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  115. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  116. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  117. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
  119. package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
  120. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  121. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  122. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  123. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  124. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  125. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  126. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  127. package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
  128. package/dist/resources/shared/package.json +3 -0
  129. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  130. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  131. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  132. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  133. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  134. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  135. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  136. package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
  137. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  138. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  139. package/dist/web/standalone/.next/BUILD_ID +1 -1
  140. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  141. package/dist/web/standalone/.next/build-manifest.json +3 -3
  142. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  143. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  144. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  145. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/index.html +1 -1
  197. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  199. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  204. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  205. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  206. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  207. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  210. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  211. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  212. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  213. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  214. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  215. package/dist/web/standalone/node_modules/postcss/lib/container.js +18 -26
  216. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +14 -47
  217. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  218. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  219. package/dist/web/standalone/node_modules/postcss/lib/input.js +29 -54
  220. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +37 -47
  221. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +9 -26
  222. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +55 -57
  223. package/dist/web/standalone/node_modules/postcss/lib/node.js +31 -99
  224. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  225. package/dist/web/standalone/node_modules/postcss/lib/parser.js +9 -10
  226. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  227. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +11 -30
  228. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  229. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  230. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  231. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +28 -69
  232. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +2 -6
  233. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  234. package/dist/web/standalone/package.json +1 -1
  235. package/dist/worktree-cli.js +3 -6
  236. package/dist/worktree-status-banner.js +7 -11
  237. package/package.json +1 -1
  238. package/packages/cloud-mcp-gateway/package.json +2 -2
  239. package/packages/contracts/dist/rpc.d.ts +1 -0
  240. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  241. package/packages/contracts/dist/rpc.js.map +1 -1
  242. package/packages/contracts/dist/workflow.d.ts +4 -0
  243. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  244. package/packages/contracts/dist/workflow.js.map +1 -1
  245. package/packages/contracts/package.json +1 -1
  246. package/packages/daemon/package.json +4 -4
  247. package/packages/gsd-agent-core/package.json +5 -5
  248. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  249. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  250. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +8 -0
  251. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  254. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  257. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  266. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  267. package/packages/gsd-agent-modes/package.json +7 -7
  268. package/packages/mcp-server/dist/cli.js +6 -3
  269. package/packages/mcp-server/dist/cli.js.map +1 -1
  270. package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
  271. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  272. package/packages/mcp-server/dist/workflow-tools.js +46 -21
  273. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  274. package/packages/mcp-server/package.json +3 -3
  275. package/packages/native/package.json +1 -1
  276. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  277. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  278. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  279. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  280. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  281. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  282. package/packages/pi-agent-core/dist/index.js +3 -0
  283. package/packages/pi-agent-core/dist/index.js.map +1 -1
  284. package/packages/pi-agent-core/package.json +1 -1
  285. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  286. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  287. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  288. package/packages/pi-ai/dist/models.generated.d.ts +478 -484
  289. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  290. package/packages/pi-ai/dist/models.generated.js +500 -533
  291. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  292. package/packages/pi-ai/package.json +1 -1
  293. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  294. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  296. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  299. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  302. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  304. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  306. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  308. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/index.js +1 -1
  310. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  312. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  314. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  315. package/packages/pi-coding-agent/package.json +7 -7
  316. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  317. package/packages/pi-tui/dist/tui.js +9 -0
  318. package/packages/pi-tui/dist/tui.js.map +1 -1
  319. package/packages/pi-tui/package.json +2 -2
  320. package/packages/rpc-client/package.json +2 -2
  321. package/pkg/package.json +1 -1
  322. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  323. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  324. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  325. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  326. package/src/resources/extensions/async-jobs/index.ts +79 -0
  327. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  328. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  329. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  330. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  331. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  332. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  333. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  334. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  335. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  336. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  337. package/src/resources/extensions/browser-tools/index.ts +71 -13
  338. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  339. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
  340. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  341. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  342. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
  343. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
  344. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
  345. package/src/resources/extensions/gsd/auto/orchestrator.ts +46 -10
  346. package/src/resources/extensions/gsd/auto/phases.ts +10 -1
  347. package/src/resources/extensions/gsd/auto-dispatch.ts +12 -0
  348. package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
  349. package/src/resources/extensions/gsd/auto-post-unit.ts +25 -7
  350. package/src/resources/extensions/gsd/auto-prompts.ts +40 -26
  351. package/src/resources/extensions/gsd/auto-start.ts +21 -22
  352. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  353. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +10 -17
  354. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  355. package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
  356. package/src/resources/extensions/gsd/auto.ts +20 -24
  357. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
  358. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
  359. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  360. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +180 -15
  361. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +29 -3
  362. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  363. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  364. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  365. package/src/resources/extensions/gsd/captures.ts +5 -16
  366. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  367. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  368. package/src/resources/extensions/gsd/constants.ts +0 -3
  369. package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
  370. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  371. package/src/resources/extensions/gsd/db/queries.ts +453 -0
  372. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  373. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  374. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  375. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  376. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  377. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  378. package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
  379. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  380. package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
  381. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  382. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  383. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  384. package/src/resources/extensions/gsd/git-service.ts +1 -0
  385. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  386. package/src/resources/extensions/gsd/gsd-db.ts +173 -2373
  387. package/src/resources/extensions/gsd/guidance.ts +139 -0
  388. package/src/resources/extensions/gsd/guided-flow.ts +50 -5
  389. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  390. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  391. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  392. package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
  393. package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
  394. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  395. package/src/resources/extensions/gsd/model-router.ts +3 -0
  396. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  397. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  398. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  399. package/src/resources/extensions/gsd/paths.ts +42 -22
  400. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  401. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  402. package/src/resources/extensions/gsd/preferences.ts +18 -0
  403. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  404. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  405. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  406. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  407. package/src/resources/extensions/gsd/prompts/run-uat.md +1 -1
  408. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  409. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  410. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  411. package/src/resources/extensions/gsd/publication.ts +122 -0
  412. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  413. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  414. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  415. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  416. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  417. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  418. package/src/resources/extensions/gsd/state.ts +4 -21
  419. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  420. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  421. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
  422. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
  423. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +16 -19
  424. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  425. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  426. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  427. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  428. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  429. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  430. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  431. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  432. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  433. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  434. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  435. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  436. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  437. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  438. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  439. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  440. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  441. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  442. package/src/resources/extensions/gsd/tests/guidance.test.ts +125 -0
  443. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  444. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
  445. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  446. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  447. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  448. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
  449. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  450. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  451. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  452. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  453. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  454. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  455. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  456. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
  457. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
  458. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  459. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  460. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
  461. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  462. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  463. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  464. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  465. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  466. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  467. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +24 -29
  468. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  469. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  470. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  471. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  472. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  473. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
  474. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  475. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
  476. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  477. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  478. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  479. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  480. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
  481. package/src/resources/extensions/gsd/tests/write-gate.test.ts +42 -0
  482. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  483. package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
  484. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  485. package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
  486. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
  487. package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
  488. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  489. package/src/resources/extensions/gsd/uat-policy.ts +2 -1
  490. package/src/resources/extensions/gsd/undo.ts +9 -8
  491. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  492. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  493. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  494. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  495. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  496. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  497. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  498. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  499. package/src/resources/extensions/gsd/worktree-lifecycle.ts +10 -1
  500. package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
  501. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  502. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  503. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  504. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  505. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  506. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  507. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  508. package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
  509. package/src/resources/shared/package.json +3 -0
  510. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  511. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  512. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  513. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  514. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  515. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  516. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  517. package/src/resources/skills/gsd-browser/SKILL.md +1 -1
  518. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  519. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → mU4QIDlpVHDdjDpeEKh5W}/_buildManifest.js +0 -0
  520. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → mU4QIDlpVHDdjDpeEKh5W}/_ssgManifest.js +0 -0
@@ -14,13 +14,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
14
14
 
15
15
  import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
16
16
  import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
17
- import type { GSDState } from "../types.js";
17
+ import type { GSDState, Phase } from "../types.js";
18
18
  import type { MinimalModelRegistry } from "../context-budget.js";
19
19
 
20
20
  type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
21
21
 
22
- import { debugCount, debugTime } from "../debug-logger.js";
22
+ import { debugCount, debugLog, debugTime } from "../debug-logger.js";
23
23
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
24
+ import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
24
25
  import { resolveDispatch } from "../auto-dispatch.js";
25
26
  import { classifyFailure } from "../recovery-classification.js";
26
27
  import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
@@ -37,7 +38,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
37
38
  import { getSessionLockStatus } from "../session-lock.js";
38
39
  import { resolveUokFlags } from "../uok/flags.js";
39
40
  import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
40
- import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
41
+ import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
41
42
  import {
42
43
  detectWorktreeName,
43
44
  getMainBranch,
@@ -330,6 +331,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
330
331
  private lastAdvanceKey: string | null = null;
331
332
  private lastFinalizedUnitKey: string | null = null;
332
333
  private dispatchKeyWindow: string[] = [];
334
+ // ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
335
+ // the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
336
+ // so the first advance of a session has no edge to assert.
337
+ private lastDerivedPhase: Phase | null = null;
333
338
  // #442: the unit key we last attempted graduated stuck-recovery for. Bounds
334
339
  // recovery to one attempt per stuck episode per run (reset on start/resume/
335
340
  // stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
@@ -612,8 +617,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
612
617
  // ── WorktreeAdapter (folded) ─────────────────────────────────────────────
613
618
 
614
619
  private getEffectiveUnitIsolationMode(basePath: string): ReturnType<typeof getIsolationMode> {
615
- const configuredMode = getIsolationMode(basePath);
616
- return configuredMode === "worktree" && this.s.isolationDegraded ? "branch" : configuredMode;
620
+ return resolveEffectiveUnitIsolationMode(
621
+ getIsolationMode(basePath),
622
+ this.s.isolationDegraded,
623
+ this.s.strandedRecoveryIsolationMode,
624
+ );
617
625
  }
618
626
 
619
627
  private buildLifecycle(): WorktreeLifecycle {
@@ -724,6 +732,21 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
724
732
  return { action: recovery.action, reason: recovery.reason };
725
733
  }
726
734
 
735
+ /**
736
+ * ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
737
+ * assertion, not a decision-maker — deriveState already chose the phase; we
738
+ * only observe illegal *derived* edges that survived reconciliation. The
739
+ * matrix is still a sparse hardening spec, so this is telemetry-only (no
740
+ * block) until it is expanded into a validated legal-edge graph. To enforce:
741
+ * `throw violation;` instead of logging — recovery-classification maps
742
+ * IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
743
+ */
744
+ private observePhaseTransition(from: Phase, to: Phase): void {
745
+ if (isLegalEdge(from, to)) return;
746
+ const violation = new IllegalPhaseTransitionError(from, to);
747
+ debugLog("phase-transition-advisory", { from, to, message: violation.message });
748
+ }
749
+
727
750
  // ── Lifecycle verbs ──────────────────────────────────────────────────────
728
751
 
729
752
  /**
@@ -787,6 +810,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
787
810
  this.lastFinalizedUnitKey = null;
788
811
  this.dispatchKeyWindow = [];
789
812
  this.lastStuckRecoveryKey = null;
813
+ this.lastDerivedPhase = null;
790
814
  this.status.phase = "running";
791
815
  this.bumpTransition();
792
816
  this.journalTransition({ name: "start" });
@@ -876,6 +900,12 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
876
900
  return blocked;
877
901
  }
878
902
 
903
+ const reconciledPhase = reconciliation.stateSnapshot.phase;
904
+ if (this.lastDerivedPhase !== null) {
905
+ this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
906
+ }
907
+ this.lastDerivedPhase = reconciledPhase;
908
+
879
909
  const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
880
910
  if (!decision) {
881
911
  const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
@@ -993,16 +1023,18 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
993
1023
  // checks coexist: idempotency for the common immediate-repeat case,
994
1024
  // stuck-loop for the saturated-window case.
995
1025
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
1026
+ // Unit already active — benign no-op. Return skipped so the loop re-polls
1027
+ // without cancelling the in-flight unit (blocked+pause would force-cancel it).
996
1028
  this.clearPendingDispatch();
997
- const blocked: AutoAdvanceResult = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
1029
+ const skipped: AutoAdvanceResult = { kind: "skipped", reason: "idempotent advance: unit already active" };
998
1030
  this.journalTransition({
999
- name: "advance-blocked",
1000
- reason: blocked.reason,
1031
+ name: "advance-skipped",
1032
+ reason: skipped.reason,
1001
1033
  unitType: decision.unitType,
1002
1034
  unitId: decision.unitId,
1003
1035
  });
1004
- this.postAdvanceRecord(blocked);
1005
- return blocked;
1036
+ this.postAdvanceRecord(skipped);
1037
+ return skipped;
1006
1038
  }
1007
1039
 
1008
1040
  // Stuck-loop detection: when the ring is saturated with copies of
@@ -1146,6 +1178,9 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1146
1178
  // Preserve dispatchKeyWindow across resume so stuck-loop detection
1147
1179
  // accumulates across pause/resume cycles rather than resetting each time.
1148
1180
  this.lastStuckRecoveryKey = null;
1181
+ // ADR-030: drop the prior "from" — the first advance after resume has no
1182
+ // edge to assert (avoids a false illegal-edge across the pause boundary).
1183
+ this.lastDerivedPhase = null;
1149
1184
  this.status.phase = "running";
1150
1185
  this.bumpTransition();
1151
1186
  this.journalTransition({ name: "resume" });
@@ -1162,6 +1197,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
1162
1197
  this.status.activeUnit = undefined;
1163
1198
  this.lastAdvanceKey = null;
1164
1199
  this.lastFinalizedUnitKey = null;
1200
+ this.lastDerivedPhase = null;
1165
1201
  // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1166
1202
  // across pause/resume cycles. Only clear on a hard stop.
1167
1203
  if (reason !== "pause") {
@@ -20,6 +20,7 @@ import {
20
20
  type PreVerificationOpts,
21
21
  } from "../auto-post-unit.js";
22
22
  import { lastAssistantText } from "../user-input-boundary.js";
23
+ import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
23
24
  import type { Phase } from "../types.js";
24
25
  import {
25
26
  MAX_RECOVERY_CHARS,
@@ -362,7 +363,15 @@ async function validateSourceWriteWorktreeSafety(
362
363
  if (!writesSource) return null;
363
364
 
364
365
  const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
365
- const isolationMode = deps.getIsolationMode(projectRoot);
366
+ // A degraded session already fell back to the milestone branch in the
367
+ // project root — validating against the canonical worktree root there
368
+ // would fail every dispatch with a false invalid-root. The same applies
369
+ // to a stranded-recovery session that adopted the milestone branch.
370
+ const isolationMode = resolveEffectiveUnitIsolationMode(
371
+ deps.getIsolationMode(projectRoot),
372
+ s.isolationDegraded,
373
+ s.strandedRecoveryIsolationMode,
374
+ );
366
375
  if (isolationMode !== "worktree") return null;
367
376
 
368
377
  const safety = createWorktreeSafetyModule();
@@ -90,7 +90,9 @@ import { MILESTONE_ID_RE } from "./milestone-ids.js";
90
90
  import {
91
91
  getWorkflowTransportSupportError,
92
92
  getRequiredWorkflowToolsForAutoUnit,
93
+ resolveWorkflowMcpProjectRoot,
93
94
  } from "./workflow-mcp.js";
95
+ import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
94
96
  import {
95
97
  PROJECT_RESEARCH_INFLIGHT_MARKER,
96
98
  } from "./project-research-policy.js";
@@ -772,6 +774,16 @@ export const DISPATCH_RULES: DispatchRule[] = [
772
774
  if (browserToolError) {
773
775
  return { action: "stop" as const, reason: browserToolError, level: "warning" as const };
774
776
  }
777
+ const browserDaemonError = prepareBrowserDaemonForUat({
778
+ uatType,
779
+ sessionProvider,
780
+ sessionAuthMode,
781
+ sessionBaseUrl,
782
+ projectRoot: resolveWorkflowMcpProjectRoot(basePath),
783
+ });
784
+ if (browserDaemonError) {
785
+ return { action: "stop" as const, reason: browserDaemonError, level: "warning" as const };
786
+ }
775
787
 
776
788
  // Cap run-uat dispatch attempts to prevent infinite replay (#3624).
777
789
  // Check before incrementing so an exhausted counter cannot create a
@@ -1041,16 +1041,36 @@ export function resolveModelId<T extends { id: string; provider: string }>(
1041
1041
  if (providerMatch) return providerMatch;
1042
1042
  }
1043
1043
 
1044
- // Prefer "anthropic" as the canonical provider for Anthropic models.
1045
- // Transport-specific tiebreaker (ADR-012): intentionally keys on provider,
1046
- // not api we want the plain Anthropic transport when multiple are available.
1047
- const anthropicMatch = candidates.find(m => m.provider === "anthropic");
1048
- if (anthropicMatch) return anthropicMatch;
1044
+ // Subscription/OAuth routes beat pay-per-token API when the same model ID
1045
+ // exists on multiple providers. Order matters — first match wins.
1046
+ for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
1047
+ const match = candidates.find(m => m.provider === provider);
1048
+ if (match) return match;
1049
+ }
1049
1050
 
1050
1051
  // Fall back to first non-extension candidate, or any candidate
1051
1052
  return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
1052
1053
  }
1053
1054
 
1055
+ /**
1056
+ * When a bare model ID exists on multiple providers, prefer subscription/OAuth
1057
+ * routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
1058
+ * but applies when *both* sides are authenticated.
1059
+ *
1060
+ * Order rationale:
1061
+ * - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
1062
+ * - google-gemini-cli before github-copilot: first-party Gemini CLI
1063
+ * - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
1064
+ * - github-copilot before openai/google: Copilot OAuth over platform API keys
1065
+ */
1066
+ export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
1067
+ "openai-codex",
1068
+ "google-gemini-cli",
1069
+ "anthropic",
1070
+ "github-copilot",
1071
+ "google-antigravity",
1072
+ ] as const;
1073
+
1054
1074
  /**
1055
1075
  * Flat-rate providers charge the same per request regardless of model.
1056
1076
  * Dynamic routing provides no cost benefit — it only degrades quality (#3453).
@@ -72,7 +72,7 @@ import {
72
72
  } from "./milestone-closeout.js";
73
73
  import type { AutoSession, SidecarItem } from "./auto/session.js";
74
74
  import { getEvidence, clearEvidenceFromDisk, isExecutionToolName } from "./safety/evidence-collector.js";
75
- import { validateFileChanges } from "./safety/file-change-validator.js";
75
+ import { validateFileChanges, effectiveFileChangeAllowlist } from "./safety/file-change-validator.js";
76
76
  import { crossReferenceEvidence, type ClaimedEvidence } from "./safety/evidence-cross-ref.js";
77
77
  import { validateContent } from "./safety/content-validator.js";
78
78
  import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
@@ -88,7 +88,7 @@ import { writeTurnGitTransaction } from "./uok/gitops.js";
88
88
  import { isClosedStatus } from "./status-guards.js";
89
89
  import { detectAbandonMilestone } from "./abandon-detect.js";
90
90
  import { getPendingGate } from "./bootstrap/write-gate.js";
91
- import { isDeterministicPolicyError } from "./auto-tool-tracking.js";
91
+ import { isDeterministicPolicyError, isToolUnavailableError } from "./auto-tool-tracking.js";
92
92
  import { formatConnectedStepStack, formatPostUnitStatusCard } from "./auto-status-message.js";
93
93
  import {
94
94
  clearProjectResearchInflightMarker,
@@ -619,8 +619,10 @@ export function _hasExecutionToolCallsInSessionForTest(entries: readonly unknown
619
619
  return true;
620
620
  }
621
621
 
622
- if (e?.type !== "message") continue;
623
- const msg = e?.message;
622
+ // Accept both session-manager entries ({type: "message", message}) and
623
+ // bare agent-end messages ({role, content}) — the auto loop passes the
624
+ // latter via opts.agentEndMessages.
625
+ const msg = e?.type === "message" ? e?.message : e;
624
626
  if (!msg || msg.role !== "assistant" || !Array.isArray(msg.content)) continue;
625
627
  for (const block of msg.content) {
626
628
  if (block?.type !== "toolCall") continue;
@@ -1535,6 +1537,11 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1535
1537
  if (safetyConfig.enabled) {
1536
1538
  const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
1537
1539
 
1540
+ const fileChangeAllowlist = effectiveFileChangeAllowlist(
1541
+ safetyConfig.file_change_allowlist,
1542
+ (prefs?.git as { manage_gitignore?: boolean } | undefined)?.manage_gitignore,
1543
+ );
1544
+
1538
1545
  // File change validation (execute-task only, after unit execution)
1539
1546
  if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
1540
1547
  try {
@@ -1554,7 +1561,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1554
1561
  files: taskRow.files,
1555
1562
  })),
1556
1563
  );
1557
- const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1564
+ const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
1558
1565
  if (audit && audit.violations.length > 0) {
1559
1566
  const warnings = audit.violations.filter(v => v.severity === "warning");
1560
1567
  for (const v of warnings) {
@@ -1576,7 +1583,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
1576
1583
  s.basePath,
1577
1584
  expectedOutput,
1578
1585
  plannedFiles,
1579
- safetyConfig.file_change_allowlist,
1586
+ fileChangeAllowlist,
1580
1587
  );
1581
1588
  if (audit && audit.violations.length > 0) {
1582
1589
  const warnings = audit.violations.filter(v => v.severity === "warning");
@@ -2015,7 +2022,18 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
2015
2022
  "error",
2016
2023
  );
2017
2024
  } else if (!triggerArtifactVerified) {
2018
- if (s.lastToolInvocationError) {
2025
+ if (s.lastToolInvocationError && isToolUnavailableError(s.lastToolInvocationError)) {
2026
+ // Tool-unavailable is the one transient invocation error: the
2027
+ // workflow MCP server registers its surface asynchronously, so a
2028
+ // Unit's first call can race the registration. Fall through to the
2029
+ // bounded verification retry instead of pausing.
2030
+ debugLog("postUnit", { phase: "tool-unavailable-retry", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError });
2031
+ ctx.ui.notify(
2032
+ `Tool unavailable for ${s.currentUnit.type}: ${s.lastToolInvocationError}. The tool surface may still be registering — retrying.`,
2033
+ "warning",
2034
+ );
2035
+ s.lastToolInvocationError = null;
2036
+ } else if (s.lastToolInvocationError) {
2019
2037
  const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
2020
2038
  const errMsg = isUserSkip
2021
2039
  ? `Tool skipped for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Queued user message interrupted the turn — pausing auto-mode.`
@@ -40,6 +40,7 @@ import {
40
40
  composeContextModeInstructions,
41
41
  composeContractedUnitContext,
42
42
  composeInlinedContext,
43
+ composeToolSurfaceInstructions,
43
44
  composeUnitContext,
44
45
  type ArtifactResolver,
45
46
  type ComposedUnitContextBlock,
@@ -292,10 +293,12 @@ function prependContextModeToBlock(
292
293
  block: string,
293
294
  renderMode: ContextModeRenderMode = "standalone",
294
295
  ): string {
296
+ const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode });
295
297
  const contextMode = renderContextModeBlockForPrompt(unitType, base, renderMode);
296
- if (!contextMode) return block;
297
- if (!block.trim()) return contextMode;
298
- return `${contextMode}\n\n${block}`;
298
+ const guidance = [toolSurface, contextMode].filter(Boolean).join("\n\n");
299
+ if (!guidance) return block;
300
+ if (!block.trim()) return guidance;
301
+ return `${guidance}\n\n${block}`;
299
302
  }
300
303
 
301
304
  function requireUnitPromptContextContract(unitType: string): UnitPromptContextContract {
@@ -2470,6 +2473,9 @@ export async function buildPlanSlicePrompt(
2470
2473
  `Either (a) add an earlier task that creates X on disk before the task that needs it, ` +
2471
2474
  `or (b) if this task IS the one that creates X, move X from inputs to expected_output. ` +
2472
2475
  `Do NOT put X in a task's expected_output if that task only reads or verifies X — only tasks that actually write X to disk should list it in expected_output.\n` +
2476
+ `- **"[file] X: ... GSD planning artifacts are projections preloaded as context / written by workflow tools"**: ` +
2477
+ `Remove X from the task's inputs, files, and expectedOutput entirely. Planning artifacts (anything under .gsd/, .planning/, or .audits/, or names like M001-CONTEXT.md / S01-PLAN.md) are preloaded as context and written by workflow tools — ` +
2478
+ `do NOT add a task that creates X and do NOT move X to expectedOutput.\n` +
2473
2479
  `- **"[file] X: Task T_early reads X but it's created by task T_late (sequence violation)"**: ` +
2474
2480
  `Either (a) reorder tasks so T_late (the creator) runs before T_early (the reader), ` +
2475
2481
  `or (b) if T_late doesn't actually create X (it only reads/tests it), remove X from T_late's expected_output entirely.\n` +
@@ -3847,18 +3853,22 @@ export async function buildReactiveExecutePrompt(
3847
3853
  const inlinedTemplates = inlineTemplate("task-summary", "Task Summary");
3848
3854
  trackPromptContext(contextTelemetry, "templates", "inline", inlinedTemplates);
3849
3855
 
3850
- const prompt = loadPrompt("reactive-execute", {
3851
- workingDirectory: base,
3852
- milestoneId: mid,
3853
- milestoneTitle: midTitle,
3854
- sliceId: sid,
3855
- sliceTitle: sTitle,
3856
- graphContext: prependContextModeToBlock("reactive-execute", base, graphContext),
3857
- readyTaskCount: String(readyTaskIds.length),
3858
- readyTaskList: readyTaskListLines.join("\n"),
3859
- subagentPrompts: subagentSections.join("\n\n---\n\n"),
3860
- inlinedTemplates,
3861
- });
3856
+ const prompt = prependContextModeToBlock(
3857
+ "reactive-execute",
3858
+ base,
3859
+ loadPrompt("reactive-execute", {
3860
+ workingDirectory: base,
3861
+ milestoneId: mid,
3862
+ milestoneTitle: midTitle,
3863
+ sliceId: sid,
3864
+ sliceTitle: sTitle,
3865
+ graphContext,
3866
+ readyTaskCount: String(readyTaskIds.length),
3867
+ readyTaskList: readyTaskListLines.join("\n"),
3868
+ subagentPrompts: subagentSections.join("\n\n---\n\n"),
3869
+ inlinedTemplates,
3870
+ }),
3871
+ );
3862
3872
  emitPromptContextTelemetry("reactive-execute", contextTelemetry, prompt);
3863
3873
  return prompt;
3864
3874
  }
@@ -4037,17 +4047,21 @@ export async function buildGateEvaluatePrompt(
4037
4047
  ].join("\n"));
4038
4048
  }
4039
4049
 
4040
- return loadPrompt("gate-evaluate", {
4041
- workingDirectory: base,
4042
- milestoneId: mid,
4043
- milestoneTitle: midTitle,
4044
- sliceId: sid,
4045
- sliceTitle: sTitle,
4046
- slicePlanContent: prependContextModeToBlock("gate-evaluate", base, planContent),
4047
- gateCount: String(pending.length),
4048
- gateList: gateListLines.join("\n"),
4049
- subagentPrompts: subagentSections.join("\n\n---\n\n"),
4050
- });
4050
+ return prependContextModeToBlock(
4051
+ "gate-evaluate",
4052
+ base,
4053
+ loadPrompt("gate-evaluate", {
4054
+ workingDirectory: base,
4055
+ milestoneId: mid,
4056
+ milestoneTitle: midTitle,
4057
+ sliceId: sid,
4058
+ sliceTitle: sTitle,
4059
+ slicePlanContent: planContent,
4060
+ gateCount: String(pending.length),
4061
+ gateList: gateListLines.join("\n"),
4062
+ subagentPrompts: subagentSections.join("\n\n---\n\n"),
4063
+ }),
4064
+ );
4051
4065
  }
4052
4066
 
4053
4067
  export async function buildRewriteDocsPrompt(
@@ -16,6 +16,7 @@ import type {
16
16
  ExtensionCommandContext,
17
17
  } from "@gsd/pi-coding-agent";
18
18
  import { deriveState } from "./state.js";
19
+ import { findWorktreeSegment, isGsdWorktreePath } from "./worktree-root.js";
19
20
  import { loadFile, getManifestStatus } from "./files.js";
20
21
  import type { InterruptedSessionAssessment } from "./interrupted-session.js";
21
22
  import {
@@ -56,7 +57,8 @@ import {
56
57
  detectWorktreeName,
57
58
  setActiveMilestoneId,
58
59
  } from "./worktree.js";
59
- import { getAutoWorktreePath, isInAutoWorktree, checkoutBranchWithStashGuard } from "./auto-worktree.js";
60
+ import { getAutoWorktreePath, isInAutoWorktree } from "./auto-worktree.js";
61
+ import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
60
62
  import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
61
63
  import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
62
64
  import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
@@ -96,7 +98,6 @@ import {
96
98
  rmSync,
97
99
  } from "node:fs";
98
100
  import { join } from "node:path";
99
- import { sep as pathSep } from "node:path";
100
101
 
101
102
  import { validateDirectory } from "./validate-directory.js";
102
103
  import {
@@ -601,7 +602,7 @@ export function auditOrphanedMilestoneBranches(
601
602
  warnings.push(`Failed to remove worktree directory for ${milestoneId}: ${err2 instanceof Error ? err2.message : String(err2)}`);
602
603
  }
603
604
  } else {
604
- warnings.push(`Orphaned worktree directory for ${milestoneId} is outside .gsd/worktrees/ — skipping removal for safety.`);
605
+ warnings.push(`Orphaned worktree directory for ${milestoneId} is outside the GSD worktrees containers — skipping removal for safety.`);
605
606
  }
606
607
  } else {
607
608
  pushAction({
@@ -717,7 +718,7 @@ export function auditOrphanedMilestoneBranches(
717
718
  if (!existsSync(wtDir)) continue;
718
719
  if (!isInsideWorktreesDir(basePath, wtDir)) {
719
720
  warnings.push(
720
- `Orphaned worktree directory for ${m.id} is outside .gsd/worktrees/ — skipping removal for safety.`,
721
+ `Orphaned worktree directory for ${m.id} is outside the GSD worktrees containers — skipping removal for safety.`,
721
722
  );
722
723
  continue;
723
724
  }
@@ -993,12 +994,14 @@ export async function bootstrapAutoSession(
993
994
  // phase-specific planning model for a discuss turn (#2829).
994
995
  //
995
996
  // Precedence:
996
- // 1) Explicit session override via /gsd model (this session)
997
- // 2) Current session model from settings/session restore (if provider ready)
998
- // 3) GSD model preferences from PREFERENCES.md (validated against live auth)
997
+ // 1) Explicit session override via /gsd model or /gsd auto --model (this session)
998
+ // 2) GSD model preferences from PREFERENCES.md (validated against live auth)
999
+ // 3) Current session model from settings/session restore (if provider ready)
999
1000
  //
1000
- // This preserves #3517 defaults while honoring explicit runtime model
1001
- // selection for subsequent /gsd runs in the same session.
1001
+ // PREFERENCES.md wins over the ambient session default (#3517) so /gsd auto
1002
+ // does not stick on claude-code/claude-sonnet-4-6 when the user configured
1003
+ // models via /gsd workflow-preferences or PREFERENCES.md. Custom providers
1004
+ // still skip PREFERENCES.md entirely (#4122).
1002
1005
  //
1003
1006
  // Exception (#4122): when the session provider is a custom provider declared
1004
1007
  // in ~/.gsd/agent/models.json (Ollama, vLLM, OpenAI-compatible proxy, etc.),
@@ -1010,7 +1013,7 @@ export async function bootstrapAutoSession(
1010
1013
  const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
1011
1014
  const preferredModel = sessionProviderIsCustom
1012
1015
  ? null
1013
- : resolveDefaultSessionModel(ctx.model?.provider);
1016
+ : resolveDefaultSessionModel(ctx.model?.provider, base);
1014
1017
  // Validate the preferred model against the live registry + provider auth so
1015
1018
  // an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
1016
1019
  // start-model snapshot. Without this, every subsequent unit would try to
@@ -1040,8 +1043,8 @@ export async function bootstrapAutoSession(
1040
1043
  : null;
1041
1044
  const startThinkingSnapshot = pi.getThinkingLevel();
1042
1045
  const startModelSnapshot = manualSessionOverride
1043
- ?? currentSessionModel
1044
1046
  ?? validatedPreferredModel
1047
+ ?? currentSessionModel
1045
1048
  ?? null;
1046
1049
 
1047
1050
  try {
@@ -1325,7 +1328,7 @@ export async function bootstrapAutoSession(
1325
1328
  (state.phase === "pre-planning" || state.phase === "complete") &&
1326
1329
  survivorIsolationMode !== "none" &&
1327
1330
  !detectWorktreeName(base) &&
1328
- !base.includes(`${pathSep}.gsd${pathSep}worktrees${pathSep}`)
1331
+ !isGsdWorktreePath(base)
1329
1332
  ) {
1330
1333
  const milestoneBranch = `milestone/${survivorMilestoneId}`;
1331
1334
  const { nativeBranchExists } = await import("./native-git-bridge.js");
@@ -1610,16 +1613,12 @@ export async function bootstrapAutoSession(
1610
1613
  // live here is gone.
1611
1614
 
1612
1615
  const isUnderGsdWorktrees = (p: string): boolean => {
1613
- // Direct layout: /.gsd/worktrees/
1614
- const marker = `${pathSep}.gsd${pathSep}worktrees${pathSep}`;
1615
- if (p.includes(marker)) return true;
1616
- const worktreesSuffix = `${pathSep}.gsd${pathSep}worktrees`;
1617
- if (p.endsWith(worktreesSuffix)) return true;
1618
- // Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
1619
- const symlinkRe = new RegExp(
1620
- `\\${pathSep}\\.gsd\\${pathSep}projects\\${pathSep}[a-f0-9]+\\${pathSep}worktrees(?:\\${pathSep}|$)`,
1621
- );
1622
- return symlinkRe.test(p);
1616
+ const normalized = p.replaceAll("\\", "/");
1617
+ if (findWorktreeSegment(normalized) !== null) return true;
1618
+ // The container directory itself (no trailing worktree name), in any layout.
1619
+ return normalized.endsWith("/.gsd/worktrees")
1620
+ || normalized.endsWith("/.gsd-worktrees")
1621
+ || /\/\.gsd\/projects\/[^/]+\/worktrees$/.test(normalized);
1623
1622
  };
1624
1623
 
1625
1624
  if (
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { stripMcpToolPrefix } from "@gsd/pi-ai";
8
+ import { TOOL_SURFACE_NOT_READY } from "./tool-surface-readiness.js";
8
9
 
9
10
  interface InFlightTool {
10
11
  startedAt: number;
@@ -132,6 +133,15 @@ export function clearInFlightTools(): void {
132
133
  const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
133
134
  const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
134
135
 
136
+ /**
137
+ * Matches the runtime's "tool not registered" error. Unlike the deterministic
138
+ * invocation failures above, this one is usually transient: the workflow MCP
139
+ * server registers its tool surface asynchronously after session start, so a
140
+ * Unit's first tool call can race the registration. Callers should retry
141
+ * (bounded) instead of breaking the loop.
142
+ */
143
+ const TOOL_UNAVAILABLE_ERROR_RE = new RegExp(`No such tool available|${TOOL_SURFACE_NOT_READY}`, "i");
144
+
135
145
  /**
136
146
  * Returns true if the error message indicates a deterministic invocation or
137
147
  * policy failure (as opposed to a normal tool execution error).
@@ -141,6 +151,15 @@ export function isToolInvocationError(errorMsg: string): boolean {
141
151
  return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
142
152
  }
143
153
 
154
+ /**
155
+ * Returns true if the error message indicates the called tool was not on the
156
+ * session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
157
+ */
158
+ export function isToolUnavailableError(errorMsg: string): boolean {
159
+ if (!errorMsg) return false;
160
+ return TOOL_UNAVAILABLE_ERROR_RE.test(errorMsg);
161
+ }
162
+
144
163
  /**
145
164
  * Returns true if the error message indicates the tool was skipped because
146
165
  * a queued user message interrupted the turn (#3595). Retrying will produce
@@ -15,22 +15,15 @@ export {
15
15
  RUN_UAT_BROWSER_TOOL_NAMES,
16
16
  } from "./unit-tool-contracts.js";
17
17
 
18
- const EXECUTE_TASK_UNIT_TYPES = new Set([
19
- "execute-task",
20
- "execute-task-simple",
21
- "reactive-execute",
22
- ]);
23
-
24
- // These units own quality gates, but their completion handlers persist verdicts
25
- // from artifact sections. gsd_save_gate_result belongs to gate-evaluate, so keep
26
- // blocking it here with a calm redirect to the section-write path.
27
- const SECTION_CLOSE_GATE_UNIT_TYPES = new Set([
28
- "execute-task",
29
- "execute-task-simple",
30
- "reactive-execute",
31
- "complete-slice",
32
- "validate-milestone",
33
- ]);
18
+ // Scope-class membership is declared per unit in the Unit Registry (ADR-033).
19
+ // EXECUTE_TASK_UNIT_TYPES = scopeClass "execute-task"; the section-close gate
20
+ // Set additionally includes scopeClass "section-close" — units whose completion
21
+ // handlers persist gate verdicts from artifact sections (gsd_save_gate_result
22
+ // belongs to gate-evaluate, so it is soft-blocked with a redirect below).
23
+ import {
24
+ EXECUTE_TASK_UNIT_TYPES,
25
+ SECTION_CLOSE_GATE_UNIT_TYPES,
26
+ } from "./unit-registry.js";
34
27
 
35
28
  const EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS = [
36
29
  "gsd_skip_slice",
@@ -110,7 +103,7 @@ function isNativeWorkflowTool(toolName: string): boolean {
110
103
  return stripMcpToolPrefix(toolName) === "Workflow";
111
104
  }
112
105
 
113
- function readStringField(input: unknown, camel: string, snake: string): string | undefined {
106
+ export function readStringField(input: unknown, camel: string, snake: string): string | undefined {
114
107
  if (!input || typeof input !== "object") return undefined;
115
108
  const record = input as Record<string, unknown>;
116
109
  const value = record[camel] ?? record[snake];
@@ -5,6 +5,7 @@ import { existsSync, lstatSync, readdirSync, type Stats } from "node:fs";
5
5
  import { join } from "node:path";
6
6
 
7
7
  import { worktreePath } from "./worktree-manager.js";
8
+ import { worktreesDirs } from "./worktree-placement.js";
8
9
  import { normalizeWorktreePathForCompare } from "./worktree-root.js";
9
10
  import type { WorktreeSafetyResult } from "./worktree-safety.js";
10
11
 
@@ -39,6 +40,16 @@ export function expectedAutoWorktreePath(
39
40
  return worktreePath(projectRoot, id);
40
41
  }
41
42
 
43
+ /** Every path the milestone worktree may legitimately live at (canonical + legacy). */
44
+ function candidateAutoWorktreePaths(
45
+ projectRoot: string,
46
+ milestoneId: string | null | undefined,
47
+ ): string[] {
48
+ const id = milestoneId?.trim();
49
+ if (!id || !isValidMilestoneId(id)) return [];
50
+ return worktreesDirs(projectRoot).map((dir) => join(dir, id));
51
+ }
52
+
42
53
  export function resolvePausedAutoWorktreePath(input: {
43
54
  basePath: string;
44
55
  originalBasePath?: string | null;
@@ -82,8 +93,8 @@ export function assessAutoWorktreeRepairTarget(input: {
82
93
  if (!expectedPath) {
83
94
  return { ok: false, reason: "missing expected worktree path" };
84
95
  }
85
- const computedExpectedPath = expectedAutoWorktreePath(input.projectRoot, input.milestoneId);
86
- if (!computedExpectedPath || !samePath(expectedPath, computedExpectedPath)) {
96
+ const candidatePaths = candidateAutoWorktreePaths(input.projectRoot, input.milestoneId);
97
+ if (candidatePaths.length === 0 || !candidatePaths.some((candidate) => samePath(expectedPath, candidate))) {
87
98
  return { ok: false, reason: "expected worktree path does not match milestone" };
88
99
  }
89
100
  if (!samePath(input.activeRoot, input.projectRoot) && !samePath(input.activeRoot, expectedPath)) {