@opengsd/gsd-core 1.11.0 → 1.13.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 (498) 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 +12 -0
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-debug-session-manager.md +1 -1
  6. package/agents/gsd-debugger.md +1 -1
  7. package/agents/gsd-dom-verifier.md +169 -0
  8. package/agents/gsd-eval-auditor.md +1 -1
  9. package/agents/gsd-executor.md +78 -42
  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 +0 -1
  13. package/agents/gsd-pattern-mapper.md +11 -0
  14. package/agents/gsd-phase-researcher.md +3 -1
  15. package/agents/gsd-plan-checker.md +91 -112
  16. package/agents/gsd-planner.md +20 -4
  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 +82 -7
  21. package/agents/gsd-ui-researcher.md +70 -3
  22. package/agents/gsd-verifier.md +24 -2
  23. package/bin/install.js +847 -200
  24. package/commands/gsd/discuss-phase.md +1 -1
  25. package/commands/gsd/execute-phase.md +1 -1
  26. package/commands/gsd/import.md +1 -1
  27. package/commands/gsd/ns-workflow.md +2 -1
  28. package/commands/gsd/phase.md +1 -1
  29. package/commands/gsd/quick-batch.md +105 -0
  30. package/commands/gsd/quick.md +8 -4
  31. package/commands/gsd/surface.md +18 -8
  32. package/gsd-core/bin/gsd-tools.cjs +761 -100
  33. package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
  34. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  35. package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
  36. package/gsd-core/bin/lib/api-coverage.cjs +30 -9
  37. package/gsd-core/bin/lib/artifacts.cjs +2 -0
  38. package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
  39. package/gsd-core/bin/lib/audit.cjs +163 -41
  40. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  41. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  42. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  43. package/gsd-core/bin/lib/capability-registry.cjs +785 -144
  44. package/gsd-core/bin/lib/capability-state.cjs +25 -4
  45. package/gsd-core/bin/lib/capability-validator.cjs +321 -18
  46. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  47. package/gsd-core/bin/lib/check-command-router.cjs +229 -6
  48. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  49. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  50. package/gsd-core/bin/lib/clusters.cjs +1 -0
  51. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  52. package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
  53. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  54. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  55. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  56. package/gsd-core/bin/lib/commands.cjs +877 -54
  57. package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
  58. package/gsd-core/bin/lib/config-loader.cjs +121 -29
  59. package/gsd-core/bin/lib/config.cjs +92 -2
  60. package/gsd-core/bin/lib/configuration.cjs +129 -37
  61. package/gsd-core/bin/lib/core-utils.cjs +118 -14
  62. package/gsd-core/bin/lib/decisions.cjs +213 -1
  63. package/gsd-core/bin/lib/edge-probe.cjs +23 -2
  64. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  65. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  66. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  67. package/gsd-core/bin/lib/frontmatter.cjs +975 -326
  68. package/gsd-core/bin/lib/gap-checker.cjs +41 -8
  69. package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
  71. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  72. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
  73. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
  74. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
  75. package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
  76. package/gsd-core/bin/lib/host-integration.cjs +96 -11
  77. package/gsd-core/bin/lib/init-command-router.cjs +132 -21
  78. package/gsd-core/bin/lib/init.cjs +252 -56
  79. package/gsd-core/bin/lib/install-engine.cjs +252 -15
  80. package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
  81. package/gsd-core/bin/lib/install-profiles.cjs +100 -18
  82. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  83. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  84. package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
  85. package/gsd-core/bin/lib/intel.cjs +101 -26
  86. package/gsd-core/bin/lib/io.cjs +195 -15
  87. package/gsd-core/bin/lib/learnings.cjs +85 -14
  88. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  89. package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
  90. package/gsd-core/bin/lib/markdown-table.cjs +175 -4
  91. package/gsd-core/bin/lib/milestone.cjs +112 -7
  92. package/gsd-core/bin/lib/model-catalog.cjs +177 -19
  93. package/gsd-core/bin/lib/model-resolver.cjs +10 -28
  94. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  95. package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
  96. package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
  97. package/gsd-core/bin/lib/phase-id.cjs +321 -13
  98. package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
  99. package/gsd-core/bin/lib/phase-locator.cjs +138 -17
  100. package/gsd-core/bin/lib/phase.cjs +1175 -115
  101. package/gsd-core/bin/lib/plan-document.cjs +273 -0
  102. package/gsd-core/bin/lib/plan-scan.cjs +13 -2
  103. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  104. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  105. package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
  106. package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
  107. package/gsd-core/bin/lib/probe-core.cjs +4 -1
  108. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  109. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  110. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  111. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  112. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  113. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  114. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
  115. package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
  116. package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
  117. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  118. package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
  119. package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
  120. package/gsd-core/bin/lib/roadmap.cjs +248 -64
  121. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
  122. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
  123. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
  124. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
  125. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  126. package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
  127. package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
  128. package/gsd-core/bin/lib/smart-entry.cjs +19 -31
  129. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  130. package/gsd-core/bin/lib/state-command-router.cjs +47 -18
  131. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  132. package/gsd-core/bin/lib/state-document.cjs +216 -5
  133. package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
  134. package/gsd-core/bin/lib/state-transition.cjs +850 -145
  135. package/gsd-core/bin/lib/state.cjs +1629 -287
  136. package/gsd-core/bin/lib/surface.cjs +33 -10
  137. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  138. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  139. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  140. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  141. package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
  142. package/gsd-core/bin/lib/uat.cjs +2542 -387
  143. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  144. package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
  145. package/gsd-core/bin/lib/unusable-input.cjs +13 -0
  146. package/gsd-core/bin/lib/update-context.cjs +6 -2
  147. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  148. package/gsd-core/bin/lib/validate.cjs +230 -12
  149. package/gsd-core/bin/lib/vendor/README.md +43 -5
  150. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  151. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  152. package/gsd-core/bin/lib/verification.cjs +287 -13
  153. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  154. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  155. package/gsd-core/bin/lib/verify.cjs +441 -56
  156. package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
  157. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  158. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  159. package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
  160. package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
  161. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  162. package/gsd-core/bin/shared/exit-codes.json +8 -0
  163. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  164. package/gsd-core/bin/shared/model-catalog.json +8 -1
  165. package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
  166. package/gsd-core/references/agent-contracts.md +6 -5
  167. package/gsd-core/references/api-coverage.md +24 -2
  168. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  169. package/gsd-core/references/checkpoints.md +37 -19
  170. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  171. package/gsd-core/references/edge-probe.md +17 -5
  172. package/gsd-core/references/execute-mvp-tdd.md +18 -18
  173. package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
  174. package/gsd-core/references/execute-phase-response-language.md +6 -0
  175. package/gsd-core/references/execute-phase-wave-guard.md +11 -9
  176. package/gsd-core/references/executor-examples.md +42 -0
  177. package/gsd-core/references/failing-direction.md +78 -0
  178. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  179. package/gsd-core/references/gate-prompts.md +1 -1
  180. package/gsd-core/references/git-integration.md +5 -5
  181. package/gsd-core/references/git-planning-commit.md +3 -3
  182. package/gsd-core/references/gsd-run-resolver.md +1 -1
  183. package/gsd-core/references/loop-hook-dispatch.md +22 -0
  184. package/gsd-core/references/model-profiles.md +1 -1
  185. package/gsd-core/references/mvp-concepts.md +2 -2
  186. package/gsd-core/references/nyquist-compliance.md +74 -0
  187. package/gsd-core/references/offer-next.md +3 -5
  188. package/gsd-core/references/phase-argument-parsing.md +3 -3
  189. package/gsd-core/references/plan-checker-examples.md +41 -0
  190. package/gsd-core/references/planner-antipatterns.md +25 -0
  191. package/gsd-core/references/planner-chunked.md +5 -1
  192. package/gsd-core/references/planner-coupling.md +42 -0
  193. package/gsd-core/references/planner-failing-direction.md +53 -0
  194. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  195. package/gsd-core/references/planner-quick-batch.md +71 -0
  196. package/gsd-core/references/planner-reviews.md +47 -0
  197. package/gsd-core/references/planner-revision.md +76 -3
  198. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  199. package/gsd-core/references/planning-config.md +39 -9
  200. package/gsd-core/references/response-language-directive.md +9 -0
  201. package/gsd-core/references/reviewer-instances.md +31 -0
  202. package/gsd-core/references/revision-loop.md +118 -11
  203. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  204. package/gsd-core/references/tdd.md +15 -12
  205. package/gsd-core/references/ui-brand.md +65 -21
  206. package/gsd-core/references/ui-consideration-probe.md +1 -1
  207. package/gsd-core/references/universal-anti-patterns.md +2 -2
  208. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  209. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  210. package/gsd-core/references/verify-mvp-mode.md +1 -1
  211. package/gsd-core/references/workstream-flag.md +11 -11
  212. package/gsd-core/templates/README.md +1 -1
  213. package/gsd-core/templates/SECURITY.md +3 -3
  214. package/gsd-core/templates/UI-SPEC.md +25 -3
  215. package/gsd-core/templates/VALIDATION.md +3 -3
  216. package/gsd-core/templates/phase-prompt.md +7 -0
  217. package/gsd-core/templates/state.md +7 -0
  218. package/gsd-core/templates/verification-report.md +5 -0
  219. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  220. package/gsd-core/workflows/add-backlog.md +3 -1
  221. package/gsd-core/workflows/add-phase.md +5 -3
  222. package/gsd-core/workflows/add-tests.md +4 -9
  223. package/gsd-core/workflows/add-todo.md +2 -2
  224. package/gsd-core/workflows/ai-integration-phase.md +5 -10
  225. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  226. package/gsd-core/workflows/audit-fix.md +14 -3
  227. package/gsd-core/workflows/audit-milestone.md +11 -9
  228. package/gsd-core/workflows/audit-uat.md +19 -2
  229. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  230. package/gsd-core/workflows/autonomous.md +12 -26
  231. package/gsd-core/workflows/check-todos.md +2 -2
  232. package/gsd-core/workflows/cleanup.md +3 -3
  233. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
  234. package/gsd-core/workflows/code-review-fix.md +3 -1
  235. package/gsd-core/workflows/code-review.md +192 -69
  236. package/gsd-core/workflows/complete-milestone.md +28 -14
  237. package/gsd-core/workflows/debug.md +6 -4
  238. package/gsd-core/workflows/diagnose-issues.md +17 -7
  239. package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
  240. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  241. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  242. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  243. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  244. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
  245. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  246. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  247. package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
  248. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  249. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  250. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
  252. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  253. package/gsd-core/workflows/discuss-phase.md +2 -2
  254. package/gsd-core/workflows/do.md +46 -19
  255. package/gsd-core/workflows/docs-update.md +6 -5
  256. package/gsd-core/workflows/edit-phase.md +3 -1
  257. package/gsd-core/workflows/eval-review.md +5 -10
  258. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
  259. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
  260. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  261. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  263. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
  264. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  265. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  266. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
  267. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  268. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  269. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  270. package/gsd-core/workflows/execute-phase.md +68 -66
  271. package/gsd-core/workflows/execute-plan.md +25 -20
  272. package/gsd-core/workflows/explore.md +3 -1
  273. package/gsd-core/workflows/extract-learnings.md +3 -1
  274. package/gsd-core/workflows/fast.md +8 -2
  275. package/gsd-core/workflows/forensics.md +3 -1
  276. package/gsd-core/workflows/graduation.md +6 -6
  277. package/gsd-core/workflows/health.md +4 -7
  278. package/gsd-core/workflows/help/modes/brief.md +2 -0
  279. package/gsd-core/workflows/help/modes/default.md +2 -0
  280. package/gsd-core/workflows/help/modes/full.md +12 -0
  281. package/gsd-core/workflows/help/modes/topic.md +2 -0
  282. package/gsd-core/workflows/help.md +2 -0
  283. package/gsd-core/workflows/import.md +17 -14
  284. package/gsd-core/workflows/inbox.md +5 -6
  285. package/gsd-core/workflows/ingest-docs.md +45 -12
  286. package/gsd-core/workflows/insert-phase.md +7 -5
  287. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  288. package/gsd-core/workflows/list-seeds.md +7 -3
  289. package/gsd-core/workflows/list-workspaces.md +3 -1
  290. package/gsd-core/workflows/manager.md +15 -26
  291. package/gsd-core/workflows/map-codebase.md +3 -1
  292. package/gsd-core/workflows/milestone-summary.md +3 -1
  293. package/gsd-core/workflows/mvp-phase.md +3 -3
  294. package/gsd-core/workflows/new-milestone.md +10 -22
  295. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  296. package/gsd-core/workflows/new-project.md +17 -29
  297. package/gsd-core/workflows/new-workspace.md +2 -2
  298. package/gsd-core/workflows/next.md +4 -2
  299. package/gsd-core/workflows/node-repair.md +2 -0
  300. package/gsd-core/workflows/note.md +2 -0
  301. package/gsd-core/workflows/onboard.md +1 -1
  302. package/gsd-core/workflows/pause-work.md +20 -5
  303. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  304. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  305. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
  306. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
  307. package/gsd-core/workflows/plan-phase.md +251 -54
  308. package/gsd-core/workflows/plan-review-convergence.md +148 -19
  309. package/gsd-core/workflows/plant-seed.md +3 -3
  310. package/gsd-core/workflows/pr-branch.md +195 -51
  311. package/gsd-core/workflows/profile-user.md +17 -15
  312. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  313. package/gsd-core/workflows/progress.md +52 -15
  314. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  315. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
  316. package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
  317. package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
  318. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  319. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  320. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  321. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  322. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  323. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  324. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  325. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  326. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  327. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  328. package/gsd-core/workflows/quick-batch.md +203 -0
  329. package/gsd-core/workflows/quick.md +33 -32
  330. package/gsd-core/workflows/reapply-patches.md +2 -0
  331. package/gsd-core/workflows/remove-phase.md +6 -4
  332. package/gsd-core/workflows/remove-workspace.md +3 -3
  333. package/gsd-core/workflows/resume-project.md +14 -14
  334. package/gsd-core/workflows/review.md +404 -21
  335. package/gsd-core/workflows/scan.md +3 -1
  336. package/gsd-core/workflows/section-manifest.json +12 -0
  337. package/gsd-core/workflows/secure-phase.md +3 -3
  338. package/gsd-core/workflows/session-report.md +2 -0
  339. package/gsd-core/workflows/settings-advanced.md +9 -9
  340. package/gsd-core/workflows/settings-integrations.md +66 -32
  341. package/gsd-core/workflows/settings.md +4 -6
  342. package/gsd-core/workflows/ship.md +22 -16
  343. package/gsd-core/workflows/sketch-wrap-up.md +13 -17
  344. package/gsd-core/workflows/sketch.md +13 -19
  345. package/gsd-core/workflows/smart-entry.md +4 -6
  346. package/gsd-core/workflows/spec-phase.md +31 -4
  347. package/gsd-core/workflows/spike-wrap-up.md +9 -11
  348. package/gsd-core/workflows/spike.md +21 -32
  349. package/gsd-core/workflows/stats.md +4 -2
  350. package/gsd-core/workflows/sync-skills.md +13 -5
  351. package/gsd-core/workflows/thread.md +13 -7
  352. package/gsd-core/workflows/transition.md +7 -5
  353. package/gsd-core/workflows/ui-phase.md +36 -21
  354. package/gsd-core/workflows/ui-review.md +7 -11
  355. package/gsd-core/workflows/ultraplan-phase.md +7 -13
  356. package/gsd-core/workflows/undo.md +9 -17
  357. package/gsd-core/workflows/update.md +47 -48
  358. package/gsd-core/workflows/validate-phase.md +3 -3
  359. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  360. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  361. package/gsd-core/workflows/verify-work.md +106 -21
  362. package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
  363. package/hooks/dist/gsd-check-update-worker.js +19 -2
  364. package/hooks/dist/gsd-config-reload.js +18 -12
  365. package/hooks/dist/gsd-context-monitor.js +302 -22
  366. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  367. package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
  368. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  369. package/hooks/dist/gsd-cursor-stop.js +2 -1
  370. package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
  371. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
  372. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  373. package/hooks/dist/gsd-graphify-update.sh +22 -18
  374. package/hooks/dist/gsd-node-runner.sh +77 -0
  375. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  376. package/hooks/dist/gsd-prompt-guard.js +46 -12
  377. package/hooks/dist/gsd-read-guard.js +18 -7
  378. package/hooks/dist/gsd-read-injection-scanner.js +22 -13
  379. package/hooks/dist/gsd-secret-read-guard.js +1079 -0
  380. package/hooks/dist/gsd-session-state.sh +1 -0
  381. package/hooks/dist/gsd-statusline.js +222 -29
  382. package/hooks/dist/gsd-validate-commit.sh +523 -12
  383. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  384. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  385. package/hooks/dist/gsd-workflow-guard.js +36 -17
  386. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  387. package/hooks/dist/gsd-write-guard.js +35 -25
  388. package/hooks/dist/lib/cli-exit.js +560 -0
  389. package/hooks/dist/lib/exit-code-registry.js +98 -0
  390. package/hooks/dist/lib/git-cmd.js +210 -1
  391. package/hooks/dist/lib/git-probe.js +84 -0
  392. package/hooks/dist/lib/hook-exit.js +81 -0
  393. package/hooks/dist/lib/injection-patterns.js +36 -6
  394. package/hooks/dist/managed-hooks-registry.cjs +4 -0
  395. package/hooks/gsd-agent-isolation-guard.js +77 -38
  396. package/hooks/gsd-check-update-worker.js +19 -2
  397. package/hooks/gsd-config-reload.js +18 -12
  398. package/hooks/gsd-context-monitor.js +302 -22
  399. package/hooks/gsd-cursor-post-tool.js +3 -1
  400. package/hooks/gsd-cursor-pre-tool.js +3 -1
  401. package/hooks/gsd-cursor-session-start.js +2 -1
  402. package/hooks/gsd-cursor-stop.js +2 -1
  403. package/hooks/gsd-cursor-subagent-start.js +28 -23
  404. package/hooks/gsd-cursor-subagent-stop.js +3 -1
  405. package/hooks/gsd-ensure-canonical-path.js +2 -1
  406. package/hooks/gsd-graphify-update.sh +22 -18
  407. package/hooks/gsd-node-runner.sh +77 -0
  408. package/hooks/gsd-phase-boundary.sh +1 -0
  409. package/hooks/gsd-prompt-guard.js +46 -12
  410. package/hooks/gsd-read-guard.js +18 -7
  411. package/hooks/gsd-read-injection-scanner.js +22 -13
  412. package/hooks/gsd-secret-read-guard.js +1079 -0
  413. package/hooks/gsd-session-state.sh +1 -0
  414. package/hooks/gsd-statusline.js +222 -29
  415. package/hooks/gsd-validate-commit.sh +523 -12
  416. package/hooks/gsd-windsurf-pre-command.js +16 -11
  417. package/hooks/gsd-windsurf-pre-write.js +22 -13
  418. package/hooks/gsd-workflow-guard.js +36 -17
  419. package/hooks/gsd-worktree-path-guard.js +36 -21
  420. package/hooks/gsd-write-guard.js +35 -25
  421. package/hooks/hooks.json +6 -0
  422. package/hooks/lib/cli-exit.js +560 -0
  423. package/hooks/lib/exit-code-registry.js +98 -0
  424. package/hooks/lib/git-cmd.js +210 -1
  425. package/hooks/lib/git-probe.js +84 -0
  426. package/hooks/lib/hook-exit.js +81 -0
  427. package/hooks/lib/injection-patterns.js +36 -6
  428. package/hooks/managed-hooks-registry.cjs +4 -0
  429. package/package.json +14 -9
  430. package/scripts/base64-scan.sh +74 -12
  431. package/scripts/build-hooks.js +12 -0
  432. package/scripts/check-glossary-refs.cjs +77 -15
  433. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  434. package/scripts/ci-check-job-near-cap.cjs +49 -0
  435. package/scripts/ci-pr-mergeability.cjs +262 -0
  436. package/scripts/ci-test-scope.cjs +52 -12
  437. package/scripts/ci-timeout-report.cjs +230 -0
  438. package/scripts/docs-guard-registry.cjs +406 -0
  439. package/scripts/gen-capability-registry.cjs +8 -6
  440. package/scripts/gen-exit-code-docs.cjs +318 -0
  441. package/scripts/gen-exit-code-registry.cjs +891 -0
  442. package/scripts/gen-features.cjs +836 -0
  443. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  444. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  445. package/scripts/gen-loop-host-contract.cjs +189 -4
  446. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  447. package/scripts/gen-state-md-docs.cjs +727 -0
  448. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  449. package/scripts/lib/ci-job-timing.cjs +72 -0
  450. package/scripts/lib/cli-exit.cjs +546 -44
  451. package/scripts/lib/drift-scan.cjs +32 -2
  452. package/scripts/lib/exit-code-registry.cjs +98 -0
  453. package/scripts/lib/ndjson-reporter.cjs +119 -0
  454. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  455. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  456. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  457. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  458. package/scripts/lint-docs-guard-registration.cjs +495 -0
  459. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
  460. package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
  461. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  462. package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
  463. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  464. package/scripts/lint-phase-enumeration-drift.cjs +45 -14
  465. package/scripts/lint-phase-id-drift.cjs +133 -8
  466. package/scripts/lint-planning-prompt-drift.cjs +38 -1
  467. package/scripts/lint-portable-grep.cjs +176 -0
  468. package/scripts/lint-removed-but-needed.cjs +184 -16
  469. package/scripts/lint-response-language-coverage.cjs +524 -0
  470. package/scripts/lint-seam-enforcement.cjs +182 -0
  471. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  472. package/scripts/lint-source-test-name-collision.cjs +241 -0
  473. package/scripts/lint-state-write-path-drift.cjs +337 -432
  474. package/scripts/lint-test-file-count.allowlist.json +124 -4
  475. package/scripts/lint-test-file-count.cjs +25 -3
  476. package/scripts/lint-unreachable-guard-drift.cjs +51 -64
  477. package/scripts/lint-vendored-deps.cjs +208 -35
  478. package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
  479. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  480. package/scripts/mutation-matrix.cjs +599 -50
  481. package/scripts/npm-audit-baseline.cjs +376 -0
  482. package/scripts/prompt-injection-scan.sh +83 -14
  483. package/scripts/require-issue-link-policy.cjs +16 -1
  484. package/scripts/secret-scan.sh +75 -13
  485. package/scripts/select-docs-guards.cjs +56 -0
  486. package/scripts/sync-runtime-launcher.cjs +22 -3
  487. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  488. package/skills/gsd-execute-phase/SKILL.md +1 -1
  489. package/skills/gsd-import/SKILL.md +1 -1
  490. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  491. package/skills/gsd-phase/SKILL.md +1 -1
  492. package/skills/gsd-quick/SKILL.md +8 -4
  493. package/skills/gsd-quick-batch/SKILL.md +105 -0
  494. package/skills/gsd-surface/SKILL.md +18 -8
  495. package/vscode/package.json +1 -1
  496. package/bin/lib/ui-safety-gate.cjs +0 -109
  497. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  498. package/scripts/state-write-path-drift-baseline.json +0 -19
@@ -16,14 +16,14 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
16
16
  ## 0. Initialize
17
17
 
18
18
  ```bash
19
- _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 [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/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; 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
20
- RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
19
+ _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
20
+ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
21
21
  INIT=$(gsd_run query init.phase-op "${PHASE_ARG}")
22
22
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
23
23
  AGENT_SKILLS_AUDITOR=$(gsd_run query agent-skills gsd-security-auditor)
24
24
  ```
25
25
 
26
- **If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
26
+ **If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
27
27
 
28
28
  Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`.
29
29
 
@@ -1,3 +1,5 @@
1
+ @~/.claude/gsd-core/references/response-language-directive.md
2
+
1
3
  <purpose>
2
4
  Generate a post-session summary document capturing work performed, outcomes achieved, and estimated resource usage. Writes SESSION_REPORT.md to .planning/reports/ for human review and stakeholder sharing.
3
5
  </purpose>
@@ -1,3 +1,5 @@
1
+ Apply response_language to all user-facing prose — narration between tool calls, status updates, progress notes, and findings included; preserve code, paths, and identifiers.
2
+
1
3
  <purpose>
2
4
  Interactive configuration of GSD power-user knobs — plan bounce, node repair, subagent timeouts,
3
5
  inline plan threshold, cross-AI execution, base branch, branch templates, response language,
@@ -22,7 +24,7 @@ Read all files referenced by the invoking prompt's execution_context before star
22
24
  Ensure config exists and resolve the workstream-aware config path (mirrors `settings.md`):
23
25
 
24
26
  ```bash
25
- _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 [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/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; 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
27
+ _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
26
28
  gsd_run query config-ensure-section
27
29
  if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
28
30
  if [[ -f .planning/active-workstream ]]; then
@@ -51,7 +53,7 @@ Planning Tuning:
51
53
  - `workflow.plan_bounce_passes` (default: `2`)
52
54
  - `workflow.plan_bounce_script` (default: `null`)
53
55
  - `workflow.subagent_timeout` (default: `300000`)
54
- - `workflow.inline_plan_threshold` (default: `3`)
56
+ - `workflow.inline_plan_threshold` (default: `2`)
55
57
 
56
58
  Execution Tuning:
57
59
  - `workflow.node_repair` (default: `true`)
@@ -434,7 +436,7 @@ AskUserQuestion([
434
436
 
435
437
  If "Other (Group B or custom)" is selected, prompt the user to enter the runtime name as a free-text string.
436
438
  If the selected runtime differs from the stored `runtime` key, update `runtime` via
437
- `gsd-tools.cjs query config-set runtime <value>` before proceeding to Step C.
439
+ `gsd_run query config-set runtime <value>` before proceeding to Step C.
438
440
 
439
441
  **Step C — Configure tier overrides for the selected runtime:**
440
442
 
@@ -494,7 +496,7 @@ change.
494
496
  Merge the new settings into the existing config at `$GSD_CONFIG_PATH`. This merge is the
495
497
  core correctness invariant: **preserve every unrelated key** — do not clobber siblings.
496
498
 
497
- Apply each selected value via `gsd-tools.cjs query config-set <key> <value>` so the central
499
+ Apply each selected value via `gsd_run query config-set <key> <value>` so the central
498
500
  validator (`isValidConfigKey`) accepts the write and the deep-merge preserves unrelated
499
501
  keys and sibling sub-objects.
500
502
 
@@ -567,7 +569,7 @@ anything not listed in Sections 1–8 MUST survive the update):
567
569
  ```
568
570
 
569
571
  Never emit a full overwrite of the file that omits keys the user did not touch. Always
570
- route each write through `gsd-tools.cjs query config-set` so sibling preservation is handled by
572
+ route each write through `gsd_run query config-set` so sibling preservation is handled by
571
573
  the central setter.
572
574
  </step>
573
575
 
@@ -747,9 +749,7 @@ Never write a tier the user explicitly chose to keep; the existing value must su
747
749
  Display:
748
750
 
749
751
  ```text
750
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
751
- GSD ► ADVANCED SETTINGS UPDATED
752
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
752
+ ### GSD ► ADVANCED SETTINGS UPDATED
753
753
 
754
754
  | Setting | Value |
755
755
  |--------------------------------------------|-------|
@@ -809,7 +809,7 @@ UI/AI phase gates), use /gsd:settings.
809
809
  - [ ] Numeric inputs validated — non-numeric rejected and re-prompted
810
810
  - [ ] Branch-template inputs validated — non-default must contain a placeholder
811
811
  - [ ] Null-allowed fields accept an empty input as a clear
812
- - [ ] Writes routed through `gsd-tools.cjs query config-set` so unrelated keys are preserved
812
+ - [ ] Writes routed through `gsd_run query config-set` so unrelated keys are preserved
813
813
  - [ ] Section 7 shows current runtime and built-in tier table
814
814
  - [ ] Group B runtimes display "(no built-in default — your runtime handles model selection)"
815
815
  - [ ] Override set/clear/keep paths all work correctly for each tier
@@ -26,10 +26,15 @@ log the plaintext value. The workflow follows these rules:
26
26
  - **`config-set` output is masked** for keys in the secret set
27
27
  (`brave_search`, `firecrawl`, `exa_search`) — see
28
28
  `gsd-core/bin/lib/secrets.cjs`.
29
- - **Agent-type and CLI slug validation.** `agent_skills.<agent-type>` and
30
- `review.models.<cli>` keys are matched against `^[a-zA-Z0-9_-]+$`. Inputs
29
+ - **Agent-type and CLI slug validation.** `agent_skills.<agent-type>` slug
30
+ inputs are checked against `^[a-zA-Z0-9_-]+$` before any write; inputs
31
31
  containing path separators (`/`, `\`, `..`), whitespace, or shell
32
- metacharacters are rejected. This closes off skill-injection attacks.
32
+ metacharacters are rejected. This closes off skill-injection attacks on
33
+ that open namespace (dynamic key pattern). For `review.models.<cli>` no
34
+ slug-shape check is needed or performed: the gate is membership in the
35
+ closed, registry-derived settable set (see the review-models section
36
+ below), which subsumes slug shape — slug shape alone never makes a
37
+ `review.models.*` key writable.
33
38
  </security>
34
39
 
35
40
  <required_reading>
@@ -42,8 +47,8 @@ Read all files referenced by the invoking prompt's execution_context before star
42
47
  Ensure config exists and resolve the active config path (flat vs workstream, #2282):
43
48
 
44
49
  ```bash
45
- _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 [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/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; 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
46
- RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
50
+ _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
51
+ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
47
52
  gsd_run query config-ensure-section
48
53
  if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
49
54
  if [[ -f .planning/active-workstream ]]; then
@@ -55,7 +60,7 @@ if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
55
60
  fi
56
61
  ```
57
62
 
58
- **If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
63
+ **If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
59
64
 
60
65
  Store `$GSD_CONFIG_PATH`. Every subsequent read/write uses it.
61
66
  </step>
@@ -69,10 +74,10 @@ integration field, compute one of:
69
74
  - `<value>` — non-secret routing/skill string, shown as-is
70
75
 
71
76
  ```bash
72
- BRAVE=$(gsd_run query config-get brave_search --default null)
73
- FIRECRAWL=$(gsd_run query config-get firecrawl --default null)
74
- EXA=$(gsd_run query config-get exa_search --default null)
75
- SEARCH_GITIGNORED=$(gsd_run query config-get search_gitignored --default false)
77
+ BRAVE=$(gsd_run query config-get brave_search --raw --default null)
78
+ FIRECRAWL=$(gsd_run query config-get firecrawl --raw --default null)
79
+ EXA=$(gsd_run query config-get exa_search --raw --default null)
80
+ SEARCH_GITIGNORED=$(gsd_run query config-get search_gitignored --raw --default false)
76
81
  ```
77
82
 
78
83
  For each secret key (`brave_search`, `firecrawl`, `exa_search`) the displayed
@@ -148,9 +153,24 @@ gsd_run query config-set brave_search null
148
153
 
149
154
  <step name="section_2_review_models">
150
155
 
151
- `review.models.<cli>` is a map that tells the code-review workflow which
152
- shell command to invoke for a given reviewer flavor. Supported flavors:
153
- `claude`, `codex`, `gemini`, `opencode`.
156
+ `review.models.<cli>` is a closed, registry-derived map that tells the review
157
+ workflow which model id a reviewer lane uses. It is not an open namespace: a
158
+ `review.models.<cli>` key is settable only when that lane's capability
159
+ declares a `modelConfigKey`, and `config-set` accepts exactly those keys
160
+ (federated from the capability registry). No dynamic-key regex governs this
161
+ namespace — any other slug fails with `Unknown config key`.
162
+
163
+ Settable keys (the shipped registry's model-bearing lanes):
164
+
165
+ `review.models.agy` (Antigravity), `review.models.claude`, `review.models.codex`,
166
+ `review.models.cursor`, `review.models.gemini`, `review.models.kimi-code`,
167
+ `review.models.llama_cpp`, `review.models.lm_studio`, `review.models.ollama`,
168
+ `review.models.opencode`.
169
+
170
+ Reviewer lanes `qwen` and `coderabbit` declare no `modelConfigKey` — there is
171
+ nothing to configure for them here (whether they should have a per-lane model
172
+ key is a separate question, out of scope for this workflow).
173
+ If the user asks for one of those, say exactly that and skip.
154
174
 
155
175
  ```text
156
176
  AskUserQuestion([
@@ -159,7 +179,7 @@ AskUserQuestion([
159
179
  header: "Review",
160
180
  multiSelect: false,
161
181
  options: [
162
- { label: "Configure CLI", description: "Pick a reviewer flavor and set/clear its command" },
182
+ { label: "Configure CLI", description: "Pick a reviewer lane and set/clear its model id" },
163
183
  { label: "Done", description: "Finish this section" }
164
184
  ]
165
185
  }
@@ -171,7 +191,7 @@ If "Configure CLI" is selected, ask:
171
191
  ```text
172
192
  AskUserQuestion([
173
193
  {
174
- question: "Which reviewer CLI do you want to configure?",
194
+ question: "Which reviewer lane do you want to configure? (Common lanes below; any settable lane from the list above works — or type its slug)",
175
195
  header: "CLI",
176
196
  multiSelect: false,
177
197
  options: [
@@ -184,7 +204,18 @@ AskUserQuestion([
184
204
  ])
185
205
  ```
186
206
 
187
- For the selected CLI, show the current value (or `(unset)`) and offer
207
+ For a slug received as free text, check it against the settable set above.
208
+ If it is not one of the settable keys, print:
209
+
210
+ ```text
211
+ Rejected: review.models.<slug> is not settable — only the reviewer lanes whose
212
+ keys are enumerated above can be configured here. (qwen and coderabbit have no
213
+ per-lane model key.)
214
+ ```
215
+
216
+ and re-prompt.
217
+
218
+ For the selected lane, show the current value (or `(unset)`) and offer
188
219
  Leave / Replace / Clear, followed by a text-input prompt for the model id
189
220
  string. Write via:
190
221
 
@@ -194,10 +225,6 @@ gsd_run query config-set review.models.<cli> "<model id>"
194
225
 
195
226
  After each update, return to the "Review model CLI mapping — what next?" question.
196
227
  Loop until the user selects "Done".
197
-
198
- The `review.models.<cli>` key is validated by the dynamic pattern
199
- `^review\.models\.[a-zA-Z0-9_-]+$`. Empty CLI slugs and path-containing slugs
200
- are rejected by `config-set` before any write.
201
228
  </step>
202
229
 
203
230
  <step name="section_3_agent_skills">
@@ -249,13 +276,24 @@ spaces, or shell metacharacters).
249
276
 
250
277
  and re-prompt.
251
278
 
252
- For a selected slug, prompt for the comma-separated skill list (text input).
253
- Show the current value if any, offer Leave / Replace / Clear. Write via:
279
+ For a selected slug, prompt for the skill list (text input; a comma-separated
280
+ reply is fine). Show the current value if any, offer Leave / Replace / Clear.
281
+
282
+ Split the reply before writing: the resolver never splits strings, so a
283
+ comma-joined string would be stored as ONE skill path that silently fails
284
+ resolution at spawn time (#3651 — `gsd-core/references/planning-config.md`:
285
+ "Paths cannot be comma-joined into one string; each path must be its own
286
+ array element"). Split on commas, trim each entry, drop empty entries, reject
287
+ any entry containing a quote character (`'` or `"` — it cannot be written
288
+ safely through the single-quoted form), and write the JSON array form:
254
289
 
255
290
  ```bash
256
- gsd_run query config-set agent_skills.<slug> "<skill-a,skill-b,skill-c>"
291
+ gsd_run query config-set agent_skills.<slug> '["skills/alpha","skills/beta"]'
257
292
  ```
258
293
 
294
+ A single skill may be written as one bare string or a one-element array —
295
+ both resolve identically.
296
+
259
297
  After each update, return to the "Agent skills mapping — what next?" question.
260
298
  Loop until "Done".
261
299
  </step>
@@ -265,9 +303,7 @@ Display the masked confirmation table. **No plaintext API keys appear in this
265
303
  output under any circumstance.**
266
304
 
267
305
  ```text
268
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
269
- GSD ► INTEGRATIONS UPDATED
270
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
306
+ ### GSD ► INTEGRATIONS UPDATED
271
307
 
272
308
  Search Integrations
273
309
  | Field | Value |
@@ -278,12 +314,10 @@ Search Integrations
278
314
  | search_gitignored | true | false |
279
315
 
280
316
  Code Review CLI Routing
281
- | CLI | Command |
317
+ | Lane | Model id |
282
318
  |-------------|--------------------------------------|
283
- | claude | <value or (session model default)> |
284
- | codex | <value or (unset)> |
285
- | gemini | <value or (unset)> |
286
- | opencode | <value or (unset)> |
319
+ | <lane> | <value or (unset)> |
320
+ | ... | ... one row per lane the user set |
287
321
 
288
322
  Agent Skills Injection
289
323
  | Agent Type | Skills |
@@ -310,6 +344,6 @@ Quick commands:
310
344
  - [ ] User presented with three sections: Search Integrations, Review CLI Routing, Agent Skills Injection
311
345
  - [ ] API keys written plaintext only to `config.json`; never echoed, never logged, never displayed
312
346
  - [ ] Masked confirmation table uses `****<last-4>` for set keys and `(unset)` for null
313
- - [ ] `review.models.<cli>` and `agent_skills.<agent-type>` keys validated against `[a-zA-Z0-9_-]+` before write
347
+ - [ ] `agent_skills.<agent-type>` slugs validated against `[a-zA-Z0-9_-]+` before write; `review.models.<cli>` slugs accepted only from the registry-derived settable set; skill lists written as JSON arrays (never comma-joined strings)
314
348
  - [ ] Config merge preserves all keys outside the three sections this workflow owns
315
349
  </success_criteria>
@@ -12,8 +12,8 @@ Read all files referenced by the invoking prompt's execution_context before star
12
12
  Ensure config exists and load current state:
13
13
 
14
14
  ```bash
15
- _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 [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/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; 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
16
- RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
15
+ _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
16
+ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
17
17
  gsd_run query config-ensure-section
18
18
  INIT=$(gsd_run query state.load)
19
19
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
@@ -28,7 +28,7 @@ if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
28
28
  fi
29
29
  ```
30
30
 
31
- **If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
31
+ **If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
32
32
 
33
33
  Creates `config.json` (at the resolved path) with defaults if missing. `INIT` still holds `state.load` output for any step that needs STATE fields.
34
34
  Store `$GSD_CONFIG_PATH` — all subsequent reads and writes use this path, not a hardcoded `.planning/config.json`, so active-workstream installs target the correct file (#2282).
@@ -606,9 +606,7 @@ Write `~/.gsd/defaults.json` with:
606
606
  Display:
607
607
 
608
608
  ```
609
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
610
- GSD ► SETTINGS UPDATED
611
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
609
+ ### GSD ► SETTINGS UPDATED
612
610
 
613
611
  | Setting | Value |
614
612
  |----------------------|-------|
@@ -24,13 +24,13 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
24
24
  Parse arguments and load project state:
25
25
 
26
26
  ```bash
27
- _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 [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/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 "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/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; 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
28
- RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --default "" 2>/dev/null || echo "")
27
+ _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
28
+ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
29
29
  INIT=$(gsd_run query init.phase-op "${PHASE_ARG}")
30
30
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
31
31
  ```
32
32
 
33
- **If `response_language` is set:** All user-facing questions, prompts, and explanations in this workflow MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
33
+ **If `response_language` is set:** All user-facing output of this workflow — narration between tool calls, status updates, progress notes, findings, questions, prompts, and explanations — MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English — only user-facing output is translated.
34
34
 
35
35
  Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`, `commit_docs`.
36
36
 
@@ -74,9 +74,15 @@ Verify the work is ready to ship:
74
74
 
75
75
  3. **On correct branch?**
76
76
  ```bash
77
- CURRENT_BRANCH=$(git branch --show-current)
77
+ CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || true)
78
+ IS_PROTECTED=$(gsd_run query git.base-branch --is-protected "$CURRENT_BRANCH") || IS_PROTECTED=""
79
+ if [ "$IS_PROTECTED" = true ]; then
80
+ echo "⚠ Current branch '$CURRENT_BRANCH' is a protected branch; shipping should happen from a feature branch." >&2
81
+ elif [ -z "$IS_PROTECTED" ]; then
82
+ echo "⚠ Could not determine whether '$CURRENT_BRANCH' is protected — the query failed. Continuing." >&2
83
+ fi
78
84
  ```
79
- If on `${BASE_BRANCH}`: warn — should be on a feature branch.
85
+ If `IS_PROTECTED` is `true`: warn — should be on a feature branch.
80
86
  If branching_strategy is `none`: offer to create a branch now.
81
87
 
82
88
  4. **Remote configured?**
@@ -303,16 +309,16 @@ Example configured sections:
303
309
 
304
310
  **8. TDD Audit section:**
305
311
 
306
- Reconstruct the per-commit TDD gate trail before squash-merge discards it. Walk the PR branch's own commits (merges excluded) and read each commit's `gate_status:` trailer with Git's native trailer machinery — never a raw `%B` grep, which would also match the string written in prose:
312
+ Reconstruct the per-commit TDD gate trail before squash-merge discards it. Walk the PR branch's own commits (merges excluded) and read each commit's `gate-status:` trailer with Git's native trailer machinery — never a raw `%B` grep, which would also match the string written in prose:
307
313
 
308
314
  ```bash
309
315
  # Anchor on the merge-base so a stale local ${BASE_BRANCH} ref cannot over-count.
310
316
  RANGE_BASE=$(git merge-base "${BASE_BRANCH}" HEAD)
311
317
  git log "${RANGE_BASE}..HEAD" --no-merges --reverse \
312
- --format='%H%x1f%s%x1f%(trailers:key=gate_status,valueonly,separator=%x2c)%x1e'
318
+ --format='%H%x1f%s%x1f%(trailers:key=gate-status,valueonly,separator=%x2c)%x1e'
313
319
  ```
314
320
 
315
- Records are separated by `\x1e`; the fields inside each are `\x1f`-separated — `<sha>`, `<subject>`, `<gate_status value>`.
321
+ Records are separated by `\x1e`; the fields inside each are `\x1f`-separated — `<sha>`, `<subject>`, `<gate-status value>`.
316
322
 
317
323
  Pair commits by their conventional-commit type (the `type:` prefix of the subject):
318
324
 
@@ -320,16 +326,16 @@ Pair commits by their conventional-commit type (the `type:` prefix of the subjec
320
326
  - A `refactor:`, `docs:`, or `chore:` commit that is not consumed as an Impl pairing is a standalone row with Impl commit `—`.
321
327
  - A `feat:`/`fix:` commit with no preceding unpaired `test:` is a standalone row.
322
328
 
323
- Surface each commit's `gate_status:` value, normalized to exactly one of `skill`, `fallback`, `exempt`, or `missing` — never the raw trailer text. A commit whose trailer is absent, whose value is none of the first three, or which carries more than one `gate_status:` trailer (ambiguous) is counted as **missing** and still listed. This section is informational; it never blocks the ship.
329
+ Surface each commit's `gate-status:` value, normalized to exactly one of `skill`, `fallback`, `exempt`, or `missing` — never the raw trailer text. A commit whose trailer is absent, whose value is none of the first three, or which carries more than one `gate-status:` trailer (ambiguous) is counted as **missing** and still listed. This section is informational; it never blocks the ship.
324
330
 
325
- **Self-suppress when every commit is missing (#2431):** the execute pipeline only writes `gate_status:` trailers when TDD mode is active. If every commit in the scan normalizes to `missing`, skip this section and the aggregate trailer (step 9) entirely — a 100%-missing table is pure noise. Only emit when at least one commit carries a real value (`skill`, `fallback`, or `exempt`).
331
+ **Self-suppress when every commit is missing (#2431):** the execute pipeline only writes `gate-status:` trailers when TDD mode is active. If every commit in the scan normalizes to `missing`, skip this section and the aggregate trailer (step 9) entirely — a 100%-missing table is pure noise. Only emit when at least one commit carries a real value (`skill`, `fallback`, or `exempt`).
326
332
 
327
- Harden every table cell against injection, not just subjects: escape `|` as `\|` and strip `\r`/`\n` from both commit subjects and the rendered `gate_status` value. Prefer NUL (`-z` / `%x00`) record separation, and reject any record whose fields contain the `\x1f`/`\x1e` delimiters, so an adversarial commit message cannot corrupt record or field boundaries.
333
+ Harden every table cell against injection, not just subjects: escape `|` as `\|` and strip `\r`/`\n` from both commit subjects and the rendered `gate-status` value. Prefer NUL (`-z` / `%x00`) record separation, and reject any record whose fields contain the `\x1f`/`\x1e` delimiters, so an adversarial commit message cannot corrupt record or field boundaries.
328
334
 
329
335
  ```markdown
330
336
  ## TDD Audit
331
337
 
332
- | Test commit | Impl commit | gate_status |
338
+ | Test commit | Impl commit | gate-status |
333
339
  |---|---|---|
334
340
  | `a1b2c3d` test: failing parser test | `e4f5g6h` feat: implement parser | skill |
335
341
  | `i7j8k9l` test: failing export test | `m0n1o2p` feat: implement export | fallback |
@@ -340,12 +346,12 @@ Aggregate: 2 skill, 1 fallback, 1 exempt — 0 missing.
340
346
 
341
347
  This `## TDD Audit` section is the final body section — it renders after the configured `pr_body_sections`, immediately before the aggregate trailer — so the frozen core sections and the append-only configured sections both keep their existing order.
342
348
 
343
- **9. Aggregate gate_status trailer (final line)** (only when step 8 was emitted — i.e., at least one real `gate_status` value exists):
349
+ **9. Aggregate gate-status trailer (final line)** (only when step 8 was emitted — i.e., at least one real `gate-status` value exists):
344
350
 
345
351
  After every other section — including any configured `pr_body_sections` — emit the audit aggregate as a single Git trailer on the **final line** of the PR body, preceded by a blank line so it parses as a valid trailer:
346
352
 
347
353
  ```
348
- gate_status: skill=2, fallback=1, exempt=1, missing=0
354
+ gate-status: skill=2, fallback=1, exempt=1, missing=0
349
355
  ```
350
356
 
351
357
  Use the exact key order `skill=`, `fallback=`, `exempt=`, `missing=` so downstream tooling parses it stably. Keeping it last means a GitHub squash-merge that defaults its commit message to the PR description carries the aggregate into `${BASE_BRANCH}`, preserving the audit footprint in `git log` after the PR branch is deleted. (Best-effort: it depends on the repo's squash-message default; the in-body `## TDD Audit` section is the source of truth regardless.)
@@ -571,7 +577,7 @@ Each dispatch is best-effort: if it errors, record a warning and continue — ne
571
577
 
572
578
  <step name="report">
573
579
  ```
574
- ───────────────────────────────────────────────────────────────
580
+ ---
575
581
 
576
582
  ## ✓ Phase {X}: {Name} — Shipped
577
583
 
@@ -587,7 +593,7 @@ Next steps:
587
593
  - /gsd:complete-milestone (if last phase in milestone)
588
594
  - /gsd:progress (to see what's next)
589
595
 
590
- ───────────────────────────────────────────────────────────────
596
+ ---
591
597
  ```
592
598
  </step>
593
599