@opengsd/gsd-core 1.14.0 → 1.16.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 (551) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +85 -5
  4. package/README.ja-JP.md +3 -3
  5. package/README.ko-KR.md +3 -3
  6. package/README.pt-BR.md +3 -3
  7. package/README.zh-CN.md +3 -3
  8. package/agents/gsd-code-fixer.compact.md +7 -6
  9. package/agents/gsd-code-fixer.md +9 -8
  10. package/agents/gsd-code-reviewer.compact.md +5 -3
  11. package/agents/gsd-code-reviewer.md +8 -6
  12. package/agents/gsd-debug-session-manager.compact.md +17 -2
  13. package/agents/gsd-debug-session-manager.md +17 -2
  14. package/agents/gsd-debugger.md +3 -3
  15. package/agents/gsd-eval-auditor.compact.md +1 -1
  16. package/agents/gsd-eval-auditor.md +1 -1
  17. package/agents/gsd-executor.md +17 -12
  18. package/agents/gsd-intel-updater.compact.md +1 -1
  19. package/agents/gsd-intel-updater.md +1 -1
  20. package/agents/gsd-mempalace-curator.md +2 -2
  21. package/agents/gsd-phase-researcher.md +19 -11
  22. package/agents/gsd-plan-checker.md +15 -9
  23. package/agents/gsd-planner.md +15 -11
  24. package/agents/gsd-project-researcher.compact.md +1 -1
  25. package/agents/gsd-project-researcher.md +1 -1
  26. package/agents/gsd-research-synthesizer.compact.md +1 -1
  27. package/agents/gsd-research-synthesizer.md +1 -1
  28. package/agents/gsd-ui-auditor.compact.md +21 -30
  29. package/agents/gsd-ui-auditor.md +166 -37
  30. package/agents/gsd-ui-researcher.compact.md +1 -1
  31. package/agents/gsd-ui-researcher.md +1 -1
  32. package/agents/gsd-verifier.md +37 -14
  33. package/bin/install.js +764 -287
  34. package/commands/gsd/add-tests.md +6 -1
  35. package/commands/gsd/ai-integration-phase.md +6 -1
  36. package/commands/gsd/audit-fix.md +5 -0
  37. package/commands/gsd/audit-milestone.md +6 -1
  38. package/commands/gsd/autonomous.md +7 -2
  39. package/commands/gsd/capture.md +9 -5
  40. package/commands/gsd/code-review.md +7 -2
  41. package/commands/gsd/complete-milestone.md +4 -0
  42. package/commands/gsd/config.md +7 -3
  43. package/commands/gsd/debug.md +11 -7
  44. package/commands/gsd/discuss-phase.md +7 -3
  45. package/commands/gsd/docs-update.md +12 -7
  46. package/commands/gsd/eval-review.md +6 -1
  47. package/commands/gsd/execute-phase.md +12 -7
  48. package/commands/gsd/extract-learnings.md +5 -0
  49. package/commands/gsd/fast.md +4 -0
  50. package/commands/gsd/forensics.md +5 -1
  51. package/commands/gsd/graphify.md +10 -6
  52. package/commands/gsd/health.md +5 -0
  53. package/commands/gsd/help.md +7 -2
  54. package/commands/gsd/import.md +7 -3
  55. package/commands/gsd/inbox.md +5 -0
  56. package/commands/gsd/ingest-docs.md +5 -1
  57. package/commands/gsd/manager.md +6 -1
  58. package/commands/gsd/map-codebase.md +7 -3
  59. package/commands/gsd/mempalace-capture.md +12 -4
  60. package/commands/gsd/mempalace-recall.md +5 -1
  61. package/commands/gsd/milestone-summary.md +5 -1
  62. package/commands/gsd/mvp-phase.md +8 -3
  63. package/commands/gsd/new-milestone.md +6 -1
  64. package/commands/gsd/new-project.md +5 -0
  65. package/commands/gsd/next.md +6 -1
  66. package/commands/gsd/ns-context.md +4 -0
  67. package/commands/gsd/ns-ideate.md +4 -0
  68. package/commands/gsd/ns-manage.md +4 -0
  69. package/commands/gsd/ns-project.md +4 -0
  70. package/commands/gsd/ns-review.md +4 -0
  71. package/commands/gsd/ns-workflow.md +4 -0
  72. package/commands/gsd/onboard.md +6 -1
  73. package/commands/gsd/pause-work.md +5 -1
  74. package/commands/gsd/phase.md +8 -4
  75. package/commands/gsd/plan-phase.md +6 -1
  76. package/commands/gsd/plan-review-convergence.md +11 -7
  77. package/commands/gsd/pr-branch.md +4 -0
  78. package/commands/gsd/profile-user.md +5 -1
  79. package/commands/gsd/progress.md +7 -2
  80. package/commands/gsd/quick-batch.md +21 -9
  81. package/commands/gsd/quick.md +12 -7
  82. package/commands/gsd/review.md +7 -4
  83. package/commands/gsd/secure-phase.md +6 -1
  84. package/commands/gsd/ship.md +5 -0
  85. package/commands/gsd/sketch.md +7 -2
  86. package/commands/gsd/spec-phase.md +5 -1
  87. package/commands/gsd/spike.md +8 -3
  88. package/commands/gsd/surface.md +5 -1
  89. package/commands/gsd/thread.md +4 -0
  90. package/commands/gsd/ui-phase.md +6 -1
  91. package/commands/gsd/ui-review.md +6 -1
  92. package/commands/gsd/ultraplan-phase.md +5 -1
  93. package/commands/gsd/undo.md +5 -1
  94. package/commands/gsd/update.md +6 -2
  95. package/commands/gsd/validate-phase.md +6 -1
  96. package/commands/gsd/verify-work.md +6 -1
  97. package/commands/gsd/workspace.md +7 -3
  98. package/gsd-core/bin/gsd-tools.cjs +477 -78
  99. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  100. package/gsd-core/bin/lib/adr-parser.cjs +3 -1
  101. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  102. package/gsd-core/bin/lib/audit.cjs +144 -42
  103. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  104. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  105. package/gsd-core/bin/lib/capability-registry.cjs +197 -222
  106. package/gsd-core/bin/lib/capability-validator.cjs +16 -1
  107. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  108. package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
  109. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  110. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  111. package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
  112. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  113. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  114. package/gsd-core/bin/lib/commands.cjs +343 -207
  115. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  116. package/gsd-core/bin/lib/config-loader.cjs +65 -4
  117. package/gsd-core/bin/lib/config.cjs +76 -19
  118. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  119. package/gsd-core/bin/lib/coverage.cjs +4 -8
  120. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  121. package/gsd-core/bin/lib/decisions.cjs +30 -14
  122. package/gsd-core/bin/lib/drift.cjs +177 -42
  123. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  124. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  125. package/gsd-core/bin/lib/frontmatter.cjs +426 -234
  126. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  127. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  128. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  129. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  130. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  131. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  132. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  133. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  134. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  135. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  136. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  137. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  138. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  139. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  140. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  141. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  142. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  143. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  144. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  145. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  146. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  147. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  148. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  149. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  150. package/gsd-core/bin/lib/graphify.cjs +10 -2
  151. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  152. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  153. package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
  154. package/gsd-core/bin/lib/init.cjs +364 -132
  155. package/gsd-core/bin/lib/install-engine.cjs +30 -33
  156. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  157. package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
  158. package/gsd-core/bin/lib/io.cjs +122 -3
  159. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  160. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  161. package/gsd-core/bin/lib/milestone.cjs +37 -6
  162. package/gsd-core/bin/lib/model-resolver.cjs +171 -62
  163. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  164. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  165. package/gsd-core/bin/lib/pattern.cjs +10 -0
  166. package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
  167. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  168. package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
  169. package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
  170. package/gsd-core/bin/lib/phase-id.cjs +110 -8
  171. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  172. package/gsd-core/bin/lib/phase-locator.cjs +29 -10
  173. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  174. package/gsd-core/bin/lib/phase.cjs +489 -88
  175. package/gsd-core/bin/lib/plan-document.cjs +142 -20
  176. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  177. package/gsd-core/bin/lib/planning-document.cjs +692 -0
  178. package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
  179. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  180. package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
  181. package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
  182. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  183. package/gsd-core/bin/lib/probe-core.cjs +7 -1
  184. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  185. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  186. package/gsd-core/bin/lib/project-root.cjs +41 -2
  187. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  188. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  189. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  190. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  191. package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
  192. package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
  193. package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
  194. package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
  195. package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
  196. package/gsd-core/bin/lib/roadmap.cjs +405 -88
  197. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
  198. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
  199. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  200. package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
  201. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
  202. package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
  203. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  204. package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
  205. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  206. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  207. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  208. package/gsd-core/bin/lib/state-document.cjs +100 -22
  209. package/gsd-core/bin/lib/state-transition.cjs +39 -2
  210. package/gsd-core/bin/lib/state.cjs +256 -105
  211. package/gsd-core/bin/lib/surface.cjs +19 -2
  212. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
  213. package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
  214. package/gsd-core/bin/lib/uat.cjs +432 -7
  215. package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
  216. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
  217. package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
  218. package/gsd-core/bin/lib/vendor/README.md +31 -9
  219. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  220. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  221. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  222. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  223. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  224. package/gsd-core/bin/lib/verification.cjs +1378 -274
  225. package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
  226. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  227. package/gsd-core/bin/lib/verify.cjs +357 -531
  228. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  229. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  230. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  231. package/gsd-core/bin/lib/workstream.cjs +11 -2
  232. package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
  233. package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
  234. package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
  235. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  236. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  237. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  238. package/gsd-core/references/checkpoints.md +5 -3
  239. package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
  240. package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
  241. package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
  242. package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
  243. package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
  244. package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
  245. package/gsd-core/references/edge-probe.md +195 -21
  246. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  247. package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
  248. package/gsd-core/references/execute-phase-response-language.md +1 -1
  249. package/gsd-core/references/execute-phase-wave-guard.md +22 -11
  250. package/gsd-core/references/gsd-run-resolver.md +1 -1
  251. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  252. package/gsd-core/references/model-profiles.md +1 -1
  253. package/gsd-core/references/offer-next.md +1 -1
  254. package/gsd-core/references/phase-argument-parsing.md +9 -7
  255. package/gsd-core/references/phase-id-convention.md +28 -0
  256. package/gsd-core/references/planner-gap-closure.md +2 -0
  257. package/gsd-core/references/planner-load-graph-context.md +24 -13
  258. package/gsd-core/references/planner-verify-command-grounding.md +14 -0
  259. package/gsd-core/references/planning-config.md +12 -3
  260. package/gsd-core/references/spidr-splitting.md +1 -1
  261. package/gsd-core/references/tdd.md +37 -8
  262. package/gsd-core/references/ui-consideration-probe.md +10 -5
  263. package/gsd-core/references/verifier-phase-gates.md +5 -2
  264. package/gsd-core/references/verify-command-path-resolvability.md +10 -2
  265. package/gsd-core/references/verify-mvp-mode.md +2 -2
  266. package/gsd-core/references/workstream-flag.md +33 -3
  267. package/gsd-core/references/worktree-path-safety.md +321 -0
  268. package/gsd-core/templates/README.md +1 -1
  269. package/gsd-core/templates/UAT.md +17 -1
  270. package/gsd-core/templates/config.json +2 -11
  271. package/gsd-core/templates/verification-report.md +1 -1
  272. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  273. package/gsd-core/workflows/add-backlog.md +1 -1
  274. package/gsd-core/workflows/add-phase.md +8 -7
  275. package/gsd-core/workflows/add-tests.md +4 -3
  276. package/gsd-core/workflows/add-todo.md +6 -5
  277. package/gsd-core/workflows/ai-integration-phase.md +13 -4
  278. package/gsd-core/workflows/audit-fix.md +1 -1
  279. package/gsd-core/workflows/audit-milestone.md +4 -3
  280. package/gsd-core/workflows/audit-uat.md +1 -1
  281. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
  282. package/gsd-core/workflows/autonomous.md +43 -23
  283. package/gsd-core/workflows/check-todos.md +7 -6
  284. package/gsd-core/workflows/cleanup.md +2 -2
  285. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
  286. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  287. package/gsd-core/workflows/code-review-fix.md +112 -25
  288. package/gsd-core/workflows/code-review.md +146 -135
  289. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  290. package/gsd-core/workflows/complete-milestone.md +13 -8
  291. package/gsd-core/workflows/debug.md +32 -7
  292. package/gsd-core/workflows/diagnose-issues.md +3 -2
  293. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  294. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  295. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  296. package/gsd-core/workflows/discuss-phase.md +4 -3
  297. package/gsd-core/workflows/do.md +2 -2
  298. package/gsd-core/workflows/docs-update.md +6 -5
  299. package/gsd-core/workflows/edit-phase.md +4 -3
  300. package/gsd-core/workflows/eval-review.md +14 -5
  301. package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
  302. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
  303. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  304. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  305. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
  306. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  307. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  308. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  309. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  310. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
  311. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  312. package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
  313. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  314. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  315. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  316. package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
  317. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  318. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  319. package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
  320. package/gsd-core/workflows/execute-phase.md +96 -178
  321. package/gsd-core/workflows/execute-plan.md +18 -23
  322. package/gsd-core/workflows/explore.md +4 -4
  323. package/gsd-core/workflows/extract-learnings.md +4 -2
  324. package/gsd-core/workflows/fast.md +1 -1
  325. package/gsd-core/workflows/forensics.md +1 -1
  326. package/gsd-core/workflows/graduation.md +1 -1
  327. package/gsd-core/workflows/health.md +3 -2
  328. package/gsd-core/workflows/help/modes/full.compact.md +3 -3
  329. package/gsd-core/workflows/help/modes/full.md +5 -5
  330. package/gsd-core/workflows/help/modes/topic.md +15 -5
  331. package/gsd-core/workflows/import.md +4 -3
  332. package/gsd-core/workflows/inbox.md +2 -2
  333. package/gsd-core/workflows/ingest-docs.md +3 -3
  334. package/gsd-core/workflows/insert-phase.md +4 -3
  335. package/gsd-core/workflows/list-seeds.md +1 -1
  336. package/gsd-core/workflows/list-workspaces.md +1 -1
  337. package/gsd-core/workflows/manager.md +6 -4
  338. package/gsd-core/workflows/map-codebase.md +5 -4
  339. package/gsd-core/workflows/milestone-summary.md +3 -2
  340. package/gsd-core/workflows/mvp-phase.md +14 -14
  341. package/gsd-core/workflows/new-milestone.md +11 -11
  342. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
  343. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
  344. package/gsd-core/workflows/new-project.md +7 -7
  345. package/gsd-core/workflows/new-workspace.md +2 -2
  346. package/gsd-core/workflows/next.md +1 -1
  347. package/gsd-core/workflows/note.md +1 -1
  348. package/gsd-core/workflows/onboard.md +1 -1
  349. package/gsd-core/workflows/pause-work.md +2 -2
  350. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  351. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
  352. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  353. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  354. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
  355. package/gsd-core/workflows/plan-phase.md +50 -24
  356. package/gsd-core/workflows/plan-review-convergence.md +21 -5
  357. package/gsd-core/workflows/plant-seed.md +62 -20
  358. package/gsd-core/workflows/pr-branch.md +113 -13
  359. package/gsd-core/workflows/profile-user.md +2 -2
  360. package/gsd-core/workflows/progress.md +19 -49
  361. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
  362. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  363. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  364. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  365. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  366. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  367. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  368. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  369. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  370. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  371. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  372. package/gsd-core/workflows/quick-batch.md +15 -10
  373. package/gsd-core/workflows/quick.md +62 -39
  374. package/gsd-core/workflows/reapply-patches.md +9 -3
  375. package/gsd-core/workflows/remove-phase.md +3 -2
  376. package/gsd-core/workflows/remove-workspace.md +2 -2
  377. package/gsd-core/workflows/resume-project.md +3 -2
  378. package/gsd-core/workflows/review.md +33 -17
  379. package/gsd-core/workflows/scan.md +3 -2
  380. package/gsd-core/workflows/secure-phase.md +13 -13
  381. package/gsd-core/workflows/settings-advanced.md +30 -10
  382. package/gsd-core/workflows/settings-integrations.md +2 -3
  383. package/gsd-core/workflows/settings.md +4 -4
  384. package/gsd-core/workflows/ship.md +14 -13
  385. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  386. package/gsd-core/workflows/sketch.md +1 -1
  387. package/gsd-core/workflows/smart-entry.md +2 -2
  388. package/gsd-core/workflows/spec-phase.md +15 -5
  389. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  390. package/gsd-core/workflows/spike.md +1 -1
  391. package/gsd-core/workflows/stats.md +1 -1
  392. package/gsd-core/workflows/sync-skills.md +5 -5
  393. package/gsd-core/workflows/thread.md +2 -2
  394. package/gsd-core/workflows/transition.md +13 -23
  395. package/gsd-core/workflows/ui-phase.md +48 -11
  396. package/gsd-core/workflows/ui-review.md +21 -6
  397. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  398. package/gsd-core/workflows/undo.md +339 -20
  399. package/gsd-core/workflows/update.md +7 -7
  400. package/gsd-core/workflows/validate-phase.md +12 -13
  401. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  402. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  403. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  404. package/gsd-core/workflows/verify-work.md +129 -55
  405. package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
  406. package/hooks/dist/gsd-check-update-worker.js +8 -0
  407. package/hooks/dist/gsd-check-update.js +8 -0
  408. package/hooks/dist/gsd-context-monitor.js +31 -8
  409. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  410. package/hooks/dist/gsd-secret-read-guard.js +161 -4
  411. package/hooks/dist/gsd-statusline.js +85 -20
  412. package/hooks/dist/gsd-update-banner.js +8 -0
  413. package/hooks/dist/gsd-validate-commit.sh +63 -4
  414. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  415. package/hooks/dist/gsd-workflow-guard.js +5 -4
  416. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  417. package/hooks/dist/lib/cli-exit.js +12 -0
  418. package/hooks/dist/lib/git-probe.js +17 -1
  419. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  420. package/hooks/gsd-agent-isolation-guard.js +32 -0
  421. package/hooks/gsd-check-update-worker.js +8 -0
  422. package/hooks/gsd-check-update.js +8 -0
  423. package/hooks/gsd-context-monitor.js +31 -8
  424. package/hooks/gsd-cursor-subagent-start.js +8 -0
  425. package/hooks/gsd-secret-read-guard.js +161 -4
  426. package/hooks/gsd-statusline.js +85 -20
  427. package/hooks/gsd-update-banner.js +8 -0
  428. package/hooks/gsd-validate-commit.sh +63 -4
  429. package/hooks/gsd-windsurf-pre-write.js +11 -2
  430. package/hooks/gsd-workflow-guard.js +5 -4
  431. package/hooks/gsd-worktree-path-guard.js +6 -2
  432. package/hooks/hooks.json +5 -5
  433. package/hooks/lib/cli-exit.js +12 -0
  434. package/hooks/lib/git-probe.js +17 -1
  435. package/hooks/lib/isolation-sentinel.js +2 -2
  436. package/package.json +22 -4
  437. package/scripts/build-hooks.js +15 -6
  438. package/scripts/changeset/parse.cjs +52 -4
  439. package/scripts/check-contract-drift.cjs +127 -11
  440. package/scripts/ci-timeout-report.cjs +770 -4
  441. package/scripts/command-contract-helpers.cjs +15 -8
  442. package/scripts/docs-guard-registry.cjs +34 -0
  443. package/scripts/gen-features.cjs +13 -8
  444. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  445. package/scripts/gen-loop-host-contract.cjs +79 -1
  446. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  447. package/scripts/gen-plugin-skills.cjs +87 -1
  448. package/scripts/gen-research-agents.cjs +24 -31
  449. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  450. package/scripts/gen-test-timings.cjs +32 -7
  451. package/scripts/lib/cli-exit.cjs +12 -0
  452. package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
  453. package/scripts/lib/ndjson-reporter.cjs +31 -5
  454. package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
  455. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  456. package/scripts/lib/vendor-bundle.cjs +59 -0
  457. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  458. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  459. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  460. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  461. package/scripts/lint-descriptions.cjs +7 -3
  462. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
  463. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  464. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  465. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  466. package/scripts/lint-phase-arg-assignment.cjs +257 -0
  467. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  468. package/scripts/lint-phase-id-drift.cjs +319 -5
  469. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  470. package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
  471. package/scripts/lint-response-language-coverage.cjs +3 -0
  472. package/scripts/lint-retired-runtime-name.cjs +619 -0
  473. package/scripts/lint-skill-deps.cjs +7 -3
  474. package/scripts/lint-state-write-path-drift.cjs +93 -0
  475. package/scripts/lint-test-file-count.allowlist.json +38 -9
  476. package/scripts/lint-test-file-count.cjs +34 -1
  477. package/scripts/lint-vendored-deps.cjs +41 -5
  478. package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
  479. package/scripts/mutation-matrix.cjs +50 -5
  480. package/scripts/prompt-injection-scan.sh +4 -0
  481. package/scripts/release-tarball-smoke.cjs +194 -1
  482. package/scripts/require-issue-link-policy.cjs +6 -2
  483. package/scripts/sync-runtime-launcher.cjs +184 -2
  484. package/scripts/verify-npm-publish.cjs +76 -20
  485. package/skills/gsd-add-tests/SKILL.md +6 -1
  486. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  487. package/skills/gsd-audit-fix/SKILL.md +5 -0
  488. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  489. package/skills/gsd-autonomous/SKILL.md +7 -2
  490. package/skills/gsd-capture/SKILL.md +9 -5
  491. package/skills/gsd-code-review/SKILL.md +7 -2
  492. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  493. package/skills/gsd-config/SKILL.md +8 -4
  494. package/skills/gsd-debug/SKILL.md +11 -7
  495. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  496. package/skills/gsd-docs-update/SKILL.md +12 -7
  497. package/skills/gsd-eval-review/SKILL.md +6 -1
  498. package/skills/gsd-execute-phase/SKILL.md +12 -7
  499. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  500. package/skills/gsd-fast/SKILL.md +4 -0
  501. package/skills/gsd-forensics/SKILL.md +5 -1
  502. package/skills/gsd-graphify/SKILL.md +10 -6
  503. package/skills/gsd-health/SKILL.md +5 -0
  504. package/skills/gsd-help/SKILL.md +7 -2
  505. package/skills/gsd-import/SKILL.md +7 -3
  506. package/skills/gsd-inbox/SKILL.md +5 -0
  507. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  508. package/skills/gsd-manager/SKILL.md +6 -1
  509. package/skills/gsd-map-codebase/SKILL.md +7 -3
  510. package/skills/gsd-mempalace-capture/SKILL.md +12 -4
  511. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  512. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  513. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  514. package/skills/gsd-new-milestone/SKILL.md +6 -1
  515. package/skills/gsd-new-project/SKILL.md +5 -0
  516. package/skills/gsd-next/SKILL.md +6 -1
  517. package/skills/gsd-ns-context/SKILL.md +4 -0
  518. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  519. package/skills/gsd-ns-manage/SKILL.md +4 -0
  520. package/skills/gsd-ns-project/SKILL.md +4 -0
  521. package/skills/gsd-ns-review/SKILL.md +4 -0
  522. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  523. package/skills/gsd-onboard/SKILL.md +6 -1
  524. package/skills/gsd-pause-work/SKILL.md +5 -1
  525. package/skills/gsd-phase/SKILL.md +8 -4
  526. package/skills/gsd-plan-phase/SKILL.md +6 -1
  527. package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
  528. package/skills/gsd-pr-branch/SKILL.md +4 -0
  529. package/skills/gsd-profile-user/SKILL.md +5 -1
  530. package/skills/gsd-progress/SKILL.md +7 -2
  531. package/skills/gsd-quick/SKILL.md +16 -10
  532. package/skills/gsd-quick-batch/SKILL.md +21 -9
  533. package/skills/gsd-review/SKILL.md +7 -4
  534. package/skills/gsd-review-backlog/SKILL.md +3 -2
  535. package/skills/gsd-secure-phase/SKILL.md +6 -1
  536. package/skills/gsd-ship/SKILL.md +5 -0
  537. package/skills/gsd-sketch/SKILL.md +7 -2
  538. package/skills/gsd-spec-phase/SKILL.md +5 -1
  539. package/skills/gsd-spike/SKILL.md +8 -3
  540. package/skills/gsd-surface/SKILL.md +5 -1
  541. package/skills/gsd-thread/SKILL.md +4 -0
  542. package/skills/gsd-ui-phase/SKILL.md +6 -1
  543. package/skills/gsd-ui-review/SKILL.md +6 -1
  544. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  545. package/skills/gsd-undo/SKILL.md +5 -1
  546. package/skills/gsd-update/SKILL.md +6 -2
  547. package/skills/gsd-validate-phase/SKILL.md +6 -1
  548. package/skills/gsd-verify-work/SKILL.md +6 -1
  549. package/skills/gsd-workspace/SKILL.md +7 -3
  550. package/skills/gsd-workstreams/SKILL.md +6 -6
  551. package/vscode/package.json +1 -1
@@ -15,15 +15,10 @@ If any of these is false, the gate is inactive — execution proceeds normally.
15
15
  For each task gated by TDD, the executor MUST verify (before running the implementation step):
16
16
 
17
17
  1. **A failing-test commit exists.** Search git log on the current branch for a commit matching `test({phase}-{plan})` whose subject mentions the same plan as the current task. The commit must touch a test file (`*.test.*`, `*.spec.*`, `tests/**`).
18
- 2. **The test was actually red — INTENTIONALLY (#3770).** A nonzero exit is not RED by itself: syntax errors, zero-test discovery, fixture crashes, parser errors, and unrelated assertions are INVALID_RED. The executor must persist the RED evidence record (command, exit code, failing test, expected result from `<behavior>`, actual result) and verify it:
19
- ```bash
20
- gsd_run check tdd-red-evidence <record.json> --raw
21
- ```
22
- - `RED_EVIDENCE_OK` (reason `target_test_failed`): the TARGET test named by the plan failed on a real assertion — the ONLY verdict that authorizes GREEN.
23
- - `INVALID_RED` (reasons `unexpected_green`, `zero_tests_discovered`, `nonzero_exit_without_test_failure`, `fixture_or_load_failure`, `no_target_test_failure`, `invalid_record`, `unreadable_record`): the gate trips — halt, fix the RED phase (test identity, fixture, discovery), and re-verify before any implementation step. A `RED:` prefix or `(RED)` tag in the commit message is NOT sufficient evidence on its own.
18
+ 2. **The test was actually red — INTENTIONALLY (#3770).** Read `gsd-core/references/tdd.md`, "Red-Green-Refactor Cycle", RED step 4, and follow its complete evidence contract before GREEN. That section owns format selection (TAP, including Node/Vitest; JUnit XML, including Surefire/Failsafe; swift-testing console; or Python `unittest` text), reporter reruns, report freshness, the classifier invocation, and semantic inspection. Require `RED_EVIDENCE_OK` for the actual run and verify the planned target assertion failed for the intended reason. An `INVALID_RED` verdict, unsupported format, or failed semantic assessment trips this gate; self-attestation cannot substitute for machine validation. A `RED:` prefix or `(RED)` tag in the commit message is not evidence.
24
19
  3. **No implementation commit yet.** No `feat({phase}-{plan})` commit may exist for the same plan ID before the failing-test commit.
25
20
 
26
- If any check fails, the gate trips. For check 2, an INVALID_RED verdict (`check tdd-red-evidence`) trips the gate — the executor MUST halt and block the implementation step.
21
+ If any check fails, the gate trips. A non-zero exit from `gsd_run check tdd-red-evidence` (`69` `UNAVAILABLE`: the record could not be read, #5170) is a command failure that has NOT authorized GREEN — the gate trips. For check 2, an `INVALID_RED` classifier verdict or a failed semantic assessment trips the gate (halt reason `invalid_red`) — the executor MUST halt and block the implementation step.
27
22
 
28
23
  ## What "behavior-adding task" means
29
24
 
@@ -52,7 +47,7 @@ The executor MUST:
52
47
  Required next step:
53
48
  1. Write a failing test for the behavior above.
54
49
  2. Commit it as: test({phase}-{plan}): {short description}
55
- 3. Re-run /gsd execute-phase
50
+ 3. Re-run /gsd:execute-phase
56
51
  ```
57
52
 
58
53
  3. Exit the current execution wave cleanly. Do NOT roll back any prior commits in the same wave.
@@ -65,7 +60,7 @@ The existing end-of-phase TDD review (in `workflows/execute-phase.md`'s `tdd_rev
65
60
  Under TDD mode, escalate this to **blocking**:
66
61
  - If any TDD plan is missing a RED or GREEN commit, the executor MUST refuse to mark the phase complete.
67
62
  - The user is shown the same review table, but the verdict line reads:
68
- > "Phase blocked: {N} TDD plan(s) violate the RED→GREEN gate sequence under TDD. Resolve and re-run /gsd execute-phase, or override with `/gsd execute-phase {phase} --force-mvp-gate` to ship anyway."
63
+ > "Phase blocked: {N} TDD plan(s) violate the RED→GREEN gate sequence under TDD. Resolve and re-run /gsd:execute-phase, or override with `/gsd:execute-phase {phase} --force-mvp-gate` to ship anyway."
69
64
 
70
65
  The `--force-mvp-gate` flag is documented but not introduced by this plan — it is the escape hatch the spec mentions; if the user later builds it, the workflow already references the contract.
71
66
 
@@ -73,7 +68,7 @@ The `--force-mvp-gate` flag is documented but not introduced by this plan — it
73
68
 
74
69
  - It does not enforce REFACTOR commits. REFACTOR remains optional (per `gsd-core/references/tdd.md`).
75
70
  - It does not check test quality (the test could be trivially weak). That's the planner's job. It DOES check that the RED failure was intentional — the target test failing an assertion (#3770).
76
- - It does not run tests. The executor only inspects git log + file system. Running tests is the implementation step's job.
71
+ - It does not start implementation by running tests. During RED, the executor runs the planned test and captures its result, rerunning the planned target with a supported reporter when the first report is unsupported (`tdd.md` RED step 4); before GREEN, this gate inspects that persisted evidence, git history, and test assertion. The implementation step starts only after the RED gate passes.
77
72
  - It does not gate config-only or doc-only tasks (see "behavior-adding task" definition).
78
73
 
79
74
  ## Compatibility with existing TDD discipline
@@ -4,6 +4,9 @@
4
4
  - `## Cross-Plan Wiring Gap` with plan/link/from/pattern rows
5
5
  - Options: investigate+fix before continue, or continue with cascade risk
6
6
  Skip key-links that reference files in the CURRENT (upcoming) wave.
7
+ Exit status (#5170): `0` all verified; `1` a link failed (read the JSON); `66` the plan declares no
8
+ key_links (nothing to check); `69` the plan is missing/unreadable (could not look — surface it, never
9
+ treat the plan as wired).
7
10
 
8
11
  7c. **Between-wave manifest reset and worktree base refresh (waves 2+ only — #1369):**
9
12
 
@@ -24,12 +27,13 @@
24
27
  # Unset per-wave manifest so wave N+1 creates a fresh one (#3384, #1369).
25
28
  unset WAVE_WORKTREE_MANIFEST
26
29
 
27
- # Between-wave base re-check (#1369, #3659): after wave N merges and tracking commits,
28
- # HEAD has advanced. Re-asserting worktree.baseRef:"head" is deliberately NOT done here —
29
- # the runtime harness does not read project-settings baseRef (#48), so in
30
- # harness-worktree mode the setting cannot influence the fork base. The safety re-check
31
- # below compares HEAD against the REAL fork base and degrades the remaining waves
32
- # whenever they diverge, avoiding the base-mismatch FATAL in executor agents.
30
+ # Between-wave base re-check (#1369, #3659, #4588): after wave N merges and tracking
31
+ # commits, HEAD has advanced. Re-asserting worktree.baseRef:"head" is NOT done here — the
32
+ # setting is either already in place (honored by GSD-created worktrees and by the Claude
33
+ # Code harness, #4588) or
34
+ # deliberately absent; a re-write would not change the fork base. The safety re-check
35
+ # below compares HEAD against the fork base and degrades the remaining waves whenever
36
+ # they diverge, avoiding the base-mismatch FATAL in executor agents.
33
37
  if [ "$ISOLATION" = "harness-worktree" ] && [ "$USE_WORKTREES" != "false" ]; then
34
38
  _BETWEEN_DEGRADE=$(gsd_run query worktree.base-check --mode "$ISOLATION" --pick shouldDegrade 2>/dev/null || echo "false")
35
39
  if [ "$_BETWEEN_DEGRADE" = "true" ]; then
@@ -2,7 +2,7 @@
2
2
 
3
3
  **If `response_language` is set:** User-facing orchestrator output (questions, narration, report-template prose) in `{response_language}`; technical terms, code, file paths, and subagent prompts stay in English. Pass `response_language: {value}` into every spawned subagent prompt so any user-facing output they produce stays in the configured language.
4
4
 
5
- **The `gsd-verifier` subagent has no workflow file of its own (#2529):** the `verify_phase_goal` step reaches it by dispatch, not by reading a workflow, so there is no file in which to place a directive — the dispatch prompt is the only place its coverage can live. That prompt MUST carry this line verbatim, immediately after `Create VERIFICATION.md.`:
5
+ **The `gsd-verifier` subagent has no workflow file of its own (#2529):** the shared verification step (`workflows/execute-phase/steps/verify-phase-goal.md`, included by execute-phase's `verify_phase_goal` and by verify-work, #5118) reaches it by dispatch, not by reading a workflow, so there is no file in which to place a directive — the dispatch prompt is the only place its coverage can live. That prompt MUST carry this line verbatim, immediately after `Create VERIFICATION.md.` (the shared step's prompt carries it inline, so both callers inject it):
6
6
 
7
7
  `Use response_language {response_language} for all user-facing prose — narration between tool calls, status updates, progress notes, and findings included; preserve code and paths.`
8
8
 
@@ -1,10 +1,10 @@
1
1
  0.5. **Inter-wave worktree base re-check (wave N+1 guard — #1369):**
2
2
 
3
3
  After Wave N merges and tracking commits advance orchestrator HEAD, Claude Code's
4
- `isolation="worktree"` still forks new worktrees from `origin/HEAD` (the "fresh" base),
5
- not the live HEAD. This means Wave N+1 worktrees would be created from the stale
6
- pre-Wave-N base, causing the `worktree_branch_check` guard inside each executor to halt
7
- immediately with a base-mismatch fatal.
4
+ `isolation="worktree"` forks new worktrees from `origin/HEAD` (the "fresh" base) unless
5
+ `worktree.baseRef:"head"` is set — not the live HEAD. Without the setting, Wave N+1
6
+ worktrees would be created from the stale pre-Wave-N base, causing the
7
+ `worktree_branch_check` guard inside each executor to halt with a base-mismatch fatal.
8
8
 
9
9
  **Run this check at the start of every wave when `USE_WORKTREES != "false"` and
10
10
  `ISOLATION = "harness-worktree"`** (#2652 — the harness caches the fork base, so this is a
@@ -30,10 +30,21 @@
30
30
  this check and may re-enable worktree isolation once `origin/HEAD` matches HEAD again
31
31
  (e.g. via `git fetch` or a push that advances it).
32
32
 
33
- **Why `worktree.baseRef:"head"` does not avoid this degrade (#48, #3659):** the runtime
34
- harness does not read project-settings `baseRef` — an isolated dispatch always forks from
35
- `origin/HEAD` regardless of the setting, so the check compares against the real fork base
36
- and degrades whenever HEAD has diverged. Parallel worktrees return once HEAD is
37
- merged/pushed so `origin/HEAD` matches it. The setting still restores parallel execution
38
- on runtimes where GSD itself creates the worktrees (orchestrator-managed isolation:
39
- Codex, OpenCode, Kimi, Kimi Code). See #683 for the base-ref configuration detail.
33
+ **How `worktree.baseRef:"head"` interacts with this degrade (#3659, #4588):** with the
34
+ setting in place the check trusts it and does not compare — the worktree creator forks from the
35
+ orchestrator HEAD (GSD's own `git worktree add` by construction; the Claude Code harness as
36
+ measured from all three settings layers, #4588; Cursor unmeasured), so outside the two
37
+ exceptions below this guard only fires when the setting
38
+ is absent and HEAD has diverged from `origin/HEAD`. Parallel worktrees then return once HEAD
39
+ is merged/pushed so `origin/HEAD` matches it, or once the setting is applied. The exceptions
40
+ (#4588): a supplied `--observed-fork-base` is compared against HEAD instead of trusted, in
41
+ both modes; and on a harness-created run with no observation, a Claude Code `WorktreeCreate`
42
+ hook in any of those settings files — or one of them that does not parse, so a hook cannot be
43
+ ruled out — withholds the trust: the hook creates the worktree without applying the setting,
44
+ so the check compares against `origin/HEAD` anyway and a mismatch degrades with
45
+ `baseref-head-bypassed-by-hook`. The #4868 prior-worktree observation does not lift that
46
+ degrade: a worktree at HEAD records nothing about which creator left it there, so one the
47
+ plain harness created before the hook was configured reads the same as one the hook created
48
+ (#4881). On a hook host only `--observed-fork-base` restores a trusted verdict. The exit-42
49
+ guard in each executor remains the backstop on a host that does not honor the setting.
50
+ See #683 for the base-ref configuration detail.
@@ -4,5 +4,5 @@ Use this bootstrap block when a workflow must call `gsd-tools` from the active w
4
4
  Keep this resolver centralized; workflows should reference this file instead of copying the shell probe.
5
5
 
6
6
  ```bash
7
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd_run is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; case "$(gsd_run runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') GSD_IDENTITY_STATUS=ok;; esac; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
7
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { set -- "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}" "$HOME/.gemini/antigravity-ide" "$HOME/.gemini/antigravity-cli" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}" "${CLINE_CONFIG_DIR:-$HOME/.cline}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}" "${CODEX_HOME:-$HOME/.codex}" "${COPILOT_CONFIG_DIR:-${COPILOT_HOME:-$HOME/.copilot}}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}" "${HERMES_HOME:-$HOME/.hermes}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}" "${KIMI_CONFIG_DIR:-$HOME/.config/agents}" "$HOME/.agents" "${KIMI_CODE_HOME:-$HOME/.kimi-code}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}" "${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}" "${TRAE_CONFIG_DIR:-$HOME/.trae}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}" "${ZCODE_CONFIG_DIR:-$HOME/.zcode}" "${GROK_AGENTS_HOME:-$HOME/.agents}"; for _h; do _gsd_at "$_h/gsd-core/bin/${_GSD_SHIM_NAME}" && return 0; done; return 1; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
8
8
  ```
@@ -108,7 +108,13 @@ Evaluate `check` (one of `query`, `predicate`, or `agentVerdict`). Then honor `b
108
108
  - `blocking: false` → advisory only; surface the message but continue regardless of outcome.
109
109
 
110
110
  Honor `onError` if the check itself errors: `skip` means treat as non-blocking and continue;
111
- `halt` means surface the error and stop.
111
+ `halt` means surface the error and stop. "Errors" means a non-zero exit from `gsd_run check ...`,
112
+ and that includes `69` (`UNAVAILABLE`, #5170): a gate verb exits `69` when it **could not look** at
113
+ its evidence, still printing the gate's usual JSON (its own fields name what could not be read, such
114
+ as `status: "unresolvable"`, `readError`, or `unreadable`). That JSON is not a verdict — do not act
115
+ on its `block`; route it by `onError` as a step-1 command failure. Exit `0` always means a
116
+ delivered verdict, a blocking one included (`block: true`): a gate verb never exits non-zero to say
117
+ "blocked".
112
118
 
113
119
  ## Empty / absent `activeHooks`
114
120
 
@@ -100,7 +100,7 @@ The three layers compose: `models` defaults a phase, `model_overrides` carves an
100
100
  - **Required when using non-Anthropic providers** (OpenRouter, local models, etc.) — otherwise GSD may call Anthropic models directly, incurring unexpected costs
101
101
  - Use when: you want GSD to follow your currently selected runtime model
102
102
 
103
- ## Using Non-Claude Runtimes (Codex, OpenCode, Gemini CLI, Kilo)
103
+ ## Using Non-Claude Runtimes (Codex, OpenCode, Antigravity CLI, Kilo)
104
104
 
105
105
  When installed for a non-Claude runtime, the GSD installer sets `resolve_model_ids: "omit"` in `~/.gsd/defaults.json`. This returns an empty model parameter for all agents, so each agent uses the runtime's default model. No manual setup is needed.
106
106
 
@@ -34,7 +34,7 @@ STOP. Do not proceed to auto-advance or transition.
34
34
  1. Parse `--auto` flag from $ARGUMENTS
35
35
  2. Read consolidated auto-mode (`active` = chain flag OR user preference; chain flag already synced in init step):
36
36
  ```bash
37
- AUTO_MODE=$(gsd_run query check auto-mode --pick active 2>/dev/null || echo "false")
37
+ AUTO_MODE=$(gsd_run query check auto-mode --pick active 2>/dev/null) || AUTO_MODE="false"
38
38
  ```
39
39
 
40
40
  **If `--auto` flag present OR `AUTO_MODE` is true (AND verification passed with no gaps):**
@@ -27,16 +27,18 @@ Returns JSON with:
27
27
 
28
28
  ## Manual Normalization (Legacy)
29
29
 
30
- Zero-pad integer phases to 2 digits. Preserve decimal suffixes.
30
+ Zero-pad the leading integer to 2 digits. Preserve a letter suffix and any dotted
31
+ segments — the canonical grammar in `src/phase-id.cts` (`normalizePhaseName`):
32
+ `8 → 08`, `2.1 → 02.1`, `3A → 03A`, `23.1.2 → 23.1.2`.
31
33
 
32
34
  ```bash
33
35
  # Normalize phase number
34
- if [[ "$PHASE" =~ ^[0-9]+$ ]]; then
35
- # Integer: 8 → 08
36
- PHASE=$(printf "%02d" "$PHASE")
37
- elif [[ "$PHASE" =~ ^([0-9]+)\.([0-9]+)$ ]]; then
38
- # Decimal: 2.1 → 02.1
39
- PHASE=$(printf "%02d.%s" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}")
36
+ # #4748: one branch for the whole canonical token — digits, optional [A-Z],
37
+ # dotted segments. Pad through $((10#…)) so an already-padded `08` is not read
38
+ # as octal by printf; anything non-canonical passes through untouched.
39
+ if [[ "$PHASE" =~ ^([0-9]+)([A-Z]?)((\.[0-9]+)*)$ ]]; then
40
+ PHASE_INT=${BASH_REMATCH[1]}
41
+ PHASE=$(printf "%02d" "$((10#$PHASE_INT))")${BASH_REMATCH[2]}${BASH_REMATCH[3]}
40
42
  fi
41
43
  ```
42
44
 
@@ -0,0 +1,28 @@
1
+ # Bracket phase-ID convention
2
+
3
+ The bracket convention is opt-in through `phase_id_convention: "bracket"`.
4
+ Its compact grammar card below is generated from `src/phase-id-card.cts`; edit
5
+ that module, not this block.
6
+
7
+ <!-- PHASE-ID-CARD:START -->
8
+ ```text
9
+ [GSD.02] 05.03-01
10
+ │ │ │ │ │
11
+ │ │ │ │ └── plan 01
12
+ │ │ │ └────── subphase 03
13
+ │ │ └───────── phase 05
14
+ │ └───────────── milestone 02
15
+ └───────────────── project GSD
16
+
17
+ milestone = bracket integer; dots = phase-levels; one hyphen = plan; no 'Phase' word, no vX.Y
18
+ ```
19
+ <!-- PHASE-ID-CARD:END -->
20
+
21
+ The display form is `[PROJECT.MM] PP[.SS][-LL]`: the bracket carries the
22
+ project and milestone, dots join phase levels, and the single hyphen introduces
23
+ the optional plan. A phase directory encodes the same identity without brackets:
24
+ `PROJECT.MM-PP[.SS]-slug/`.
25
+
26
+ Human-facing bracket surfaces omit both the literal `Phase` label and the
27
+ legacy `vX.Y` milestone marker. Repositories using the unset, `sequential`, or
28
+ `milestone-prefixed` conventions retain their existing display forms.
@@ -60,3 +60,5 @@ autonomous: true
60
60
  gap_closure: true # Flag for tracking
61
61
  ---
62
62
  ```
63
+
64
+ **9. Number threat IDs after the phase's existing registers** (#4683): when `security_enforcement` is on, read the `<threat_model>` blocks of the phase's existing PLAN files and continue after their highest `T-{phase}-NN` — do not renumber from `T-{phase}-01`. Every ID already names a specific threat in an earlier plan; reusing it makes `SECURITY.md` rows and `VALIDATION.md`'s Threat Ref column ambiguous. `T-{phase}-SC` is reserved and every plan keeps it. The execute-phase init reports any cross-plan duplicates and hard-stops on them (`threat_id_duplicates`), so a collision surfaces here as a failed plan check.
@@ -2,35 +2,46 @@
2
2
 
3
3
  > Loaded by `gsd-planner` at the `load_graph_context` step.
4
4
 
5
- Check for knowledge graph:
6
-
7
- ```bash
8
- ls .planning/graphs/graph.json 2>/dev/null
9
- ```
10
-
11
- If graph.json exists, check freshness:
5
+ Check for a knowledge graph and read its freshness in one call. `status` resolves the
6
+ graph through `graphify.graph_path`, so it is also the presence gate — a bare
7
+ `ls` of the default location misses an umbrella graph shared across sibling repos:
12
8
 
13
9
  ```bash
14
10
  _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
15
11
  gsd_run graphify status
16
12
  ```
17
13
 
14
+ If `exists` is `false`, continue without graph context — skip the rest of this step.
15
+
18
16
  If the status response has `stale: true`, note for later: "Graph is {age_hours}h old -- treat semantic relationships as approximate." Include this annotation inline with any graph context injected below.
19
17
 
20
- Query the graph for phase-relevant dependency context (single query per D-06):
18
+ The same response carries `graph_path` — the resolved graph location. Substitute it for `<graph>` below. `graph_path` comes from `graphify.graph_path` in `.planning/config.json`, a config surface already trusted elsewhere; if it ever carried attacker-controlled content, the literal double-quoted substitution below would need escaping.
19
+
20
+ Query the graph for phase-relevant dependency context (single query per D-06). Prefer the `graphify` CLI when it is on PATH; fall back to the built-in reader otherwise:
21
21
 
22
22
  ```bash
23
- gsd_run graphify query "<phase-goal-keyword>" --budget 2000
23
+ if command -v graphify >/dev/null 2>&1; then
24
+ graphify query "<phase-goal-keyword>" --graph "<graph>" --budget 2000
25
+ graphify affected "<phase-goal-keyword>" --graph "<graph>" --depth 2
26
+ else
27
+ gsd_run graphify query "<phase-goal-keyword>" --budget 2000
28
+ fi
24
29
  ```
25
30
 
26
- Use the keyword that best captures the phase goal. Examples:
27
- - Phase "User Authentication" -> query term "auth"
31
+ Why the CLI is preferred: it ranks seeds (IDF weighting, fuzzy matching) and applies context filters before traversal, where the built-in reader seeds by case-insensitive substring over label and description — so a term like "auth" seeds equally on `author` and `authorize` — and then expands a fixed two hops. `affected` answers "which subsystems may be affected by changes in this phase" directly, by reverse traversal; it has no built-in equivalent, so the fallback path runs the query alone.
32
+
33
+ The two paths return **different shapes**: the CLI emits prose, the built-in emits JSON with per-edge confidence tiers and `budget_met`/`budget_estimate`. `--budget` caps rendered output on the CLI and estimated payload bytes in the built-in — same flag name, different unit. Read whichever you get; do not assume a stable shape and do not paste raw output into PLAN.md.
34
+
35
+ Use the keyword that best captures the phase goal. Prefer the full domain word over a
36
+ prefix of it — on the fallback path a prefix is matched as a substring, so "auth" also
37
+ seeds on `author` and `authoring`. Examples:
38
+ - Phase "User Authentication" -> query term "authentication"
28
39
  - Phase "Payment Integration" -> query term "payment"
29
40
  - Phase "Database Migration" -> query term "migration"
30
41
 
31
- If the query returns nodes and edges, incorporate as dependency context for planning:
42
+ If the query returns related nodes, incorporate as dependency context for planning:
32
43
  - Which modules/files are semantically related to this phase's domain
33
44
  - Which subsystems may be affected by changes in this phase
34
45
  - Cross-document relationships that inform task ordering and wave structure
35
46
 
36
- If no results or graph.json absent, continue without graph context.
47
+ If nothing comes back, continue without graph context.
@@ -15,3 +15,17 @@ command, must hold the matching `package.json`/`Makefile`. `npm --prefix <dir> r
15
15
  preferred over `cd <dir> && npm run <script>` — it does not depend on the executor's cwd. If
16
16
  `prior_verify_commands` is empty and you cannot ground a path, say so in the plan instead of
17
17
  guessing one.
18
+
19
+ **Root-relative, never absolute (#4767).** The paths in your prompt's `<required_reading>` are
20
+ absolute on purpose — a subagent's cwd may differ from the orchestrator's (#2376). That rule
21
+ covers prompt *inputs* only. Every path in the plan *body* — `<files>`, `<verify>`, `<automated>`,
22
+ task actions — is repo-root-relative, and every `<automated>` command assumes cwd at the checkout
23
+ root. An absolute path copied from the prompt into `<automated>` pins the command to the
24
+ orchestrator's checkout; under worktree isolation the executor's checkout is a different
25
+ directory, so the command `cd`s into the main tree, finds it, runs, and **passes against code the
26
+ worktree changed and the main tree did not**. The path probe reports such a target as
27
+ `outside_root` (a warning), but only when the target is outside the *orchestrator's* root — an
28
+ absolute path *inside* it is exactly the shape that passes the probe and still misfires under
29
+ isolation. The authoring rule is the fix; the probe is the backstop. It binds `prior_verify_commands`
30
+ too: a harvested command that carries an absolute path is re-rooted before reuse, never copied
31
+ verbatim — it "worked" in a run that may have been verifying the wrong checkout.
@@ -40,6 +40,7 @@ Configuration options for `.planning/` directory behavior.
40
40
  | `git.quick_branch_template` | `null` | Optional branch template for quick-task runs |
41
41
  | `workflow.use_worktrees` | `true` | Whether executor agents run in isolated git worktrees. Set to `false` to disable worktrees — agents execute sequentially on the main working tree instead. Recommended for solo developers or when worktree merges cause issues. Note: if your branch is ahead of `origin/HEAD` (a diverged milestone or feature branch), GSD auto-degrades to sequential and prints a warning; set `worktree.baseRef:"head"` in `.claude/settings.local.json` to restore parallel execution. See the branch-divergence note below. |
42
42
  | `workflow.subagent_timeout` | `300000` | Timeout in milliseconds for parallel subagent tasks (e.g. codebase mapping). Increase for large codebases or slower models. Default: 300000 (5 minutes). |
43
+ | `planner.stall_detection_enabled` | `true` | Default-on bounded stall detection for planner and plan-checker agents. Set to `false` to await runtime-native completion without watchdog polling; this gives up bounded automatic recovery if the completion handoff is lost. _Loader projection:_ `planner_stall_detection_enabled`. |
43
44
  | `workflow.inline_plan_threshold` | `2` | Plans with this many tasks or fewer execute inline (Pattern C) instead of spawning a subagent. Avoids ~14K token spawn overhead for small plans. Set to `0` to always spawn subagents. |
44
45
  | `workflow.test_command` | `null` | Custom shell command run as the regression/test gate by execute-phase, audit-fix, and post-merge-gate. When unset, GSD auto-detects (Makefile / package.json / Cargo.toml / go.mod / pyproject.toml). Example: `npm test`. |
45
46
  | `workflow.build_command` | `null` | Custom shell command run as the build gate by the post-merge gate. When unset, the build step is skipped/auto-detected. Example: `npm run build`. |
@@ -266,7 +267,7 @@ Generated from `CONFIG_DEFAULTS` (configuration.cjs) and `VALID_CONFIG_KEYS` (co
266
267
  | `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models |
267
268
  | `resolve_model_ids` | boolean\|string | `false` | `false`, `true`, `"omit"` | Map model aliases to full Claude IDs; `"omit"` returns empty string |
268
269
  | `context` | string\|null | `null` | `"dev"`, `"research"`, `"review"` | Execution context profile that adjusts agent behavior: `"dev"` for development tasks, `"research"` for investigation/exploration, `"review"` for code review workflows |
269
- | `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd:review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
270
+ | `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /gsd:review (e.g., `review.models.codex`). Falls back to CLI default when null. |
270
271
  | `review.max_prompt_tokens` | number\|null | `null` | Any positive integer, or `null` | Central, cross-lane default cap (in estimated tokens) on the assembled review prompt; `null` means no trim. A per-lane `review.max_prompt_tokens_per_reviewer.<slug>` value overrides it for that lane: `-1` means unset (inherits this global default), `0` means "do not trim that lane" (not unset — it is an explicit, standing opt-out). _Alias:_ `max_prompt_tokens` is the flat-key form used in `CONFIG_DEFAULTS`; `review.max_prompt_tokens` is the canonical namespaced form. |
271
272
 
272
273
  ### Workflow Fields
@@ -313,6 +314,14 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
313
314
  | `workflow.security_block_on` | string | `"high"` | `"critical"`, `"high"`, `"medium"`, `"low"`, `"none"` | Minimum threat severity that blocks phase advancement. The auditor counts only open threats at or above this severity toward the blocking gate (SECURITY.md `threats_open`); `none` disables severity blocking. |
314
315
  | `workflow.post_planning_gaps` | boolean | `true` | `true`, `false` | Post-planning gap report (#2493). After plans are generated, scans REQUIREMENTS.md and CONTEXT.md `<decisions>` against all PLAN.md files and emits a unified `Source \| Item \| Status` table. Non-blocking. Set to `false` to skip Step 13e of plan-phase. _Alias:_ `post_planning_gaps` is the flat-key form used in `CONFIG_DEFAULTS`; `workflow.post_planning_gaps` is the canonical namespaced form. |
315
316
 
317
+ ### Planner Fields
318
+
319
+ Set via the `planner.*` namespace. These settings affect only planner/plan-checker waits; executor stall controls are independent.
320
+
321
+ | Key | Type | Default | Allowed Values | Description |
322
+ |-----|------|---------|----------------|-------------|
323
+ | `planner.stall_detection_enabled` | boolean | `true` | `true`, `false` | Default-on bounded stall detection for the standard planner, chunked outline/per-plan planners, plan-checker, and revision planner. `false` skips `gsd_stall_watch` polling but still awaits and consumes the real runtime-native agent result. It gives up bounded automatic recovery if the runtime loses the completion handoff. _Loader projection:_ `planner_stall_detection_enabled`. |
324
+
316
325
  ### Ship Fields
317
326
 
318
327
  Set via `ship.*` namespace in config.json. These fields affect `/gsd:ship` PRD-style pull request body composition only.
@@ -423,7 +432,7 @@ Several config fields affect each other or trigger special behavior:
423
432
 
424
433
  4. **`parallelization` polymorphism** -- Accepts both a simple boolean and an object with an `enabled` field. `loadConfig()` normalizes either form to a boolean. `{ "enabled": true }` is equivalent to `true`.
425
434
 
426
- 5. **Search API keys and flags** -- `brave_search`, `firecrawl`, and `exa_search` are auto-set to `true` during project creation if the corresponding API key is detected (environment variable or `~/.gsd/<name>_api_key` file). Setting them to `true` without the API key has no effect.
435
+ 5. **Search API keys and flags** -- `brave_search`, `firecrawl`, and `exa_search` are auto-set to `true` during project creation if the corresponding API key is detected (environment variable or `$GSD_HOME/.gsd/<name>_api_key` file; `GSD_HOME` defaults to the home directory). Setting them to `true` without the API key has no effect.
427
436
 
428
437
  6. **`planning.*` and top-level equivalence** -- `planning.commit_docs` and `commit_docs` are equivalent; `planning.search_gitignored` and `search_gitignored` are equivalent. If both are set, the top-level value takes precedence.
429
438
 
@@ -431,7 +440,7 @@ Several config fields affect each other or trigger special behavior:
431
440
 
432
441
  8. **`sub_repos` auto-sync** -- On every config load, GSD scans for child directories with `.git` and updates the `sub_repos` array if the filesystem has changed. Legacy `multiRepo: true` is automatically migrated to a detected `sub_repos` array.
433
442
 
434
- 9. **`workflow.use_worktrees` and branch divergence** -- When `use_worktrees` is `true` (default), executor worktrees are forked from `origin/HEAD` -- by the host's own harness on `dispatch.isolation: harness-worktree` runtimes (Claude Code, Cursor), or by GSD itself on `orchestrator-worktree` runtimes (Codex, OpenCode, Kimi, Kimi Code). The divergence behavior below is identical either way, because the fork base is a property of the repository rather than of whoever creates the worktree. If your current branch has commits that `origin/HEAD` does not (for example an unmerged milestone or feature branch), GSD automatically degrades to sequential execution for that run and prints a one-line `⚠ Worktree base mismatch` warning. To restore parallel execution permanently, set `worktree.baseRef:"head"` in `.claude/settings.local.json` (run `gsd_run worktree set-baseref`). This makes the harness fork worktrees from the live HEAD instead of `origin/HEAD`. Both fresh installs and upgrades of GSD Core set this automatically (no-clobber) when `use_worktrees` is enabled; you can also run the command manually at any time. Setting `workflow.use_worktrees: false` is the alternative if worktrees are not needed at all. On a runtime whose declared `dispatch.isolation` is `none`, an explicit `true` is a config the execution workflows fail closed on; `/gsd:health` reports it as warning `W025` and `/gsd:settings` offers to repair it (#2486).
443
+ 9. **`workflow.use_worktrees` and branch divergence** -- When `use_worktrees` is `true` (default) and `worktree.baseRef` is unset, executor worktrees are forked from `origin/HEAD` -- by the host's own harness on `dispatch.isolation: harness-worktree` runtimes (Claude Code, Cursor), or by GSD itself on `orchestrator-worktree` runtimes (Codex, OpenCode, Kimi, Kimi Code). The divergence behavior below is identical either way, because the fork base is a property of the repository rather than of whoever creates the worktree. If your current branch has commits that `origin/HEAD` does not (for example an unmerged milestone or feature branch), GSD automatically degrades to sequential execution for that run and prints a one-line `⚠ Worktree base mismatch` warning. To restore parallel execution permanently, set `worktree.baseRef:"head"` in `.claude/settings.local.json` (run `gsd_run worktree set-baseref`). GSD-created worktrees then fork from the live HEAD instead of `origin/HEAD` by construction, and the Claude Code harness does the same as measured from every settings layer (#4588; Cursor has not been measured — its exit-42 spawn-time guard is the backstop). A configured Claude Code `WorktreeCreate` hook is the exception: it creates the worktree without applying the setting, so GSD keeps comparing against `origin/HEAD` on such a host (#4588). A prior harness worktree at the current HEAD does not lift that comparison — it records no creator, so one left there before the hook was configured would read as evidence for the hook; pass `--observed-fork-base` for a trusted verdict (#4881). Both fresh installs and upgrades of GSD Core set this automatically (no-clobber) when `use_worktrees` is enabled; you can also run the command manually at any time. Setting `workflow.use_worktrees: false` is the alternative if worktrees are not needed at all. On a runtime whose declared `dispatch.isolation` is `none`, an explicit `true` is a config the execution workflows fail closed on; `/gsd:health` reports it as warning `W025` and `/gsd:settings` offers to repair it (#2486).
435
444
 
436
445
  ---
437
446
 
@@ -55,7 +55,7 @@ When SPIDR triggers, the workflow:
55
55
  2. Asks "Which SPIDR axis fits best?" with the five options above.
56
56
  3. Walks through the chosen axis interactively (one focused question), produces a split proposal: "Phase N (this one): X. Phase N+1: Y. Phase N+2: Z."
57
57
  4. Confirms the split with the user.
58
- 5. On accept: writes the FIRST phase's story to the current ROADMAP entry; defers creating new phases for the splits to a follow-up step (the workflow surfaces a list of `/gsd add-phase` invocations the user can run after `mvp-phase` completes — but does not run them automatically, to preserve user control over phase numbering).
58
+ 5. On accept: writes the FIRST phase's story to the current ROADMAP entry; defers creating new phases for the splits to a follow-up step (the workflow surfaces a list of `/gsd:phase` invocations the user can run after `mvp-phase` completes — but does not run them automatically, to preserve user control over phase numbering).
59
59
  6. On reject: proceeds with the original story unchanged.
60
60
 
61
61
  ## Anti-patterns to reject
@@ -78,7 +78,7 @@ Output: [Working, tested feature]
78
78
 
79
79
  <output>
80
80
  After completion, create SUMMARY.md with:
81
- - RED: What test was written, why it failed
81
+ - RED: What test was written, why it failed, and the semantic assessment of its RED evidence
82
82
  - GREEN: What implementation made it pass
83
83
  - REFACTOR: What cleanup was done (if any)
84
84
  - Commits: List of commits produced
@@ -95,7 +95,13 @@ After completion, create SUMMARY.md with:
95
95
  1. Create test file following project conventions
96
96
  2. Write test describing expected behavior (from `<behavior>` element)
97
97
  3. Run test - it MUST fail **intentionally** (#3770): the TARGET test you named must be the test that fails, on an assertion for the planned behavior. A nonzero exit alone is NOT RED — syntax errors, zero-test discovery, fixture crashes, parser errors, and unrelated assertions are INVALID_RED and must not authorize GREEN.
98
- 4. Persist the RED evidence record (command, exit code, failing test, expected result, actual result) and verify it: `gsd_run check tdd-red-evidence <record.json>`. Only verdict `RED_EVIDENCE_OK` satisfies the RED gate; `INVALID_RED` blocks GREEN until the RED phase is fixed.
98
+ 4. Persist the RED evidence from the actual command: `{command, exitCode, output, targetTest, targetFile, expected, actual}`. Preserve the real exit status and unmodified report; record the planned expected result and observed actual result. Write the record inside the project directory; the classifier refuses a path outside it. It reads only these fields, so the further fields below stay in the record for review.
99
+ - Select evidence by **report format**, regardless of runner or package manager. The classifier has a shared TAP adapter for Node's built-in test runner and Vitest (`tap` / `tap-flat`), a JUnit XML adapter for Maven Surefire/Failsafe, a swift-testing console adapter for `swift test`, and a Python `unittest` text adapter. Other producers of these formats use the same adapters.
100
+ - TAP: capture the complete reporter output, including its test plan. Node summary comments are optional. The report must start with its TAP output: capture the reporter's own stdout (for npm scripts, `npm run --silent`), not package-manager banners. Use the target test's exact name; when names repeat, use its qualified name as emitted in the report (`tap-flat` emits only the full `file > suite > test` name). Suite/file summary failures are not target assertions. If the reporter is incompatible, rerun the planned target with a supported reporter through the project's test command, capture that real command and result, then submit the rerun's record to the classifier below. Preserve other console output separately rather than editing the report to make it parse.
101
+ - JUnit XML: capture the unchanged target report generated by the actual run. For Maven this is `target/surefire-reports/TEST-*.xml` or `target/failsafe-reports/TEST-*.xml`. Record the report path, run start, and modification time as `reportPath`, `runStartedAt`, and `reportModifiedAt`; require the report to be newer than the run start and verify the named target class or method executed in that run. Name the target as the method, the class (simple or package-qualified), or `<package.Class>#<method>`. Put one complete XML document in `output`, preserving console output alongside it. Missing, stale, or ambiguous reports require STOP and investigation.
102
+ - swift-testing and `unittest`: capture the complete console output without color (`NO_COLOR=1`), including the final summary. swift-testing needs one `Test` result line (passed, failed, skipped, or cancelled) for every test its `Test run with N tests` summary counts; it names a test by its quoted display name or, without one, by its function name (`addsNumbers()`), and either name identifies the target; repeated swift-testing names are ambiguous and block GREEN. `unittest` needs one `FAIL:`/`ERROR:` header for every failure or error its `FAILED (...)` line counts; repeated headers from one test's failing subTests count as one failing test, a method name that repeats across classes needs its `module.Class.method` id, and a `unittest.loader._FailedTest` entry is a load failure, never RED.
103
+ - Pass the unchanged record to `gsd_run check tdd-red-evidence <record.json> --raw` and require `RED_EVIDENCE_OK` before GREEN. Every `INVALID_RED` reason (`unexpected_green`, `zero_tests_discovered`, `nonzero_exit_without_test_failure`, `fixture_or_load_failure`, `no_target_test_failure`, `invalid_record`, `unreadable_record`) trips the gate. `invalid_record` includes unsupported or malformed reports; inspect `evidence.report_errors`. An unsupported format requires a supported reporter or a parser adapter before GREEN. Classifier rejection never authorizes a fallback to self-attestation.
104
+ - After machine validation, inspect whether the target actually executed and failed on the planned assertion for the intended reason. Zero tests, a missing, skipped, or cancelled target, setup, collection, import, syntax, or fixture faults, unrelated failures, unexpected green, and incomplete or ambiguous evidence block GREEN. Record this semantic assessment as `semanticAssessment` in the RED evidence and in the SUMMARY's RED entry; never fabricate reports, counters, or parser verdicts.
99
105
  5. If test passes: feature exists or test is wrong. Investigate.
100
106
  6. Commit: `test({phase}-{plan}): add failing test for [feature]`
101
107
 
@@ -178,10 +184,32 @@ cargo test # Rust
178
184
  ```
179
185
 
180
186
  **5. Create first test file:**
181
- Follow project conventions for test location:
182
- - `*.test.ts` / `*.spec.ts` next to source
187
+ Follow project conventions for test location. The RED-commit gate
188
+ (`workflows/execute-phase.md`) recognises the patterns below at any depth, repo root
189
+ included. Note the gate's pathspec is deliberately **wider than the project types the
190
+ detection step above enumerates** — it costs nothing to recognise a convention the
191
+ onboarding flow does not yet auto-detect, and a project using one should not have its
192
+ RED commits go unseen:
193
+ - `*.test.*` / `*.spec.*` next to source — JS/TS and anything sharing the convention
183
194
  - `__tests__/` directory
184
195
  - `tests/` directory at root
196
+ - `*_test.go` — Go
197
+ - `test_*.py` / `*_test.py` — Python (in addition to `tests/`)
198
+ - `*_test.exs` — Elixir
199
+ - `*_spec.rb` / `*_test.rb` — Ruby
200
+
201
+ **Cost of the broad pathspec (#4379).** `*.spec.*` can match a non-test file that happens to carry
202
+ the word — `api.spec.json`, `openapi.spec.yaml` — which lets the RED gate pass on a commit touching
203
+ only that. This is not new: the previous `**/*.spec.*` already matched those at any nested path, so
204
+ dropping the `**/` prefix only extends the same false-positive class to the repo root. It is
205
+ accepted rather than narrowed, because narrowing it is a behaviour change to the
206
+ currently-supported case and not part of making other languages visible.
207
+
208
+ **Known gap — Rust (#4379).** `#[test]` conventionally lives inside the implementation file, so a
209
+ Rust RED commit touches `src/*.rs` and no path-based gate can distinguish it from ordinary source.
210
+ Widening the pathspec to cover it would match all source and make the gate meaningless. `cargo test`
211
+ works; the RED-*commit* gate cannot see it, so a Rust project using `workflow.tdd_mode` should
212
+ expect the gate to trip.
185
213
 
186
214
  Framework setup is a one-time cost included in the first TDD plan's RED phase.
187
215
  </framework_setup>
@@ -257,14 +285,14 @@ When `workflow.tdd_mode` is enabled in config, the RED/GREEN/REFACTOR gate seque
257
285
 
258
286
  | Gate | Required | Commit Pattern | Validation |
259
287
  |------|----------|---------------|------------|
260
- | RED | Yes | `test({phase}-{plan}): ...` | Test exists AND fails before implementation — intentionally: `check tdd-red-evidence` returns `RED_EVIDENCE_OK` (target test failed on an assertion for the behavior; anything else is INVALID_RED) |
288
+ | RED | Yes | `test({phase}-{plan}): ...` | Target test exists AND fails before implementation: a complete report in a supported format (RED step 4) from the current run must return `RED_EVIDENCE_OK`, followed by semantic inspection of the planned assertion (RED step 4) |
261
289
  | GREEN | Yes | `feat({phase}-{plan}): ...` | Test passes after implementation |
262
290
  | REFACTOR | No | `refactor({phase}-{plan}): ...` | Tests still pass after cleanup |
263
291
 
264
292
  ### Fail-Fast Rules
265
293
 
266
294
  1. **Unexpected GREEN in RED phase:** If the test passes before any implementation code is written, STOP. The feature may already exist or the test is wrong. Investigate before proceeding.
267
- 2. **INVALID_RED in RED phase (#3770):** A nonzero exit is not RED by itself. Zero-test discovery, fixture/load crashes, nonzero exits with no failing test, unrelated failing tests, and unexpected greens all classify as INVALID_RED (`gsd_run check tdd-red-evidence`). STOP and fix the RED phase — do NOT proceed to GREEN.
295
+ 2. **INVALID_RED in RED phase (#3770):** A nonzero exit is not RED by itself. Follow the format-based evidence contract in RED step 4, including reporter reruns and report freshness. An `INVALID_RED` verdict or failed semantic assessment halts GREEN. Unsupported, incomplete, ambiguous, or contradictory evidence cannot authorize implementation.
268
296
  3. **Missing RED commit:** If no `test(...)` commit precedes the `feat(...)` commit, the TDD discipline was violated. Flag in SUMMARY.md.
269
297
  4. **REFACTOR breaks tests:** Undo the refactor immediately. Commit was premature — refactor in smaller steps.
270
298
 
@@ -275,8 +303,9 @@ After completing a `type: tdd` plan, the executor validates the git log:
275
303
  # The commit protocol promises no zero-padding for ${PHASE}/${PLAN} — strip both and
276
304
  # match the commit-scope position anchored (#4003). #4619: PHASE may be decimal/
277
305
  # N-segment; zero-strip only the leading integer segment, escape the rest.
278
- PHASE_INT=${PHASE%%.*}; PHASE_FRAC=${PHASE#"$PHASE_INT"}
279
- PHASE_N="$((10#$PHASE_INT))${PHASE_FRAC//./\\.}"
306
+ # #4748: it may also carry a letter suffix (03A), so split at the first non-digit.
307
+ PHASE_INT=${PHASE%%[!0-9]*}; PHASE_REST=${PHASE#"$PHASE_INT"}
308
+ PHASE_N="$((10#$PHASE_INT))${PHASE_REST//./\\.}"
280
309
  PLAN_N=$((10#${PLAN}))
281
310
  # Check for RED gate commit
282
311
  git log --oneline -E --grep="^test\((0*${PHASE_N})-(0*${PLAN_N})\):" | head -1
@@ -15,11 +15,16 @@ here. Forcing them into a closed compiled taxonomy is the wrong model.
15
15
 
16
16
  ## Inputs
17
17
 
18
- A list of UI elements, each a `{ id, text, elements? }` record where `text` is the
19
- researcher-authored description and `elements` is an optional author-supplied override of the
20
- element classification. The six element kinds are: `form`, `list-collection`, `nav`, `media`,
21
- `interactive-control`, `static-content`. When `elements` is absent, a heuristic classifier
22
- proposes kinds from the prose (propose-then-confirm) — the author may correct the kind.
18
+ A list of UI elements, each a `{ id, text, text_en?, elements? }` record where `text` is the
19
+ researcher-authored description, `elements` is an optional author-supplied override of the
20
+ element classification, and `text_en` is an optional English translation of `text`
21
+ (#4657). The element cues are English word-boundary patterns, so a non-English `text` (a
22
+ project running with `response_language` set) classifies to zero kinds unless `text_en`
23
+ carries a faithful English rendering — engine input, never user-facing output; `text`
24
+ itself keeps the UI-SPEC's own language and is never translated. The six element kinds are:
25
+ `form`, `list-collection`, `nav`, `media`, `interactive-control`, `static-content`. When
26
+ `elements` is absent, a heuristic classifier proposes kinds from the prose
27
+ (`text_en ?? text`, propose-then-confirm) — the author may correct the kind.
23
28
 
24
29
  ## Taxonomy (8 categories)
25
30
 
@@ -34,12 +34,15 @@ no `<decisions>` block.
34
34
  GATE_CFG=$(gsd_run query config-get workflow.context_coverage_gate 2>/dev/null || echo "true")
35
35
  if [ "$GATE_CFG" != "false" ]; then
36
36
  CONTEXT_PATH=$(ls "${PHASE_DIR}"/*-CONTEXT.md 2>/dev/null | head -1) # #2962: not a for-glob (zsh aborts)
37
- DECISION_RESULT=$(gsd_run query check.decision-coverage-verify "${PHASE_DIR}" "${CONTEXT_PATH}")
37
+ DECISION_RESULT=$(gsd_run query check.decision-coverage-verify "${PHASE_DIR}" "${CONTEXT_PATH}") && DECISION_EXIT=0 || DECISION_EXIT=$?
38
38
  fi
39
39
  ```
40
40
 
41
41
  The handler returns JSON `{ skipped, blocking: false, total, honored,
42
- not_honored: [...], message }`.
42
+ not_honored: [...], message }`. A non-zero `DECISION_EXIT` (`69` `UNAVAILABLE`: the gate
43
+ could not read CONTEXT.md or the phase artifacts, #5170) is **not** "no decisions": record
44
+ `Decision coverage: not evaluated (the gate could not read its evidence)` in VERIFICATION.md
45
+ and do not report counts.
43
46
 
44
47
  **Reporting:** Append the handler's `message` (a `### Decision Coverage`
45
48
  section) to VERIFICATION.md regardless of outcome — even when all
@@ -11,8 +11,9 @@ checker flagged a bad `cd ../../frontend` (correct), then prescribed two success
11
11
  replacement paths — the second citing a `package.json` that did not exist. Consume the
12
12
  deterministic probe result, never re-derive it yourself.
13
13
 
14
- `gsd-core/workflows/plan-phase.md` already runs the probe **before** spawning this checker and
15
- interpolates the result into the verification prompt as `{VERIFY_PATHS}`, inside a
14
+ `gsd-core/workflows/plan-phase.md` — and, since #4767, quick mode's
15
+ `quick/steps/plan-checker-loop.md` (via `--dir`) — already runs the probe **before** spawning this
16
+ checker and interpolates the result into the verification prompt as `{VERIFY_PATHS}`, inside a
16
17
  `<verify_command_path_probe>` block. This dimension reads that already-supplied JSON — it never
17
18
  invokes `gsd_run check verify-command-paths` itself. If `{VERIFY_PATHS}` is absent from the
18
19
  prompt, treat this dimension as silent (nothing to check) rather than trying to run the probe.
@@ -37,6 +38,13 @@ Rules:
37
38
  a finding.** Say nothing.
38
39
  - `unresolvable` means the probe could not ground the path (a variable, glob, substitution, or
39
40
  `~`). That is a WARNING, never a BLOCKER — and never a licence to guess the literal path.
41
+ - `outside_root` covers two shapes: a bare ancestor climb (`cd ../..`) and an **absolute target
42
+ outside the project root** (#4767). Both are ambiguous across worktrees; the absolute one is
43
+ pinned to a single checkout, so under worktree isolation it runs against the wrong tree and
44
+ passes. Report it as a WARNING with the target verbatim. Note the probe's root is the
45
+ *orchestrator's*: an absolute path inside it passes here and still misfires under isolation,
46
+ which is why the planner's path-form rule (root-relative, cwd at the checkout root) is the fix
47
+ and this probe the backstop.
40
48
  - A non-empty `readError` means the probe **could not look**. Report that as a WARNING in its
41
49
  own words; it is not a clean bill of health.
42
50
  - `MISSING …` sentinels are Dimension 8's business — this dimension stays silent on them.