@opengsd/gsd-core 1.10.0 → 1.12.0

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 (544) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/agents/gsd-code-fixer.md +1 -1
  4. package/agents/gsd-debug-session-manager.md +12 -1
  5. package/agents/gsd-debugger.md +1 -1
  6. package/agents/gsd-doc-synthesizer.md +2 -4
  7. package/agents/gsd-dom-verifier.md +169 -0
  8. package/agents/gsd-eval-auditor.md +1 -1
  9. package/agents/gsd-executor.md +22 -14
  10. package/agents/gsd-framework-selector.md +1 -3
  11. package/agents/gsd-intel-updater.md +1 -1
  12. package/agents/gsd-mempalace-curator.md +5 -3
  13. package/agents/gsd-pattern-mapper.md +11 -0
  14. package/agents/gsd-phase-researcher.md +23 -2
  15. package/agents/gsd-plan-checker.md +50 -53
  16. package/agents/gsd-planner.md +50 -50
  17. package/agents/gsd-project-researcher.md +1 -1
  18. package/agents/gsd-research-synthesizer.md +2 -2
  19. package/agents/gsd-roadmapper.md +15 -11
  20. package/agents/gsd-ui-checker.md +63 -4
  21. package/agents/gsd-ui-researcher.md +41 -3
  22. package/agents/gsd-user-profiler.md +3 -0
  23. package/agents/gsd-verifier.md +13 -4
  24. package/bin/install.js +1448 -1103
  25. package/commands/gsd/code-review.md +1 -1
  26. package/commands/gsd/discuss-phase.md +1 -1
  27. package/commands/gsd/execute-phase.md +1 -1
  28. package/commands/gsd/import.md +1 -1
  29. package/commands/gsd/map-codebase.md +1 -1
  30. package/commands/gsd/mempalace-capture.md +1 -1
  31. package/commands/gsd/mempalace-recall.md +1 -1
  32. package/commands/gsd/new-milestone.md +1 -1
  33. package/commands/gsd/quick.md +9 -5
  34. package/commands/gsd/review-backlog.md +2 -1
  35. package/commands/gsd/verify-work.md +1 -1
  36. package/gsd-core/bin/gsd-tools.cjs +1035 -138
  37. package/gsd-core/bin/lib/active-workstream-store.cjs +146 -22
  38. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  39. package/gsd-core/bin/lib/agent-install-check.cjs +392 -32
  40. package/gsd-core/bin/lib/api-coverage.cjs +33 -14
  41. package/gsd-core/bin/lib/artifacts.cjs +5 -0
  42. package/gsd-core/bin/lib/assumption-delta.cjs +32 -15
  43. package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
  44. package/gsd-core/bin/lib/audit.cjs +1026 -268
  45. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  46. package/gsd-core/bin/lib/capability-consent.cjs +149 -15
  47. package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
  48. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  49. package/gsd-core/bin/lib/capability-registry.cjs +845 -130
  50. package/gsd-core/bin/lib/capability-source.cjs +92 -0
  51. package/gsd-core/bin/lib/capability-state.cjs +18 -3
  52. package/gsd-core/bin/lib/capability-trust.cjs +444 -25
  53. package/gsd-core/bin/lib/capability-validator.cjs +700 -40
  54. package/gsd-core/bin/lib/capability-writer.cjs +3 -2
  55. package/gsd-core/bin/lib/check-command-router.cjs +216 -42
  56. package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
  57. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  58. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  59. package/gsd-core/bin/lib/codex-agent-toml.cjs +735 -0
  60. package/gsd-core/bin/lib/command-aliases.cjs +22 -0
  61. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  62. package/gsd-core/bin/lib/command-roster.cjs +44 -1
  63. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  64. package/gsd-core/bin/lib/commands.cjs +1172 -108
  65. package/gsd-core/bin/lib/commonjs-marker.cjs +12 -6
  66. package/gsd-core/bin/lib/complexity-trigger.cjs +1192 -0
  67. package/gsd-core/bin/lib/config-loader.cjs +187 -23
  68. package/gsd-core/bin/lib/config.cjs +102 -3
  69. package/gsd-core/bin/lib/configuration.cjs +129 -37
  70. package/gsd-core/bin/lib/core-utils.cjs +208 -33
  71. package/gsd-core/bin/lib/decisions.cjs +23 -0
  72. package/gsd-core/bin/lib/edge-probe.cjs +9 -1
  73. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  74. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  75. package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
  76. package/gsd-core/bin/lib/frontmatter.cjs +899 -229
  77. package/gsd-core/bin/lib/gap-checker.cjs +95 -10
  78. package/gsd-core/bin/lib/git-base-branch.cjs +276 -39
  79. package/gsd-core/bin/lib/gsd2-import.cjs +10 -1
  80. package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
  81. package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
  82. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +149 -0
  83. package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
  84. package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
  85. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
  86. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +268 -0
  87. package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
  88. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
  89. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +187 -0
  90. package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
  91. package/gsd-core/bin/lib/health-diagnostic.cjs +451 -0
  92. package/gsd-core/bin/lib/host-integration.cjs +39 -6
  93. package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
  94. package/gsd-core/bin/lib/init-command-router.cjs +118 -21
  95. package/gsd-core/bin/lib/init.cjs +439 -168
  96. package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
  97. package/gsd-core/bin/lib/install-engine.cjs +811 -259
  98. package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
  99. package/gsd-core/bin/lib/install-model-override-resolver.cjs +235 -0
  100. package/gsd-core/bin/lib/install-profiles.cjs +212 -61
  101. package/gsd-core/bin/lib/install-scope.cjs +270 -0
  102. package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
  103. package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
  104. package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
  105. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  106. package/gsd-core/bin/lib/installer-migrations.cjs +148 -38
  107. package/gsd-core/bin/lib/intel.cjs +101 -26
  108. package/gsd-core/bin/lib/io.cjs +170 -15
  109. package/gsd-core/bin/lib/learnings.cjs +85 -14
  110. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  111. package/gsd-core/bin/lib/markdown-sectionizer.cjs +2 -1
  112. package/gsd-core/bin/lib/markdown-table.cjs +183 -22
  113. package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
  114. package/gsd-core/bin/lib/milestone.cjs +842 -73
  115. package/gsd-core/bin/lib/model-catalog.cjs +232 -16
  116. package/gsd-core/bin/lib/model-resolver.cjs +193 -68
  117. package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
  118. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  119. package/gsd-core/bin/lib/pattern.cjs +122 -0
  120. package/gsd-core/bin/lib/phase-estimation.cjs +18 -9
  121. package/gsd-core/bin/lib/phase-id.cjs +514 -40
  122. package/gsd-core/bin/lib/phase-lifecycle.cjs +52 -19
  123. package/gsd-core/bin/lib/phase-locator.cjs +262 -34
  124. package/gsd-core/bin/lib/phase.cjs +1038 -214
  125. package/gsd-core/bin/lib/plan-dependency-graph.cjs +72 -1
  126. package/gsd-core/bin/lib/plan-document.cjs +263 -0
  127. package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
  128. package/gsd-core/bin/lib/plan-scan.cjs +98 -3
  129. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  130. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  131. package/gsd-core/bin/lib/planning-scope.cjs +31 -0
  132. package/gsd-core/bin/lib/planning-snapshot.cjs +894 -0
  133. package/gsd-core/bin/lib/planning-workspace.cjs +112 -6
  134. package/gsd-core/bin/lib/probe-core.cjs +5 -2
  135. package/gsd-core/bin/lib/profile-output.cjs +1 -1
  136. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  137. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  138. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  139. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +766 -0
  140. package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +11 -6
  141. package/gsd-core/bin/lib/review-lane-descriptor.cjs +22 -13
  142. package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
  143. package/gsd-core/bin/lib/review-lane-runner.cjs +421 -66
  144. package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
  145. package/gsd-core/bin/lib/roadmap-command-router.cjs +59 -11
  146. package/gsd-core/bin/lib/roadmap-parser.cjs +1006 -184
  147. package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
  148. package/gsd-core/bin/lib/roadmap.cjs +442 -96
  149. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +702 -52
  150. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
  151. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +459 -55
  152. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
  153. package/gsd-core/bin/lib/runtime-homes.cjs +69 -3
  154. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +402 -58
  155. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  156. package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
  157. package/gsd-core/bin/lib/runtime-slash.cjs +96 -8
  158. package/gsd-core/bin/lib/security.cjs +104 -5
  159. package/gsd-core/bin/lib/shell-command-projection.cjs +342 -7
  160. package/gsd-core/bin/lib/smart-entry.cjs +133 -23
  161. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  162. package/gsd-core/bin/lib/state-command-router.cjs +52 -19
  163. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  164. package/gsd-core/bin/lib/state-document.cjs +338 -8
  165. package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
  166. package/gsd-core/bin/lib/state-transition.cjs +846 -176
  167. package/gsd-core/bin/lib/state.cjs +2589 -369
  168. package/gsd-core/bin/lib/surface.cjs +33 -11
  169. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  170. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  171. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  172. package/gsd-core/bin/lib/text-lines.cjs +80 -0
  173. package/gsd-core/bin/lib/token-scanner.cjs +76 -0
  174. package/gsd-core/bin/lib/uat-predicate.cjs +67 -23
  175. package/gsd-core/bin/lib/uat.cjs +1761 -167
  176. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  177. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
  178. package/gsd-core/bin/lib/ui-safety-gate.cjs +51 -12
  179. package/gsd-core/bin/lib/unusable-input.cjs +37 -0
  180. package/gsd-core/bin/lib/update-context.cjs +8 -2
  181. package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
  182. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  183. package/gsd-core/bin/lib/validate.cjs +20 -6
  184. package/gsd-core/bin/lib/vendor/README.md +75 -0
  185. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  186. package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
  187. package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
  188. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  189. package/gsd-core/bin/lib/verification.cjs +272 -9
  190. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  191. package/gsd-core/bin/lib/verify.cjs +453 -918
  192. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +53 -32
  193. package/gsd-core/bin/lib/workstream-inventory.cjs +63 -10
  194. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  195. package/gsd-core/bin/lib/workstream.cjs +2 -2
  196. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  197. package/gsd-core/bin/lib/worktree-safety.cjs +341 -18
  198. package/gsd-core/bin/shared/config-defaults.manifest.json +8 -1
  199. package/gsd-core/bin/shared/config-schema.manifest.json +12 -1
  200. package/gsd-core/bin/shared/exit-codes.json +8 -0
  201. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  202. package/gsd-core/bin/shared/model-catalog.json +8 -1
  203. package/gsd-core/references/agent-contracts.md +44 -26
  204. package/gsd-core/references/api-coverage.md +24 -2
  205. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  206. package/gsd-core/references/checkpoints.md +39 -21
  207. package/gsd-core/references/context-budget.md +1 -1
  208. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  209. package/gsd-core/references/dispatch-isolation-gate.md +138 -0
  210. package/gsd-core/references/doc-conflict-engine.md +1 -1
  211. package/gsd-core/references/edge-probe.md +8 -0
  212. package/gsd-core/references/execute-mvp-tdd.md +4 -6
  213. package/gsd-core/references/execute-phase-between-wave-reset.md +15 -14
  214. package/gsd-core/references/execute-phase-context-guard.md +1 -1
  215. package/gsd-core/references/execute-phase-response-language.md +1 -1
  216. package/gsd-core/references/execute-phase-wave-guard.md +17 -11
  217. package/gsd-core/references/failing-direction.md +78 -0
  218. package/gsd-core/references/gate-prompts.md +1 -1
  219. package/gsd-core/references/git-integration.md +5 -5
  220. package/gsd-core/references/git-planning-commit.md +5 -4
  221. package/gsd-core/references/gsd-run-resolver.md +1 -1
  222. package/gsd-core/references/loop-hook-dispatch.md +61 -2
  223. package/gsd-core/references/model-profiles.md +12 -4
  224. package/gsd-core/references/mvp-concepts.md +9 -9
  225. package/gsd-core/references/nyquist-compliance.md +74 -0
  226. package/gsd-core/references/offer-next.md +3 -5
  227. package/gsd-core/references/phase-argument-parsing.md +3 -3
  228. package/gsd-core/references/planner-failing-direction.md +53 -0
  229. package/gsd-core/references/planner-guidance.md +3 -9
  230. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  231. package/gsd-core/references/planner-preconditions.md +1 -1
  232. package/gsd-core/references/planner-reviews.md +1 -1
  233. package/gsd-core/references/planner-revision.md +1 -1
  234. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  235. package/gsd-core/references/planning-config.md +44 -13
  236. package/gsd-core/references/reviewer-instances.md +31 -0
  237. package/gsd-core/references/revision-loop.md +1 -1
  238. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  239. package/gsd-core/references/specless-probe-fallback.md +1 -1
  240. package/gsd-core/references/tdd.md +1 -3
  241. package/gsd-core/references/ui-brand.md +65 -21
  242. package/gsd-core/references/ui-consideration-probe.md +1 -1
  243. package/gsd-core/references/universal-anti-patterns.md +5 -5
  244. package/gsd-core/references/verifier-phase-gates.md +192 -0
  245. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  246. package/gsd-core/references/verify-mvp-mode.md +2 -2
  247. package/gsd-core/references/workstream-flag.md +33 -17
  248. package/gsd-core/templates/README.md +1 -1
  249. package/gsd-core/templates/SECURITY.md +3 -3
  250. package/gsd-core/templates/UI-SPEC.md +25 -3
  251. package/gsd-core/templates/VALIDATION.md +3 -3
  252. package/gsd-core/templates/discussion-log.md +1 -1
  253. package/gsd-core/templates/phase-prompt.md +5 -4
  254. package/gsd-core/templates/state.md +11 -4
  255. package/gsd-core/templates/verification-report.md +9 -1
  256. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  257. package/gsd-core/workflows/add-backlog.md +1 -1
  258. package/gsd-core/workflows/add-phase.md +3 -3
  259. package/gsd-core/workflows/add-tests.md +3 -8
  260. package/gsd-core/workflows/add-todo.md +1 -1
  261. package/gsd-core/workflows/ai-integration-phase.md +13 -20
  262. package/gsd-core/workflows/audit-fix.md +12 -3
  263. package/gsd-core/workflows/audit-milestone.md +9 -9
  264. package/gsd-core/workflows/audit-uat.md +17 -2
  265. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  266. package/gsd-core/workflows/autonomous.md +11 -27
  267. package/gsd-core/workflows/check-todos.md +1 -1
  268. package/gsd-core/workflows/cleanup.md +64 -5
  269. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +14 -4
  270. package/gsd-core/workflows/code-review-fix.md +38 -11
  271. package/gsd-core/workflows/code-review.md +159 -52
  272. package/gsd-core/workflows/complete-milestone.md +151 -23
  273. package/gsd-core/workflows/debug.md +12 -8
  274. package/gsd-core/workflows/diagnose-issues.md +47 -15
  275. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  276. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -8
  277. package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
  278. package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
  279. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  280. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  281. package/gsd-core/workflows/discuss-phase.md +1 -1
  282. package/gsd-core/workflows/do.md +3 -6
  283. package/gsd-core/workflows/docs-update.md +5 -4
  284. package/gsd-core/workflows/edit-phase.md +27 -2
  285. package/gsd-core/workflows/eval-review.md +7 -14
  286. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
  287. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +142 -15
  288. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  289. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  290. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
  291. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +24 -4
  292. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  293. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  294. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -2
  295. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  296. package/gsd-core/workflows/execute-phase.md +72 -100
  297. package/gsd-core/workflows/execute-plan.md +52 -15
  298. package/gsd-core/workflows/explore.md +131 -4
  299. package/gsd-core/workflows/extract-learnings.md +1 -1
  300. package/gsd-core/workflows/fast.md +10 -2
  301. package/gsd-core/workflows/forensics.md +1 -1
  302. package/gsd-core/workflows/graduation.md +5 -5
  303. package/gsd-core/workflows/health.md +76 -10
  304. package/gsd-core/workflows/import.md +18 -15
  305. package/gsd-core/workflows/inbox.md +4 -5
  306. package/gsd-core/workflows/ingest-docs.md +49 -16
  307. package/gsd-core/workflows/insert-phase.md +5 -5
  308. package/gsd-core/workflows/list-seeds.md +5 -3
  309. package/gsd-core/workflows/list-workspaces.md +1 -1
  310. package/gsd-core/workflows/manager.md +12 -23
  311. package/gsd-core/workflows/map-codebase.md +1 -1
  312. package/gsd-core/workflows/milestone-summary.md +1 -1
  313. package/gsd-core/workflows/mvp-phase.md +8 -5
  314. package/gsd-core/workflows/new-milestone.md +22 -29
  315. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  316. package/gsd-core/workflows/new-project.md +26 -40
  317. package/gsd-core/workflows/new-workspace.md +1 -1
  318. package/gsd-core/workflows/next.md +14 -2
  319. package/gsd-core/workflows/pause-work.md +1 -1
  320. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  321. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
  322. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
  323. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
  324. package/gsd-core/workflows/plan-phase.md +162 -59
  325. package/gsd-core/workflows/plan-review-convergence.md +96 -11
  326. package/gsd-core/workflows/plant-seed.md +2 -2
  327. package/gsd-core/workflows/pr-branch.md +187 -51
  328. package/gsd-core/workflows/profile-user.md +16 -14
  329. package/gsd-core/workflows/progress.md +61 -18
  330. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  331. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +5 -7
  332. package/gsd-core/workflows/quick/steps/quick-verification.md +28 -9
  333. package/gsd-core/workflows/quick/steps/research-phase.md +4 -6
  334. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  335. package/gsd-core/workflows/quick.md +55 -44
  336. package/gsd-core/workflows/remove-phase.md +4 -4
  337. package/gsd-core/workflows/remove-workspace.md +2 -2
  338. package/gsd-core/workflows/resume-project.md +8 -12
  339. package/gsd-core/workflows/review.md +219 -20
  340. package/gsd-core/workflows/scan.md +1 -1
  341. package/gsd-core/workflows/secure-phase.md +3 -3
  342. package/gsd-core/workflows/session-report.md +2 -1
  343. package/gsd-core/workflows/settings-advanced.md +7 -9
  344. package/gsd-core/workflows/settings-integrations.md +64 -31
  345. package/gsd-core/workflows/settings.md +69 -7
  346. package/gsd-core/workflows/ship.md +116 -50
  347. package/gsd-core/workflows/sketch-wrap-up.md +11 -17
  348. package/gsd-core/workflows/sketch.md +12 -18
  349. package/gsd-core/workflows/smart-entry.md +3 -5
  350. package/gsd-core/workflows/spec-phase.md +53 -13
  351. package/gsd-core/workflows/spike-wrap-up.md +7 -11
  352. package/gsd-core/workflows/spike.md +20 -31
  353. package/gsd-core/workflows/stats.md +2 -2
  354. package/gsd-core/workflows/sync-skills.md +64 -9
  355. package/gsd-core/workflows/thread.md +11 -7
  356. package/gsd-core/workflows/transition.md +49 -14
  357. package/gsd-core/workflows/ui-phase.md +15 -21
  358. package/gsd-core/workflows/ui-review.md +8 -12
  359. package/gsd-core/workflows/ultraplan-phase.md +5 -13
  360. package/gsd-core/workflows/undo.md +8 -16
  361. package/gsd-core/workflows/update.md +7 -11
  362. package/gsd-core/workflows/validate-phase.md +3 -3
  363. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  364. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  365. package/gsd-core/workflows/verify-work.md +66 -25
  366. package/hooks/dist/gsd-agent-isolation-guard.js +158 -30
  367. package/hooks/dist/gsd-check-update-worker.js +56 -13
  368. package/hooks/dist/gsd-check-update.js +19 -1
  369. package/hooks/dist/gsd-config-reload.js +18 -12
  370. package/hooks/dist/gsd-context-monitor.js +19 -10
  371. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  372. package/hooks/dist/gsd-cursor-pre-tool.js +2 -3
  373. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  374. package/hooks/dist/gsd-cursor-stop.js +2 -1
  375. package/hooks/dist/gsd-cursor-subagent-start.js +83 -3
  376. package/hooks/dist/gsd-cursor-subagent-stop.js +6 -3
  377. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  378. package/hooks/dist/gsd-graphify-update.sh +22 -18
  379. package/hooks/dist/gsd-node-runner.sh +76 -0
  380. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  381. package/hooks/dist/gsd-prompt-guard.js +37 -27
  382. package/hooks/dist/gsd-read-guard.js +16 -7
  383. package/hooks/dist/gsd-read-injection-scanner.js +55 -32
  384. package/hooks/dist/gsd-session-state.sh +1 -0
  385. package/hooks/dist/gsd-statusline.js +231 -24
  386. package/hooks/dist/gsd-update-banner.js +22 -1
  387. package/hooks/dist/gsd-validate-commit.sh +80 -6
  388. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  389. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  390. package/hooks/dist/gsd-workflow-guard.js +162 -46
  391. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  392. package/hooks/dist/gsd-write-guard.js +35 -25
  393. package/hooks/dist/lib/cli-exit.js +560 -0
  394. package/hooks/dist/lib/exit-code-registry.js +98 -0
  395. package/hooks/dist/lib/git-cmd.js +92 -59
  396. package/hooks/dist/lib/git-probe.js +84 -0
  397. package/hooks/dist/lib/hook-exit.js +81 -0
  398. package/hooks/dist/lib/injection-patterns.js +45 -0
  399. package/hooks/dist/lib/isolation-deny-reason.js +39 -0
  400. package/hooks/dist/lib/isolation-sentinel.js +9 -0
  401. package/hooks/dist/managed-hooks-registry.cjs +3 -0
  402. package/hooks/gsd-agent-isolation-guard.js +158 -30
  403. package/hooks/gsd-check-update-worker.js +56 -13
  404. package/hooks/gsd-check-update.js +19 -1
  405. package/hooks/gsd-config-reload.js +18 -12
  406. package/hooks/gsd-context-monitor.js +19 -10
  407. package/hooks/gsd-cursor-post-tool.js +3 -1
  408. package/hooks/gsd-cursor-pre-tool.js +2 -3
  409. package/hooks/gsd-cursor-session-start.js +2 -1
  410. package/hooks/gsd-cursor-stop.js +2 -1
  411. package/hooks/gsd-cursor-subagent-start.js +83 -3
  412. package/hooks/gsd-cursor-subagent-stop.js +6 -3
  413. package/hooks/gsd-ensure-canonical-path.js +2 -1
  414. package/hooks/gsd-graphify-update.sh +22 -18
  415. package/hooks/gsd-node-runner.sh +76 -0
  416. package/hooks/gsd-phase-boundary.sh +1 -0
  417. package/hooks/gsd-prompt-guard.js +37 -27
  418. package/hooks/gsd-read-guard.js +16 -7
  419. package/hooks/gsd-read-injection-scanner.js +55 -32
  420. package/hooks/gsd-session-state.sh +1 -0
  421. package/hooks/gsd-statusline.js +231 -24
  422. package/hooks/gsd-update-banner.js +22 -1
  423. package/hooks/gsd-validate-commit.sh +80 -6
  424. package/hooks/gsd-windsurf-pre-command.js +16 -11
  425. package/hooks/gsd-windsurf-pre-write.js +22 -13
  426. package/hooks/gsd-workflow-guard.js +162 -46
  427. package/hooks/gsd-worktree-path-guard.js +36 -21
  428. package/hooks/gsd-write-guard.js +35 -25
  429. package/hooks/lib/cli-exit.js +560 -0
  430. package/hooks/lib/exit-code-registry.js +98 -0
  431. package/hooks/lib/git-cmd.js +92 -59
  432. package/hooks/lib/git-probe.js +84 -0
  433. package/hooks/lib/hook-exit.js +81 -0
  434. package/hooks/lib/injection-patterns.js +45 -0
  435. package/hooks/lib/isolation-deny-reason.js +39 -0
  436. package/hooks/lib/isolation-sentinel.js +9 -0
  437. package/hooks/managed-hooks-registry.cjs +3 -0
  438. package/package.json +28 -11
  439. package/pi/gsd.cjs +19 -5
  440. package/scripts/base64-scan.sh +74 -12
  441. package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
  442. package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
  443. package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
  444. package/scripts/build-hooks.js +5 -0
  445. package/scripts/changeset/lint.cjs +60 -5
  446. package/scripts/check-alias-drift.cjs +7 -43
  447. package/scripts/check-contract-drift.cjs +297 -0
  448. package/scripts/check-glossary-refs.cjs +77 -15
  449. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  450. package/scripts/ci-check-job-near-cap.cjs +49 -0
  451. package/scripts/ci-pr-mergeability.cjs +262 -0
  452. package/scripts/ci-test-scope.cjs +64 -14
  453. package/scripts/ci-timeout-report.cjs +230 -0
  454. package/scripts/command-contract-helpers.cjs +903 -1
  455. package/scripts/docs-guard-registry.cjs +396 -0
  456. package/scripts/gen-adr-index.cjs +728 -38
  457. package/scripts/gen-capability-registry.cjs +11 -21
  458. package/scripts/gen-context-index.cjs +2 -11
  459. package/scripts/gen-exit-code-docs.cjs +318 -0
  460. package/scripts/gen-exit-code-registry.cjs +891 -0
  461. package/scripts/gen-features.cjs +836 -0
  462. package/scripts/gen-health-docs.cjs +390 -0
  463. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  464. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  465. package/scripts/gen-inventory-manifest.cjs +50 -4
  466. package/scripts/gen-loop-host-contract.cjs +138 -25
  467. package/scripts/gen-registry.cjs +3 -14
  468. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  469. package/scripts/gen-state-md-docs.cjs +727 -0
  470. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  471. package/scripts/lib/alias-drift-families.cjs +46 -0
  472. package/scripts/lib/ci-job-timing.cjs +72 -0
  473. package/scripts/lib/cli-exit.cjs +546 -44
  474. package/scripts/lib/drift-scan.cjs +308 -0
  475. package/scripts/lib/exit-code-registry.cjs +98 -0
  476. package/scripts/lib/ndjson-reporter.cjs +119 -0
  477. package/scripts/lint-allow-test-rule-refs.allowlist.json +1 -26
  478. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
  479. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
  480. package/scripts/lint-canary-version-leak.cjs +73 -0
  481. package/scripts/lint-command-contract.cjs +96 -13
  482. package/scripts/lint-completion-predicate-drift.cjs +933 -0
  483. package/scripts/lint-completion-ratio-drift.cjs +214 -0
  484. package/scripts/lint-default-flip-documentation.cjs +193 -0
  485. package/scripts/lint-docs-guard-registration.cjs +495 -0
  486. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
  487. package/scripts/lint-eslint-glob-coverage.allowlist.json +38 -0
  488. package/scripts/lint-eslint-glob-coverage.cjs +340 -0
  489. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  490. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
  491. package/scripts/lint-health-diagnostic-rule-table.cjs +461 -0
  492. package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
  493. package/scripts/lint-milestone-window-drift.cjs +468 -0
  494. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  495. package/scripts/lint-phase-enumeration-drift.cjs +492 -0
  496. package/scripts/lint-plan-count-drift.cjs +318 -0
  497. package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
  498. package/scripts/lint-planning-prompt-drift.cjs +471 -0
  499. package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
  500. package/scripts/lint-regression-test-names.cjs +15 -13
  501. package/scripts/lint-removed-but-needed.cjs +488 -0
  502. package/scripts/lint-seam-enforcement.cjs +182 -0
  503. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  504. package/scripts/lint-source-test-name-collision.cjs +241 -0
  505. package/scripts/lint-state-field-drift.cjs +805 -0
  506. package/scripts/lint-state-write-path-drift.cjs +950 -0
  507. package/scripts/lint-test-file-count.allowlist.json +137 -8
  508. package/scripts/lint-test-file-count.cjs +25 -3
  509. package/scripts/lint-unreachable-guard-drift.cjs +830 -0
  510. package/scripts/lint-vendored-deps.cjs +297 -0
  511. package/scripts/mutation-matrix.cjs +599 -50
  512. package/scripts/pr-changed-files.cjs +63 -0
  513. package/scripts/pr-template-policy.cjs +14 -4
  514. package/scripts/prompt-injection-scan.sh +100 -14
  515. package/scripts/require-issue-link-policy.cjs +192 -0
  516. package/scripts/secret-scan.sh +75 -13
  517. package/scripts/select-docs-guards.cjs +56 -0
  518. package/scripts/sync-runtime-launcher.cjs +24 -7
  519. package/skills/gsd-autonomous/SKILL.md +0 -1
  520. package/skills/gsd-code-review/SKILL.md +1 -1
  521. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  522. package/skills/gsd-execute-phase/SKILL.md +1 -2
  523. package/skills/gsd-import/SKILL.md +1 -1
  524. package/skills/gsd-map-codebase/SKILL.md +1 -1
  525. package/skills/gsd-mempalace-capture/SKILL.md +1 -1
  526. package/skills/gsd-mempalace-recall/SKILL.md +1 -1
  527. package/skills/gsd-new-milestone/SKILL.md +1 -1
  528. package/skills/gsd-next/SKILL.md +0 -1
  529. package/skills/gsd-plan-phase/SKILL.md +0 -1
  530. package/skills/gsd-progress/SKILL.md +0 -1
  531. package/skills/gsd-quick/SKILL.md +9 -5
  532. package/skills/gsd-review-backlog/SKILL.md +2 -1
  533. package/skills/gsd-stats/SKILL.md +0 -1
  534. package/skills/gsd-verify-work/SKILL.md +1 -1
  535. package/vscode/package.json +1 -1
  536. package/bin/lib/ui-safety-gate.cjs +0 -107
  537. package/gsd-core/workflows/discovery-phase.md +0 -298
  538. package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
  539. package/gsd-core/workflows/verify-phase.md +0 -574
  540. package/scripts/affected-tests-lib.cjs +0 -554
  541. package/scripts/lint-allow-test-rule-refs.cjs +0 -162
  542. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  543. package/scripts/run-affected-tests.cjs +0 -7
  544. package/scripts/run-tests.cjs +0 -1051
@@ -22,7 +22,7 @@ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs")
22
22
  const clock_cjs_1 = require("./clock.cjs");
23
23
  // eslint-disable-next-line @typescript-eslint/no-require-imports
24
24
  const activeWorkstreamStore = require("./active-workstream-store.cjs");
25
- const { createSharedPointerAdapter, createSessionScopedPointerAdapter, createMemoryPointerAdapter, getActiveWorkstream: getStoredActiveWorkstream, setActiveWorkstream: setStoredActiveWorkstream, clearActiveWorkstream: clearStoredActiveWorkstream, } = activeWorkstreamStore;
25
+ const { createSharedPointerAdapter, createSessionScopedPointerAdapter, createMemoryPointerAdapter, getActiveWorkstream: getStoredActiveWorkstream, peekActiveWorkstream: peekStoredActiveWorkstream, setActiveWorkstream: setStoredActiveWorkstream, clearActiveWorkstream: clearStoredActiveWorkstream, diagnoseUnresolvedActiveWorkstream: diagnoseUnresolvedStoredActiveWorkstream, } = activeWorkstreamStore;
26
26
  // Track .planning/.lock files held by this process so they can be removed on exit.
27
27
  const _heldPlanningLocks = new Set();
28
28
  process.on('exit', () => {
@@ -120,6 +120,61 @@ function planningDir(cwd, ws, project) {
120
120
  function planningRoot(cwd) {
121
121
  return node_path_1.default.join(cwd, '.planning');
122
122
  }
123
+ /**
124
+ * #3972: the ONE owner of "is this planning scope opted out of worktrees?" —
125
+ * the effective `workflow.use_worktrees === false` read every
126
+ * isolation-deciding surface must share (config-get's merged view is the
127
+ * contract). Ladder: the scoped config's OWN key wins (planningDir is
128
+ * project- and workstream-aware); otherwise the flat root's key, but only
129
+ * under the GSD_WORKSTREAM env gate — config-get deliberately does NOT
130
+ * inherit root under GSD_PROJECT alone, and this read must not diverge
131
+ * (#3963). Strict `=== false` (never coerced); any read failure degrades to
132
+ * "not opted out" (worktrees on — the fail-safe direction: the guard keeps
133
+ * enforcing). Direct file reads only — never loadConfig, which normalizes
134
+ * and rewrites config on paths that back sentinel writes.
135
+ */
136
+ function worktreesOptedOut(cwd) {
137
+ // #3972 review: the WHOLE body is guarded — planningDir/planningRoot
138
+ // themselves throw on a GSD_PROJECT/GSD_WORKSTREAM value containing path
139
+ // separators or `..`, and this contract ("any failure degrades to not
140
+ // opted out — worktrees on, keep enforcing") must hold for that shape too.
141
+ try {
142
+ return worktreesOptedOutUnguarded(cwd);
143
+ }
144
+ catch {
145
+ return false;
146
+ }
147
+ }
148
+ function worktreesOptedOutUnguarded(cwd) {
149
+ const readCfg = (p) => {
150
+ try {
151
+ return JSON.parse(String(node_fs_1.default.readFileSync(p, 'utf8')));
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ };
157
+ const ownKey = (cfg) => {
158
+ if (cfg === null || typeof cfg !== 'object')
159
+ return { present: false, value: undefined };
160
+ const wf = cfg.workflow;
161
+ if (wf === null || typeof wf !== 'object' || Array.isArray(wf))
162
+ return { present: false, value: undefined };
163
+ const wfRec = wf;
164
+ return Object.prototype.hasOwnProperty.call(wfRec, 'use_worktrees')
165
+ ? { present: true, value: wfRec['use_worktrees'] }
166
+ : { present: false, value: undefined };
167
+ };
168
+ const scoped = ownKey(readCfg(node_path_1.default.join(planningDir(cwd), 'config.json')));
169
+ if (scoped.present)
170
+ return scoped.value === false;
171
+ if (process.env['GSD_WORKSTREAM']) {
172
+ const root = ownKey(readCfg(node_path_1.default.join(planningRoot(cwd), 'config.json')));
173
+ if (root.present)
174
+ return root.value === false;
175
+ }
176
+ return false;
177
+ }
123
178
  // Sorted list of workstream directory names under `<root>/.planning/workstreams`,
124
179
  // or `[]` when the project is flat (no workstreams dir). Single source of truth
125
180
  // for the "workstream mode" detection shared by the #1912/#2028 fail-safe guards
@@ -136,6 +191,15 @@ function listAvailableWorkstreams(cwd) {
136
191
  return [];
137
192
  }
138
193
  }
194
+ // #2142: the quick-task directory. Exported as its own function (not only as a
195
+ // `planningPaths` key) because `audit.cts`'s `scanQuickTasks` receives an
196
+ // already-resolved planning base rather than a `cwd`, so it cannot reach
197
+ // `planningPaths`. Without this shared helper, adding the `quick` key would
198
+ // leave TWO composers of `<planning>/quick` — the DEFECT.GENERATIVE-FIX shape
199
+ // the `debug` key (#3149) was introduced to eliminate.
200
+ function quickDirFrom(planningBase) {
201
+ return node_path_1.default.join(planningBase, 'quick');
202
+ }
139
203
  function planningPaths(cwd, ws) {
140
204
  const base = planningDir(cwd, ws);
141
205
  return {
@@ -150,6 +214,8 @@ function planningPaths(cwd, ws) {
150
214
  // `debug_dir` field and `init.debug`'s — previously each composed its own
151
215
  // `path.join(planning, 'debug')` (DEFECT.GENERATIVE-FIX).
152
216
  debug: node_path_1.default.join(base, 'debug'),
217
+ // #2142: quick-task directory, composed via the shared quickDirFrom helper.
218
+ quick: quickDirFrom(base),
153
219
  };
154
220
  }
155
221
  /**
@@ -172,11 +238,15 @@ function withPlanningLock(cwd, fn, clock) {
172
238
  // on every call with no self-heal. Mirrors acquireStateLock's deadmanCeilingMs.
173
239
  const deadmanCeilingMs = 60000;
174
240
  const start = clock.now();
175
- // Ensure .planning/ exists
176
- try {
177
- (0, shell_command_projection_cjs_1.platformEnsureDir)(planningDir(cwd));
178
- }
179
- catch { /* ok */ }
241
+ // Ensure .planning/ exists. A genuine failure here (EACCES/ENOSPC/EROFS/EMFILE)
242
+ // MUST surface immediately: the prior `catch { /* ok */ }` swallowed it, the lock
243
+ // write below then failed with ENOENT (parent dir missing), and ENOENT is retryable
244
+ // (PLANNING_LOCK_RETRY_ERRNOS — added for a Docker overlay-fs race), so the loop
245
+ // spun the full 10s budget and reported a PHANTOM "held by a live process"
246
+ // contention pointing at a nonexistent holder (epic #1879 / F16, #1884).
247
+ // `mkdirSync(recursive:true)` does not throw on an existing dir, so the normal
248
+ // path (dir already present) is unaffected; only real creation failures propagate.
249
+ (0, shell_command_projection_cjs_1.platformEnsureDir)(planningDir(cwd));
180
250
  function acquireLock() {
181
251
  // Atomic create — fails if file exists
182
252
  node_fs_1.default.writeFileSync(lockPath, JSON.stringify({
@@ -345,9 +415,40 @@ function createPlanningWorkspace(cwd, opts = {}) {
345
415
  function getActiveWorkstream(cwd) {
346
416
  return getStoredActiveWorkstream(cwd);
347
417
  }
418
+ // #3579 root-cause fix: read-only sibling of getActiveWorkstream, thin
419
+ // pass-through to active-workstream-store's non-mutating peek. Callers that
420
+ // only need to KNOW whether a workstream resolves (a guard's initial check,
421
+ // a bootstrap that will re-derive the answer anyway) must use this instead
422
+ // of getActiveWorkstream — the mutating variant self-heals (clears) a
423
+ // present-but-unresolvable chain[0] value, and a later read in the SAME
424
+ // process (another getActiveWorkstream call, or diagnoseUnresolvedActiveWorkstream)
425
+ // would then observe already-cleared state instead of the original evidence,
426
+ // silently changing the answer or losing the diagnostic reason. Self-heal
427
+ // still happens — exactly once, wherever the real consuming call site invokes
428
+ // getActiveWorkstream — this sibling just avoids triggering it prematurely.
429
+ function peekActiveWorkstream(cwd) {
430
+ return peekStoredActiveWorkstream(cwd);
431
+ }
348
432
  function setActiveWorkstream(cwd, name) {
349
433
  setStoredActiveWorkstream(cwd, name);
350
434
  }
435
+ // #3579 item 1: read-only diagnostic sibling of getActiveWorkstream, thin
436
+ // pass-through to active-workstream-store's chain walk. Lets the #1912/#2028
437
+ // fail-safe guards (init.progress, phase.complete) distinguish "no marker at
438
+ // all" from "a marker exists but didn't resolve" without duplicating the
439
+ // resolution predicate.
440
+ function diagnoseUnresolvedActiveWorkstream(cwd) {
441
+ return diagnoseUnresolvedStoredActiveWorkstream(cwd);
442
+ }
443
+ // #3579 item 1: human-readable clause for diagnoseUnresolvedActiveWorkstream's
444
+ // `reason`, shared by the init.progress and phase.complete fail-safe guards so
445
+ // the two error messages describe the same failure the same way instead of
446
+ // drifting (CLAUDE.md's Generative Fix Divergence anti-pattern).
447
+ function describeUnresolvedWorkstreamReason(reason) {
448
+ if (reason === 'invalid_name')
449
+ return 'the name is not a valid workstream name';
450
+ return "its workstream directory doesn't exist (it may have been renamed or removed)";
451
+ }
351
452
  /**
352
453
  * Locate the CONTEXT.md file in a phase directory, handling both the bare
353
454
  * form (`CONTEXT.md`) and the padded-prefix convention (`NN-CONTEXT.md`,
@@ -385,6 +486,7 @@ function findContextMdIn(absDirOrFiles) {
385
486
  }
386
487
  }
387
488
  module.exports = {
489
+ worktreesOptedOut,
388
490
  createPlanningWorkspace,
389
491
  createSharedPointerAdapter,
390
492
  createSessionScopedPointerAdapter,
@@ -393,9 +495,13 @@ module.exports = {
393
495
  planningRoot,
394
496
  listAvailableWorkstreams,
395
497
  planningPaths,
498
+ quickDirFrom,
396
499
  withPlanningLock,
397
500
  getActiveWorkstream,
501
+ peekActiveWorkstream,
398
502
  setActiveWorkstream,
503
+ diagnoseUnresolvedActiveWorkstream,
504
+ describeUnresolvedWorkstreamReason,
399
505
  findContextMdIn,
400
506
  // Test seam (audit M1): inject a deterministic isPidAlive so the liveness-gated
401
507
  // steal decision is exercised without real pids. Mirrors capability-lock.cts.
@@ -43,6 +43,9 @@ exports.projectTruths = projectTruths;
43
43
  exports.dispositionForUnverifiableTruth = dispositionForUnverifiableTruth;
44
44
  exports.runProbeCli = runProbeCli;
45
45
  const node_fs_1 = __importDefault(require("node:fs"));
46
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
47
+ const cliExitModule = require("./cli-exit.cjs");
48
+ const { ExitError } = cliExitModule;
46
49
  /** The LOCKED set of valid lifecycle statuses (the re-cut: no covered/backstop). */
47
50
  exports.VALID_STATUS = ['resolved', 'dismissed', 'unresolved'];
48
51
  function errMessage(e) {
@@ -372,7 +375,7 @@ function dispositionForProhibition(prohibition, context = {}) {
372
375
  };
373
376
  }
374
377
  // D4 GUARD: a judgment-tier (or unknown-tier) prohibition is NEVER a silent green from this
375
- // deterministic helper — it always routes to human/LLM judgment review (ADR-550 D4; verify-phase.md).
378
+ // deterministic helper — it always routes to human/LLM judgment review (ADR-550 D4; gsd-verifier.md + references/verifier-phase-gates.md).
376
379
  // Only a test-tier item with wired enforcement evidence may go green; the producer that supplies
377
380
  // that evidence (`prohibition-enforcement`, #1259) runs the wired check and requires a genuine pass.
378
381
  if (tier === 'test') {
@@ -497,7 +500,7 @@ function runProbeCli(analyze, options) {
497
500
  const readFile = options.readFile ?? ((p) => node_fs_1.default.readFileSync(p, 'utf8'));
498
501
  const write = options.write ?? ((s) => { process.stdout.write(s); });
499
502
  const writeErr = options.writeErr ?? ((s) => { process.stderr.write(s); });
500
- const exit = options.exit ?? ((code) => { process.exit(code); });
503
+ const exit = options.exit ?? ((code) => { throw new ExitError(code); });
501
504
  const reqPath = argv[2];
502
505
  const resPath = argv[3];
503
506
  if (!reqPath) {
@@ -477,7 +477,7 @@ function generateSkillsSection(cwd) {
477
477
  */
478
478
  function extractSkillFrontmatter(content) {
479
479
  const result = { name: '', description: '' };
480
- const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
480
+ const fmMatch = content.match(/^---\s*\r?\n([\s\S]*?)\r?\n---/);
481
481
  if (!fmMatch)
482
482
  return result;
483
483
  const fmBlock = fmMatch[1];
@@ -13,12 +13,55 @@
13
13
  * Async note: cmdExtractMessages and cmdProfileSample are async functions.
14
14
  * dispatchCapabilityCommand (gsd-tools.cjs:366-371) explicitly errors if a
15
15
  * router returns a Promise. Therefore these router functions call the async
16
- * function WITHOUT await and WITHOUT returning the Promise. The async functions
17
- * end with output() or process.exit() so the process terminates correctly once
18
- * the event loop drains. Unhandled rejections are caught by the .catch() wrapper
19
- * to surface errors via the error() callback.
16
+ * function WITHOUT await and WITHOUT returning the Promise; the event loop
17
+ * drains once the returned promise settles. Since ADR-3889 (#3910), the
18
+ * pipeline functions terminate by THROWING ExitError (never process.exit()
19
+ * directly), so a rejection surfacing here can carry either a genuine error
20
+ * OR a declared ExitError termination — the `.catch()` below must
21
+ * distinguish them: an ExitError sets process.exitCode directly (mirroring
22
+ * cli-exit.cjs's own runMain, the only other place ExitError is caught),
23
+ * while any other rejection is surfaced via the `error()` callback exactly
24
+ * as before. Calling `error(exitErr.message)` for an ExitError would be
25
+ * wrong on two counts: it discards the real exit code (error() always
26
+ * terminates at 1) and it re-derives a message from ExitError's generic
27
+ * "process exit N" constructor default rather than the (already emitted, or
28
+ * intentionally absent) stderr output the throwing call site controls.
20
29
  */
21
- const { ERROR_REASON } = require('./io.cjs');
30
+ const { ERROR_REASON, getJsonErrorMode } = require('./io.cjs');
31
+ const { ExitError } = require('./cli-exit.cjs');
32
+
33
+ /**
34
+ * Interpret a rejection from a fire-and-forget async pipeline call: an
35
+ * ExitError sets process.exitCode (and, for a non-zero code carrying a user
36
+ * message, writes it to stderr) exactly like runMain does; anything else
37
+ * reproduces io.cjs's error() stderr output byte-for-byte and sets
38
+ * process.exitCode directly instead of calling error() itself.
39
+ *
40
+ * error() (src/io.cts) is `never`-typed: it always throws ExitError(1) after
41
+ * writing to stderr. Calling it from inside this `.catch()` callback would
42
+ * throw from a detached promise chain that nothing awaits or re-catches —
43
+ * an unhandled promise rejection that Node (>=15, this repo's
44
+ * engines.node >= 24 default is --unhandled-rejections=throw) dumps as a
45
+ * raw stack trace on top of the clean line error() already wrote. Writing
46
+ * the same bytes directly and setting process.exitCode = 1 in place gets
47
+ * the identical observable stderr + exit code without ever throwing here.
48
+ */
49
+ function _handlePipelineRejection(e, error) {
50
+ void error;
51
+ if (e instanceof ExitError) {
52
+ if (e.hasUserMessage && e.code !== 0) process.stderr.write(`${e.message}\n`);
53
+ process.exitCode = e.code;
54
+ return;
55
+ }
56
+ const message = e && e.message ? e.message : String(e);
57
+ if (getJsonErrorMode()) {
58
+ const payload = JSON.stringify({ ok: false, reason: ERROR_REASON.UNKNOWN, message }) + '\n';
59
+ process.stderr.write(payload);
60
+ } else {
61
+ process.stderr.write('Error: ' + message + '\n');
62
+ }
63
+ process.exitCode = 1;
64
+ }
22
65
 
23
66
  // ─── Pipeline phase commands ───────────────────────────────────────────────────
24
67
 
@@ -51,7 +94,7 @@ function routeExtractMessages({ args, cwd, raw, error, _pipeline }) {
51
94
  // The function ends with output() or process.exit(); the event loop will drain.
52
95
  void cwd;
53
96
  p.cmdExtractMessages(projectArg, { sessionId, limit }, raw, sessionsPath)
54
- .catch(e => { error(e && e.message ? e.message : String(e)); });
97
+ .catch(e => { _handlePipelineRejection(e, error); });
55
98
  }
56
99
 
57
100
  function routeProfileSample({ args, cwd, raw, error, _pipeline }) {
@@ -67,7 +110,7 @@ function routeProfileSample({ args, cwd, raw, error, _pipeline }) {
67
110
  const maxChars = maxCharsIdx !== -1 ? parseInt(args[maxCharsIdx + 1], 10) : 500;
68
111
  // cmdProfileSample is async — do NOT return the Promise.
69
112
  p.cmdProfileSample(sessionsPath, { limit, maxPerProject, maxChars }, raw)
70
- .catch(e => { error(e && e.message ? e.message : String(e)); });
113
+ .catch(e => { _handlePipelineRejection(e, error); });
71
114
  }
72
115
 
73
116
  // ─── Output phase commands ─────────────────────────────────────────────────────
@@ -22,6 +22,9 @@ const node_readline_1 = __importDefault(require("node:readline"));
22
22
  // eslint-disable-next-line @typescript-eslint/no-require-imports
23
23
  const ioModule = require("./io.cjs");
24
24
  const { output, error, reapStaleTempFiles, ensureGsdTempDir, GSD_TEMP_DIR } = ioModule;
25
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
26
+ const cliExitModule = require("./cli-exit.cjs");
27
+ const { ExitError } = cliExitModule;
25
28
  // ─── Session I/O Helpers ──────────────────────────────────────────────────────
26
29
  function getSessionsDir(overridePath) {
27
30
  const dir = overridePath || node_path_1.default.join(node_os_1.default.homedir(), '.claude', 'projects');
@@ -250,7 +253,7 @@ function cmdScanSessions(overridePath, options, raw) {
250
253
  }
251
254
  }
252
255
  process.stdout.write(`\nTotal: ${projects.length} projects\n`);
253
- process.exit(0);
256
+ throw new ExitError(0);
254
257
  }
255
258
  }
256
259
  async function cmdExtractMessages(projectArg, options, raw, overridePath) {
@@ -376,11 +379,11 @@ async function cmdExtractMessages(projectArg, options, raw, overridePath) {
376
379
  };
377
380
  if (sessionsSkipped > 0 && sessionsProcessed > 0) {
378
381
  process.stdout.write(JSON.stringify(result, null, 2));
379
- process.exit(2);
382
+ throw new ExitError(2);
380
383
  }
381
384
  else if (sessionsProcessed === 0 && sessionsSkipped > 0) {
382
385
  process.stdout.write(JSON.stringify(result, null, 2));
383
- process.exit(1);
386
+ throw new ExitError(1);
384
387
  }
385
388
  else {
386
389
  output(result, raw, undefined);