gsd-pi 2.75.0-dev.063e5a3 → 2.75.0-dev.96d4bb599

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 (760) hide show
  1. package/README.md +186 -149
  2. package/dist/claude-cli-check.d.ts +10 -0
  3. package/dist/claude-cli-check.js +13 -3
  4. package/dist/headless-events.d.ts +1 -1
  5. package/dist/headless-events.js +5 -2
  6. package/dist/headless.js +5 -6
  7. package/dist/loader.js +0 -0
  8. package/dist/onboarding.d.ts +20 -1
  9. package/dist/onboarding.js +99 -39
  10. package/dist/resources/extensions/ask-user-questions.js +17 -5
  11. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +12 -2
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +76 -4
  14. package/dist/resources/extensions/gsd/auto/detect-stuck.js +9 -0
  15. package/dist/resources/extensions/gsd/auto/loop.js +67 -4
  16. package/dist/resources/extensions/gsd/auto/phases.js +70 -47
  17. package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
  19. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
  21. package/dist/resources/extensions/gsd/auto-dashboard.js +15 -7
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +112 -6
  23. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +11 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -8
  26. package/dist/resources/extensions/gsd/auto-prompts.js +173 -39
  27. package/dist/resources/extensions/gsd/auto-recovery.js +57 -0
  28. package/dist/resources/extensions/gsd/auto-start.js +5 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +3 -3
  30. package/dist/resources/extensions/gsd/auto-worktree.js +55 -1
  31. package/dist/resources/extensions/gsd/auto.js +57 -25
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
  34. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +128 -0
  35. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
  38. package/dist/resources/extensions/gsd/bootstrap/system-context.js +17 -4
  39. package/dist/resources/extensions/gsd/commands/catalog.js +81 -9
  40. package/dist/resources/extensions/gsd/commands/handlers/core.js +64 -24
  41. package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
  42. package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +159 -0
  43. package/dist/resources/extensions/gsd/commands/handlers/ops.js +21 -0
  44. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +228 -29
  45. package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
  46. package/dist/resources/extensions/gsd/commands-config.js +5 -0
  47. package/dist/resources/extensions/gsd/commands-debug.js +388 -0
  48. package/dist/resources/extensions/gsd/commands-do.js +1 -0
  49. package/dist/resources/extensions/gsd/commands-extract-learnings.js +233 -75
  50. package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
  51. package/dist/resources/extensions/gsd/commands-memory.js +462 -0
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +40 -12
  53. package/dist/resources/extensions/gsd/commands-scan.js +94 -0
  54. package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
  55. package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
  56. package/dist/resources/extensions/gsd/db-writer.js +1 -0
  57. package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
  58. package/dist/resources/extensions/gsd/definition-loader.js +7 -0
  59. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  60. package/dist/resources/extensions/gsd/doctor-environment.js +2 -1
  61. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  62. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
  63. package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
  64. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -4
  65. package/dist/resources/extensions/gsd/doctor.js +7 -1
  66. package/dist/resources/extensions/gsd/error-classifier.js +6 -3
  67. package/dist/resources/extensions/gsd/escalation.js +321 -0
  68. package/dist/resources/extensions/gsd/forensics.js +26 -29
  69. package/dist/resources/extensions/gsd/git-service.js +0 -1
  70. package/dist/resources/extensions/gsd/graph.js +26 -2
  71. package/dist/resources/extensions/gsd/gsd-db.js +490 -32
  72. package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
  73. package/dist/resources/extensions/gsd/health-widget.js +7 -4
  74. package/dist/resources/extensions/gsd/init-wizard.js +86 -45
  75. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -5
  76. package/dist/resources/extensions/gsd/memory-embeddings.js +219 -0
  77. package/dist/resources/extensions/gsd/memory-extractor.js +78 -27
  78. package/dist/resources/extensions/gsd/memory-ingest.js +218 -0
  79. package/dist/resources/extensions/gsd/memory-relations.js +189 -0
  80. package/dist/resources/extensions/gsd/memory-source-store.js +113 -0
  81. package/dist/resources/extensions/gsd/memory-store.js +299 -6
  82. package/dist/resources/extensions/gsd/metrics.js +1 -0
  83. package/dist/resources/extensions/gsd/model-cost-table.js +3 -1
  84. package/dist/resources/extensions/gsd/model-router.js +16 -6
  85. package/dist/resources/extensions/gsd/native-git-bridge.js +137 -5
  86. package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
  87. package/dist/resources/extensions/gsd/notification-widget.js +24 -39
  88. package/dist/resources/extensions/gsd/notifications.js +4 -0
  89. package/dist/resources/extensions/gsd/onboarding-state.js +133 -0
  90. package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
  91. package/dist/resources/extensions/gsd/pre-execution-checks.js +97 -4
  92. package/dist/resources/extensions/gsd/preferences-models.js +1 -0
  93. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  94. package/dist/resources/extensions/gsd/preferences-validation.js +42 -8
  95. package/dist/resources/extensions/gsd/preferences.js +10 -10
  96. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  97. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  98. package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  99. package/dist/resources/extensions/gsd/prompts/execute-task.md +12 -0
  100. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  102. package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
  103. package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  104. package/dist/resources/extensions/gsd/python-resolver.js +70 -0
  105. package/dist/resources/extensions/gsd/run-manager.js +37 -17
  106. package/dist/resources/extensions/gsd/setup-catalog.js +75 -0
  107. package/dist/resources/extensions/gsd/state.js +47 -3
  108. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  109. package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
  110. package/dist/resources/extensions/gsd/tools/memory-tools.js +306 -0
  111. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
  112. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
  113. package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
  114. package/dist/resources/extensions/gsd/uok/flags.js +7 -7
  115. package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
  116. package/dist/resources/extensions/gsd/verification-gate.js +2 -1
  117. package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
  118. package/dist/resources/extensions/gsd/workflow-install.js +327 -0
  119. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -0
  120. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -6
  121. package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
  122. package/dist/resources/extensions/gsd/workflow-projections.js +17 -15
  123. package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  124. package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  125. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  126. package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  127. package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  128. package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  129. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  130. package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  131. package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  132. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  133. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  134. package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  135. package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  136. package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  137. package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  138. package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  139. package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  140. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  141. package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  142. package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
  143. package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  144. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  145. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  146. package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  147. package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  148. package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
  149. package/dist/resources/extensions/remote-questions/commands.js +380 -0
  150. package/dist/resources/extensions/remote-questions/manager.js +39 -5
  151. package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
  152. package/dist/resources/extensions/shared/interview-ui.js +189 -1
  153. package/dist/resources/extensions/shared/layout-utils.js +17 -0
  154. package/dist/resources/extensions/shared/rtk-shared.js +47 -0
  155. package/dist/resources/extensions/shared/rtk.js +3 -46
  156. package/dist/resources/skills/create-workflow/SKILL.md +33 -6
  157. package/dist/rtk-shared.d.ts +10 -0
  158. package/dist/rtk-shared.js +47 -0
  159. package/dist/rtk.d.ts +2 -6
  160. package/dist/rtk.js +3 -48
  161. package/dist/shared/workspace-types.d.ts +52 -0
  162. package/dist/shared/workspace-types.js +1 -0
  163. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  164. package/dist/update-check.d.ts +10 -0
  165. package/dist/update-check.js +24 -3
  166. package/dist/web/standalone/.next/BUILD_ID +1 -1
  167. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  168. package/dist/web/standalone/.next/build-manifest.json +3 -3
  169. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  170. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  171. package/dist/web/standalone/.next/required-server-files.json +1 -1
  172. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  174. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  181. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  183. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  184. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  185. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  190. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  197. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  212. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  218. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  220. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  222. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  223. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  224. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  235. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  236. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  242. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  245. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  247. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  248. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  249. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  254. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/index.html +1 -1
  256. package/dist/web/standalone/.next/server/app/index.rsc +3 -3
  257. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  258. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  259. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  260. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  261. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  262. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  264. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  265. package/dist/web/standalone/.next/server/chunks/7461.js +1 -0
  266. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  267. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  268. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  269. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  270. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  271. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  272. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +9 -0
  273. package/dist/web/standalone/.next/static/chunks/{2008.71ee9230ad78df21.js → 3621.fc7480022c972438.js} +2 -2
  274. package/dist/web/standalone/.next/static/chunks/app/{page-f1e30ab6bb269149.js → page-5b113fd32bc2a1c3.js} +1 -1
  275. package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-5fc74f13a25fa1bb.js} +1 -1
  276. package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
  277. package/dist/web/standalone/server.js +1 -1
  278. package/dist/welcome-screen.js +48 -24
  279. package/dist/wizard.js +2 -2
  280. package/dist/worktree-cli.d.ts +6 -5
  281. package/dist/worktree-cli.js +23 -7
  282. package/package.json +3 -3
  283. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  284. package/packages/mcp-server/dist/server.js +12 -10
  285. package/packages/mcp-server/dist/server.js.map +1 -1
  286. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  287. package/packages/mcp-server/dist/session-manager.js +8 -1
  288. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  289. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -0
  290. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  291. package/packages/mcp-server/dist/workflow-tools.js +113 -14
  292. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  293. package/packages/mcp-server/src/mcp-server.test.ts +40 -4
  294. package/packages/mcp-server/src/server.ts +12 -10
  295. package/packages/mcp-server/src/session-manager.ts +10 -3
  296. package/packages/mcp-server/src/workflow-tools.test.ts +91 -1
  297. package/packages/mcp-server/src/workflow-tools.ts +128 -18
  298. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  299. package/packages/native/tsconfig.tsbuildinfo +1 -1
  300. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  301. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/models/capability-patches.js +3 -2
  303. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  304. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +68 -0
  305. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -1
  306. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +68 -0
  307. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -1
  308. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +17 -0
  309. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -1
  310. package/packages/pi-ai/dist/models/generated/anthropic.js +17 -0
  311. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -1
  312. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +17 -0
  313. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/models/generated/google-antigravity.js +17 -0
  315. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -1
  316. package/packages/pi-ai/dist/models/generated/groq.d.ts +0 -153
  317. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/models/generated/groq.js +0 -153
  319. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -1
  320. package/packages/pi-ai/dist/models/generated/index.d.ts +136 -153
  321. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  322. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  323. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  324. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  325. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  326. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +17 -0
  327. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -1
  328. package/packages/pi-ai/dist/models/generated/openrouter.js +17 -0
  329. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -1
  330. package/packages/pi-ai/dist/models.generated.test.js +17 -0
  331. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  332. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
  333. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  334. package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -6
  335. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  336. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
  337. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
  338. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
  339. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
  340. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
  341. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  342. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +20 -1
  343. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  344. package/packages/pi-ai/dist/providers/anthropic-shared.js +32 -2
  345. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  346. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
  347. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  348. package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
  349. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/anthropic.js +18 -1
  351. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  352. package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  353. package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
  354. package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  355. package/packages/pi-ai/package.json +1 -1
  356. package/packages/pi-ai/scripts/generate-models.ts +50 -0
  357. package/packages/pi-ai/src/models/capability-patches.ts +5 -2
  358. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +68 -0
  359. package/packages/pi-ai/src/models/generated/anthropic.ts +17 -0
  360. package/packages/pi-ai/src/models/generated/google-antigravity.ts +17 -0
  361. package/packages/pi-ai/src/models/generated/groq.ts +0 -153
  362. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  363. package/packages/pi-ai/src/models/generated/openrouter.ts +17 -0
  364. package/packages/pi-ai/src/models.generated.test.ts +17 -0
  365. package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
  366. package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -7
  367. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
  368. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
  369. package/packages/pi-ai/src/providers/anthropic-shared.ts +36 -3
  370. package/packages/pi-ai/src/providers/anthropic.ts +19 -1
  371. package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
  372. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  373. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
  374. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
  375. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
  376. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
  377. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +14 -0
  378. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/auth-storage.js +34 -0
  380. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +74 -0
  382. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +4 -1
  384. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
  386. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/sdk.js +32 -0
  389. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
  391. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  392. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  393. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +17 -7
  394. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  395. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  396. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
  397. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
  399. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  400. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +83 -33
  401. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  402. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  403. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  404. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +77 -0
  405. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  406. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -66
  407. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
  409. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
  411. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  412. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +192 -24
  413. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  414. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
  415. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +83 -0
  416. package/packages/pi-coding-agent/src/core/auth-storage.ts +35 -0
  417. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +4 -1
  418. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
  419. package/packages/pi-coding-agent/src/core/sdk.ts +41 -0
  420. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
  421. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +19 -7
  422. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
  423. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +88 -36
  424. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +83 -0
  425. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +2 -83
  426. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +208 -27
  427. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  428. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  429. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  430. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  431. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  432. package/pkg/dist/modes/interactive/theme/theme-schema.js +77 -0
  433. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  434. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -66
  435. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  436. package/pkg/dist/modes/interactive/theme/theme.js +1 -75
  437. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  438. package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
  439. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  440. package/pkg/dist/modes/interactive/theme/themes.js +192 -24
  441. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  442. package/src/resources/extensions/ask-user-questions.ts +24 -6
  443. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  444. package/src/resources/extensions/claude-code-cli/readiness.ts +13 -2
  445. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +94 -4
  446. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +84 -0
  447. package/src/resources/extensions/gsd/auto/detect-stuck.ts +10 -0
  448. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  449. package/src/resources/extensions/gsd/auto/loop.ts +109 -3
  450. package/src/resources/extensions/gsd/auto/phases.ts +94 -60
  451. package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
  452. package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
  453. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  454. package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
  455. package/src/resources/extensions/gsd/auto-dashboard.ts +21 -4
  456. package/src/resources/extensions/gsd/auto-dispatch.ts +123 -5
  457. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  458. package/src/resources/extensions/gsd/auto-model-selection.ts +14 -3
  459. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -8
  460. package/src/resources/extensions/gsd/auto-prompts.ts +201 -40
  461. package/src/resources/extensions/gsd/auto-recovery.ts +63 -1
  462. package/src/resources/extensions/gsd/auto-start.ts +8 -6
  463. package/src/resources/extensions/gsd/auto-verification.ts +3 -3
  464. package/src/resources/extensions/gsd/auto-worktree.ts +65 -0
  465. package/src/resources/extensions/gsd/auto.ts +61 -28
  466. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
  467. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
  468. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +158 -0
  469. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
  470. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  471. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  472. package/src/resources/extensions/gsd/bootstrap/system-context.ts +20 -4
  473. package/src/resources/extensions/gsd/commands/catalog.ts +74 -9
  474. package/src/resources/extensions/gsd/commands/handlers/core.ts +69 -27
  475. package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
  476. package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +196 -0
  477. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  478. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +279 -29
  479. package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
  480. package/src/resources/extensions/gsd/commands-config.ts +10 -0
  481. package/src/resources/extensions/gsd/commands-debug.ts +484 -0
  482. package/src/resources/extensions/gsd/commands-do.ts +1 -0
  483. package/src/resources/extensions/gsd/commands-extract-learnings.ts +295 -76
  484. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  485. package/src/resources/extensions/gsd/commands-memory.ts +551 -0
  486. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -12
  487. package/src/resources/extensions/gsd/commands-scan.ts +125 -0
  488. package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
  489. package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
  490. package/src/resources/extensions/gsd/db-writer.ts +3 -0
  491. package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
  492. package/src/resources/extensions/gsd/definition-loader.ts +7 -0
  493. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  494. package/src/resources/extensions/gsd/doctor-environment.ts +2 -1
  495. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -1
  496. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
  497. package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
  498. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +23 -4
  499. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  500. package/src/resources/extensions/gsd/doctor.ts +7 -1
  501. package/src/resources/extensions/gsd/error-classifier.ts +6 -3
  502. package/src/resources/extensions/gsd/escalation.ts +367 -0
  503. package/src/resources/extensions/gsd/forensics.ts +25 -29
  504. package/src/resources/extensions/gsd/git-service.ts +0 -1
  505. package/src/resources/extensions/gsd/graph.ts +33 -3
  506. package/src/resources/extensions/gsd/gsd-db.ts +578 -32
  507. package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
  508. package/src/resources/extensions/gsd/health-widget.ts +7 -3
  509. package/src/resources/extensions/gsd/init-wizard.ts +87 -54
  510. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -5
  511. package/src/resources/extensions/gsd/memory-embeddings.ts +235 -0
  512. package/src/resources/extensions/gsd/memory-extractor.ts +100 -34
  513. package/src/resources/extensions/gsd/memory-ingest.ts +286 -0
  514. package/src/resources/extensions/gsd/memory-relations.ts +240 -0
  515. package/src/resources/extensions/gsd/memory-source-store.ts +138 -0
  516. package/src/resources/extensions/gsd/memory-store.ts +351 -7
  517. package/src/resources/extensions/gsd/metrics.ts +1 -0
  518. package/src/resources/extensions/gsd/model-cost-table.ts +3 -1
  519. package/src/resources/extensions/gsd/model-router.ts +25 -6
  520. package/src/resources/extensions/gsd/native-git-bridge.ts +134 -6
  521. package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
  522. package/src/resources/extensions/gsd/notification-widget.ts +25 -43
  523. package/src/resources/extensions/gsd/notifications.ts +6 -0
  524. package/src/resources/extensions/gsd/onboarding-state.ts +146 -0
  525. package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
  526. package/src/resources/extensions/gsd/pre-execution-checks.ts +98 -8
  527. package/src/resources/extensions/gsd/preferences-models.ts +1 -0
  528. package/src/resources/extensions/gsd/preferences-types.ts +10 -2
  529. package/src/resources/extensions/gsd/preferences-validation.ts +33 -7
  530. package/src/resources/extensions/gsd/preferences.ts +10 -10
  531. package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  532. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  533. package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  534. package/src/resources/extensions/gsd/prompts/execute-task.md +12 -0
  535. package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  536. package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  537. package/src/resources/extensions/gsd/prompts/scan.md +79 -0
  538. package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  539. package/src/resources/extensions/gsd/python-resolver.ts +76 -0
  540. package/src/resources/extensions/gsd/run-manager.ts +53 -19
  541. package/src/resources/extensions/gsd/setup-catalog.ts +105 -0
  542. package/src/resources/extensions/gsd/state.ts +50 -2
  543. package/src/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  544. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
  545. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
  546. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +45 -31
  547. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +63 -0
  548. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +12 -0
  549. package/src/resources/extensions/gsd/tests/auto-prompts-fallback.test.ts +35 -0
  550. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
  551. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
  552. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
  553. package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
  554. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +333 -21
  555. package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
  556. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +8 -6
  557. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +6 -8
  558. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  559. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
  560. package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
  561. package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
  562. package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
  563. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
  564. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
  565. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
  566. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
  567. package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
  568. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +29 -12
  569. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +106 -0
  570. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
  571. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
  572. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
  573. package/src/resources/extensions/gsd/tests/health-widget.test.ts +8 -2
  574. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +190 -0
  575. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +39 -0
  576. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
  577. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +68 -1
  578. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +109 -11
  579. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
  580. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +2 -2
  581. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  582. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +171 -1
  583. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  584. package/src/resources/extensions/gsd/tests/memory-embeddings.test.ts +213 -0
  585. package/src/resources/extensions/gsd/tests/memory-ingest.test.ts +153 -0
  586. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +107 -0
  587. package/src/resources/extensions/gsd/tests/memory-relations.test.ts +175 -0
  588. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  589. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +295 -0
  590. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
  591. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
  592. package/src/resources/extensions/gsd/tests/model-router.test.ts +51 -1
  593. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
  594. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
  595. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
  596. package/src/resources/extensions/gsd/tests/onboarding-state.test.ts +105 -0
  597. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +114 -0
  598. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +4 -5
  599. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
  600. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
  601. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +275 -6
  602. package/src/resources/extensions/gsd/tests/preferences.test.ts +69 -1
  603. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
  604. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +11 -2
  605. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
  606. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +27 -0
  607. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
  608. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
  609. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +33 -0
  610. package/src/resources/extensions/gsd/tests/python-resolver.test.ts +131 -0
  611. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +67 -0
  612. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
  613. package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
  614. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
  615. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
  616. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
  617. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
  618. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
  619. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
  620. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +2 -1
  621. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +31 -1
  622. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
  623. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +35 -0
  624. package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
  625. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +15 -6
  626. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  627. package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
  628. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
  629. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
  630. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
  631. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
  632. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  633. package/src/resources/extensions/gsd/tools/memory-tools.ts +380 -0
  634. package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
  635. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
  636. package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
  637. package/src/resources/extensions/gsd/types.ts +62 -0
  638. package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
  639. package/src/resources/extensions/gsd/uok/contracts.ts +2 -1
  640. package/src/resources/extensions/gsd/uok/flags.ts +7 -7
  641. package/src/resources/extensions/gsd/uok/kernel.ts +16 -4
  642. package/src/resources/extensions/gsd/verification-gate.ts +2 -1
  643. package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
  644. package/src/resources/extensions/gsd/workflow-install.ts +423 -0
  645. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  646. package/src/resources/extensions/gsd/workflow-manifest.ts +8 -0
  647. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -6
  648. package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
  649. package/src/resources/extensions/gsd/workflow-projections.ts +18 -16
  650. package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  651. package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  652. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  653. package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  654. package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  655. package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  656. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  657. package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  658. package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  659. package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  660. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  661. package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  662. package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  663. package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  664. package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  665. package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  666. package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  667. package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  668. package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  669. package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
  670. package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  671. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  672. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  673. package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  674. package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  675. package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
  676. package/src/resources/extensions/gsd/workspace-index.ts +9 -4
  677. package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
  678. package/src/resources/extensions/remote-questions/commands.ts +480 -0
  679. package/src/resources/extensions/remote-questions/manager.ts +49 -4
  680. package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
  681. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
  682. package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
  683. package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
  684. package/src/resources/extensions/shared/interview-ui.ts +195 -1
  685. package/src/resources/extensions/shared/layout-utils.ts +26 -0
  686. package/src/resources/extensions/shared/rtk-shared.ts +58 -0
  687. package/src/resources/extensions/shared/rtk.ts +12 -52
  688. package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
  689. package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
  690. package/src/resources/skills/create-workflow/SKILL.md +33 -6
  691. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
  692. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  693. package/packages/native/dist/ps/types.d.ts +0 -5
  694. package/packages/native/dist/ps/types.js +0 -2
  695. package/packages/native/src/ps/types.ts +0 -5
  696. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
  697. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
  698. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
  699. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
  700. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
  701. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
  702. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
  703. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
  704. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
  705. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
  706. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
  707. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
  708. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
  709. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
  710. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
  711. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
  712. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
  713. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
  714. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
  715. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
  716. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
  717. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
  718. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
  719. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
  720. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
  721. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
  722. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
  723. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
  724. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
  725. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
  726. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
  727. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
  728. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
  729. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
  730. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
  731. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
  732. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
  733. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
  734. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
  735. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
  736. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
  737. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
  738. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
  739. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
  740. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
  741. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
  742. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
  743. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
  744. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
  745. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
  746. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
  747. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
  748. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
  749. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
  750. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
  751. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
  752. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
  753. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
  754. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
  755. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
  756. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
  757. package/packages/pi-ai/oauth.d.ts +0 -1
  758. package/packages/pi-ai/oauth.js +0 -1
  759. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → o61X3klsB6C0UE0X1x3PA}/_buildManifest.js +0 -0
  760. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → o61X3klsB6C0UE0X1x3PA}/_ssgManifest.js +0 -0
@@ -0,0 +1,818 @@
1
+ // GSD Extension — ADR-011 Phase 2 Mid-Execution Escalation tests
2
+ // Covers: artifact write/read, detection, resolution (A|B|accept|reject-blocker),
3
+ // DB claim race, carry-forward injection, schema v16/v17 migration, feature flag.
4
+
5
+ import test from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { tmpdir } from "node:os";
10
+
11
+ import {
12
+ openDatabase,
13
+ closeDatabase,
14
+ insertMilestone,
15
+ insertSlice,
16
+ insertTask,
17
+ updateTaskStatus,
18
+ getTask,
19
+ claimEscalationOverride,
20
+ findUnappliedEscalationOverride,
21
+ listEscalationArtifacts,
22
+ _getAdapter,
23
+ } from "../gsd-db.ts";
24
+ import {
25
+ buildEscalationArtifact,
26
+ writeEscalationArtifact,
27
+ readEscalationArtifact,
28
+ detectPendingEscalation,
29
+ resolveEscalation,
30
+ claimOverrideForInjection,
31
+ escalationArtifactPath,
32
+ } from "../escalation.ts";
33
+ import type { EscalationOption } from "../types.ts";
34
+
35
+ // ─── Fixture helpers ──────────────────────────────────────────────────────
36
+
37
+ function makeBase(): string {
38
+ const base = mkdtempSync(join(tmpdir(), "gsd-adr011-p2-"));
39
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
40
+ return base;
41
+ }
42
+
43
+ function cleanup(base: string): void {
44
+ try { closeDatabase(); } catch { /* noop */ }
45
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* noop */ }
46
+ }
47
+
48
+ function writePrefs(base: string, enabled: boolean): void {
49
+ const path = join(base, ".gsd", "PREFERENCES.md");
50
+ writeFileSync(path, [
51
+ "---",
52
+ "version: 1",
53
+ "phases:",
54
+ ` mid_execution_escalation: ${enabled}`,
55
+ "---",
56
+ ].join("\n"));
57
+ }
58
+
59
+ function seedCompletedTask(base: string, taskId: string): void {
60
+ openDatabase(join(base, ".gsd", "gsd.db"));
61
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
62
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Slice" });
63
+ insertTask({
64
+ id: taskId, sliceId: "S01", milestoneId: "M001", title: "Task",
65
+ status: "complete",
66
+ });
67
+ }
68
+
69
+ const sampleOptions: EscalationOption[] = [
70
+ { id: "A", label: "Separate table", tradeoffs: "More flexible; requires migration." },
71
+ { id: "B", label: "JSON array", tradeoffs: "Simpler; limited to ~1000 entries." },
72
+ ];
73
+
74
+ // ═══════════════════════════════════════════════════════════════════════════
75
+ // Tests
76
+ // ═══════════════════════════════════════════════════════════════════════════
77
+
78
+ test("ADR-011 P2: writeEscalationArtifact persists canonical JSON at tasks/T##-ESCALATION.json", (t) => {
79
+ const base = makeBase();
80
+ t.after(() => cleanup(base));
81
+ seedCompletedTask(base, "T03");
82
+
83
+ const art = buildEscalationArtifact({
84
+ taskId: "T03", sliceId: "S01", milestoneId: "M001",
85
+ question: "Where should we store notifications?",
86
+ options: sampleOptions,
87
+ recommendation: "B",
88
+ recommendationRationale: "Single-user display only.",
89
+ continueWithDefault: false,
90
+ });
91
+ const path = writeEscalationArtifact(base, art);
92
+ assert.ok(existsSync(path), "artifact file must exist");
93
+ assert.ok(path.endsWith("/tasks/T03-ESCALATION.json"), `path should end with tasks/T03-ESCALATION.json, got ${path}`);
94
+
95
+ const roundTrip = readEscalationArtifact(path);
96
+ assert.ok(roundTrip, "artifact must round-trip");
97
+ assert.equal(roundTrip!.taskId, "T03");
98
+ assert.equal(roundTrip!.recommendation, "B");
99
+ assert.equal(roundTrip!.options.length, 2);
100
+
101
+ // DB flag flipped to pending (continueWithDefault=false).
102
+ const row = getTask("M001", "S01", "T03");
103
+ assert.equal(row?.escalation_pending, 1);
104
+ assert.equal(row?.escalation_awaiting_review, 0);
105
+ assert.equal(row?.escalation_artifact_path, path);
106
+ });
107
+
108
+ test("ADR-011 P2: continueWithDefault=true sets awaiting_review (NOT pending) — no pause", (t) => {
109
+ const base = makeBase();
110
+ t.after(() => cleanup(base));
111
+ seedCompletedTask(base, "T04");
112
+
113
+ const art = buildEscalationArtifact({
114
+ taskId: "T04", sliceId: "S01", milestoneId: "M001",
115
+ question: "Q",
116
+ options: sampleOptions,
117
+ recommendation: "A",
118
+ recommendationRationale: "r",
119
+ continueWithDefault: true,
120
+ });
121
+ writeEscalationArtifact(base, art);
122
+
123
+ const row = getTask("M001", "S01", "T04");
124
+ assert.equal(row?.escalation_pending, 0, "fire-and-correct must NOT set escalation_pending");
125
+ assert.equal(row?.escalation_awaiting_review, 1);
126
+ });
127
+
128
+ test("ADR-011 P2: detectPendingEscalation returns only pause-scoped escalations", (t) => {
129
+ const base = makeBase();
130
+ t.after(() => cleanup(base));
131
+ seedCompletedTask(base, "T01");
132
+ seedCompletedTask(base, "T02");
133
+
134
+ // T01: continueWithDefault=true (awaiting_review, not pending)
135
+ writeEscalationArtifact(base, buildEscalationArtifact({
136
+ taskId: "T01", sliceId: "S01", milestoneId: "M001",
137
+ question: "Q1", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
138
+ continueWithDefault: true,
139
+ }));
140
+ // T02: continueWithDefault=false (pause)
141
+ writeEscalationArtifact(base, buildEscalationArtifact({
142
+ taskId: "T02", sliceId: "S01", milestoneId: "M001",
143
+ question: "Q2", options: sampleOptions, recommendation: "B", recommendationRationale: "r",
144
+ continueWithDefault: false,
145
+ }));
146
+
147
+ const tasks = [getTask("M001", "S01", "T01")!, getTask("M001", "S01", "T02")!];
148
+ const id = detectPendingEscalation(tasks, base);
149
+ assert.equal(id, "T02", "only T02 is pause-worthy; T01 is awaiting_review");
150
+ });
151
+
152
+ test("ADR-011 P2: resolveEscalation(accept) marks artifact + clears flags", (t) => {
153
+ const base = makeBase();
154
+ t.after(() => cleanup(base));
155
+ seedCompletedTask(base, "T05");
156
+
157
+ writeEscalationArtifact(base, buildEscalationArtifact({
158
+ taskId: "T05", sliceId: "S01", milestoneId: "M001",
159
+ question: "Q", options: sampleOptions, recommendation: "B", recommendationRationale: "r",
160
+ continueWithDefault: false,
161
+ }));
162
+
163
+ const result = resolveEscalation(base, "M001", "S01", "T05", "accept", "looks good");
164
+ assert.equal(result.status, "resolved");
165
+ assert.equal(result.chosenOption?.id, "B");
166
+
167
+ const row = getTask("M001", "S01", "T05");
168
+ assert.equal(row?.escalation_pending, 0);
169
+ assert.equal(row?.escalation_awaiting_review, 0);
170
+
171
+ const artPath = escalationArtifactPath(base, "M001", "S01", "T05")!;
172
+ const art = readEscalationArtifact(artPath);
173
+ assert.ok(art?.respondedAt, "artifact must record respondedAt");
174
+ assert.equal(art?.userChoice, "accept");
175
+ assert.equal(art?.userRationale, "looks good");
176
+ });
177
+
178
+ test("ADR-011 P2: resolveEscalation(reject-blocker) sets blocker_discovered + blocker_source", (t) => {
179
+ const base = makeBase();
180
+ t.after(() => cleanup(base));
181
+ seedCompletedTask(base, "T06");
182
+
183
+ writeEscalationArtifact(base, buildEscalationArtifact({
184
+ taskId: "T06", sliceId: "S01", milestoneId: "M001",
185
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
186
+ continueWithDefault: false,
187
+ }));
188
+
189
+ const result = resolveEscalation(base, "M001", "S01", "T06", "reject-blocker", "none of these work");
190
+ assert.equal(result.status, "rejected-to-blocker");
191
+
192
+ const row = getTask("M001", "S01", "T06");
193
+ assert.equal(row?.blocker_discovered, true, "reject-blocker must flip blocker_discovered=1");
194
+ assert.equal(row?.blocker_source, "reject-escalation", "blocker_source must record provenance");
195
+ assert.equal(row?.escalation_pending, 0);
196
+ });
197
+
198
+ test("ADR-011 P2: resolveEscalation(invalid-choice) returns error + leaves state untouched", (t) => {
199
+ const base = makeBase();
200
+ t.after(() => cleanup(base));
201
+ seedCompletedTask(base, "T07");
202
+
203
+ writeEscalationArtifact(base, buildEscalationArtifact({
204
+ taskId: "T07", sliceId: "S01", milestoneId: "M001",
205
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
206
+ continueWithDefault: false,
207
+ }));
208
+
209
+ const result = resolveEscalation(base, "M001", "S01", "T07", "Z", "");
210
+ assert.equal(result.status, "invalid-choice");
211
+
212
+ // State must NOT have changed.
213
+ const row = getTask("M001", "S01", "T07");
214
+ assert.equal(row?.escalation_pending, 1, "flag must still be pending after invalid choice");
215
+ });
216
+
217
+ test("ADR-011 P2: claimEscalationOverride is atomic — only one claimer wins the race", (t) => {
218
+ const base = makeBase();
219
+ t.after(() => cleanup(base));
220
+ seedCompletedTask(base, "T08");
221
+
222
+ writeEscalationArtifact(base, buildEscalationArtifact({
223
+ taskId: "T08", sliceId: "S01", milestoneId: "M001",
224
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
225
+ continueWithDefault: false,
226
+ }));
227
+ resolveEscalation(base, "M001", "S01", "T08", "A", "pick A");
228
+
229
+ const first = claimEscalationOverride("M001", "S01", "T08");
230
+ const second = claimEscalationOverride("M001", "S01", "T08");
231
+ assert.equal(first, true, "first claim wins");
232
+ assert.equal(second, false, "second claim must fail — override already applied");
233
+ });
234
+
235
+ test("ADR-011 P2: claimOverrideForInjection returns null when flag ON but no unapplied override", (t) => {
236
+ const base = makeBase();
237
+ t.after(() => cleanup(base));
238
+ seedCompletedTask(base, "T09");
239
+
240
+ const claimed = claimOverrideForInjection(base, "M001", "S01");
241
+ assert.equal(claimed, null);
242
+ });
243
+
244
+ test("ADR-011 P2: claim does NOT fire on unresolved awaiting_review — resolution is preserved until user responds", (t) => {
245
+ // Regression for peer-review Bug 2: previously findUnappliedEscalationOverride
246
+ // matched `escalation_pending=0` alone, so an awaiting_review task (created
247
+ // by continueWithDefault=true) was silently claimed before the user had
248
+ // a chance to resolve, permanently dropping the override.
249
+ const base = makeBase();
250
+ t.after(() => cleanup(base));
251
+ seedCompletedTask(base, "T09a");
252
+ seedCompletedTask(base, "T09b");
253
+
254
+ // Write a continueWithDefault=true artifact (awaiting_review=1, no respondedAt).
255
+ writeEscalationArtifact(base, buildEscalationArtifact({
256
+ taskId: "T09a", sliceId: "S01", milestoneId: "M001",
257
+ question: "Which DB?", options: sampleOptions,
258
+ recommendation: "A", recommendationRationale: "r",
259
+ continueWithDefault: true,
260
+ }));
261
+
262
+ // NEXT task's prompt build — must NOT claim the unresolved awaiting_review.
263
+ const premature = claimOverrideForInjection(base, "M001", "S01");
264
+ assert.equal(premature, null, "awaiting_review without respondedAt must not be claimed");
265
+
266
+ const midState = getTask("M001", "S01", "T09a");
267
+ assert.equal(midState?.escalation_override_applied_at, null, "applied_at must still be null");
268
+
269
+ // User now resolves.
270
+ resolveEscalation(base, "M001", "S01", "T09a", "B", "actually B is better");
271
+
272
+ // NEXT task's prompt build — NOW the override must be claimed and injected.
273
+ const claimed = claimOverrideForInjection(base, "M001", "S01");
274
+ assert.ok(claimed, "after user resolution, the override must be injectable");
275
+ assert.equal(claimed!.sourceTaskId, "T09a");
276
+ assert.match(claimed!.injectionBlock, /Escalation Override/);
277
+ });
278
+
279
+ test("ADR-011 P2: claimOverrideForInjection returns markdown block once, then null", (t) => {
280
+ const base = makeBase();
281
+ t.after(() => cleanup(base));
282
+ seedCompletedTask(base, "T10");
283
+
284
+ writeEscalationArtifact(base, buildEscalationArtifact({
285
+ taskId: "T10", sliceId: "S01", milestoneId: "M001",
286
+ question: "Which storage?",
287
+ options: sampleOptions,
288
+ recommendation: "A",
289
+ recommendationRationale: "r",
290
+ continueWithDefault: false,
291
+ }));
292
+ resolveEscalation(base, "M001", "S01", "T10", "A", "pick A");
293
+
294
+ const first = claimOverrideForInjection(base, "M001", "S01");
295
+ assert.ok(first, "first claim returns the override");
296
+ assert.match(first!.injectionBlock, /Escalation Override/);
297
+ assert.equal(first!.sourceTaskId, "T10");
298
+
299
+ const second = claimOverrideForInjection(base, "M001", "S01");
300
+ assert.equal(second, null, "second call returns null (idempotent)");
301
+ });
302
+
303
+ test("ADR-011 P2: listEscalationArtifacts filters to actionable by default", (t) => {
304
+ const base = makeBase();
305
+ t.after(() => cleanup(base));
306
+ seedCompletedTask(base, "T11");
307
+ seedCompletedTask(base, "T12");
308
+
309
+ // Pending (actionable)
310
+ writeEscalationArtifact(base, buildEscalationArtifact({
311
+ taskId: "T11", sliceId: "S01", milestoneId: "M001",
312
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
313
+ continueWithDefault: false,
314
+ }));
315
+ // Resolved (not actionable by default)
316
+ writeEscalationArtifact(base, buildEscalationArtifact({
317
+ taskId: "T12", sliceId: "S01", milestoneId: "M001",
318
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
319
+ continueWithDefault: false,
320
+ }));
321
+ resolveEscalation(base, "M001", "S01", "T12", "A", "");
322
+
323
+ const actionable = listEscalationArtifacts("M001", false);
324
+ const all = listEscalationArtifacts("M001", true);
325
+ assert.equal(actionable.length, 1, "only T11 is actionable");
326
+ assert.equal(actionable[0]!.id, "T11");
327
+ assert.equal(all.length, 2, "both surface with --all");
328
+ });
329
+
330
+ test("ADR-011 P2: schema v20 fresh DB has all escalation columns on tasks + source on decisions", (t) => {
331
+ const base = makeBase();
332
+ t.after(() => cleanup(base));
333
+ openDatabase(join(base, ".gsd", "gsd.db"));
334
+
335
+ const adapter = _getAdapter()!;
336
+ const tasksCols = adapter.prepare("PRAGMA table_info(tasks)").all().map((r) => r["name"] as string);
337
+ for (const col of [
338
+ "blocker_source",
339
+ "escalation_pending",
340
+ "escalation_awaiting_review",
341
+ "escalation_artifact_path",
342
+ "escalation_override_applied_at",
343
+ ]) {
344
+ assert.ok(tasksCols.includes(col), `tasks table must have ${col} column`);
345
+ }
346
+
347
+ const decCols = adapter.prepare("PRAGMA table_info(decisions)").all().map((r) => r["name"] as string);
348
+ assert.ok(decCols.includes("source"), "decisions table must have source column");
349
+
350
+ const version = adapter.prepare("SELECT MAX(version) as v FROM schema_version").get();
351
+ assert.equal(version?.["v"], 20);
352
+ });
353
+
354
+ test("ADR-011 P2: findUnappliedEscalationOverride returns null when escalation_pending=1 (still pending)", (t) => {
355
+ const base = makeBase();
356
+ t.after(() => cleanup(base));
357
+ seedCompletedTask(base, "T13");
358
+
359
+ writeEscalationArtifact(base, buildEscalationArtifact({
360
+ taskId: "T13", sliceId: "S01", milestoneId: "M001",
361
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
362
+ continueWithDefault: false,
363
+ }));
364
+
365
+ // Don't resolve — just query.
366
+ const found = findUnappliedEscalationOverride("M001", "S01");
367
+ assert.equal(found, null, "pending escalation must not surface as unapplied override");
368
+ });
369
+
370
+ // ═══════════════════════════════════════════════════════════════════════════
371
+ // ADR-011 Phase 3 integration-style tests (concurrent / timeout / recovery /
372
+ // latency — adapted from refine-slice phase patterns).
373
+ // ═══════════════════════════════════════════════════════════════════════════
374
+
375
+ test("ADR-011 P3: concurrent escalations queue in arrival order — list returns multiple", (t) => {
376
+ const base = makeBase();
377
+ t.after(() => cleanup(base));
378
+ seedCompletedTask(base, "T20");
379
+ seedCompletedTask(base, "T21");
380
+
381
+ writeEscalationArtifact(base, buildEscalationArtifact({
382
+ taskId: "T20", sliceId: "S01", milestoneId: "M001",
383
+ question: "Q1", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
384
+ continueWithDefault: false,
385
+ }));
386
+ writeEscalationArtifact(base, buildEscalationArtifact({
387
+ taskId: "T21", sliceId: "S01", milestoneId: "M001",
388
+ question: "Q2", options: sampleOptions, recommendation: "B", recommendationRationale: "r",
389
+ continueWithDefault: false,
390
+ }));
391
+
392
+ const pending = listEscalationArtifacts("M001", false);
393
+ assert.equal(pending.length, 2);
394
+ // Both are pause-worthy — state derivation returns the first.
395
+ const first = detectPendingEscalation([getTask("M001", "S01", "T20")!, getTask("M001", "S01", "T21")!], base);
396
+ assert.equal(first, "T20", "detection returns first pending in arrival order");
397
+ });
398
+
399
+ test("ADR-011 P3: recovery — malformed artifact returns null from read, does not crash", (t) => {
400
+ const base = makeBase();
401
+ t.after(() => cleanup(base));
402
+ seedCompletedTask(base, "T22");
403
+
404
+ const artPath = escalationArtifactPath(base, "M001", "S01", "T22")!;
405
+ mkdirSync(join(artPath, ".."), { recursive: true });
406
+ writeFileSync(artPath, "{ this is not json");
407
+ const result = readEscalationArtifact(artPath);
408
+ assert.equal(result, null, "malformed JSON must return null (no throw)");
409
+ });
410
+
411
+ test("ADR-011 P3: resolve-on-missing-artifact returns not-found without partial state", (t) => {
412
+ const base = makeBase();
413
+ t.after(() => cleanup(base));
414
+ seedCompletedTask(base, "T23");
415
+
416
+ const result = resolveEscalation(base, "M001", "S01", "T23", "A", "");
417
+ assert.equal(result.status, "not-found");
418
+ const row = getTask("M001", "S01", "T23");
419
+ assert.equal(row?.escalation_pending, 0, "untouched");
420
+ });
421
+
422
+ test("ADR-011 P3: escalation write + detect latency — 20 tasks, one escalation, detection under 100ms", (t) => {
423
+ const base = makeBase();
424
+ t.after(() => cleanup(base));
425
+ openDatabase(join(base, ".gsd", "gsd.db"));
426
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
427
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Slice" });
428
+ for (let i = 1; i <= 20; i++) {
429
+ const tid = `T${String(i).padStart(2, "0")}`;
430
+ insertTask({ id: tid, sliceId: "S01", milestoneId: "M001", title: `Task ${i}`, status: "complete" });
431
+ }
432
+ // Escalation on T15 only.
433
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
434
+ writeEscalationArtifact(base, buildEscalationArtifact({
435
+ taskId: "T15", sliceId: "S01", milestoneId: "M001",
436
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
437
+ continueWithDefault: false,
438
+ }));
439
+
440
+ const tasks = Array.from({ length: 20 }, (_, i) => getTask("M001", "S01", `T${String(i + 1).padStart(2, "0")}`)!);
441
+ const start = Date.now();
442
+ const found = detectPendingEscalation(tasks, base);
443
+ const elapsed = Date.now() - start;
444
+ assert.equal(found, "T15");
445
+ assert.ok(elapsed < 100, `detection must complete under 100ms, took ${elapsed}ms`);
446
+ });
447
+
448
+ // ═══════════════════════════════════════════════════════════════════════════
449
+ // ADR-011 Phase 3 — Integration: Mid-Execution Escalation
450
+ // ═══════════════════════════════════════════════════════════════════════════
451
+
452
+ test("ADR-011 P3 #20: E2E escalation lifecycle — write → pause → resolve → resume via override injection", (t) => {
453
+ // Exercises the full escalation loop across two tasks in one slice:
454
+ // 1. Executor writes ESCALATION.json on T30 with continueWithDefault=false.
455
+ // 2. detectPendingEscalation returns T30 (state.ts:998 is what pauses the loop).
456
+ // 3. User calls resolveEscalation with a specific option choice.
457
+ // 4. detectPendingEscalation returns null — pause condition cleared.
458
+ // 5. The *next* task (T31) in the slice picks up the override block via
459
+ // claimOverrideForInjection exactly once (idempotent across retries).
460
+ const base = makeBase();
461
+ t.after(() => cleanup(base));
462
+ seedCompletedTask(base, "T30");
463
+ seedCompletedTask(base, "T31");
464
+
465
+ // Step 1: executor escalates on T30 (pause-scoped).
466
+ writeEscalationArtifact(base, buildEscalationArtifact({
467
+ taskId: "T30", sliceId: "S01", milestoneId: "M001",
468
+ question: "Storage format for the new metrics table?",
469
+ options: sampleOptions, recommendation: "A", recommendationRationale: "A is simpler",
470
+ continueWithDefault: false,
471
+ }));
472
+
473
+ // Step 2: scheduler sees the pause signal.
474
+ let tasks = [getTask("M001", "S01", "T30")!, getTask("M001", "S01", "T31")!];
475
+ assert.equal(
476
+ detectPendingEscalation(tasks, base),
477
+ "T30",
478
+ "scheduler must pause on T30 before dispatching T31",
479
+ );
480
+
481
+ // Claim attempted mid-pause must fail (override not yet resolved).
482
+ assert.equal(
483
+ claimOverrideForInjection(base, "M001", "S01"),
484
+ null,
485
+ "no injection should fire while escalation is still pending",
486
+ );
487
+
488
+ // Step 3: user responds with option B + rationale.
489
+ const result = resolveEscalation(base, "M001", "S01", "T30", "B", "B fits better");
490
+ assert.equal(result.status, "resolved");
491
+ assert.equal(result.chosenOption?.id, "B");
492
+
493
+ // Step 4: pause condition clears.
494
+ tasks = [getTask("M001", "S01", "T30")!, getTask("M001", "S01", "T31")!];
495
+ assert.equal(
496
+ detectPendingEscalation(tasks, base),
497
+ null,
498
+ "after resolve, scheduler must not re-pause on T30",
499
+ );
500
+
501
+ // Step 5: next task (T31) picks up the override exactly once.
502
+ const injected = claimOverrideForInjection(base, "M001", "S01");
503
+ assert.ok(injected, "T31's prompt build must claim the resolved override");
504
+ assert.equal(injected!.sourceTaskId, "T30");
505
+ assert.match(injected!.injectionBlock, /Escalation Override/);
506
+ assert.match(injected!.injectionBlock, /B/, "injection must reflect user's chosen option id");
507
+
508
+ const secondClaim = claimOverrideForInjection(base, "M001", "S01");
509
+ assert.equal(secondClaim, null, "override must be consumed exactly once");
510
+ });
511
+
512
+ test("ADR-011 P3 #21: blocker takes priority over escalation when both flags coexist on same task", (t) => {
513
+ // Two invariants together give blocker-priority:
514
+ // a) state.ts:977-991 checks detectBlockers BEFORE the escalation branch
515
+ // at state.ts:996-1010, so a blocker flag short-circuits the escalation
516
+ // pause.
517
+ // b) resolveEscalation(reject-blocker) atomically clears escalation flags
518
+ // AND sets blocker_discovered=1 (escalation.ts:227-230), so there is no
519
+ // post-resolve window where both flags could surface simultaneously.
520
+ // This test pins (b): after reject-blocker, the escalation pause signal is
521
+ // gone and the task is exclusively in blocker-state.
522
+ const base = makeBase();
523
+ t.after(() => cleanup(base));
524
+ seedCompletedTask(base, "T40");
525
+
526
+ writeEscalationArtifact(base, buildEscalationArtifact({
527
+ taskId: "T40", sliceId: "S01", milestoneId: "M001",
528
+ question: "Which storage?", options: sampleOptions,
529
+ recommendation: "A", recommendationRationale: "r",
530
+ continueWithDefault: false,
531
+ }));
532
+
533
+ // Pre-condition: escalation is active, blocker is not.
534
+ let row = getTask("M001", "S01", "T40");
535
+ assert.equal(row?.escalation_pending, 1);
536
+ assert.equal(row?.blocker_discovered, false);
537
+ assert.equal(detectPendingEscalation([row!], base), "T40");
538
+
539
+ // User rejects to blocker — single transition.
540
+ const result = resolveEscalation(
541
+ base, "M001", "S01", "T40", "reject-blocker", "none of these fit the observed constraints",
542
+ );
543
+ assert.equal(result.status, "rejected-to-blocker");
544
+
545
+ // Post-condition: blocker is set, escalation flags are cleared.
546
+ row = getTask("M001", "S01", "T40");
547
+ assert.equal(row?.blocker_discovered, true, "blocker_discovered must be set after reject-blocker");
548
+ assert.equal(row?.blocker_source, "reject-escalation", "blocker_source records provenance");
549
+ assert.equal(row?.escalation_pending, 0, "escalation_pending must be cleared");
550
+ assert.equal(row?.escalation_awaiting_review, 0, "escalation_awaiting_review must be cleared");
551
+
552
+ // detectPendingEscalation must no longer return T40 — scheduler would
553
+ // otherwise race the blocker branch and pick the wrong phase.
554
+ assert.equal(
555
+ detectPendingEscalation([row!], base),
556
+ null,
557
+ "after reject-blocker, escalation must not pause — blocker path owns the task",
558
+ );
559
+ });
560
+
561
+ test("ADR-011 P3 #22: ADR-009 audit envelopes emitted across the escalation lifecycle", (t) => {
562
+ // Verifies that every user-visible escalation event writes a structured
563
+ // audit envelope (eventId, traceId, category, type, ts, payload) to
564
+ // .gsd/audit/events.jsonl. ADR-009 control-plane consumers depend on this
565
+ // shape. Covered event types:
566
+ // - escalation-manual-attention-created (on write)
567
+ // - escalation-user-responded (on resolve with option)
568
+ // - escalation-rejected-to-blocker (on reject-blocker)
569
+ const base = makeBase();
570
+ t.after(() => cleanup(base));
571
+ seedCompletedTask(base, "T50");
572
+ seedCompletedTask(base, "T51");
573
+
574
+ // 1) write → created
575
+ writeEscalationArtifact(base, buildEscalationArtifact({
576
+ taskId: "T50", sliceId: "S01", milestoneId: "M001",
577
+ question: "Q50", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
578
+ continueWithDefault: false,
579
+ }));
580
+
581
+ // 2) resolve(accept) → responded
582
+ resolveEscalation(base, "M001", "S01", "T50", "accept", "sounds right");
583
+
584
+ // 3) another write + reject-blocker → rejected
585
+ writeEscalationArtifact(base, buildEscalationArtifact({
586
+ taskId: "T51", sliceId: "S01", milestoneId: "M001",
587
+ question: "Q51", options: sampleOptions, recommendation: "B", recommendationRationale: "r",
588
+ continueWithDefault: false,
589
+ }));
590
+ resolveEscalation(base, "M001", "S01", "T51", "reject-blocker", "blocker path");
591
+
592
+ // Read audit log and parse each JSONL envelope.
593
+ const logPath = join(base, ".gsd", "audit", "events.jsonl");
594
+ assert.ok(existsSync(logPath), "audit log must exist at .gsd/audit/events.jsonl");
595
+ const lines = readFileSync(logPath, "utf-8").split("\n").filter((l) => l.length > 0);
596
+ const events = lines.map((l) => JSON.parse(l) as Record<string, unknown>);
597
+ const escalationEvents = events.filter((e) => typeof e["type"] === "string" && (e["type"] as string).startsWith("escalation-"));
598
+
599
+ // All four lifecycle events must be present.
600
+ const types = escalationEvents.map((e) => e["type"] as string).sort();
601
+ assert.deepEqual(types, [
602
+ "escalation-manual-attention-created",
603
+ "escalation-manual-attention-created",
604
+ "escalation-rejected-to-blocker",
605
+ "escalation-user-responded",
606
+ ]);
607
+
608
+ // Every envelope must carry the ADR-009 contract fields.
609
+ for (const env of escalationEvents) {
610
+ assert.equal(typeof env["eventId"], "string", "envelope must include eventId");
611
+ assert.equal(typeof env["traceId"], "string", "envelope must include traceId");
612
+ assert.match(env["traceId"] as string, /^escalation:M001:S01:T5[01]$/, "traceId must be stable and task-scoped");
613
+ assert.equal(env["category"], "gate", "escalation events belong to the gate control plane");
614
+ assert.equal(typeof env["ts"], "string");
615
+ assert.ok(env["payload"] && typeof env["payload"] === "object", "payload must be an object");
616
+ const payload = env["payload"] as Record<string, unknown>;
617
+ assert.equal(payload["milestoneId"], "M001");
618
+ assert.equal(payload["sliceId"], "S01");
619
+ assert.ok(payload["taskId"] === "T50" || payload["taskId"] === "T51");
620
+ }
621
+ });
622
+
623
+ test("ADR-011 P3 #23: concurrent escalations across parallel slices — only the escalating branch pauses", (t) => {
624
+ // In parallel-slice execution each slice has its own active-task view.
625
+ // The scheduler calls detectPendingEscalation(tasks, base) with *that
626
+ // slice's* tasks only (state.ts:998). So if S01-T60 escalates and S02-T70
627
+ // does not, the S02 branch must remain dispatchable while S01 waits.
628
+ //
629
+ // This test pins: (a) each slice's detectPendingEscalation returns only
630
+ // its own pending tasks, (b) neither branch can see the other's
631
+ // escalation by accident, and (c) resolving one slice's escalation does
632
+ // not clear the other's pause signal.
633
+ const base = makeBase();
634
+ t.after(() => cleanup(base));
635
+
636
+ openDatabase(join(base, ".gsd", "gsd.db"));
637
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
638
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Slice A" });
639
+ insertSlice({ id: "S02", milestoneId: "M001", title: "Slice B" });
640
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S02", "tasks"), { recursive: true });
641
+ insertTask({ id: "T60", sliceId: "S01", milestoneId: "M001", title: "Task A", status: "complete" });
642
+ insertTask({ id: "T70", sliceId: "S02", milestoneId: "M001", title: "Task B", status: "complete" });
643
+ insertTask({ id: "T71", sliceId: "S02", milestoneId: "M001", title: "Task B2", status: "complete" });
644
+
645
+ // Both slices escalate at the same time (parallel execution scenario).
646
+ writeEscalationArtifact(base, buildEscalationArtifact({
647
+ taskId: "T60", sliceId: "S01", milestoneId: "M001",
648
+ question: "S01 ambiguity?", options: sampleOptions,
649
+ recommendation: "A", recommendationRationale: "r",
650
+ continueWithDefault: false,
651
+ }));
652
+ writeEscalationArtifact(base, buildEscalationArtifact({
653
+ taskId: "T70", sliceId: "S02", milestoneId: "M001",
654
+ question: "S02 ambiguity?", options: sampleOptions,
655
+ recommendation: "B", recommendationRationale: "r",
656
+ continueWithDefault: false,
657
+ }));
658
+
659
+ // Per-slice detection: each branch sees only its own pending task.
660
+ const s01Tasks = [getTask("M001", "S01", "T60")!];
661
+ const s02Tasks = [getTask("M001", "S02", "T70")!, getTask("M001", "S02", "T71")!];
662
+ assert.equal(detectPendingEscalation(s01Tasks, base), "T60");
663
+ assert.equal(detectPendingEscalation(s02Tasks, base), "T70");
664
+
665
+ // Resolve S01's escalation — must NOT clear S02's pause signal.
666
+ resolveEscalation(base, "M001", "S01", "T60", "A", "pick A");
667
+ assert.equal(detectPendingEscalation([getTask("M001", "S01", "T60")!], base), null);
668
+ assert.equal(
669
+ detectPendingEscalation([getTask("M001", "S02", "T70")!, getTask("M001", "S02", "T71")!], base),
670
+ "T70",
671
+ "resolving one slice's escalation must leave the other slice paused",
672
+ );
673
+
674
+ // Resolving S02 independently clears the second pause.
675
+ resolveEscalation(base, "M001", "S02", "T70", "B", "pick B");
676
+ assert.equal(detectPendingEscalation([getTask("M001", "S02", "T70")!], base), null);
677
+ });
678
+
679
+ test("ADR-011 P3 #24: continueWithDefault timeout — late user response injects into the next task dispatched AFTER the response", (t) => {
680
+ // Timeline this test pins (the "timeout" is implicit — it's just the
681
+ // elapsed wall-clock where the loop keeps running after T80's
682
+ // continueWithDefault=true write):
683
+ //
684
+ // 1. T80 writes continueWithDefault=true → awaiting_review=1, loop
685
+ // continues dispatching T81, T82. Neither claim fires because the
686
+ // user has not responded (pins Bug 2 behavior, tested at line 244).
687
+ // 2. The user responds LATE (after T81/T82 already dispatched).
688
+ // 3. The very next prompt build (for T83) claims the override exactly
689
+ // once. T81/T82 are in the past — they must not retroactively
690
+ // receive the injection even though they ran during the window.
691
+ const base = makeBase();
692
+ t.after(() => cleanup(base));
693
+ seedCompletedTask(base, "T80");
694
+ seedCompletedTask(base, "T81");
695
+ seedCompletedTask(base, "T82");
696
+ seedCompletedTask(base, "T83");
697
+
698
+ // Phase 1 — T80 escalates with continueWithDefault=true, loop continues.
699
+ writeEscalationArtifact(base, buildEscalationArtifact({
700
+ taskId: "T80", sliceId: "S01", milestoneId: "M001",
701
+ question: "Which cache strategy?", options: sampleOptions,
702
+ recommendation: "A", recommendationRationale: "A matches current telemetry",
703
+ continueWithDefault: true,
704
+ }));
705
+
706
+ // T80 is awaiting_review (not pending) — scheduler does not pause.
707
+ assert.equal(getTask("M001", "S01", "T80")?.escalation_awaiting_review, 1);
708
+ assert.equal(getTask("M001", "S01", "T80")?.escalation_pending, 0);
709
+ assert.equal(detectPendingEscalation([getTask("M001", "S01", "T80")!], base), null);
710
+
711
+ // T81 + T82 dispatch during the response window — neither gets the injection.
712
+ assert.equal(
713
+ claimOverrideForInjection(base, "M001", "S01"),
714
+ null,
715
+ "T81's prompt build must not claim the unresolved awaiting_review",
716
+ );
717
+ assert.equal(
718
+ claimOverrideForInjection(base, "M001", "S01"),
719
+ null,
720
+ "T82's prompt build must also not claim the unresolved awaiting_review",
721
+ );
722
+
723
+ // The response window remains open across N tasks — still no override applied.
724
+ assert.equal(
725
+ getTask("M001", "S01", "T80")?.escalation_override_applied_at,
726
+ null,
727
+ "applied_at must stay null throughout the response window",
728
+ );
729
+
730
+ // Phase 2 — user responds LATE with a different option than the recommendation.
731
+ const resolveResult = resolveEscalation(
732
+ base, "M001", "S01", "T80", "B", "after reviewing, B is the call",
733
+ );
734
+ assert.equal(resolveResult.status, "resolved");
735
+ assert.equal(resolveResult.chosenOption?.id, "B");
736
+
737
+ // Phase 3 — the very next prompt build (T83) claims the override exactly once.
738
+ const claimed = claimOverrideForInjection(base, "M001", "S01");
739
+ assert.ok(claimed, "T83's prompt build must claim the late-resolved override");
740
+ assert.equal(claimed!.sourceTaskId, "T80");
741
+ assert.match(claimed!.injectionBlock, /Escalation Override/);
742
+ assert.match(
743
+ claimed!.injectionBlock,
744
+ /JSON array|B/,
745
+ "injection must reflect the user's B choice, NOT the original A recommendation",
746
+ );
747
+
748
+ // Idempotent — subsequent prompts do not re-inject.
749
+ assert.equal(claimOverrideForInjection(base, "M001", "S01"), null);
750
+ });
751
+
752
+ test("ADR-011 P3 #25: artifact write failure surfaces, leaves DB flags clean, and retries successfully once recovered", async (t) => {
753
+ // Failure modes covered:
754
+ // 1. writeEscalationArtifact with an unresolvable slice path (no slice
755
+ // dir on disk) throws synchronously — no DB flag flip, no audit.
756
+ // 2. After the flag still reads 0, the caller can retry once the dir
757
+ // exists. Retry succeeds and atomically flips escalation_pending=1
758
+ // plus emits exactly one audit envelope (not two — idempotent
759
+ // recovery, not replay).
760
+ const base = makeBase();
761
+ t.after(() => cleanup(base));
762
+ openDatabase(join(base, ".gsd", "gsd.db"));
763
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
764
+ insertSlice({ id: "S09", milestoneId: "M001", title: "Unseeded slice" });
765
+ insertTask({ id: "T90", sliceId: "S09", milestoneId: "M001", title: "T", status: "complete" });
766
+
767
+ const artifact = buildEscalationArtifact({
768
+ taskId: "T90", sliceId: "S09", milestoneId: "M001",
769
+ question: "Q", options: sampleOptions, recommendation: "A", recommendationRationale: "r",
770
+ continueWithDefault: false,
771
+ });
772
+
773
+ // Phase 1 — slice dir does NOT exist yet; write must throw.
774
+ // escalationArtifactPath returns null, writeEscalationArtifact throws.
775
+ assert.throws(
776
+ () => writeEscalationArtifact(base, artifact),
777
+ /cannot resolve tasks dir/,
778
+ "missing slice dir must raise — caller is expected to run doctor before retry",
779
+ );
780
+
781
+ // DB flag must NOT be set — atomic failure semantics.
782
+ const midRow = getTask("M001", "S09", "T90");
783
+ assert.equal(midRow?.escalation_pending, 0, "failed write must leave escalation_pending=0");
784
+ assert.equal(midRow?.escalation_awaiting_review, 0);
785
+ assert.equal(midRow?.escalation_artifact_path, null);
786
+
787
+ // Audit log must have no escalation-created events from the failed write.
788
+ const logPath = join(base, ".gsd", "audit", "events.jsonl");
789
+ const preLines = existsSync(logPath)
790
+ ? readFileSync(logPath, "utf-8").split("\n").filter((l) => l.length > 0)
791
+ : [];
792
+ const preCount = preLines.filter((l) => l.includes("escalation-manual-attention-created")).length;
793
+ assert.equal(preCount, 0, "failed write must not emit an audit envelope");
794
+
795
+ // Phase 2 — caller recovers (creates the slice dir), retries.
796
+ // clearPathCache() because resolveSlicePath caches directory reads and
797
+ // the first failed attempt populated a miss for S09.
798
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S09", "tasks"), { recursive: true });
799
+ const { clearPathCache } = await import("../paths.ts");
800
+ clearPathCache();
801
+ const path = writeEscalationArtifact(base, artifact);
802
+ assert.ok(existsSync(path), "retry must atomically land the artifact on disk");
803
+
804
+ // DB flag flipped on successful retry.
805
+ const afterRow = getTask("M001", "S09", "T90");
806
+ assert.equal(afterRow?.escalation_pending, 1, "successful retry must flip escalation_pending=1");
807
+ assert.equal(afterRow?.escalation_artifact_path, path);
808
+
809
+ // Audit log now contains exactly one escalation-created event for T90.
810
+ const postLines = readFileSync(logPath, "utf-8").split("\n").filter((l) => l.length > 0);
811
+ const t90Events = postLines
812
+ .map((l) => JSON.parse(l) as Record<string, unknown>)
813
+ .filter((e) =>
814
+ e["type"] === "escalation-manual-attention-created"
815
+ && (e["payload"] as Record<string, unknown>)?.["taskId"] === "T90",
816
+ );
817
+ assert.equal(t90Events.length, 1, "successful retry must emit exactly one audit envelope");
818
+ });