@opengsd/gsd-core 1.12.0 → 1.14.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 (455) 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-advisor-researcher.compact.md +85 -0
  5. package/agents/gsd-ai-researcher.compact.md +96 -0
  6. package/agents/gsd-assumptions-analyzer.compact.md +81 -0
  7. package/agents/gsd-code-fixer.compact.md +458 -0
  8. package/agents/gsd-code-fixer.md +5 -5
  9. package/agents/gsd-code-reviewer.compact.md +269 -0
  10. package/agents/gsd-code-reviewer.md +15 -3
  11. package/agents/gsd-codebase-mapper.compact.md +760 -0
  12. package/agents/gsd-debug-session-manager.compact.md +345 -0
  13. package/agents/gsd-doc-classifier.compact.md +192 -0
  14. package/agents/gsd-doc-synthesizer.compact.md +200 -0
  15. package/agents/gsd-doc-verifier.compact.md +143 -0
  16. package/agents/gsd-doc-writer.compact.md +440 -0
  17. package/agents/gsd-dom-verifier.compact.md +138 -0
  18. package/agents/gsd-domain-researcher.compact.md +141 -0
  19. package/agents/gsd-eval-auditor.compact.md +160 -0
  20. package/agents/gsd-eval-planner.compact.md +137 -0
  21. package/agents/gsd-executor.md +63 -35
  22. package/agents/gsd-framework-selector.compact.md +82 -0
  23. package/agents/gsd-integration-checker.compact.md +245 -0
  24. package/agents/gsd-intel-updater.compact.md +226 -0
  25. package/agents/gsd-mempalace-curator.compact.md +45 -0
  26. package/agents/gsd-nyquist-auditor.compact.md +179 -0
  27. package/agents/gsd-pattern-mapper.compact.md +275 -0
  28. package/agents/gsd-plan-checker.md +76 -57
  29. package/agents/gsd-planner.md +14 -0
  30. package/agents/gsd-project-researcher.compact.md +587 -0
  31. package/agents/gsd-research-synthesizer.compact.md +212 -0
  32. package/agents/gsd-roadmapper.compact.md +454 -0
  33. package/agents/gsd-roadmapper.md +13 -0
  34. package/agents/gsd-security-auditor.compact.md +162 -0
  35. package/agents/gsd-ui-auditor.compact.md +404 -0
  36. package/agents/gsd-ui-checker.compact.md +277 -0
  37. package/agents/gsd-ui-checker.md +19 -3
  38. package/agents/gsd-ui-researcher.compact.md +282 -0
  39. package/agents/gsd-ui-researcher.md +29 -0
  40. package/agents/gsd-user-profiler.compact.md +108 -0
  41. package/agents/gsd-verifier.md +23 -1
  42. package/bin/install.js +444 -134
  43. package/commands/gsd/cleanup.md +1 -0
  44. package/commands/gsd/code-review.md +2 -1
  45. package/commands/gsd/complete-milestone.md +1 -0
  46. package/commands/gsd/config.md +1 -0
  47. package/commands/gsd/debug.md +1 -0
  48. package/commands/gsd/execute-phase.md +1 -1
  49. package/commands/gsd/graphify.md +1 -0
  50. package/commands/gsd/health.md +1 -0
  51. package/commands/gsd/mempalace-capture.md +1 -0
  52. package/commands/gsd/mempalace-recall.md +1 -0
  53. package/commands/gsd/new-milestone.md +1 -0
  54. package/commands/gsd/new-project.md +1 -0
  55. package/commands/gsd/next.md +1 -0
  56. package/commands/gsd/ns-workflow.md +2 -1
  57. package/commands/gsd/pause-work.md +1 -0
  58. package/commands/gsd/phase.md +2 -1
  59. package/commands/gsd/pr-branch.md +1 -0
  60. package/commands/gsd/quick-batch.md +105 -0
  61. package/commands/gsd/resume-work.md +1 -0
  62. package/commands/gsd/review-backlog.md +1 -0
  63. package/commands/gsd/settings.md +2 -1
  64. package/commands/gsd/stats.md +1 -0
  65. package/commands/gsd/surface.md +18 -8
  66. package/commands/gsd/thread.md +1 -0
  67. package/commands/gsd/workspace.md +1 -0
  68. package/commands/gsd/workstreams.md +1 -0
  69. package/gsd-core/bin/check-latest-version.cjs +8 -3
  70. package/gsd-core/bin/gsd-tools.cjs +532 -174
  71. package/gsd-core/bin/lib/adr-parser.cjs +1 -1
  72. package/gsd-core/bin/lib/artifacts.cjs +2 -1
  73. package/gsd-core/bin/lib/audit.cjs +39 -22
  74. package/gsd-core/bin/lib/broken-windows.cjs +168 -49
  75. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  76. package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
  77. package/gsd-core/bin/lib/capability-loader.cjs +135 -1
  78. package/gsd-core/bin/lib/capability-registry.cjs +528 -116
  79. package/gsd-core/bin/lib/capability-source.cjs +19 -2
  80. package/gsd-core/bin/lib/capability-state.cjs +7 -1
  81. package/gsd-core/bin/lib/capability-validator.cjs +134 -5
  82. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  83. package/gsd-core/bin/lib/check-command-router.cjs +198 -38
  84. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  85. package/gsd-core/bin/lib/clusters.cjs +1 -0
  86. package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
  87. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  88. package/gsd-core/bin/lib/commands.cjs +981 -79
  89. package/gsd-core/bin/lib/config-loader.cjs +4 -0
  90. package/gsd-core/bin/lib/config.cjs +153 -38
  91. package/gsd-core/bin/lib/core-utils.cjs +34 -7
  92. package/gsd-core/bin/lib/coverage.cjs +1 -1
  93. package/gsd-core/bin/lib/decisions.cjs +343 -28
  94. package/gsd-core/bin/lib/edge-probe.cjs +14 -1
  95. package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
  96. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  97. package/gsd-core/bin/lib/frontmatter.cjs +137 -23
  98. package/gsd-core/bin/lib/gap-checker.cjs +22 -13
  99. package/gsd-core/bin/lib/git-base-branch.cjs +10 -2
  100. package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
  101. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  102. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +54 -11
  103. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +87 -23
  104. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
  105. package/gsd-core/bin/lib/host-integration.cjs +57 -5
  106. package/gsd-core/bin/lib/init-command-router.cjs +14 -0
  107. package/gsd-core/bin/lib/init.cjs +539 -60
  108. package/gsd-core/bin/lib/install-engine.cjs +199 -14
  109. package/gsd-core/bin/lib/install-model-override-resolver.cjs +45 -0
  110. package/gsd-core/bin/lib/install-profiles.cjs +36 -14
  111. package/gsd-core/bin/lib/installer-migration-report.cjs +1 -0
  112. package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
  113. package/gsd-core/bin/lib/io.cjs +35 -0
  114. package/gsd-core/bin/lib/loop-resolver.cjs +64 -39
  115. package/gsd-core/bin/lib/markdown-table.cjs +123 -0
  116. package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
  117. package/gsd-core/bin/lib/milestone.cjs +41 -10
  118. package/gsd-core/bin/lib/model-resolver.cjs +101 -10
  119. package/gsd-core/bin/lib/phase-command-router.cjs +20 -7
  120. package/gsd-core/bin/lib/phase-id.cjs +412 -31
  121. package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
  122. package/gsd-core/bin/lib/phase.cjs +941 -98
  123. package/gsd-core/bin/lib/plan-document.cjs +10 -0
  124. package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
  125. package/gsd-core/bin/lib/planning-snapshot.cjs +206 -30
  126. package/gsd-core/bin/lib/planning-workspace.cjs +153 -29
  127. package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
  128. package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
  129. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  130. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  131. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  132. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +61 -2
  133. package/gsd-core/bin/lib/research-store.cjs +11 -12
  134. package/gsd-core/bin/lib/review-lane-descriptor.cjs +53 -5
  135. package/gsd-core/bin/lib/review-lane-invocation.cjs +96 -1
  136. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  137. package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
  138. package/gsd-core/bin/lib/roadmap-parser.cjs +555 -41
  139. package/gsd-core/bin/lib/roadmap.cjs +292 -69
  140. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +260 -43
  141. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +28 -20
  142. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +294 -108
  143. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +408 -47
  144. package/gsd-core/bin/lib/security.cjs +126 -7
  145. package/gsd-core/bin/lib/shell-command-projection.cjs +4 -0
  146. package/gsd-core/bin/lib/smart-entry.cjs +7 -9
  147. package/gsd-core/bin/lib/state-document.cjs +159 -32
  148. package/gsd-core/bin/lib/state-md-schema.cjs +44 -27
  149. package/gsd-core/bin/lib/state-transition.cjs +465 -62
  150. package/gsd-core/bin/lib/state.cjs +906 -151
  151. package/gsd-core/bin/lib/surface.cjs +83 -10
  152. package/gsd-core/bin/lib/task-command-router.cjs +12 -6
  153. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  154. package/gsd-core/bin/lib/uat.cjs +1420 -516
  155. package/gsd-core/bin/lib/update-context.cjs +36 -26
  156. package/gsd-core/bin/lib/validate.cjs +230 -12
  157. package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
  158. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  159. package/gsd-core/bin/lib/verification.cjs +316 -23
  160. package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
  161. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  162. package/gsd-core/bin/lib/verify.cjs +531 -36
  163. package/gsd-core/bin/lib/workstream-inventory.cjs +21 -2
  164. package/gsd-core/bin/lib/worktree-safety.cjs +21 -7
  165. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  166. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  167. package/gsd-core/bin/verify-reapply-patches.cjs +507 -81
  168. package/gsd-core/references/agent-contracts.md +3 -3
  169. package/gsd-core/references/compact-content-gate.md +66 -0
  170. package/gsd-core/references/edge-probe.md +17 -13
  171. package/gsd-core/references/execute-mvp-tdd.md +18 -16
  172. package/gsd-core/references/execute-phase-response-language.md +6 -0
  173. package/gsd-core/references/executor-examples.md +42 -0
  174. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  175. package/gsd-core/references/loop-hook-dispatch.md +18 -0
  176. package/gsd-core/references/model-profiles.md +12 -3
  177. package/gsd-core/references/mvp-concepts.md +2 -2
  178. package/gsd-core/references/plan-checker-examples.md +41 -0
  179. package/gsd-core/references/planner-antipatterns.md +25 -0
  180. package/gsd-core/references/planner-chunked.md +5 -1
  181. package/gsd-core/references/planner-coupling.md +42 -0
  182. package/gsd-core/references/planner-quick-batch.md +71 -0
  183. package/gsd-core/references/planner-reviews.md +47 -0
  184. package/gsd-core/references/planner-revision.md +75 -2
  185. package/gsd-core/references/planning-config.md +5 -1
  186. package/gsd-core/references/response-language-directive.md +9 -0
  187. package/gsd-core/references/revision-loop.md +118 -11
  188. package/gsd-core/references/tdd.md +17 -9
  189. package/gsd-core/references/thinking-models-planning.md +18 -2
  190. package/gsd-core/references/verification-patterns.md +17 -4
  191. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  192. package/gsd-core/references/worktree-path-safety.md +112 -2
  193. package/gsd-core/templates/README.md +7 -1
  194. package/gsd-core/templates/phase-prompt.md +4 -0
  195. package/gsd-core/templates/state.md +6 -3
  196. package/gsd-core/templates/summary.compact.md +212 -0
  197. package/gsd-core/templates/user-setup.compact.md +199 -0
  198. package/gsd-core/templates/user-setup.md +0 -9
  199. package/gsd-core/templates/verification-report.md +5 -0
  200. package/gsd-core/workflows/add-backlog.md +2 -0
  201. package/gsd-core/workflows/add-phase.md +2 -0
  202. package/gsd-core/workflows/add-tests.md +1 -1
  203. package/gsd-core/workflows/add-todo.md +4 -3
  204. package/gsd-core/workflows/ai-integration-phase.md +1 -1
  205. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  206. package/gsd-core/workflows/audit-fix.md +2 -0
  207. package/gsd-core/workflows/audit-milestone.md +2 -0
  208. package/gsd-core/workflows/audit-uat.md +2 -0
  209. package/gsd-core/workflows/autonomous.md +15 -10
  210. package/gsd-core/workflows/check-todos.md +5 -3
  211. package/gsd-core/workflows/cleanup.md +4 -2
  212. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +22 -13
  213. package/gsd-core/workflows/code-review-fix.md +5 -3
  214. package/gsd-core/workflows/code-review.md +211 -43
  215. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
  216. package/gsd-core/workflows/complete-milestone.md +40 -254
  217. package/gsd-core/workflows/debug.md +1 -1
  218. package/gsd-core/workflows/diagnose-issues.md +5 -1
  219. package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -0
  220. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  221. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  222. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  223. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  224. package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -0
  225. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  226. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  227. package/gsd-core/workflows/discuss-phase/modes/text.md +2 -0
  228. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  229. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  230. package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
  231. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  232. package/gsd-core/workflows/discuss-phase.md +1 -1
  233. package/gsd-core/workflows/do.md +43 -13
  234. package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
  235. package/gsd-core/workflows/docs-update.md +15 -156
  236. package/gsd-core/workflows/edit-phase.md +2 -0
  237. package/gsd-core/workflows/eval-review.md +1 -1
  238. package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
  239. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +20 -3
  240. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
  241. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +24 -3
  242. package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
  243. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +8 -2
  244. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -0
  245. package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
  246. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  247. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  248. package/gsd-core/workflows/execute-phase.md +78 -159
  249. package/gsd-core/workflows/execute-plan.md +28 -15
  250. package/gsd-core/workflows/explore.md +2 -0
  251. package/gsd-core/workflows/extract-learnings.md +2 -0
  252. package/gsd-core/workflows/fast.md +6 -0
  253. package/gsd-core/workflows/forensics.md +2 -0
  254. package/gsd-core/workflows/graduation.md +1 -1
  255. package/gsd-core/workflows/health.md +1 -1
  256. package/gsd-core/workflows/help/modes/brief.md +2 -0
  257. package/gsd-core/workflows/help/modes/default.md +2 -0
  258. package/gsd-core/workflows/help/modes/full.compact.md +398 -0
  259. package/gsd-core/workflows/help/modes/full.md +12 -0
  260. package/gsd-core/workflows/help/modes/topic.md +2 -0
  261. package/gsd-core/workflows/help.md +3 -1
  262. package/gsd-core/workflows/import.md +3 -3
  263. package/gsd-core/workflows/inbox.md +1 -1
  264. package/gsd-core/workflows/ingest-docs.md +1 -1
  265. package/gsd-core/workflows/insert-phase.md +2 -0
  266. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  267. package/gsd-core/workflows/list-seeds.md +2 -0
  268. package/gsd-core/workflows/list-workspaces.md +2 -0
  269. package/gsd-core/workflows/manager.md +3 -3
  270. package/gsd-core/workflows/map-codebase.md +52 -3
  271. package/gsd-core/workflows/milestone-summary.md +2 -0
  272. package/gsd-core/workflows/mvp-phase.md +1 -1
  273. package/gsd-core/workflows/new-milestone.md +55 -13
  274. package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
  275. package/gsd-core/workflows/new-project.md +37 -205
  276. package/gsd-core/workflows/new-workspace.md +1 -1
  277. package/gsd-core/workflows/next.md +2 -0
  278. package/gsd-core/workflows/node-repair.md +2 -0
  279. package/gsd-core/workflows/note.md +2 -0
  280. package/gsd-core/workflows/onboard.md +1 -1
  281. package/gsd-core/workflows/pause-work.md +19 -4
  282. package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
  283. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  284. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -0
  285. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +9 -0
  286. package/gsd-core/workflows/plan-phase.md +144 -185
  287. package/gsd-core/workflows/plan-review-convergence.md +102 -10
  288. package/gsd-core/workflows/plant-seed.md +1 -1
  289. package/gsd-core/workflows/pr-branch.md +30 -10
  290. package/gsd-core/workflows/profile-user.md +1 -1
  291. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  292. package/gsd-core/workflows/progress.md +25 -3
  293. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +37 -2
  294. package/gsd-core/workflows/quick/steps/research-phase.md +3 -3
  295. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  296. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  297. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  298. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  299. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  300. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  301. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  302. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  303. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  304. package/gsd-core/workflows/quick-batch.md +203 -0
  305. package/gsd-core/workflows/quick.md +21 -4
  306. package/gsd-core/workflows/reapply-patches.md +79 -3
  307. package/gsd-core/workflows/remove-phase.md +2 -0
  308. package/gsd-core/workflows/remove-workspace.md +1 -1
  309. package/gsd-core/workflows/resume-project.md +6 -2
  310. package/gsd-core/workflows/review.md +215 -10
  311. package/gsd-core/workflows/scan.md +2 -0
  312. package/gsd-core/workflows/section-manifest.json +12 -0
  313. package/gsd-core/workflows/secure-phase.md +1 -1
  314. package/gsd-core/workflows/session-report.md +2 -0
  315. package/gsd-core/workflows/settings-advanced.md +2 -0
  316. package/gsd-core/workflows/settings-integrations.md +9 -8
  317. package/gsd-core/workflows/settings.md +19 -6
  318. package/gsd-core/workflows/ship.md +10 -10
  319. package/gsd-core/workflows/sketch-wrap-up.md +2 -0
  320. package/gsd-core/workflows/sketch.md +1 -1
  321. package/gsd-core/workflows/smart-entry.md +1 -1
  322. package/gsd-core/workflows/spec-phase.md +24 -19
  323. package/gsd-core/workflows/spike-wrap-up.md +2 -0
  324. package/gsd-core/workflows/spike.md +1 -1
  325. package/gsd-core/workflows/stats.md +2 -0
  326. package/gsd-core/workflows/sync-skills.md +12 -4
  327. package/gsd-core/workflows/thread.md +2 -0
  328. package/gsd-core/workflows/transition.md +2 -0
  329. package/gsd-core/workflows/ui-phase.md +26 -5
  330. package/gsd-core/workflows/ui-review.md +1 -1
  331. package/gsd-core/workflows/ultraplan-phase.md +2 -0
  332. package/gsd-core/workflows/undo.md +1 -1
  333. package/gsd-core/workflows/update.md +48 -43
  334. package/gsd-core/workflows/validate-phase.md +1 -1
  335. package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
  336. package/gsd-core/workflows/verify-work.md +68 -182
  337. package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
  338. package/hooks/dist/gsd-check-update-worker.js +19 -2
  339. package/hooks/dist/gsd-context-monitor.js +371 -27
  340. package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
  341. package/hooks/dist/gsd-node-runner.sh +1 -0
  342. package/hooks/dist/gsd-prompt-guard.js +30 -5
  343. package/hooks/dist/gsd-read-guard.js +2 -0
  344. package/hooks/dist/gsd-read-injection-scanner.js +5 -5
  345. package/hooks/dist/gsd-secret-read-guard.js +1105 -0
  346. package/hooks/dist/gsd-statusline.js +18 -10
  347. package/hooks/dist/gsd-validate-commit.sh +474 -7
  348. package/hooks/dist/gsd-workflow-guard.js +2 -1
  349. package/hooks/dist/gsd-worktree-path-guard.js +25 -14
  350. package/hooks/dist/gsd-write-guard.js +46 -1
  351. package/hooks/dist/lib/dispatch-identity.js +187 -0
  352. package/hooks/dist/lib/filename-classification.js +64 -0
  353. package/hooks/dist/lib/git-cmd.js +210 -1
  354. package/hooks/dist/lib/injection-patterns.js +36 -6
  355. package/hooks/dist/lib/isolation-deny-reason.js +53 -1
  356. package/hooks/dist/lib/isolation-sentinel.js +58 -19
  357. package/hooks/dist/managed-hooks-registry.cjs +1 -0
  358. package/hooks/gsd-agent-isolation-guard.js +42 -16
  359. package/hooks/gsd-check-update-worker.js +19 -2
  360. package/hooks/gsd-context-monitor.js +371 -27
  361. package/hooks/gsd-cursor-subagent-start.js +34 -14
  362. package/hooks/gsd-node-runner.sh +1 -0
  363. package/hooks/gsd-prompt-guard.js +30 -5
  364. package/hooks/gsd-read-guard.js +2 -0
  365. package/hooks/gsd-read-injection-scanner.js +5 -5
  366. package/hooks/gsd-secret-read-guard.js +1105 -0
  367. package/hooks/gsd-statusline.js +18 -10
  368. package/hooks/gsd-validate-commit.sh +474 -7
  369. package/hooks/gsd-workflow-guard.js +2 -1
  370. package/hooks/gsd-worktree-path-guard.js +25 -14
  371. package/hooks/gsd-write-guard.js +46 -1
  372. package/hooks/hooks.json +6 -0
  373. package/hooks/lib/dispatch-identity.js +187 -0
  374. package/hooks/lib/filename-classification.js +64 -0
  375. package/hooks/lib/git-cmd.js +210 -1
  376. package/hooks/lib/injection-patterns.js +36 -6
  377. package/hooks/lib/isolation-deny-reason.js +53 -1
  378. package/hooks/lib/isolation-sentinel.js +58 -19
  379. package/hooks/managed-hooks-registry.cjs +1 -0
  380. package/package.json +13 -9
  381. package/scripts/benchmark-compact-content-variants.cjs +298 -0
  382. package/scripts/benchmark-compact-content.cjs +368 -0
  383. package/scripts/build-hooks.js +11 -4
  384. package/scripts/check-contract-drift.cjs +4 -1
  385. package/scripts/check-env.cjs +36 -8
  386. package/scripts/check-glossary-refs.cjs +25 -21
  387. package/scripts/ci-next-health.cjs +271 -0
  388. package/scripts/ci-prepare-test-scope.cjs +7 -7
  389. package/scripts/ci-test-scope.cjs +133 -20
  390. package/scripts/ci-timeout-report.cjs +1 -1
  391. package/scripts/diff-touches-shipped-paths.cjs +1 -1
  392. package/scripts/docs-guard-registry.cjs +17 -2
  393. package/scripts/gen-adr-index.cjs +8 -2
  394. package/scripts/gen-inventory-manifest.cjs +12 -0
  395. package/scripts/gen-loop-host-contract.cjs +67 -15
  396. package/scripts/gen-platform-conformance-tier.cjs +557 -0
  397. package/scripts/lib/drift-scan.cjs +1 -1
  398. package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
  399. package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
  400. package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
  401. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  402. package/scripts/lib/suite-detection.cjs +32 -0
  403. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  404. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  405. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  406. package/scripts/lint-allowed-tools-parity.cjs +221 -0
  407. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +24 -2
  408. package/scripts/lint-phase-enumeration-drift.cjs +24 -6
  409. package/scripts/lint-phase-id-drift.cjs +465 -15
  410. package/scripts/lint-portable-grep.cjs +176 -0
  411. package/scripts/lint-response-language-coverage.cjs +530 -0
  412. package/scripts/lint-source-test-name-collision.cjs +1 -1
  413. package/scripts/lint-test-file-count.allowlist.json +4 -1
  414. package/scripts/lint-vendored-deps.cjs +128 -17
  415. package/scripts/lint-workflow-shellcheck-baseline.json +1112 -0
  416. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  417. package/scripts/npm-audit-baseline.cjs +376 -0
  418. package/scripts/prompt-injection-scan.sh +22 -0
  419. package/scripts/require-issue-link-policy.cjs +16 -1
  420. package/scripts/workflow-size.cjs +139 -0
  421. package/skills/gsd-cleanup/SKILL.md +1 -0
  422. package/skills/gsd-code-review/SKILL.md +2 -1
  423. package/skills/gsd-complete-milestone/SKILL.md +1 -0
  424. package/skills/gsd-config/SKILL.md +1 -0
  425. package/skills/gsd-debug/SKILL.md +1 -0
  426. package/skills/gsd-execute-phase/SKILL.md +1 -1
  427. package/skills/gsd-graphify/SKILL.md +1 -0
  428. package/skills/gsd-health/SKILL.md +1 -0
  429. package/skills/gsd-mempalace-capture/SKILL.md +1 -0
  430. package/skills/gsd-mempalace-recall/SKILL.md +1 -0
  431. package/skills/gsd-new-milestone/SKILL.md +1 -0
  432. package/skills/gsd-new-project/SKILL.md +1 -0
  433. package/skills/gsd-next/SKILL.md +1 -0
  434. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  435. package/skills/gsd-pause-work/SKILL.md +1 -0
  436. package/skills/gsd-phase/SKILL.md +2 -1
  437. package/skills/gsd-pr-branch/SKILL.md +1 -0
  438. package/skills/gsd-quick-batch/SKILL.md +105 -0
  439. package/skills/gsd-resume-work/SKILL.md +1 -0
  440. package/skills/gsd-review-backlog/SKILL.md +1 -0
  441. package/skills/gsd-settings/SKILL.md +2 -1
  442. package/skills/gsd-stats/SKILL.md +1 -0
  443. package/skills/gsd-surface/SKILL.md +18 -8
  444. package/skills/gsd-thread/SKILL.md +1 -0
  445. package/skills/gsd-workspace/SKILL.md +1 -0
  446. package/skills/gsd-workstreams/SKILL.md +1 -0
  447. package/vscode/package.json +1 -1
  448. package/gsd-core/templates/claude-md.md +0 -145
  449. package/gsd-core/templates/codebase/concerns.md +0 -310
  450. package/gsd-core/templates/codebase/conventions.md +0 -307
  451. package/gsd-core/templates/codebase/integrations.md +0 -280
  452. package/gsd-core/templates/codebase/structure.md +0 -285
  453. package/gsd-core/templates/codebase/testing.md +0 -480
  454. package/gsd-core/templates/debug-subagent-prompt.md +0 -91
  455. package/gsd-core/templates/discovery.md +0 -146
@@ -0,0 +1,169 @@
1
+ **Step 6: Worktree create + executor dispatch**
2
+
3
+ This is the batch's MUTATING wave — worktree create/executor dispatch/merge
4
+ are the operations `isolation == "none"` caps to concurrency 1 (row 6),
5
+ unlike planning/research above.
6
+
7
+ **Auto-degrade on stale fork base (row 38, mirrors `/gsd:quick`'s own #1941
8
+ guard):**
9
+ ```bash
10
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _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
11
+ if [ "$ISOLATION" = "harness-worktree" ] && [ "${USE_WORKTREES:-true}" != "false" ]; then
12
+ _QB_SHOULD_DEGRADE=$(gsd_run query worktree.base-check --mode "$ISOLATION" --pick shouldDegrade 2>/dev/null || true)
13
+ if [ "$_QB_SHOULD_DEGRADE" = "true" ]; then
14
+ echo "⚠ [#1941] Worktree fork base diverged — auto-degrading quick-batch to sequential mode." >&2
15
+ USE_WORKTREES=false
16
+ ISOLATION=none
17
+ fi
18
+ fi
19
+ gsd_run query dispatch-isolation --raw --force-isolation "$ISOLATION" >/dev/null 2>&1 || true
20
+ ```
21
+
22
+ **Effective concurrency for this MUTATING wave** (`mutating` forces
23
+ `isolation == none` to 1 regardless of `--jobs`/capacity — row 6):
24
+ ```bash
25
+ QB_EXEC_CONC_JSON=$(gsd_run quick-batch effective-concurrency --jobs "$JOBS" --task-count "$ITEM_COUNT" --capacity "$CAPACITY" --isolation "$ISOLATION" --mutating --raw)
26
+ EXEC_CONCURRENCY=$(printf '%s' "$QB_EXEC_CONC_JSON" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{try{const j=JSON.parse(s);process.stdout.write(String(j.concurrency))}catch{process.stdout.write("1")}})')
27
+ ```
28
+
29
+ **Dispatch rounds.** Repeat until no item is eligible-and-not-yet-dispatched
30
+ (bounded by `$ITEM_COUNT` rounds):
31
+
32
+ 1. Re-derive eligibility (also reconciles crash-window/blocked-propagation —
33
+ safe to call repeatedly, idempotent when nothing changed):
34
+ ```bash
35
+ QB_ELIG_JSON=$(gsd_run quick-batch resume --batch "$BATCH_ID" --raw)
36
+ ```
37
+ Parse `eligible` (quick ids ready to execute — every dependency already
38
+ `complete`) and refresh `$BATCH_MANIFEST_JSON` from its `manifest`.
39
+
40
+ **Crash-window guard (mirrors `planner-wave.md`'s PLAN.md-existence
41
+ check one layer earlier — #3677):** `quick-batch resume`'s `eligible` is
42
+ purely status/dependency-derived; it does NOT know an item already
43
+ finished executing. A coordinator crash between this step returning
44
+ (executor committed, `SUMMARY.md` written) and Step 7's merge leaves
45
+ `BATCH.json` at `pending` with no STATE.md row yet (that row is written
46
+ only in Step 9) — so on `--resume`, such an item still comes back
47
+ `eligible` here. Before computing `spawn-plan`, determine which eligible
48
+ items already have `${item_dir}/${quick_id}-SUMMARY.md` on disk (same
49
+ `item_dir` derivation via `generate-slug` every other step uses), then
50
+ let the PURE `quick-batch filter-executed` verb
51
+ (`filterAlreadyExecuted`, `src/quick-batch-dispatch.cts`) decide which
52
+ ids are actually safe to spawn — never re-derive that split inline:
53
+ ```bash
54
+ EXECUTED_IDS_JSON="[]" # JSON array of quick_ids whose SUMMARY.md already exists on disk this round
55
+ QB_FILTER_JSON=$(gsd_run quick-batch filter-executed --eligible "$ELIGIBLE_IDS_JSON" --executed "$EXECUTED_IDS_JSON" --raw)
56
+ ```
57
+ Parse `spawnEligible` (safe to spawn this round) and `alreadyExecuted`
58
+ (diagnostic only — report these as "already executed, routing to merge"
59
+ rather than dispatching them). Replace `$ELIGIBLE_IDS_JSON` with
60
+ `spawnEligible` before continuing to backpressure below.
61
+
62
+ NEVER re-dispatch it into a second worktree for any id `filter-executed`
63
+ returns in `alreadyExecuted`. It is not lost: Step 7's own mergeable-wave
64
+ criterion
65
+ (`gsd-core/workflows/quick-batch/steps/merge-wave.md` Step 1) already
66
+ picks up any `pending` item with an on-disk `SUMMARY.md` that isn't yet
67
+ merged, independent of this eligible/spawn list — dropping it here only
68
+ prevents the duplicate dispatch, it does not remove it from the batch.
69
+
70
+ 2. **Backpressure.** Not every eligible item necessarily spawns this round —
71
+ cap fan-out at `$EXEC_CONCURRENCY` minus current in-flight count (row
72
+ 27/39):
73
+ ```bash
74
+ QB_SPAWN_JSON=$(gsd_run quick-batch spawn-plan --eligible "$ELIGIBLE_IDS_JSON" --capacity "$EXEC_CONCURRENCY" --in-flight "$IN_FLIGHT_COUNT" --raw)
75
+ ```
76
+ Parse `spawn` (dispatch these now) and `pending` (leave `pending` in
77
+ `BATCH.json` — already the case, no write needed; NEVER mark these
78
+ `failed`, NEVER increase fan-out to compensate).
79
+
80
+ 3. **Create worktrees + dispatch executors, ONE AT A TIME per `spawn` item**
81
+ (`git worktree add` races on `.git/config.lock` — never simultaneous,
82
+ `execute-phase.md`'s own discipline):
83
+
84
+ For each item in `spawn`, in order:
85
+
86
+ ```bash
87
+ SLUG=$(gsd_run query generate-slug "$description" --raw)
88
+ ITEM_DIR="${quick_dir}/${quick_id}-${SLUG}"
89
+ ```
90
+
91
+ **`isolation == "harness-worktree"`:** one `Agent()` per message,
92
+ `run_in_background: true`. Same prompt shape as `/gsd:quick`'s own
93
+ executor dispatch (Step 6 of `quick.md`) — required_reading, agent skills,
94
+ `<submodule_commit_guard>` using this project's `$SUBMODULE_PATHS`
95
+ (identical block, verbatim) — with these differences:
96
+ ```
97
+ Agent(
98
+ prompt="
99
+ Execute quick-batch item ${quick_id}.
100
+
101
+ <required_reading>
102
+ - ${ITEM_DIR}/${quick_id}-PLAN.md (Plan)
103
+ - ${STATE_PATH} (Project state — READ ONLY, do not write it)
104
+ - ./CLAUDE.md or ./.claude/CLAUDE.md (if exists)
105
+ </required_reading>
106
+
107
+ ${AGENT_SKILLS_EXECUTOR}
108
+
109
+ <submodule_commit_guard>
110
+ (same SUBMODULE_PATHS fail-loud guard as /gsd:quick — see gsd-core/workflows/quick.md Step 6)
111
+ </submodule_commit_guard>
112
+
113
+ <constraints>
114
+ - Execute all tasks in the plan; commit each task atomically
115
+ - Create summary at: ${ITEM_DIR}/${quick_id}-SUMMARY.md with `status: complete` in frontmatter
116
+ - NEVER invoke /gsd:quick or any other GSD command — you are a leaf, not a coordinator
117
+ - NEVER write .planning/quick-batches/${BATCH_ID}/BATCH.json
118
+ - Do NOT update STATE.md or ROADMAP.md — the orchestrator owns those writes after every item in this dispatch round completes (ADR-1239 single-writer invariant)
119
+ - Do NOT commit docs artifacts (SUMMARY.md, STATE.md, PLAN.md) — the orchestrator commits them at completion
120
+ </constraints>
121
+ ",
122
+ subagent_type="gsd-executor",
123
+ model="{executor_model}",
124
+ {harnessFlag}
125
+ description="Execute ${quick_id}: ${description}"
126
+ )
127
+ ```
128
+ Record `{agent_id, worktree_path, branch, expected_base, allowed_bases}`
129
+ from the executor's return into `$QUICK_BATCH_WORKTREE_MANIFEST` (a JSON
130
+ file, initialized `{"worktrees":[]}` before the first round — same shape
131
+ `/gsd:quick`'s own `QUICK_WORKTREE_MANIFEST` uses).
132
+
133
+ **`isolation == "orchestrator-worktree"`:** GSD creates the worktree
134
+ (`gsd_run query worktree.create --manifest "$QUICK_BATCH_WORKTREE_MANIFEST" --agent-id ... --path ... --branch ... --base ... --files "$PLAN_FILES" --deletions "$PLAN_DELETIONS"`) then
135
+ process-spawns the executor via `dispatch-isolation --json --cwd-target
136
+ --prompt`, exactly as `gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md`'s
137
+ "orchestrator-worktree" section
138
+ describes — reuse that mechanism verbatim, substituting this item's
139
+ `${quick_id}`/`${ITEM_DIR}`/`${quick_id}-PLAN.md` for its
140
+ `{plan_number}`/`{phase_dir}`/`{plan_file}` placeholders.
141
+
142
+ **`isolation == "none"`:** no worktree. Dispatch the executor inline on the
143
+ primary checkout (same prompt, minus the worktree-only framing), one item
144
+ at a time — `EXEC_CONCURRENCY` is already forced to 1 in this mode.
145
+
146
+ **Durable worktree-recovery persistence (#3677 — `harness-worktree`/
147
+ `orchestrator-worktree` only, skip for `none`):** immediately after
148
+ recording `{agent_id, worktree_path, branch, expected_base}` into the
149
+ EPHEMERAL `$QUICK_BATCH_WORKTREE_MANIFEST` above, ALSO persist the same
150
+ triple durably onto this item in `BATCH.json`:
151
+ ```bash
152
+ gsd_run quick-batch update --batch "$BATCH_ID" --updates '[{"quickId":"'"$quick_id"'","dispatchedWorktree":"'"$worktree_path"'","dispatchedBranch":"'"$branch"'","dispatchedBase":"'"$expected_base"'"}]'
153
+ ```
154
+ The ephemeral manifest is a per-process `mktemp` file (same shape
155
+ `/gsd:quick`'s own `QUICK_WORKTREE_MANIFEST` uses) — it does NOT survive
156
+ a coordinator crash/restart. A RESUMED coordinator's Step 7
157
+ (`merge-wave.md`) reads this durable BATCH.json triple as its fallback
158
+ for any item the crash-window guard above correctly did NOT re-dispatch
159
+ in the current process.
160
+
161
+ > **ORCHESTRATOR RULE — CODEX RUNTIME**: after each `Agent()` call above, wait for it to return before starting the next worktree create.
162
+
163
+ 4. **After every item dispatched this round returns:** verify
164
+ `${ITEM_DIR}/${quick_id}-SUMMARY.md` exists. If missing, the item stays
165
+ `pending`/its worktree preserved for diagnosis rather than guessing
166
+ completion — do not proceed to merge for it this round.
167
+
168
+ Continue to Step 7 once every eligible item has been dispatched (across
169
+ however many rounds backpressure required) and returned.
@@ -0,0 +1,203 @@
1
+ @~/.claude/gsd-core/references/response-language-directive.md
2
+ <purpose>
3
+ Batch several `/gsd:quick`-shaped tasks together (#3676, epic #3344, ADR-1239
4
+ "Quick-batch binding"). ONE coordinator (this workflow) owns every shared
5
+ write — `BATCH.json`, STATE.md, worktree create/merge/cleanup — and never
6
+ delegates them to a leaf. Leaves (planner/researcher/checker/executor/
7
+ verifier) return structured results only; they never invoke `/gsd:quick`,
8
+ never touch `BATCH.json`, and never write STATE.md/ROADMAP.md themselves
9
+ (single-writer invariant).
10
+
11
+ Dispatch decisions (effective concurrency, deterministic merge order, spawn
12
+ backpressure, failure/verification routing) are computed by the pure
13
+ `quick-batch-dispatch.cts` module (via the `quick-batch` CLI verbs) — this
14
+ workflow never re-derives that logic inline.
15
+ </purpose>
16
+
17
+ <required_reading>
18
+ Read all files referenced by the invoking prompt's execution_context before starting.
19
+ </required_reading>
20
+
21
+ <available_agent_types>
22
+ Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
23
+ - gsd-phase-researcher — Researches technical approaches for an item
24
+ - gsd-planner — Creates a plan for one item (`quick-batch` mode)
25
+ - gsd-plan-checker — Reviews one item's plan before execution
26
+ - gsd-executor — Executes one item's plan, commits, creates SUMMARY.md
27
+ - gsd-verifier — Verifies one item's goal achievement
28
+ </available_agent_types>
29
+
30
+ <process>
31
+ **Step 1: Parse arguments, resolve mode**
32
+
33
+ ```bash
34
+ _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
35
+ RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
36
+ ```
37
+
38
+ **If `response_language` is set:** all user-facing questions/prompts/explanations MUST be presented in `{response_language}`. Technical terms, code, file paths, and subagent prompts stay in English.
39
+
40
+ Validate `$ARGUMENTS` through the CLI's own grammar — never re-derive it inline (single source of truth: `parseQuickBatchArgs`, `src/quick-batch-dispatch.cts`). `$ARGUMENTS` is raw, attacker-influenced task text — pass it as ONE quoted argument via `--text` so the shell never word-splits or glob-expands it; `quick-batch parse-args` does the whitespace split itself, in Node, after the shell is done:
41
+
42
+ ```bash
43
+ QB_PARSE_JSON=$(gsd_run quick-batch parse-args --raw --text "$ARGUMENTS")
44
+ QB_PARSE_RC=$?
45
+ if [ $QB_PARSE_RC -ne 0 ]; then
46
+ echo "$QB_PARSE_JSON" >&2
47
+ exit 1
48
+ fi
49
+ if [[ "$QB_PARSE_JSON" == @file:* ]]; then QB_PARSE_JSON=$(cat "${QB_PARSE_JSON#@file:}"); fi
50
+ ```
51
+
52
+ Parse `$QB_PARSE_JSON` for `jobs` (`"auto"` or an integer), `validate` (bool), `research` (bool), `resume` (batch id or null). Store as `$JOBS`, `$VALIDATE_MODE`, `$RESEARCH_MODE`, `$RESUME_BATCH_ID`.
53
+
54
+ Extract the raw task-list text / `--file <path>` from `$ARGUMENTS` (everything that is not `--jobs <v>`, `--validate`, `--research`, `--resume <id>`, or `--file <path>`'s own flag pair).
55
+
56
+ ```bash
57
+ VALIDATE_PARAM=""; if [ "$VALIDATE_MODE" = true ]; then VALIDATE_PARAM="--validate"; fi
58
+ RESEARCH_PARAM=""; if [ "$RESEARCH_MODE" = true ]; then RESEARCH_PARAM="--research"; fi
59
+ INIT=$(gsd_run query init.quick-batch $VALIDATE_PARAM $RESEARCH_PARAM)
60
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
61
+ AGENT_SKILLS_PLANNER=$(gsd_run query agent-skills gsd-planner)
62
+ AGENT_SKILLS_EXECUTOR=$(gsd_run query agent-skills gsd-executor)
63
+ AGENT_SKILLS_CHECKER=$(gsd_run query agent-skills gsd-plan-checker)
64
+ AGENT_SKILLS_VERIFIER=$(gsd_run query agent-skills gsd-verifier)
65
+ AGENT_SKILLS_RESEARCHER=$(gsd_run query agent-skills gsd-phase-researcher)
66
+ ```
67
+
68
+ Parse `$INIT` for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `researcher_model`, `commit_docs`, `quick_dir`, `quick_batches_dir`, `roadmap_exists`, `planning_exists`.
69
+
70
+ <!-- #2517 model-omit-on-inherit -->
71
+
72
+ > **Model omission (#2517).** Every `Agent()` dispatch below (planner, researcher, plan-checker, executor, verifier) MUST omit the `model` parameter entirely when the value it would carry (`planner_model`, `checker_model`, `executor_model`, `verifier_model`, `researcher_model`) is `"inherit"` or empty. An empty value 404s on runtimes without native tier aliases — the default on non-Claude runtimes, where the installer writes `resolve_model_ids:"omit"`. Omitting it inherits the orchestrator's model. See @gsd-core/references/model-profile-resolution.md.
73
+
74
+ ```bash
75
+ STATE_PATH="${quick_dir%/quick}/STATE.md"
76
+ PROJECT_PATH="${quick_dir%/quick}/PROJECT.md"
77
+ USE_WORKTREES=$(gsd_run query config-get workflow.use_worktrees --raw 2>/dev/null || echo "true")
78
+ RUNTIME=$(gsd_run query config-get runtime --default claude --raw 2>/dev/null || echo "claude")
79
+ ```
80
+
81
+ **If `roadmap_exists` is false:** Error — quick-batch requires an active project with ROADMAP.md. Run `/gsd:new-project` first.
82
+
83
+ If the project uses git submodules, parse `SUBMODULE_PATHS` from `.gitmodules` exactly as `/gsd:quick` does (a fail-loud commit-time guard, applied per item at commit time — see `gsd-core/workflows/quick.md` Step 2 for the identical block, reused verbatim below):
84
+
85
+ ```bash
86
+ if [ -f .gitmodules ]; then
87
+ SUBMODULE_PATHS=$(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' 2>/dev/null | awk '{print $2}')
88
+ else
89
+ SUBMODULE_PATHS=""
90
+ fi
91
+ ```
92
+
93
+ **Resolve capacity now (#3676 design row 3-4).** `--jobs auto`/omitted uses this
94
+ value alone; `--jobs N` is capped by it (`min(taskCount, N, capacity)` — the
95
+ `quick-batch effective-concurrency` verb, called per-wave below, does the
96
+ arithmetic; this is only the raw resolve):
97
+ ```bash
98
+ CAPACITY=$(gsd_run query dispatch-capacity --raw 2>/dev/null || echo 1)
99
+ ```
100
+
101
+ **Resolve isolation now (row 6, 20-22).** Read
102
+ @gsd-core/references/dispatch-isolation-gate.md and run its `Resolve
103
+ ISOLATION`, `Single-agent dispatch sites`, and `Resolve the harness flag`
104
+ blocks in order; they set `ISOLATION`/`HARNESS_FLAG` via `query
105
+ dispatch-isolation`. `ISOLATION` gates every worktree decision below —
106
+ substitute `{harnessFlag}` in Step 6's `Agent()` with `$HARNESS_FLAG`+comma
107
+ when `ISOLATION = "harness-worktree"`, else empty.
108
+
109
+ If `USE_WORKTREES` is not `"false"`, sweep orphaned worktrees before dispatching anything (mirrors `/gsd:quick`'s own startup sweep):
110
+ ```bash
111
+ if [ "$USE_WORKTREES" != "false" ]; then
112
+ gsd_run query worktree.reap-orphans 2>/dev/null || true
113
+ fi
114
+ ```
115
+
116
+ Display banner:
117
+ ```
118
+ ### GSD ► QUICK BATCH
119
+ ◆ jobs=${JOBS} validate=${VALIDATE_MODE} research=${RESEARCH_MODE}${RESUME_BATCH_ID:+ resume=${RESUME_BATCH_ID}}
120
+ ```
121
+
122
+ ---
123
+
124
+ **Step 2: Resume or create**
125
+
126
+ If `$RESUME_BATCH_ID` is set: read and execute `gsd-core/workflows/quick-batch/steps/resume-mode.md`.
127
+ It loads the batch via `quick-batch
128
+ resume`, refuses closed on an unknown batch id or a diverged base revision,
129
+ and sets `$BATCH_ID`/`$BATCH_MANIFEST_JSON` for the steps below. Task-list
130
+ parsing and `quick-batch create` are skipped entirely.
131
+
132
+ Otherwise: read and execute `gsd-core/workflows/quick-batch/steps/batch-init.md`.
133
+ It parses the task list (inline or `--file`) and creates the
134
+ batch via `quick-batch create`, setting the same `$BATCH_ID`/
135
+ `$BATCH_MANIFEST_JSON` pair.
136
+
137
+ Either path converges on the same post-condition — continue to Step 3.
138
+
139
+ ---
140
+
141
+ <!-- gsd:section id="research-phase" when="flag:--research" -->
142
+ If `section_manifest` is `null` or `"research-phase"` is in its `included` list: read and execute `gsd-core/workflows/quick-batch/steps/research-phase.md`. Otherwise skip — do not read the file.
143
+ <!-- /gsd:section -->
144
+
145
+ ---
146
+
147
+ **Step 4: Per-DAG-layer planning**
148
+
149
+ Read and execute `gsd-core/workflows/quick-batch/steps/planner-wave.md`. It
150
+ dispatches a planner per eligible item (one `Agent()` per message, full task
151
+ catalog in every prompt), persists parsed `depends_on`/`files_modified` via
152
+ `quick-batch update` after each layer, and — when `$VALIDATE_MODE` — runs the
153
+ per-item plan-checker loop (`gsd-core/workflows/quick-batch/steps/plan-checker-loop.md`)
154
+ before advancing to the next layer.
155
+
156
+ ---
157
+
158
+ **Step 6: Worktree create + executor dispatch**
159
+
160
+ Read and execute `gsd-core/workflows/quick-batch/steps/worktree-dispatch.md`.
161
+ Worktree create/executor dispatch is serialized per item (one `git worktree
162
+ add` in flight at a time); already-created worktrees run concurrently up to
163
+ the effective MUTATING-wave concurrency.
164
+
165
+ ---
166
+
167
+ **Step 7: Deterministic merge**
168
+
169
+ Read and execute `gsd-core/workflows/quick-batch/steps/merge-wave.md`. Merges
170
+ apply strictly in the wave's original dispatch order (`quick-batch
171
+ merge-eligible`), never completion order.
172
+
173
+ ---
174
+
175
+ <!-- gsd:section id="verification-wave" when="flag:--validate" -->
176
+ If `section_manifest` is `null` or `"verification-wave"` is in its `included` list: read and execute `gsd-core/workflows/quick-batch/steps/verification-wave.md`. Otherwise skip — do not read the file.
177
+ <!-- /gsd:section -->
178
+
179
+ ---
180
+
181
+ **Step 9: Completion**
182
+
183
+ Read and execute `gsd-core/workflows/quick-batch/steps/completion.md`. Calls
184
+ `completeQuickItem` (via `quick-batch complete`) only for a genuinely
185
+ complete item, updates STATE.md, and prints the final batch report.
186
+
187
+ </process>
188
+
189
+ <success_criteria>
190
+ - [ ] `--discuss`/`--full` rejected with a usage error before any dispatch
191
+ - [ ] A malformed `--jobs` value rejected before any dispatch
192
+ - [ ] `--resume <batch-id>` skips task-list parsing, dispatches only eligible items
193
+ - [ ] Task list parsed (inline or `--file`, ≥2 items) and batch created otherwise
194
+ - [ ] Planner dispatched per eligible item per DAG layer, full task catalog in prompt, `depends_on`/`files_modified` requested ALWAYS
195
+ - [ ] (--research) Researcher dispatched per item before planning
196
+ - [ ] (--validate) Plan-checker loop runs per item after planning (≤2 iterations)
197
+ - [ ] Worktree create/merge/cleanup serialized; concurrent leaves inside already-created worktrees
198
+ - [ ] `isolation == none` forces a mutating wave's concurrency to 1; a research-only wave is unaffected
199
+ - [ ] Merges apply in deterministic wave order, never completion order
200
+ - [ ] (--validate) Verifier dispatched per item post-merge; `human_needed` never completes the item, `gaps_found` fails it without rollback or retry
201
+ - [ ] A merge_failed/scope_violation item is marked failed with the worktree PRESERVED
202
+ - [ ] `completeQuickItem` called only for genuinely complete items; STATE.md updated; artifacts committed
203
+ </success_criteria>
@@ -43,7 +43,7 @@ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-pars
43
43
  RESPONSE_LANGUAGE=$(gsd_run query config-get response_language --raw --default "" 2>/dev/null || echo "")
44
44
  ```
45
45
 
46
- **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.
46
+ **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.
47
47
 
48
48
  If `$DESCRIPTION` is empty after parsing, prompt user interactively:
49
49
 
@@ -127,9 +127,10 @@ AGENT_SKILLS_PLANNER=$(gsd_run query agent-skills gsd-planner)
127
127
  AGENT_SKILLS_EXECUTOR=$(gsd_run query agent-skills gsd-executor)
128
128
  AGENT_SKILLS_CHECKER=$(gsd_run query agent-skills gsd-plan-checker)
129
129
  AGENT_SKILLS_VERIFIER=$(gsd_run query agent-skills gsd-verifier)
130
+ AGENT_SKILLS_RESEARCHER=$(gsd_run query agent-skills gsd-phase-researcher)
130
131
  ```
131
132
 
132
- Parse JSON for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `reviewer_model`, `commit_docs`, `branch_name`, `quick_id`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`, `response_language`.
133
+ Parse JSON for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `reviewer_model`, `researcher_model`, `commit_docs`, `branch_name`, `quick_id`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`, `response_language`.
133
134
 
134
135
  `init.quick` does not emit dedicated `state_path`/`project_path` fields, so derive them from the already-absolute `quick_dir` (#2376 — files handed to a spawned subagent must resolve regardless of that subagent's own cwd):
135
136
  ```bash
@@ -286,6 +287,13 @@ If `section_manifest` is `null` or `"research-phase"` is in its `included` list:
286
287
 
287
288
  **Step 5: Spawn planner (quick mode)**
288
289
 
290
+ **Capability gate:**
291
+ ```bash
292
+ PLAN_PRE_HOOKS_JSON=$(gsd_run loop render-hooks plan:pre --raw)
293
+ ```
294
+
295
+ **Contribution dispatch (#3778):** read `PLAN_PRE_HOOKS_JSON.activeHooks` directly in context. In registry order, inject only active entries with `kind == "contribution"` and `into == "planner"` into each Quick planner prompt below, using `fragment.inline` verbatim plus resolved `configValues`. Do not paste `rendered`. Empty, inactive, incompatible, or non-planner entries inject nothing and do not error. Reuse this snapshot for revisions; do not render again.
296
+
289
297
  **If `$VALIDATE_MODE`:** Use `quick-full` mode with stricter constraints.
290
298
 
291
299
  **If NOT `$VALIDATE_MODE`:** Use standard `quick` mode.
@@ -312,6 +320,8 @@ ${AGENT_SKILLS_PLANNER}
312
320
 
313
321
  **Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, plans should account for project skill rules
314
322
 
323
+ {For each active entry in `PLAN_PRE_HOOKS_JSON` where `kind == "contribution"` and `into == "planner"` (in array order): inject the entry's `fragment.inline` verbatim here, plus its resolved `configValues` when the entry carries them. If no active planner contributions exist, omit this block entirely.}
324
+
315
325
  </planning_context>
316
326
 
317
327
  <constraints>
@@ -559,7 +569,14 @@ else
559
569
  fi
560
570
 
561
571
  if [ -n "$DIFF_BASE" ]; then
562
- CHANGED_FILES=$(git diff --name-only "${DIFF_BASE}..HEAD" -- . ':!.planning' 2>/dev/null | tr '\n' ' ')
572
+ # #4466: bound the tip at the quick task's own last commit, not HEAD --
573
+ # QUICK_COMMITS is already the complete, newest-first list of this task's
574
+ # commits, so its first line is the correct tip. An unbounded `..HEAD`
575
+ # picks up any later commit landed on the same tree in the window between
576
+ # this task's commits and this review step (worktree merge-back, a shared
577
+ # tree, another session) and folds it into this task's own review scope.
578
+ QUICK_TIP=$(echo "$QUICK_COMMITS" | head -1)
579
+ CHANGED_FILES=$(git diff --name-only "${DIFF_BASE}..${QUICK_TIP}" -- . ':!.planning' 2>/dev/null | tr '\n' ' ')
563
580
  else
564
581
  CHANGED_FILES=""
565
582
  fi
@@ -619,7 +636,7 @@ Insert after `### Blockers/Concerns` section:
619
636
  |---|-------------|------|--------|-----------|
620
637
  ```
621
638
 
622
- **Note:** If the table already exists, match its existing column format. If adding `--validate` (or `--full`) to a project that already has quick tasks without a Status column, add the Status column to the header and separator rows, and leave Status empty for the new row's predecessors.
639
+ **Note:** If the table already exists in a legacy (pre-registry) column format, first run `gsd_run quick-tasks-migrate` — the maintainer-decided repair path (#3730) that rewrites the table onto the canonical schema, losslessly bucketing unmapped columns into Description. It is a silent no-op when the table is already canonical or the section is absent, so running it before the first append of every quick task migrates exactly once and never prompts otherwise. After migration, use the canonical column format below.
623
640
 
624
641
  **7c. Append new row to table:**
625
642
 
@@ -1,3 +1,5 @@
1
+ @~/.claude/gsd-core/references/response-language-directive.md
2
+
1
3
  # Reapply Local Patches Workflow
2
4
 
3
5
  Invoked by `/gsd:update --reapply` (`commands/gsd/update.md`).
@@ -167,7 +169,7 @@ Check if a `gsd-pristine/` directory exists alongside `gsd-local-patches/`:
167
169
  ```bash
168
170
  PRISTINE_DIR="$CONFIG_DIR/gsd-pristine"
169
171
  ```
170
- If it exists, the installer saved pristine copies at install time. Use these as the baseline.
172
+ If it exists, the installer saved pristine copies at install time. Use these as the baseline. Both the deterministic verifier and the installer's preserve-check resolve each file's snapshot at its canonical path first and, when that misses, by the SHA-256 recorded in `pristine_hashes` — so a snapshot stored at a legacy path (for example, without the `gsd-core/` prefix an earlier release dropped) is still found and, on the next update, relocated to its canonical path (#4145). When no snapshot resolves under `gsd-pristine/`, the deterministic verifier additionally falls back to Option A's git-history walk itself (read-only, same recorded-hash match), which is what keeps Step 5a coverage non-zero on multi-version updates where the hash-validated regeneration had nothing it could promote (#4135).
171
173
 
172
174
  ### Option C: No baseline available (two-way fallback)
173
175
  If neither git history nor pristine snapshots are available, fall back to two-way comparison — but with **strengthened heuristics** (see Step 3).
@@ -190,6 +192,58 @@ If neither git history nor pristine snapshots are available, fall back to two-wa
190
192
 
191
193
  ## Step 4: Merge each file
192
194
 
195
+ ### Step 4 pre-flight: classify superseded customizations (#4136)
196
+
197
+ Before merging anything, run the deterministic classifier. It computes, per backed-up file,
198
+ whether the user's added lines (diff of the backup against the hash-validated pristine
199
+ baseline) are ALREADY present verbatim in the newly installed version — i.e. upstream
200
+ adopted the customization. That is the only ground on which the `Incorporated` status
201
+ below is valid. Never conclude `Incorporated` from a signature line, a heading, or general
202
+ resemblance: the classifier excludes structural/trivial lines and requires every
203
+ significant user-added line to be present, because a false `Incorporated` silently retires
204
+ a live customization.
205
+
206
+ ```bash
207
+ PRISTINE_DIR="${CONFIG_DIR}/gsd-pristine"
208
+
209
+ # Build args as a bash array so paths with spaces survive expansion intact.
210
+ CLASSIFY_ARGS=(
211
+ --patches-dir "$PATCHES_DIR"
212
+ --config-dir "$CONFIG_DIR"
213
+ )
214
+ if [ -d "$PRISTINE_DIR" ]; then
215
+ CLASSIFY_ARGS+=(--pristine-dir "$PRISTINE_DIR")
216
+ fi
217
+ CLASSIFY_ARGS+=(--classify --json)
218
+
219
+ # Informational: exits 0. The binding gate is Step 5a's post-merge verification run.
220
+ CLASSIFY_OUTPUT="$(node "${GSD_HOME}/gsd-core/bin/verify-reapply-patches.cjs" "${CLASSIFY_ARGS[@]}")"
221
+ INCORPORATED_FILES="$(echo "$CLASSIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));(d.incorporated_files||[]).forEach(f=>process.stdout.write(f+'\n'))")"
222
+ ```
223
+
224
+ **For every file in `INCORPORATED_FILES`:**
225
+
226
+ - **Do NOT merge it. Do NOT re-apply its diff.** Leave the newly installed file exactly as
227
+ shipped — the user's customization is already in it. Re-grafting the diff onto a version
228
+ that already contains it duplicates the content (both copies run; a stale graft can
229
+ contradict a richer native upstream step that replaced it).
230
+ - Report the per-file status `Incorporated` — "Already in upstream v{version}" — in the
231
+ Step 3 summary and the Step 7 report.
232
+ - No Hunk Verification Table rows are required for these files (nothing was merged); the
233
+ classifier's structured output is the evidence. If EVERY backed-up file is Incorporated,
234
+ still emit the table with a header row and a single note line naming the incorporated
235
+ files, so the Step 5b absent-table halt is not tripped. Step 5a passes these files
236
+ without special-casing — every user-added line is present in the untouched install.
237
+ - This is what ends the re-graft cycle: because the installed file stays identical to what
238
+ the release ships, the next update's hash comparison no longer flags it as modified, and
239
+ the file drops out of `gsd-local-patches/` on the next cycle.
240
+
241
+ Files NOT in `INCORPORATED_FILES` — reported `needs_merge` (with the lines still missing
242
+ from the new version) or `unknown` (no confirmable pristine baseline) — take the normal
243
+ merge paths below, unchanged. If the classifier cannot run at all (e.g. `GSD_HOME`
244
+ unset), fall back to merging every file as before; never report `Incorporated` without the
245
+ classifier's structured confirmation.
246
+
193
247
  For each file in `backup-meta.json`:
194
248
 
195
249
  1. **Read the backed-up version** (user's modified copy from `gsd-local-patches/`)
@@ -207,6 +261,9 @@ Compare the three versions to isolate changes:
207
261
  - Sections changed only by upstream → accept upstream version
208
262
  - Sections changed by both → flag as CONFLICT, show both, ask user
209
263
  - Sections unchanged by either → use new version (identical to all three)
264
+ - User-added content already present verbatim in the new version → already incorporated
265
+ upstream — do NOT re-apply it (the file-level outcome is `Incorporated` when ALL
266
+ user-added content is thus present, as determined by the Step 4 pre-flight classifier)
210
267
 
211
268
  ### Two-way merge (fallback when no baseline)
212
269
 
@@ -263,7 +320,7 @@ After writing each merged file, verify that user modifications survived the merg
263
320
  6. **Report status per file:**
264
321
  - `Merged` — user modifications applied cleanly (show summary of what was preserved)
265
322
  - `Conflict` — user reviewed and chose resolution
266
- - `Incorporated` — user's modification was already adopted upstream (only valid when pristine baseline confirms this)
323
+ - `Incorporated` — user's modification was already adopted upstream (only valid when pristine baseline confirms this — determined exclusively by the Step 4 pre-flight classifier's `incorporated_files`, never by inspection)
267
324
 
268
325
  **Never report `Skipped — no custom content`.** If a file is in the backup, it has custom content.
269
326
 
@@ -305,9 +362,27 @@ VERIFY_STATUS=$?
305
362
  DRIFTED_COUNT="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(String(d.drifted||0))")"
306
363
  DRIFTED_FILES="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));(d.drifted_files||[]).forEach(f=>process.stdout.write(f+'\n'))")"
307
364
  NO_BASELINE_COUNT="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(String(d.no_baseline||0))")"
308
- NO_BASELINE_FILES="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));(d.no_baseline_files||[]).forEach(f=>process.stdout.write(f+'\n'))")"
365
+ NO_BASELINE_FILES="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));(d.no_baseline_files||[]).forEach(f=>process.stdout.write(f+'\n'))")"
366
+ BASELINE_COVERED="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(String(d.baseline_covered||0))")"
367
+ CHECKED_COUNT="$(echo "$VERIFY_OUTPUT" | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));process.stdout.write(String(d.checked||0))")"
309
368
  ```
310
369
 
370
+ **Baseline coverage headline (#4135)** — BEFORE any pass/fail statement, print the coverage
371
+ N-of-M line. A run where 12 of 13 files were not diff-verified must never present the same way
372
+ as a fully-verified one:
373
+
374
+ ```text
375
+ Baseline coverage: {BASELINE_COVERED} of {CHECKED_COUNT} file(s) verified against a pristine
376
+ baseline ({CHECKED_COUNT - BASELINE_COVERED} unverified)
377
+ ```
378
+
379
+ The verifier also reports this on every run (JSON field `baseline_covered`; the human summary
380
+ leads with the same line). Operators who want the gate itself to fail on low coverage (cautious
381
+ environments) pass the opt-in strict flag when invoking the verifier:
382
+ `--min-baseline-coverage <fraction between 0 and 1>` — below the threshold the verifier exits
383
+ with code 3 (a real content failure still exits 1 and outranks it). Without the flag the
384
+ default advisory posture is unchanged.
385
+
311
386
  **If `NO_BASELINE_COUNT` is greater than 0**, emit an advisory warning (non-blocking — the gate still exits 0 for these files). Do NOT halt:
312
387
 
313
388
  ```text
@@ -437,6 +512,7 @@ Ask user:
437
512
  - [ ] No file classified as "no custom content" or "SKIP" — every backed-up file is definitionally modified
438
513
  - [ ] Three-way merge used when pristine baseline available (git history or gsd-pristine/)
439
514
  - [ ] User modifications identified and merged into new version
515
+ - [ ] Superseded customizations classified `Incorporated` by the deterministic pre-flight classifier (pristine-confirmed) and not re-grafted
440
516
  - [ ] Conflicts surfaced to user with both versions shown
441
517
  - [ ] Status reported for each file with summary of what was preserved
442
518
  - [ ] Post-merge verification checks each file for dropped hunks and warns if content appears missing
@@ -1,3 +1,5 @@
1
+ @~/.claude/gsd-core/references/response-language-directive.md
2
+
1
3
  <purpose>
2
4
  Remove an unstarted future phase from the project roadmap, delete its directory, renumber all subsequent phases to maintain a clean linear sequence, and commit the change. The git commit serves as the historical record of removal.
3
5
  </purpose>
@@ -19,7 +19,7 @@ INIT=$(gsd_run query init.remove-workspace "$WORKSPACE_NAME")
19
19
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
20
20
  ```
21
21
 
22
- **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.
22
+ **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.
23
23
 
24
24
  Parse JSON for: `workspace_name`, `workspace_path`, `has_manifest`, `strategy`, `repos`, `repo_count`, `dirty_repos`, `has_dirty_repos`.
25
25
 
@@ -1,3 +1,5 @@
1
+ @~/.claude/gsd-core/references/response-language-directive.md
2
+
1
3
  <trigger>
2
4
  Use this workflow when:
3
5
  - Starting a new session on an existing project
@@ -25,10 +27,12 @@ INIT=$(gsd_run query init.resume)
25
27
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
26
28
  ```
27
29
 
28
- Parse JSON for: `state_exists`, `roadmap_exists`, `project_exists`, `planning_exists`, `has_interrupted_agent`, `interrupted_agent_id`, `commit_docs`.
30
+ Parse JSON for: `state_exists`, `roadmap_exists`, `project_exists`, `planning_exists`, `requirements_exists`, `init_incomplete`, `has_interrupted_agent`, `interrupted_agent_id`, `commit_docs`.
31
+
32
+ **If `init_incomplete` is true (#4040 — interrupted bootstrap):** `.planning/` exists but initialization never finished — one or more of `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` were never created. This is NOT a STATE.md-reconstruction case (there is no project history to reconstruct from). Route to initialization recovery: resume `/gsd:new-project`, which continues from the first missing artifact and keeps the existing PROJECT.md and any already-created artifacts. Do not proceed to load_state.
29
33
 
30
34
  **If `state_exists` is true:** Proceed to load_state
31
- **If `state_exists` is false but `roadmap_exists` or `project_exists` is true:** Offer to reconstruct STATE.md
35
+ **If `state_exists` is false but `roadmap_exists` or `project_exists` is true (and `init_incomplete` is false):** Offer to reconstruct STATE.md
32
36
  **If `planning_exists` is false:** This is a new project - route to /gsd:new-project
33
37
  </step>
34
38