@opengsd/gsd-core 1.13.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 (257) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/agents/gsd-advisor-researcher.compact.md +85 -0
  4. package/agents/gsd-ai-researcher.compact.md +96 -0
  5. package/agents/gsd-assumptions-analyzer.compact.md +81 -0
  6. package/agents/gsd-code-fixer.compact.md +458 -0
  7. package/agents/gsd-code-fixer.md +5 -5
  8. package/agents/gsd-code-reviewer.compact.md +269 -0
  9. package/agents/gsd-code-reviewer.md +15 -3
  10. package/agents/gsd-codebase-mapper.compact.md +760 -0
  11. package/agents/gsd-debug-session-manager.compact.md +345 -0
  12. package/agents/gsd-doc-classifier.compact.md +192 -0
  13. package/agents/gsd-doc-synthesizer.compact.md +200 -0
  14. package/agents/gsd-doc-verifier.compact.md +143 -0
  15. package/agents/gsd-doc-writer.compact.md +440 -0
  16. package/agents/gsd-dom-verifier.compact.md +138 -0
  17. package/agents/gsd-domain-researcher.compact.md +141 -0
  18. package/agents/gsd-eval-auditor.compact.md +160 -0
  19. package/agents/gsd-eval-planner.compact.md +137 -0
  20. package/agents/gsd-framework-selector.compact.md +82 -0
  21. package/agents/gsd-integration-checker.compact.md +245 -0
  22. package/agents/gsd-intel-updater.compact.md +226 -0
  23. package/agents/gsd-mempalace-curator.compact.md +45 -0
  24. package/agents/gsd-nyquist-auditor.compact.md +179 -0
  25. package/agents/gsd-pattern-mapper.compact.md +275 -0
  26. package/agents/gsd-project-researcher.compact.md +587 -0
  27. package/agents/gsd-research-synthesizer.compact.md +212 -0
  28. package/agents/gsd-roadmapper.compact.md +454 -0
  29. package/agents/gsd-roadmapper.md +13 -0
  30. package/agents/gsd-security-auditor.compact.md +162 -0
  31. package/agents/gsd-ui-auditor.compact.md +404 -0
  32. package/agents/gsd-ui-checker.compact.md +277 -0
  33. package/agents/gsd-ui-researcher.compact.md +282 -0
  34. package/agents/gsd-user-profiler.compact.md +108 -0
  35. package/bin/install.js +206 -68
  36. package/commands/gsd/cleanup.md +1 -0
  37. package/commands/gsd/code-review.md +2 -1
  38. package/commands/gsd/complete-milestone.md +1 -0
  39. package/commands/gsd/config.md +1 -0
  40. package/commands/gsd/debug.md +1 -0
  41. package/commands/gsd/graphify.md +1 -0
  42. package/commands/gsd/health.md +1 -0
  43. package/commands/gsd/mempalace-capture.md +1 -0
  44. package/commands/gsd/mempalace-recall.md +1 -0
  45. package/commands/gsd/new-milestone.md +1 -0
  46. package/commands/gsd/new-project.md +1 -0
  47. package/commands/gsd/next.md +1 -0
  48. package/commands/gsd/pause-work.md +1 -0
  49. package/commands/gsd/phase.md +1 -0
  50. package/commands/gsd/pr-branch.md +1 -0
  51. package/commands/gsd/resume-work.md +1 -0
  52. package/commands/gsd/review-backlog.md +1 -0
  53. package/commands/gsd/settings.md +2 -1
  54. package/commands/gsd/stats.md +1 -0
  55. package/commands/gsd/thread.md +1 -0
  56. package/commands/gsd/workspace.md +1 -0
  57. package/commands/gsd/workstreams.md +1 -0
  58. package/gsd-core/bin/check-latest-version.cjs +8 -3
  59. package/gsd-core/bin/gsd-tools.cjs +338 -125
  60. package/gsd-core/bin/lib/adr-parser.cjs +1 -1
  61. package/gsd-core/bin/lib/artifacts.cjs +2 -1
  62. package/gsd-core/bin/lib/audit.cjs +39 -22
  63. package/gsd-core/bin/lib/broken-windows.cjs +168 -49
  64. package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
  65. package/gsd-core/bin/lib/capability-loader.cjs +135 -1
  66. package/gsd-core/bin/lib/capability-registry.cjs +79 -67
  67. package/gsd-core/bin/lib/capability-source.cjs +19 -2
  68. package/gsd-core/bin/lib/capability-validator.cjs +14 -1
  69. package/gsd-core/bin/lib/check-command-router.cjs +113 -36
  70. package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
  71. package/gsd-core/bin/lib/commands.cjs +650 -72
  72. package/gsd-core/bin/lib/config-loader.cjs +1 -0
  73. package/gsd-core/bin/lib/config.cjs +153 -38
  74. package/gsd-core/bin/lib/coverage.cjs +1 -1
  75. package/gsd-core/bin/lib/decisions.cjs +137 -34
  76. package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
  77. package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
  78. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +12 -1
  79. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
  80. package/gsd-core/bin/lib/init.cjs +409 -47
  81. package/gsd-core/bin/lib/install-engine.cjs +16 -3
  82. package/gsd-core/bin/lib/install-profiles.cjs +14 -0
  83. package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
  84. package/gsd-core/bin/lib/loop-resolver.cjs +50 -31
  85. package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
  86. package/gsd-core/bin/lib/milestone.cjs +19 -8
  87. package/gsd-core/bin/lib/model-resolver.cjs +101 -10
  88. package/gsd-core/bin/lib/phase-command-router.cjs +7 -1
  89. package/gsd-core/bin/lib/phase-id.cjs +161 -22
  90. package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
  91. package/gsd-core/bin/lib/phase.cjs +167 -63
  92. package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
  93. package/gsd-core/bin/lib/planning-snapshot.cjs +61 -12
  94. package/gsd-core/bin/lib/planning-workspace.cjs +50 -1
  95. package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
  96. package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
  97. package/gsd-core/bin/lib/quick-batch.cjs +1 -1
  98. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +61 -2
  99. package/gsd-core/bin/lib/research-store.cjs +11 -12
  100. package/gsd-core/bin/lib/review-lane-invocation.cjs +23 -0
  101. package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
  102. package/gsd-core/bin/lib/roadmap-parser.cjs +56 -15
  103. package/gsd-core/bin/lib/roadmap.cjs +108 -14
  104. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +27 -10
  105. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +12 -3
  106. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +13 -5
  107. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +193 -4
  108. package/gsd-core/bin/lib/security.cjs +126 -7
  109. package/gsd-core/bin/lib/state-document.cjs +130 -28
  110. package/gsd-core/bin/lib/state-md-schema.cjs +21 -14
  111. package/gsd-core/bin/lib/state-transition.cjs +142 -28
  112. package/gsd-core/bin/lib/state.cjs +223 -27
  113. package/gsd-core/bin/lib/surface.cjs +60 -2
  114. package/gsd-core/bin/lib/task-command-router.cjs +12 -6
  115. package/gsd-core/bin/lib/uat.cjs +1 -1
  116. package/gsd-core/bin/lib/update-context.cjs +30 -24
  117. package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
  118. package/gsd-core/bin/lib/verification.cjs +47 -15
  119. package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
  120. package/gsd-core/bin/lib/verify.cjs +188 -23
  121. package/gsd-core/bin/lib/workstream-inventory.cjs +1 -0
  122. package/gsd-core/bin/lib/worktree-safety.cjs +13 -7
  123. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  124. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  125. package/gsd-core/bin/verify-reapply-patches.cjs +439 -80
  126. package/gsd-core/references/compact-content-gate.md +66 -0
  127. package/gsd-core/references/loop-hook-dispatch.md +18 -0
  128. package/gsd-core/references/model-profiles.md +12 -3
  129. package/gsd-core/references/planning-config.md +3 -0
  130. package/gsd-core/references/tdd.md +5 -2
  131. package/gsd-core/references/thinking-models-planning.md +18 -2
  132. package/gsd-core/references/verification-patterns.md +17 -4
  133. package/gsd-core/references/worktree-path-safety.md +112 -2
  134. package/gsd-core/templates/README.md +7 -1
  135. package/gsd-core/templates/state.md +6 -3
  136. package/gsd-core/templates/summary.compact.md +212 -0
  137. package/gsd-core/templates/user-setup.compact.md +199 -0
  138. package/gsd-core/templates/user-setup.md +0 -9
  139. package/gsd-core/workflows/add-todo.md +3 -2
  140. package/gsd-core/workflows/autonomous.md +13 -10
  141. package/gsd-core/workflows/check-todos.md +4 -2
  142. package/gsd-core/workflows/cleanup.md +3 -1
  143. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +7 -0
  144. package/gsd-core/workflows/code-review-fix.md +3 -3
  145. package/gsd-core/workflows/code-review.md +156 -30
  146. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
  147. package/gsd-core/workflows/complete-milestone.md +39 -262
  148. package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
  149. package/gsd-core/workflows/docs-update.md +14 -155
  150. package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
  151. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +18 -3
  152. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
  153. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +7 -2
  154. package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
  155. package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
  156. package/gsd-core/workflows/execute-phase.md +53 -152
  157. package/gsd-core/workflows/execute-plan.md +20 -7
  158. package/gsd-core/workflows/help/modes/full.compact.md +398 -0
  159. package/gsd-core/workflows/help.md +1 -1
  160. package/gsd-core/workflows/map-codebase.md +50 -3
  161. package/gsd-core/workflows/new-milestone.md +54 -12
  162. package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
  163. package/gsd-core/workflows/new-project.md +32 -202
  164. package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
  165. package/gsd-core/workflows/plan-phase.md +22 -181
  166. package/gsd-core/workflows/pr-branch.md +19 -7
  167. package/gsd-core/workflows/quick.md +8 -1
  168. package/gsd-core/workflows/reapply-patches.md +77 -3
  169. package/gsd-core/workflows/settings.md +18 -5
  170. package/gsd-core/workflows/update.md +7 -5
  171. package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
  172. package/gsd-core/workflows/verify-work.md +20 -180
  173. package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
  174. package/hooks/dist/gsd-context-monitor.js +88 -15
  175. package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
  176. package/hooks/dist/gsd-secret-read-guard.js +44 -18
  177. package/hooks/dist/gsd-statusline.js +11 -7
  178. package/hooks/dist/gsd-validate-commit.sh +34 -4
  179. package/hooks/dist/gsd-worktree-path-guard.js +25 -14
  180. package/hooks/dist/gsd-write-guard.js +46 -1
  181. package/hooks/dist/lib/dispatch-identity.js +187 -0
  182. package/hooks/dist/lib/filename-classification.js +64 -0
  183. package/hooks/dist/lib/isolation-deny-reason.js +53 -1
  184. package/hooks/dist/lib/isolation-sentinel.js +58 -19
  185. package/hooks/gsd-agent-isolation-guard.js +42 -16
  186. package/hooks/gsd-context-monitor.js +88 -15
  187. package/hooks/gsd-cursor-subagent-start.js +34 -14
  188. package/hooks/gsd-secret-read-guard.js +44 -18
  189. package/hooks/gsd-statusline.js +11 -7
  190. package/hooks/gsd-validate-commit.sh +34 -4
  191. package/hooks/gsd-worktree-path-guard.js +25 -14
  192. package/hooks/gsd-write-guard.js +46 -1
  193. package/hooks/lib/dispatch-identity.js +187 -0
  194. package/hooks/lib/filename-classification.js +64 -0
  195. package/hooks/lib/isolation-deny-reason.js +53 -1
  196. package/hooks/lib/isolation-sentinel.js +58 -19
  197. package/package.json +10 -6
  198. package/scripts/benchmark-compact-content-variants.cjs +298 -0
  199. package/scripts/benchmark-compact-content.cjs +368 -0
  200. package/scripts/check-contract-drift.cjs +4 -1
  201. package/scripts/check-env.cjs +36 -8
  202. package/scripts/check-glossary-refs.cjs +25 -21
  203. package/scripts/ci-next-health.cjs +271 -0
  204. package/scripts/ci-prepare-test-scope.cjs +7 -7
  205. package/scripts/ci-test-scope.cjs +126 -20
  206. package/scripts/ci-timeout-report.cjs +1 -1
  207. package/scripts/diff-touches-shipped-paths.cjs +1 -1
  208. package/scripts/docs-guard-registry.cjs +7 -2
  209. package/scripts/gen-adr-index.cjs +8 -2
  210. package/scripts/gen-inventory-manifest.cjs +12 -0
  211. package/scripts/gen-platform-conformance-tier.cjs +557 -0
  212. package/scripts/lib/drift-scan.cjs +1 -1
  213. package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
  214. package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
  215. package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
  216. package/scripts/lib/suite-detection.cjs +32 -0
  217. package/scripts/lint-allowed-tools-parity.cjs +221 -0
  218. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +19 -2
  219. package/scripts/lint-phase-id-drift.cjs +338 -13
  220. package/scripts/lint-response-language-coverage.cjs +9 -3
  221. package/scripts/lint-source-test-name-collision.cjs +1 -1
  222. package/scripts/lint-test-file-count.allowlist.json +1 -0
  223. package/scripts/lint-vendored-deps.cjs +128 -17
  224. package/scripts/lint-workflow-shellcheck-baseline.json +85 -0
  225. package/scripts/prompt-injection-scan.sh +14 -0
  226. package/scripts/workflow-size.cjs +139 -0
  227. package/skills/gsd-cleanup/SKILL.md +1 -0
  228. package/skills/gsd-code-review/SKILL.md +2 -1
  229. package/skills/gsd-complete-milestone/SKILL.md +1 -0
  230. package/skills/gsd-config/SKILL.md +1 -0
  231. package/skills/gsd-debug/SKILL.md +1 -0
  232. package/skills/gsd-graphify/SKILL.md +1 -0
  233. package/skills/gsd-health/SKILL.md +1 -0
  234. package/skills/gsd-mempalace-capture/SKILL.md +1 -0
  235. package/skills/gsd-mempalace-recall/SKILL.md +1 -0
  236. package/skills/gsd-new-milestone/SKILL.md +1 -0
  237. package/skills/gsd-new-project/SKILL.md +1 -0
  238. package/skills/gsd-next/SKILL.md +1 -0
  239. package/skills/gsd-pause-work/SKILL.md +1 -0
  240. package/skills/gsd-phase/SKILL.md +1 -0
  241. package/skills/gsd-pr-branch/SKILL.md +1 -0
  242. package/skills/gsd-resume-work/SKILL.md +1 -0
  243. package/skills/gsd-review-backlog/SKILL.md +1 -0
  244. package/skills/gsd-settings/SKILL.md +2 -1
  245. package/skills/gsd-stats/SKILL.md +1 -0
  246. package/skills/gsd-thread/SKILL.md +1 -0
  247. package/skills/gsd-workspace/SKILL.md +1 -0
  248. package/skills/gsd-workstreams/SKILL.md +1 -0
  249. package/vscode/package.json +1 -1
  250. package/gsd-core/templates/claude-md.md +0 -145
  251. package/gsd-core/templates/codebase/concerns.md +0 -310
  252. package/gsd-core/templates/codebase/conventions.md +0 -307
  253. package/gsd-core/templates/codebase/integrations.md +0 -280
  254. package/gsd-core/templates/codebase/structure.md +0 -285
  255. package/gsd-core/templates/codebase/testing.md +0 -480
  256. package/gsd-core/templates/debug-subagent-prompt.md +0 -91
  257. package/gsd-core/templates/discovery.md +0 -146
@@ -0,0 +1,209 @@
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
+
3
+ # plan-phase — Detail
4
+
5
+ Elaboration deferred from the `plan-phase.md` spine under ADR-4139 (Compact Content mode). Read via `gsd-core/references/compact-content-gate.md` when `workflow.compact_content` is `false`. This file supplements the spine — it does not stand alone.
6
+
7
+ ## § 9a — Filesystem Fallback (Planner)
8
+
9
+ This elaborates the spine's §9a trigger condition (above) — the recovery banner and its three options.
10
+
11
+ ```bash
12
+ # #3218: this asks "did the planner write files to disk at all" — a
13
+ # planner-produced-nothing check, not outstanding-work counting — so it
14
+ # takes the PHYSICAL set (`plan_count_all`, status:superseded INCLUDED): a
15
+ # superseded plan is still a file the planner wrote, and this check must not
16
+ # read "nothing written" just because every plan happens to be superseded.
17
+ ```
18
+
19
+ The spine already computed `DISK_PLANS` (above) before reaching this elaboration.
20
+
21
+ **If `DISK_PLANS` > 0:** The planner wrote plans to disk but the Agent() return was empty or
22
+ truncated (the Windows stdio hang pattern — the subagent finished but the return never
23
+ arrived). Display:
24
+
25
+ ```text
26
+ ◆ Planner wrote {DISK_PLANS} plan(s) to disk but did not emit a PLANNING COMPLETE marker.
27
+ This is a known Windows stdio hang pattern — work is likely recoverable.
28
+
29
+ Plans found on disk:
30
+ {ls output of *-PLAN.md}
31
+ ```
32
+
33
+ Offer 3 options:
34
+ 1. **Accept plans** — treat as `## PLANNING COMPLETE` and continue through step 9 `## PLANNING COMPLETE` handling (so `--skip-verify` / `plan_checker_enabled=false` are honored — may skip to step 13 rather than step 10)
35
+ 2. **Retry planner** — re-spawn the planner with the same prompt (return to step 8)
36
+ 3. **Stop** — exit; user can re-run `/gsd:plan-phase {N}` to resume
37
+
38
+ **If `DISK_PLANS` is 0 and no marker:** The planner produced no output. Treat as
39
+ `## PLANNING INCONCLUSIVE` and handle accordingly.
40
+
41
+ ## § 9b — Handle Phase Split Recommendation
42
+
43
+ When the planner returns `## PHASE SPLIT RECOMMENDED`, it means the phase's source items exceed the context budget for full-fidelity implementation. The planner proposes groupings.
44
+
45
+ **Extract from planner return:**
46
+ - Proposed sub-phases (e.g., "17a: processing core (D-01 to D-19)", "17b: billing + config UX (D-20 to D-27)")
47
+ - Which source items (REQ-IDs, D-XX decisions, RESEARCH items) go in each sub-phase
48
+ - Why the split is necessary (context cost estimate, file count)
49
+
50
+ **Present to user:**
51
+ ```
52
+ ## Phase {X} exceeds context budget for full-fidelity implementation
53
+
54
+ The planner found {N} source items that exceed the context budget when
55
+ planned at full fidelity. Instead of reducing scope, we recommend splitting:
56
+
57
+ **Option 1: Split into sub-phases**
58
+ - Phase {X}a: {name} — {items} ({N} source items, ~{P}% context)
59
+ - Phase {X}b: {name} — {items} ({M} source items, ~{Q}% context)
60
+
61
+ **Option 2: Proceed anyway** (planner will attempt all, quality may degrade past 50% context)
62
+
63
+ **Option 3: Prioritize** — you choose which items to implement now,
64
+ rest become a follow-up phase
65
+ ```
66
+
67
+ Use AskUserQuestion with these 3 options.
68
+
69
+ **If "Split":** Use `/gsd:phase --insert` to create the sub-phases, then replan each.
70
+ **If "Proceed":** Return to planner with instruction to attempt all items at full fidelity, accepting more plans/tasks.
71
+ **If "Prioritize":** Use AskUserQuestion (multiSelect) to let user pick which items are "now" vs "later". Create CONTEXT.md for each sub-phase with the selected items.
72
+
73
+ ## § 9c — Handle Source Audit Gaps
74
+
75
+ When the planner returns `## ⚠ Source Audit: Unplanned Items Found`, it means items from REQUIREMENTS.md, RESEARCH.md, ROADMAP goal, or CONTEXT.md decisions have no corresponding plan.
76
+
77
+ **Extract from planner return:**
78
+ - Each unplanned item with its source artifact and section
79
+ - The planner's suggested options (A: add plan, B: split phase, C: defer with confirmation)
80
+
81
+ **Present each gap to user.** For each unplanned item:
82
+
83
+ ```
84
+ ## ⚠ Unplanned: {item description}
85
+
86
+ Source: {RESEARCH.md / REQUIREMENTS.md / ROADMAP goal / CONTEXT.md}
87
+ Details: {why the planner flagged this}
88
+
89
+ Options:
90
+ 1. Add a plan to cover this item (recommended)
91
+ 2. Split phase — move to a sub-phase with related items
92
+ 3. Defer — add to backlog (developer confirms this is intentional)
93
+ ```
94
+
95
+ Use AskUserQuestion for each gap (or batch if multiple gaps).
96
+
97
+ **If "Add plan":** Return to planner (step 8) with instruction to add plans covering the missing items, preserving existing plans.
98
+ **If "Split":** Use `/gsd:phase --insert` for overflow items, then replan.
99
+ **If "Defer":** Record in CONTEXT.md `## Deferred Ideas` with developer's confirmation. Proceed to step 10.
100
+
101
+ ## § 11a — Filesystem Fallback (Checker)
102
+
103
+ Fires when the checker's Agent() call comes back without either completion marker (`## VERIFICATION PASSED` / `## ISSUES FOUND`). The spine already computed `DISK_PLANS` before reaching this elaboration.
104
+
105
+ **If `DISK_PLANS` > 0:** Plans exist on disk; the checker return was empty or truncated (the
106
+ Windows stdio hang pattern — the subagent finished but the return never arrived). Display:
107
+
108
+ ```text
109
+ ◆ Checker return was empty or truncated. {DISK_PLANS} plan(s) exist on disk.
110
+ This is a known Windows stdio hang pattern — checker may have completed without returning.
111
+ ```
112
+
113
+ Offer 3 options:
114
+ 1. **Accept verification** — treat as `## VERIFICATION PASSED` and continue to step 13
115
+ 2. **Retry checker** — re-spawn the checker with the same prompt (return to step 10)
116
+ 3. **Stop** — exit; user can re-run `/gsd:plan-phase {N}` to resume
117
+
118
+ **If `DISK_PLANS` is 0:** No plans on disk — something is seriously wrong. Display error and stop.
119
+
120
+ ## § 11 thinking-partner — Thinking Partner For Architectural Tradeoffs
121
+
122
+ **Thinking partner for architectural tradeoffs (conditional):**
123
+ If `features.thinking_partner` is enabled, scan the checker's issues for architectural tradeoff keywords
124
+ ("architecture", "approach", "strategy", "pattern", "vs", "alternative"). If found:
125
+
126
+ ```
127
+ The plan-checker flagged an architectural decision point:
128
+ {issue description}
129
+
130
+ Brief analysis:
131
+ - Option A: {approach_from_plan} — {pros/cons}
132
+ - Option B: {alternative_approach} — {pros/cons}
133
+ - Recommendation: {choice} aligned with {phase_goal}
134
+
135
+ Apply this to the revision? [Yes] / [No, I'll decide]
136
+ ```
137
+
138
+ If yes: include the recommendation in the revision prompt. If no: proceed to revision loop as normal.
139
+ If thinking_partner disabled: skip this block entirely.
140
+
141
+ ## § 12.5 — Plan Bounce (Optional External Refinement)
142
+
143
+ **Skip if:** `--skip-bounce` flag, `--gaps` flag, or bounce is not activated.
144
+
145
+ **Activation:** Bounce runs when `--bounce` flag is present OR `workflow.plan_bounce` config is `true`. The `--skip-bounce` flag always wins (disables bounce even if config enables it). The `--gaps` flag also disables bounce (gap-closure mode should not modify plans externally).
146
+
147
+ **Prerequisites:** `workflow.plan_bounce_script` must be set to a valid script path. If bounce is activated but no script is configured, display warning and skip:
148
+ ```
149
+ ⚠ Plan bounce activated but no script configured.
150
+ Set workflow.plan_bounce_script to the path of your refinement script.
151
+ Skipping bounce step.
152
+ ```
153
+
154
+ **Read pass count:**
155
+ ```bash
156
+ _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
157
+ BOUNCE_PASSES=$(gsd_run query config-get workflow.plan_bounce_passes --raw 2>/dev/null || echo "2")
158
+ BOUNCE_SCRIPT=$(gsd_run query config-get workflow.plan_bounce_script --raw 2>/dev/null || true)
159
+ ```
160
+
161
+ Display banner:
162
+ ```
163
+ ### GSD ► BOUNCING PLANS (External Refinement)
164
+
165
+ Script: ${BOUNCE_SCRIPT}
166
+ Max passes: ${BOUNCE_PASSES}
167
+ ```
168
+
169
+ **For each PLAN.md file in the phase directory:**
170
+
171
+ 1. **Backup:** Copy `*-PLAN.md` to `*-PLAN.pre-bounce.md`
172
+ ```bash
173
+ cp "${PLAN_FILE}" "${PLAN_FILE%.md}.pre-bounce.md"
174
+ ```
175
+
176
+ 2. **Invoke bounce script:**
177
+ ```bash
178
+ "${BOUNCE_SCRIPT}" "${PLAN_FILE}" "${BOUNCE_PASSES}"
179
+ ```
180
+
181
+ 3. **Validate bounced plan — YAML frontmatter integrity:**
182
+ After the script returns, check that the bounced file still has valid YAML frontmatter (opening and closing `---` delimiters with parseable content between them). If the bounced plan breaks YAML frontmatter validation, restore the original from the pre-bounce.md backup and continue to the next plan:
183
+ ```
184
+ ⚠ Bounced plan ${PLAN_FILE} has broken YAML frontmatter — restoring original from pre-bounce backup.
185
+ ```
186
+
187
+ 4. **Handle script failure:** If the bounce script exits non-zero, restore the original plan from the pre-bounce.md backup and continue to the next plan:
188
+ ```
189
+ ⚠ Bounce script failed for ${PLAN_FILE} (exit code ${EXIT_CODE}) — restoring original from pre-bounce backup.
190
+ ```
191
+
192
+ **After all plans are bounced:**
193
+
194
+ 5. **Re-run plan checker on bounced plans:** Spawn gsd-plan-checker (same as step 10) on all modified plans. If a bounced plan fails the checker, restore original from its pre-bounce.md backup:
195
+ ```
196
+ ⚠ Bounced plan ${PLAN_FILE} failed checker validation — restoring original from pre-bounce backup.
197
+ ```
198
+
199
+ 6. **Commit surviving bounced plans:** If at least one plan survived both the frontmatter validation and the checker re-run, commit the changes:
200
+ ```bash
201
+ gsd_run query commit "refactor(${padded_phase}): bounce plans through external refinement" --files "${PHASE_DIR}/*-PLAN.md"
202
+ ```
203
+
204
+ Display summary:
205
+ ```
206
+ Plan bounce complete: {survived}/{total} plans refined
207
+ ```
208
+
209
+ **Clean up:** Remove all `*-PLAN.pre-bounce.md` backup files after the bounce step completes (whether plans survived or were restored).
@@ -61,6 +61,10 @@ for the plan-checker gate to be meaningful.
61
61
 
62
62
  **Do not create, rename, or switch git branches during plan-phase.** Branch identity is established at discuss-phase and is owned by the user's git workflow. A phase rename in ROADMAP.md is a plan-level change only — it does not mutate git branch names. If `phase_slug` in the init JSON differs from the current branch name, that is expected and correct; leave the branch unchanged.
63
63
 
64
+ ## 0.5. Compact Content Gate
65
+
66
+ Read and follow `gsd-core/references/compact-content-gate.md` now — it states the `workflow.compact_content` check and the resolution rule this spine defers to. When it directs a Read, read `gsd-core/workflows/plan-phase/detail/elaboration.md` in full before continuing past this point; its content elaborates on several steps below.
67
+
64
68
  ## 1. Initialize
65
69
 
66
70
  Load all context in one call (paths only to minimize orchestrator context):
@@ -124,7 +128,7 @@ In research-only mode, two modifiers control behavior when `RESEARCH.md` already
124
128
  ```bash
125
129
  RESEARCH_ONLY=false
126
130
  VIEW_ONLY=false
127
- if [[ "$ARGUMENTS" =~ --research-phase[[:space:]]+([0-9]+(\.[0-9]+)?) ]]; then
131
+ if [[ "$ARGUMENTS" =~ --research-phase[[:space:]]+([0-9]+(\.[0-9]+)*) ]]; then
128
132
  RESEARCH_ONLY=true
129
133
  PHASE="${BASH_REMATCH[1]}"
130
134
  fi
@@ -409,6 +413,7 @@ Agent(
409
413
  )
410
414
  ```
411
415
 
416
+ <!-- gsd:protected -->
412
417
  > **ORCHESTRATOR RULE — ALL RUNTIMES**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available. Never call `ScheduleWakeup` or any host wake/sleep-scheduling tool to literalize this wait (#4079) — the Agent() call returns on its own; a partial-args wake call surfaces a red validation error.
413
418
 
414
419
  ### Handle Researcher Return
@@ -675,6 +680,7 @@ Agent(
675
680
  )
676
681
  ```
677
682
 
683
+ <!-- gsd:protected -->
678
684
  > **ORCHESTRATOR RULE — ALL RUNTIMES**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available. Never call `ScheduleWakeup` or any host wake/sleep-scheduling tool to literalize this wait (#4079) — the Agent() call returns on its own; a partial-args wake call surfaces a red validation error.
679
685
 
680
686
  **Handle return:**
@@ -806,6 +812,7 @@ inherited paths: fix a mirror path, never inherit. Submodule files: check
806
812
  from within the submodule.
807
813
  </tracked_source_paths>
808
814
 
815
+ <!-- gsd:protected:start -->
809
816
  <failing_direction_contract>
810
817
  **Stated failing direction (#3172):** Every runnable `<automated>` verify command
811
818
  you write MUST be followed by a `<fails_when>` sibling naming what output
@@ -830,6 +837,7 @@ doing nothing, what in its output would tell me? If you cannot answer, fix the
830
837
  command — do not invent a statement for it.
831
838
  Rules + worked examples: @gsd-core/references/planner-failing-direction.md
832
839
  </failing_direction_contract>
840
+ <!-- gsd:protected:end -->
833
841
 
834
842
  **Project instructions:** Read ./CLAUDE.md or ./.claude/CLAUDE.md if either exists — follow project-specific guidelines
835
843
  **Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, plans should account for project skill rules
@@ -865,6 +873,7 @@ ${SPECLESS_FALLBACK_DISABLED ? `
865
873
 
866
874
  </planning_context>
867
875
 
876
+ <!-- gsd:protected:start -->
868
877
  <downstream_consumer>
869
878
  Output consumed by /gsd:execute-phase. Plans need:
870
879
  - Frontmatter (wave, depends_on, files_modified, autonomous)
@@ -876,6 +885,7 @@ Output consumed by /gsd:execute-phase. Plans need:
876
885
  - If a `-UI-SPEC.md` exists (resolved above as `UI_SPEC_PATH`) with a `## UI Considerations` section, lift it by the **identical rule** as `## Edge Coverage` above — resolved (explicit) → `must_haves.truths` string, resolved (backstop) → flat scalar `{ statement, verification: backstop }`, `unresolved` → explicit planner assumption (no new verb — ADR-550 #1278/#1154; #1867). Read it from `UI_SPEC_PATH` (the SPEC glob excludes `-UI-SPEC.md`).
877
886
  - **"Artifacts this phase produces" section (MANDATORY)** — list every symbol this phase creates: decorators, classes, functions, CLI flags, struct/dataclass fields, new file paths. The plan-review-convergence source-grounding pass reads this section to exclude newly-created symbols from drift verification; omitting it causes new symbols to be flagged for acknowledgement.
878
887
  </downstream_consumer>
888
+ <!-- gsd:protected:end -->
879
889
 
880
890
  <deep_work_rules>
881
891
  ## Anti-Shallow Execution Rules (MANDATORY)
@@ -908,6 +918,7 @@ Every task MUST include these fields — they are NOT optional:
908
918
  **Why this matters:** Executor agents work from the plan text. Vague instructions like "update the config to match production" produce shallow one-line changes. Concrete instructions like "add DATABASE_URL, set POOL_SIZE=20, add REDIS_URL, and read config/runtime.ts before editing" produce complete work without turning the planner into the executor.
909
919
  </deep_work_rules>
910
920
 
921
+ <!-- gsd:protected:start -->
911
922
  <quality_gate>
912
923
  - [ ] PLAN.md files created in phase directory
913
924
  - [ ] Each plan has valid frontmatter
@@ -923,6 +934,7 @@ Every task MUST include these fields — they are NOT optional:
923
934
  - [ ] Every UI-SPEC ## UI Considerations resolved consideration is represented in a plan's must_haves (no silent drops)
924
935
  - [ ] Every SPEC ## Prohibitions resolved item is represented in a plan's must_haves.prohibitions (no silent drops)
925
936
  </quality_gate>
937
+ <!-- gsd:protected:end -->
926
938
  ```
927
939
 
928
940
  **If `CHUNKED_MODE` is `false` (default):** Spawn the planner as a single long-lived Agent:
@@ -959,93 +971,18 @@ If `section_manifest` is `null` or `"chunked-planning-mode"` is in its `included
959
971
  **Triggered when:** Agent() returns but the return contains no recognized marker (`## PLANNING COMPLETE`, `## PHASE SPLIT RECOMMENDED`, `## ⚠ Source Audit`, `## CHECKPOINT REACHED`, `## PLANNING INCONCLUSIVE`).
960
972
 
961
973
  ```bash
962
- # #3218: this asks "did the planner write files to disk at all" — a
963
- # planner-produced-nothing check, not outstanding-work counting — so it
964
- # takes the PHYSICAL set (`plan_count_all`, status:superseded INCLUDED): a
965
- # superseded plan is still a file the planner wrote, and this check must not
966
- # read "nothing written" just because every plan happens to be superseded.
967
974
  DISK_PLANS=$(gsd_run query find-phase "${PHASE_NUMBER}" | jq -r '.plan_count_all // 0')
968
975
  ```
969
976
 
970
- **If `DISK_PLANS` > 0:** The planner wrote plans to disk but the Agent() return was empty or
971
- truncated (the Windows stdio hang pattern — the subagent finished but the return never
972
- arrived). Display:
973
-
974
- ```text
975
- ◆ Planner wrote {DISK_PLANS} plan(s) to disk but did not emit a PLANNING COMPLETE marker.
976
- This is a known Windows stdio hang pattern — work is likely recoverable.
977
-
978
- Plans found on disk:
979
- {ls output of *-PLAN.md}
980
- ```
981
-
982
- Offer 3 options:
983
- 1. **Accept plans** — treat as `## PLANNING COMPLETE` and continue through step 9 `## PLANNING COMPLETE` handling (so `--skip-verify` / `plan_checker_enabled=false` are honored — may skip to step 13 rather than step 10)
984
- 2. **Retry planner** — re-spawn the planner with the same prompt (return to step 8)
985
- 3. **Stop** — exit; user can re-run `/gsd:plan-phase {N}` to resume
986
-
987
- **If `DISK_PLANS` is 0 and no marker:** The planner produced no output. Treat as
988
- `## PLANNING INCONCLUSIVE` and handle accordingly.
977
+ If `DISK_PLANS` is greater than 0 (a known Windows stdio hang pattern — the planner wrote plans to disk but the return never arrived), offer: 1) Accept plans (treat as `## PLANNING COMPLETE`), 2) Retry planner (return to step 8), 3) Stop. If it is 0 and no marker, treat as `## PLANNING INCONCLUSIVE`. Full banner text: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 9a.
989
978
 
990
979
  ## 9b. Handle Phase Split Recommendation
991
980
 
992
- When the planner returns `## PHASE SPLIT RECOMMENDED`, it means the phase's source items exceed the context budget for full-fidelity implementation. The planner proposes groupings.
993
-
994
- **Extract from planner return:**
995
- - Proposed sub-phases (e.g., "17a: processing core (D-01 to D-19)", "17b: billing + config UX (D-20 to D-27)")
996
- - Which source items (REQ-IDs, D-XX decisions, RESEARCH items) go in each sub-phase
997
- - Why the split is necessary (context cost estimate, file count)
998
-
999
- **Present to user:**
1000
- ```
1001
- ## Phase {X} exceeds context budget for full-fidelity implementation
1002
-
1003
- The planner found {N} source items that exceed the context budget when
1004
- planned at full fidelity. Instead of reducing scope, we recommend splitting:
1005
-
1006
- **Option 1: Split into sub-phases**
1007
- - Phase {X}a: {name} — {items} ({N} source items, ~{P}% context)
1008
- - Phase {X}b: {name} — {items} ({M} source items, ~{Q}% context)
1009
-
1010
- **Option 2: Proceed anyway** (planner will attempt all, quality may degrade past 50% context)
1011
-
1012
- **Option 3: Prioritize** — you choose which items to implement now,
1013
- rest become a follow-up phase
1014
- ```
1015
-
1016
- Use AskUserQuestion with these 3 options.
1017
-
1018
- **If "Split":** Use `/gsd:phase --insert` to create the sub-phases, then replan each.
1019
- **If "Proceed":** Return to planner with instruction to attempt all items at full fidelity, accepting more plans/tasks.
1020
- **If "Prioritize":** Use AskUserQuestion (multiSelect) to let user pick which items are "now" vs "later". Create CONTEXT.md for each sub-phase with the selected items.
981
+ When the planner returns `## PHASE SPLIT RECOMMENDED`, the phase's source items exceed the context budget for full-fidelity implementation. Extract the planner's proposed sub-phase groupings and present the user three options via AskUserQuestion: Split into sub-phases (use `/gsd:phase --insert`, then replan each), Proceed anyway (return to planner accepting degraded quality), or Prioritize (AskUserQuestion multiSelect to choose now vs. later, create CONTEXT.md per sub-phase). Full banner text: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 9b.
1021
982
 
1022
983
  ## 9c. Handle Source Audit Gaps
1023
984
 
1024
- When the planner returns `## ⚠ Source Audit: Unplanned Items Found`, it means items from REQUIREMENTS.md, RESEARCH.md, ROADMAP goal, or CONTEXT.md decisions have no corresponding plan.
1025
-
1026
- **Extract from planner return:**
1027
- - Each unplanned item with its source artifact and section
1028
- - The planner's suggested options (A: add plan, B: split phase, C: defer with confirmation)
1029
-
1030
- **Present each gap to user.** For each unplanned item:
1031
-
1032
- ```
1033
- ## ⚠ Unplanned: {item description}
1034
-
1035
- Source: {RESEARCH.md / REQUIREMENTS.md / ROADMAP goal / CONTEXT.md}
1036
- Details: {why the planner flagged this}
1037
-
1038
- Options:
1039
- 1. Add a plan to cover this item (recommended)
1040
- 2. Split phase — move to a sub-phase with related items
1041
- 3. Defer — add to backlog (developer confirms this is intentional)
1042
- ```
1043
-
1044
- Use AskUserQuestion for each gap (or batch if multiple gaps).
1045
-
1046
- **If "Add plan":** Return to planner (step 8) with instruction to add plans covering the missing items, preserving existing plans.
1047
- **If "Split":** Use `/gsd:phase --insert` for overflow items, then replan.
1048
- **If "Defer":** Record in CONTEXT.md `## Deferred Ideas` with developer's confirmation. Proceed to step 10.
985
+ When the planner returns `## ⚠ Source Audit: Unplanned Items Found`, items from REQUIREMENTS.md, RESEARCH.md, ROADMAP goal, or CONTEXT.md decisions have no corresponding plan. Present each gap to the user with three options: Add a plan (return to planner, step 8), Split phase (`/gsd:phase --insert`, then replan), or Defer (record in CONTEXT.md `## Deferred Ideas` with developer confirmation, proceed to step 10). Full banner text: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 9c.
1049
986
 
1050
987
  ## 10. Spawn gsd-plan-checker Agent
1051
988
 
@@ -1150,52 +1087,17 @@ Agent(
1150
1087
  - **`stalled`:** Automatically surface 11a's recovery choice (Accept verification / Retry checker / Stop) — no manual interrupt needed.
1151
1088
  - **Empty / truncated / no recognized marker:** → Filesystem fallback (step 11a).
1152
1089
 
1153
- **Thinking partner for architectural tradeoffs (conditional):**
1154
- If `features.thinking_partner` is enabled, scan the checker's issues for architectural tradeoff keywords
1155
- ("architecture", "approach", "strategy", "pattern", "vs", "alternative"). If found:
1156
-
1157
- ```
1158
- The plan-checker flagged an architectural decision point:
1159
- {issue description}
1160
-
1161
- Brief analysis:
1162
- - Option A: {approach_from_plan} — {pros/cons}
1163
- - Option B: {alternative_approach} — {pros/cons}
1164
- - Recommendation: {choice} aligned with {phase_goal}
1165
-
1166
- Apply this to the revision? [Yes] / [No, I'll decide]
1167
- ```
1168
-
1169
- If yes: include the recommendation in the revision prompt. If no: proceed to revision loop as normal.
1170
- If thinking_partner disabled: skip this block entirely.
1090
+ **Thinking partner for architectural tradeoffs (conditional):** If `features.thinking_partner` is enabled and the checker's issues contain architectural tradeoff keywords ("architecture", "approach", "strategy", "pattern", "vs", "alternative"), present a brief Option A/B analysis with a recommendation and ask "Apply this to the revision? [Yes] / [No, I'll decide]". If disabled, skip. Full prompt template: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 11 thinking-partner.
1171
1091
 
1172
1092
  ## 11a. Filesystem Fallback (Checker)
1173
1093
 
1174
1094
  **Triggered when:** Checker Agent() returns but the return contains neither `## VERIFICATION PASSED` nor `## ISSUES FOUND`.
1175
1095
 
1176
1096
  ```bash
1177
- # #3218: this asks "did the planner write files to disk at all" — a
1178
- # planner-produced-nothing check, not outstanding-work counting — so it
1179
- # takes the PHYSICAL set (`plan_count_all`, status:superseded INCLUDED): a
1180
- # superseded plan is still a file the planner wrote, and this check must not
1181
- # read "nothing written" just because every plan happens to be superseded.
1182
1097
  DISK_PLANS=$(gsd_run query find-phase "${PHASE_NUMBER}" | jq -r '.plan_count_all // 0')
1183
1098
  ```
1184
1099
 
1185
- **If `DISK_PLANS` > 0:** Plans exist on disk; the checker return was empty or truncated (the
1186
- Windows stdio hang pattern — the subagent finished but the return never arrived). Display:
1187
-
1188
- ```text
1189
- ◆ Checker return was empty or truncated. {DISK_PLANS} plan(s) exist on disk.
1190
- This is a known Windows stdio hang pattern — checker may have completed without returning.
1191
- ```
1192
-
1193
- Offer 3 options:
1194
- 1. **Accept verification** — treat as `## VERIFICATION PASSED` and continue to step 13
1195
- 2. **Retry checker** — re-spawn the checker with the same prompt (return to step 10)
1196
- 3. **Stop** — exit; user can re-run `/gsd:plan-phase {N}` to resume
1197
-
1198
- **If `DISK_PLANS` is 0:** No plans on disk — something is seriously wrong. Display error and stop.
1100
+ If `DISK_PLANS` is greater than 0 (plans exist on disk; a known Windows stdio hang pattern), offer: 1) Accept verification (treat as `## VERIFICATION PASSED`, continue to step 13), 2) Retry checker (return to step 10), 3) Stop. If it is 0, something is seriously wrong — display error and stop. Full banner text: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 11a.
1199
1101
 
1200
1102
  ## 12. Revision Loop (Max 3 Iterations)
1201
1103
 
@@ -1353,72 +1255,9 @@ Offer: 1) Force proceed, 2) Provide guidance and retry, 3) Abandon
1353
1255
 
1354
1256
  ## 12.5. Plan Bounce (Optional External Refinement)
1355
1257
 
1356
- **Skip if:** `--skip-bounce` flag, `--gaps` flag, or bounce is not activated.
1357
-
1358
- **Activation:** Bounce runs when `--bounce` flag is present OR `workflow.plan_bounce` config is `true`. The `--skip-bounce` flag always wins (disables bounce even if config enables it). The `--gaps` flag also disables bounce (gap-closure mode should not modify plans externally).
1359
-
1360
- **Prerequisites:** `workflow.plan_bounce_script` must be set to a valid script path. If bounce is activated but no script is configured, display warning and skip:
1361
- ```
1362
- ⚠ Plan bounce activated but no script configured.
1363
- Set workflow.plan_bounce_script to the path of your refinement script.
1364
- Skipping bounce step.
1365
- ```
1366
-
1367
- **Read pass count:**
1368
- ```bash
1369
- BOUNCE_PASSES=$(gsd_run query config-get workflow.plan_bounce_passes --raw 2>/dev/null || echo "2")
1370
- BOUNCE_SCRIPT=$(gsd_run query config-get workflow.plan_bounce_script --raw 2>/dev/null || true)
1371
- ```
1372
-
1373
- Display banner:
1374
- ```
1375
- ### GSD ► BOUNCING PLANS (External Refinement)
1376
-
1377
- Script: ${BOUNCE_SCRIPT}
1378
- Max passes: ${BOUNCE_PASSES}
1379
- ```
1380
-
1381
- **For each PLAN.md file in the phase directory:**
1382
-
1383
- 1. **Backup:** Copy `*-PLAN.md` to `*-PLAN.pre-bounce.md`
1384
- ```bash
1385
- cp "${PLAN_FILE}" "${PLAN_FILE%.md}.pre-bounce.md"
1386
- ```
1387
-
1388
- 2. **Invoke bounce script:**
1389
- ```bash
1390
- "${BOUNCE_SCRIPT}" "${PLAN_FILE}" "${BOUNCE_PASSES}"
1391
- ```
1392
-
1393
- 3. **Validate bounced plan — YAML frontmatter integrity:**
1394
- After the script returns, check that the bounced file still has valid YAML frontmatter (opening and closing `---` delimiters with parseable content between them). If the bounced plan breaks YAML frontmatter validation, restore the original from the pre-bounce.md backup and continue to the next plan:
1395
- ```
1396
- ⚠ Bounced plan ${PLAN_FILE} has broken YAML frontmatter — restoring original from pre-bounce backup.
1397
- ```
1398
-
1399
- 4. **Handle script failure:** If the bounce script exits non-zero, restore the original plan from the pre-bounce.md backup and continue to the next plan:
1400
- ```
1401
- ⚠ Bounce script failed for ${PLAN_FILE} (exit code ${EXIT_CODE}) — restoring original from pre-bounce backup.
1402
- ```
1403
-
1404
- **After all plans are bounced:**
1405
-
1406
- 5. **Re-run plan checker on bounced plans:** Spawn gsd-plan-checker (same as step 10) on all modified plans. If a bounced plan fails the checker, restore original from its pre-bounce.md backup:
1407
- ```
1408
- ⚠ Bounced plan ${PLAN_FILE} failed checker validation — restoring original from pre-bounce backup.
1409
- ```
1410
-
1411
- 6. **Commit surviving bounced plans:** If at least one plan survived both the frontmatter validation and the checker re-run, commit the changes:
1412
- ```bash
1413
- gsd_run query commit "refactor(${padded_phase}): bounce plans through external refinement" --files "${PHASE_DIR}/*-PLAN.md"
1414
- ```
1415
-
1416
- Display summary:
1417
- ```
1418
- Plan bounce complete: {survived}/{total} plans refined
1419
- ```
1258
+ **Skip if:** `--skip-bounce`, `--gaps`, or bounce not activated (`--bounce` flag or `workflow.plan_bounce` config; `--skip-bounce` always wins). Requires `workflow.plan_bounce_script` set to a valid script path — warn and skip if bounce is activated with no script configured.
1420
1259
 
1421
- **Clean up:** Remove all `*-PLAN.pre-bounce.md` backup files after the bounce step completes (whether plans survived or were restored).
1260
+ For each `*-PLAN.md`: back it up to `*-PLAN.pre-bounce.md`, invoke `${BOUNCE_SCRIPT}` with the plan file and `workflow.plan_bounce_passes` (default 2), validate the result's YAML frontmatter integrity, and restore from backup on either broken frontmatter or a non-zero script exit. After all plans are bounced, re-run the plan checker (step 10) on the modified plans, restoring any that fail. Commit surviving bounced plans if at least one survived (`refactor(${padded_phase}): bounce plans through external refinement`), display a `{survived}/{total}` summary, and remove all `*-PLAN.pre-bounce.md` backups. Exact banner text, messages, and commands: `gsd-core/workflows/plan-phase/detail/elaboration.md` § 12.5.
1422
1261
 
1423
1262
  ## 13. Requirements Coverage Gate
1424
1263
 
@@ -1722,6 +1561,7 @@ Verification: {Passed | Passed with override | Skipped}
1722
1561
  Read `gsd-core/workflows/plan-phase/steps/windows-troubleshooting.md` if plan-phase freezes on Windows during agent spawning (stdio deadlocks with MCP servers, anthropics/claude-code#28126) — it covers force-kill, orphaned-node cleanup, stale task-dir cleanup, reducing the MCP server count, and the `--skip-research` fallback.
1723
1562
  </windows_troubleshooting>
1724
1563
 
1564
+ <!-- gsd:protected:start -->
1725
1565
  <success_criteria>
1726
1566
  - [ ] .planning/ directory validated
1727
1567
  - [ ] Phase validated against roadmap
@@ -1737,3 +1577,4 @@ Read `gsd-core/workflows/plan-phase/steps/windows-troubleshooting.md` if plan-ph
1737
1577
  - [ ] User sees status between agent spawns
1738
1578
  - [ ] User knows next steps
1739
1579
  </success_criteria>
1580
+ <!-- gsd:protected:end -->
@@ -278,16 +278,27 @@ For each commit, check what it touches:
278
278
  FILES=$(git diff-tree --no-commit-id --name-only -r $HASH)
279
279
  NON_PLANNING=$(echo "$FILES" | grep -c -v "^\.planning/" || true)
280
280
  STRUCTURAL=$(echo "$FILES" | grep -Ec "$STRUCTURAL_RE" || true)
281
+ PLANNING_COUNT=$(echo "$FILES" | grep -c "^\.planning/" || true)
281
282
  ```
282
283
 
283
- Classify:
284
- - **Code commits**: touch at least one non-`.planning/` file → INCLUDE (both modes)
285
- - **Mixed commits**: touch code + any planning files → INCLUDE (both modes; the planning
286
- paths are filtered out by `create_pr_branch`, not the commit)
287
- - **Structural planning commits**: touch only structural `.planning/` files → INCLUDE in
284
+ Classify, using `NON_PLANNING`, `STRUCTURAL`, and `PLANNING_COUNT` computed above — every arm's
285
+ condition is explicit and computable so no reading of it is ambiguous:
286
+ - **Code commits**: `NON_PLANNING > 0` and `PLANNING_COUNT == 0` → INCLUDE (both modes)
287
+ - **Mixed code+planning commits**: `NON_PLANNING > 0` and `PLANNING_COUNT > 0` → INCLUDE (both
288
+ modes; the planning paths are filtered out by `create_pr_branch`, not the commit)
289
+ - **Structural-only planning commits**: `NON_PLANNING == 0` and `STRUCTURAL == PLANNING_COUNT`
290
+ and `PLANNING_COUNT > 0` (every `.planning/` file touched is structural) → INCLUDE in
288
291
  **default** mode; **EXCLUDE** in strict mode, which has no structural carve-out
289
- - **Transient planning commits**: touch only `.planning/` paths that are not structural →
290
- EXCLUDE (both modes)
292
+ - **Mixed planning commits (#4447)**: `NON_PLANNING == 0` and `STRUCTURAL > 0` and
293
+ `STRUCTURAL < PLANNING_COUNT` (some but not all `.planning/` files touched are structural —
294
+ the rest are transient and/or the "other" bucket, e.g. `config.json`/`intel/`) → INCLUDE in
295
+ **default** mode (the transient-dir subset of the non-structural paths is filtered out by
296
+ `create_pr_branch`'s universal per-commit filter exactly as for a mixed code+planning commit;
297
+ any "other" non-structural, non-transient path — `config.json`, `intel/`, etc. — is simply
298
+ preserved, same as default mode already does for such paths on any commit); **EXCLUDE** in
299
+ strict mode
300
+ - **Transient-only planning commits**: `NON_PLANNING == 0` and `STRUCTURAL == 0` and
301
+ `PLANNING_COUNT > 0` → EXCLUDE (both modes)
291
302
 
292
303
  In strict mode this collapses to a single rule: `NON_PLANNING > 0` → INCLUDE, else EXCLUDE.
293
304
 
@@ -297,6 +308,7 @@ Commits to include: {N} (code changes{, + structural planning — default mode o
297
308
  Commits to exclude: {N} (planning-only)
298
309
  Mixed commits: {N} (code + planning — included, planning paths filtered)
299
310
  Structural planning commits: {N} ({included|excluded — strict mode})
311
+ Mixed planning commits: {N} ({included — structural + transient/other, planning paths filtered|excluded — strict mode})
300
312
  ```
301
313
  </step>
302
314
 
@@ -569,7 +569,14 @@ else
569
569
  fi
570
570
 
571
571
  if [ -n "$DIFF_BASE" ]; then
572
- 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' ' ')
573
580
  else
574
581
  CHANGED_FILES=""
575
582
  fi