@opengsd/gsd-core 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +85 -5
  4. package/README.ja-JP.md +3 -3
  5. package/README.ko-KR.md +3 -3
  6. package/README.pt-BR.md +3 -3
  7. package/README.zh-CN.md +3 -3
  8. package/agents/gsd-code-fixer.compact.md +7 -6
  9. package/agents/gsd-code-fixer.md +9 -8
  10. package/agents/gsd-code-reviewer.compact.md +5 -3
  11. package/agents/gsd-code-reviewer.md +8 -6
  12. package/agents/gsd-debug-session-manager.compact.md +17 -2
  13. package/agents/gsd-debug-session-manager.md +17 -2
  14. package/agents/gsd-debugger.md +3 -3
  15. package/agents/gsd-eval-auditor.compact.md +1 -1
  16. package/agents/gsd-eval-auditor.md +1 -1
  17. package/agents/gsd-executor.md +17 -12
  18. package/agents/gsd-intel-updater.compact.md +1 -1
  19. package/agents/gsd-intel-updater.md +1 -1
  20. package/agents/gsd-mempalace-curator.md +2 -2
  21. package/agents/gsd-phase-researcher.md +19 -11
  22. package/agents/gsd-plan-checker.md +15 -9
  23. package/agents/gsd-planner.md +15 -11
  24. package/agents/gsd-project-researcher.compact.md +1 -1
  25. package/agents/gsd-project-researcher.md +1 -1
  26. package/agents/gsd-research-synthesizer.compact.md +1 -1
  27. package/agents/gsd-research-synthesizer.md +1 -1
  28. package/agents/gsd-ui-auditor.compact.md +21 -30
  29. package/agents/gsd-ui-auditor.md +166 -37
  30. package/agents/gsd-ui-researcher.compact.md +1 -1
  31. package/agents/gsd-ui-researcher.md +1 -1
  32. package/agents/gsd-verifier.md +37 -14
  33. package/bin/install.js +764 -287
  34. package/commands/gsd/add-tests.md +6 -1
  35. package/commands/gsd/ai-integration-phase.md +6 -1
  36. package/commands/gsd/audit-fix.md +5 -0
  37. package/commands/gsd/audit-milestone.md +6 -1
  38. package/commands/gsd/autonomous.md +7 -2
  39. package/commands/gsd/capture.md +9 -5
  40. package/commands/gsd/code-review.md +7 -2
  41. package/commands/gsd/complete-milestone.md +4 -0
  42. package/commands/gsd/config.md +7 -3
  43. package/commands/gsd/debug.md +11 -7
  44. package/commands/gsd/discuss-phase.md +7 -3
  45. package/commands/gsd/docs-update.md +12 -7
  46. package/commands/gsd/eval-review.md +6 -1
  47. package/commands/gsd/execute-phase.md +12 -7
  48. package/commands/gsd/extract-learnings.md +5 -0
  49. package/commands/gsd/fast.md +4 -0
  50. package/commands/gsd/forensics.md +5 -1
  51. package/commands/gsd/graphify.md +10 -6
  52. package/commands/gsd/health.md +5 -0
  53. package/commands/gsd/help.md +7 -2
  54. package/commands/gsd/import.md +7 -3
  55. package/commands/gsd/inbox.md +5 -0
  56. package/commands/gsd/ingest-docs.md +5 -1
  57. package/commands/gsd/manager.md +6 -1
  58. package/commands/gsd/map-codebase.md +7 -3
  59. package/commands/gsd/mempalace-capture.md +12 -4
  60. package/commands/gsd/mempalace-recall.md +5 -1
  61. package/commands/gsd/milestone-summary.md +5 -1
  62. package/commands/gsd/mvp-phase.md +8 -3
  63. package/commands/gsd/new-milestone.md +6 -1
  64. package/commands/gsd/new-project.md +5 -0
  65. package/commands/gsd/next.md +6 -1
  66. package/commands/gsd/ns-context.md +4 -0
  67. package/commands/gsd/ns-ideate.md +4 -0
  68. package/commands/gsd/ns-manage.md +4 -0
  69. package/commands/gsd/ns-project.md +4 -0
  70. package/commands/gsd/ns-review.md +4 -0
  71. package/commands/gsd/ns-workflow.md +4 -0
  72. package/commands/gsd/onboard.md +6 -1
  73. package/commands/gsd/pause-work.md +5 -1
  74. package/commands/gsd/phase.md +8 -4
  75. package/commands/gsd/plan-phase.md +6 -1
  76. package/commands/gsd/plan-review-convergence.md +11 -7
  77. package/commands/gsd/pr-branch.md +4 -0
  78. package/commands/gsd/profile-user.md +5 -1
  79. package/commands/gsd/progress.md +7 -2
  80. package/commands/gsd/quick-batch.md +21 -9
  81. package/commands/gsd/quick.md +12 -7
  82. package/commands/gsd/review.md +7 -4
  83. package/commands/gsd/secure-phase.md +6 -1
  84. package/commands/gsd/ship.md +5 -0
  85. package/commands/gsd/sketch.md +7 -2
  86. package/commands/gsd/spec-phase.md +5 -1
  87. package/commands/gsd/spike.md +8 -3
  88. package/commands/gsd/surface.md +5 -1
  89. package/commands/gsd/thread.md +4 -0
  90. package/commands/gsd/ui-phase.md +6 -1
  91. package/commands/gsd/ui-review.md +6 -1
  92. package/commands/gsd/ultraplan-phase.md +5 -1
  93. package/commands/gsd/undo.md +5 -1
  94. package/commands/gsd/update.md +6 -2
  95. package/commands/gsd/validate-phase.md +6 -1
  96. package/commands/gsd/verify-work.md +6 -1
  97. package/commands/gsd/workspace.md +7 -3
  98. package/gsd-core/bin/gsd-tools.cjs +477 -78
  99. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  100. package/gsd-core/bin/lib/adr-parser.cjs +3 -1
  101. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  102. package/gsd-core/bin/lib/audit.cjs +144 -42
  103. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  104. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  105. package/gsd-core/bin/lib/capability-registry.cjs +197 -222
  106. package/gsd-core/bin/lib/capability-validator.cjs +16 -1
  107. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  108. package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
  109. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  110. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  111. package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
  112. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  113. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  114. package/gsd-core/bin/lib/commands.cjs +343 -207
  115. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  116. package/gsd-core/bin/lib/config-loader.cjs +65 -4
  117. package/gsd-core/bin/lib/config.cjs +76 -19
  118. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  119. package/gsd-core/bin/lib/coverage.cjs +4 -8
  120. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  121. package/gsd-core/bin/lib/decisions.cjs +30 -14
  122. package/gsd-core/bin/lib/drift.cjs +177 -42
  123. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  124. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  125. package/gsd-core/bin/lib/frontmatter.cjs +426 -234
  126. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  127. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  128. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  129. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  130. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  131. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  132. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  133. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  134. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  135. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  136. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  137. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  138. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  139. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  140. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  141. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  142. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  143. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  144. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  145. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  146. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  147. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  148. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  149. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  150. package/gsd-core/bin/lib/graphify.cjs +10 -2
  151. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  152. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  153. package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
  154. package/gsd-core/bin/lib/init.cjs +364 -132
  155. package/gsd-core/bin/lib/install-engine.cjs +30 -33
  156. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  157. package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
  158. package/gsd-core/bin/lib/io.cjs +122 -3
  159. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  160. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  161. package/gsd-core/bin/lib/milestone.cjs +37 -6
  162. package/gsd-core/bin/lib/model-resolver.cjs +171 -62
  163. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  164. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  165. package/gsd-core/bin/lib/pattern.cjs +10 -0
  166. package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
  167. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  168. package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
  169. package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
  170. package/gsd-core/bin/lib/phase-id.cjs +110 -8
  171. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  172. package/gsd-core/bin/lib/phase-locator.cjs +29 -10
  173. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  174. package/gsd-core/bin/lib/phase.cjs +489 -88
  175. package/gsd-core/bin/lib/plan-document.cjs +142 -20
  176. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  177. package/gsd-core/bin/lib/planning-document.cjs +692 -0
  178. package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
  179. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  180. package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
  181. package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
  182. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  183. package/gsd-core/bin/lib/probe-core.cjs +7 -1
  184. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  185. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  186. package/gsd-core/bin/lib/project-root.cjs +41 -2
  187. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  188. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  189. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  190. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  191. package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
  192. package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
  193. package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
  194. package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
  195. package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
  196. package/gsd-core/bin/lib/roadmap.cjs +405 -88
  197. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
  198. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
  199. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  200. package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
  201. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
  202. package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
  203. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  204. package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
  205. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  206. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  207. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  208. package/gsd-core/bin/lib/state-document.cjs +100 -22
  209. package/gsd-core/bin/lib/state-transition.cjs +39 -2
  210. package/gsd-core/bin/lib/state.cjs +256 -105
  211. package/gsd-core/bin/lib/surface.cjs +19 -2
  212. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
  213. package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
  214. package/gsd-core/bin/lib/uat.cjs +432 -7
  215. package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
  216. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
  217. package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
  218. package/gsd-core/bin/lib/vendor/README.md +31 -9
  219. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  220. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  221. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  222. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  223. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  224. package/gsd-core/bin/lib/verification.cjs +1378 -274
  225. package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
  226. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  227. package/gsd-core/bin/lib/verify.cjs +357 -531
  228. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  229. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  230. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  231. package/gsd-core/bin/lib/workstream.cjs +11 -2
  232. package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
  233. package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
  234. package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
  235. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  236. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  237. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  238. package/gsd-core/references/checkpoints.md +5 -3
  239. package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
  240. package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
  241. package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
  242. package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
  243. package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
  244. package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
  245. package/gsd-core/references/edge-probe.md +195 -21
  246. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  247. package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
  248. package/gsd-core/references/execute-phase-response-language.md +1 -1
  249. package/gsd-core/references/execute-phase-wave-guard.md +22 -11
  250. package/gsd-core/references/gsd-run-resolver.md +1 -1
  251. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  252. package/gsd-core/references/model-profiles.md +1 -1
  253. package/gsd-core/references/offer-next.md +1 -1
  254. package/gsd-core/references/phase-argument-parsing.md +9 -7
  255. package/gsd-core/references/phase-id-convention.md +28 -0
  256. package/gsd-core/references/planner-gap-closure.md +2 -0
  257. package/gsd-core/references/planner-load-graph-context.md +24 -13
  258. package/gsd-core/references/planner-verify-command-grounding.md +14 -0
  259. package/gsd-core/references/planning-config.md +12 -3
  260. package/gsd-core/references/spidr-splitting.md +1 -1
  261. package/gsd-core/references/tdd.md +37 -8
  262. package/gsd-core/references/ui-consideration-probe.md +10 -5
  263. package/gsd-core/references/verifier-phase-gates.md +5 -2
  264. package/gsd-core/references/verify-command-path-resolvability.md +10 -2
  265. package/gsd-core/references/verify-mvp-mode.md +2 -2
  266. package/gsd-core/references/workstream-flag.md +33 -3
  267. package/gsd-core/references/worktree-path-safety.md +321 -0
  268. package/gsd-core/templates/README.md +1 -1
  269. package/gsd-core/templates/UAT.md +17 -1
  270. package/gsd-core/templates/config.json +2 -11
  271. package/gsd-core/templates/verification-report.md +1 -1
  272. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  273. package/gsd-core/workflows/add-backlog.md +1 -1
  274. package/gsd-core/workflows/add-phase.md +8 -7
  275. package/gsd-core/workflows/add-tests.md +4 -3
  276. package/gsd-core/workflows/add-todo.md +6 -5
  277. package/gsd-core/workflows/ai-integration-phase.md +13 -4
  278. package/gsd-core/workflows/audit-fix.md +1 -1
  279. package/gsd-core/workflows/audit-milestone.md +4 -3
  280. package/gsd-core/workflows/audit-uat.md +1 -1
  281. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
  282. package/gsd-core/workflows/autonomous.md +43 -23
  283. package/gsd-core/workflows/check-todos.md +7 -6
  284. package/gsd-core/workflows/cleanup.md +2 -2
  285. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
  286. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  287. package/gsd-core/workflows/code-review-fix.md +112 -25
  288. package/gsd-core/workflows/code-review.md +146 -135
  289. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  290. package/gsd-core/workflows/complete-milestone.md +13 -8
  291. package/gsd-core/workflows/debug.md +32 -7
  292. package/gsd-core/workflows/diagnose-issues.md +3 -2
  293. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  294. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  295. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  296. package/gsd-core/workflows/discuss-phase.md +4 -3
  297. package/gsd-core/workflows/do.md +2 -2
  298. package/gsd-core/workflows/docs-update.md +6 -5
  299. package/gsd-core/workflows/edit-phase.md +4 -3
  300. package/gsd-core/workflows/eval-review.md +14 -5
  301. package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
  302. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
  303. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  304. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  305. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
  306. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  307. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  308. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  309. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  310. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
  311. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  312. package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
  313. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  314. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  315. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  316. package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
  317. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  318. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  319. package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
  320. package/gsd-core/workflows/execute-phase.md +96 -178
  321. package/gsd-core/workflows/execute-plan.md +18 -23
  322. package/gsd-core/workflows/explore.md +4 -4
  323. package/gsd-core/workflows/extract-learnings.md +4 -2
  324. package/gsd-core/workflows/fast.md +1 -1
  325. package/gsd-core/workflows/forensics.md +1 -1
  326. package/gsd-core/workflows/graduation.md +1 -1
  327. package/gsd-core/workflows/health.md +3 -2
  328. package/gsd-core/workflows/help/modes/full.compact.md +3 -3
  329. package/gsd-core/workflows/help/modes/full.md +5 -5
  330. package/gsd-core/workflows/help/modes/topic.md +15 -5
  331. package/gsd-core/workflows/import.md +4 -3
  332. package/gsd-core/workflows/inbox.md +2 -2
  333. package/gsd-core/workflows/ingest-docs.md +3 -3
  334. package/gsd-core/workflows/insert-phase.md +4 -3
  335. package/gsd-core/workflows/list-seeds.md +1 -1
  336. package/gsd-core/workflows/list-workspaces.md +1 -1
  337. package/gsd-core/workflows/manager.md +6 -4
  338. package/gsd-core/workflows/map-codebase.md +5 -4
  339. package/gsd-core/workflows/milestone-summary.md +3 -2
  340. package/gsd-core/workflows/mvp-phase.md +14 -14
  341. package/gsd-core/workflows/new-milestone.md +11 -11
  342. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
  343. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
  344. package/gsd-core/workflows/new-project.md +7 -7
  345. package/gsd-core/workflows/new-workspace.md +2 -2
  346. package/gsd-core/workflows/next.md +1 -1
  347. package/gsd-core/workflows/note.md +1 -1
  348. package/gsd-core/workflows/onboard.md +1 -1
  349. package/gsd-core/workflows/pause-work.md +2 -2
  350. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  351. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
  352. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  353. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  354. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
  355. package/gsd-core/workflows/plan-phase.md +50 -24
  356. package/gsd-core/workflows/plan-review-convergence.md +21 -5
  357. package/gsd-core/workflows/plant-seed.md +62 -20
  358. package/gsd-core/workflows/pr-branch.md +113 -13
  359. package/gsd-core/workflows/profile-user.md +2 -2
  360. package/gsd-core/workflows/progress.md +19 -49
  361. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
  362. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  363. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  364. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  365. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  366. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  367. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  368. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  369. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  370. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  371. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  372. package/gsd-core/workflows/quick-batch.md +15 -10
  373. package/gsd-core/workflows/quick.md +62 -39
  374. package/gsd-core/workflows/reapply-patches.md +9 -3
  375. package/gsd-core/workflows/remove-phase.md +3 -2
  376. package/gsd-core/workflows/remove-workspace.md +2 -2
  377. package/gsd-core/workflows/resume-project.md +3 -2
  378. package/gsd-core/workflows/review.md +33 -17
  379. package/gsd-core/workflows/scan.md +3 -2
  380. package/gsd-core/workflows/secure-phase.md +13 -13
  381. package/gsd-core/workflows/settings-advanced.md +30 -10
  382. package/gsd-core/workflows/settings-integrations.md +2 -3
  383. package/gsd-core/workflows/settings.md +4 -4
  384. package/gsd-core/workflows/ship.md +14 -13
  385. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  386. package/gsd-core/workflows/sketch.md +1 -1
  387. package/gsd-core/workflows/smart-entry.md +2 -2
  388. package/gsd-core/workflows/spec-phase.md +15 -5
  389. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  390. package/gsd-core/workflows/spike.md +1 -1
  391. package/gsd-core/workflows/stats.md +1 -1
  392. package/gsd-core/workflows/sync-skills.md +5 -5
  393. package/gsd-core/workflows/thread.md +2 -2
  394. package/gsd-core/workflows/transition.md +13 -23
  395. package/gsd-core/workflows/ui-phase.md +48 -11
  396. package/gsd-core/workflows/ui-review.md +21 -6
  397. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  398. package/gsd-core/workflows/undo.md +339 -20
  399. package/gsd-core/workflows/update.md +7 -7
  400. package/gsd-core/workflows/validate-phase.md +12 -13
  401. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  402. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  403. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  404. package/gsd-core/workflows/verify-work.md +129 -55
  405. package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
  406. package/hooks/dist/gsd-check-update-worker.js +8 -0
  407. package/hooks/dist/gsd-check-update.js +8 -0
  408. package/hooks/dist/gsd-context-monitor.js +31 -8
  409. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  410. package/hooks/dist/gsd-secret-read-guard.js +161 -4
  411. package/hooks/dist/gsd-statusline.js +85 -20
  412. package/hooks/dist/gsd-update-banner.js +8 -0
  413. package/hooks/dist/gsd-validate-commit.sh +63 -4
  414. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  415. package/hooks/dist/gsd-workflow-guard.js +5 -4
  416. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  417. package/hooks/dist/lib/cli-exit.js +12 -0
  418. package/hooks/dist/lib/git-probe.js +17 -1
  419. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  420. package/hooks/gsd-agent-isolation-guard.js +32 -0
  421. package/hooks/gsd-check-update-worker.js +8 -0
  422. package/hooks/gsd-check-update.js +8 -0
  423. package/hooks/gsd-context-monitor.js +31 -8
  424. package/hooks/gsd-cursor-subagent-start.js +8 -0
  425. package/hooks/gsd-secret-read-guard.js +161 -4
  426. package/hooks/gsd-statusline.js +85 -20
  427. package/hooks/gsd-update-banner.js +8 -0
  428. package/hooks/gsd-validate-commit.sh +63 -4
  429. package/hooks/gsd-windsurf-pre-write.js +11 -2
  430. package/hooks/gsd-workflow-guard.js +5 -4
  431. package/hooks/gsd-worktree-path-guard.js +6 -2
  432. package/hooks/hooks.json +5 -5
  433. package/hooks/lib/cli-exit.js +12 -0
  434. package/hooks/lib/git-probe.js +17 -1
  435. package/hooks/lib/isolation-sentinel.js +2 -2
  436. package/package.json +22 -4
  437. package/scripts/build-hooks.js +15 -6
  438. package/scripts/changeset/parse.cjs +52 -4
  439. package/scripts/check-contract-drift.cjs +127 -11
  440. package/scripts/ci-timeout-report.cjs +770 -4
  441. package/scripts/command-contract-helpers.cjs +15 -8
  442. package/scripts/docs-guard-registry.cjs +34 -0
  443. package/scripts/gen-features.cjs +13 -8
  444. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  445. package/scripts/gen-loop-host-contract.cjs +79 -1
  446. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  447. package/scripts/gen-plugin-skills.cjs +87 -1
  448. package/scripts/gen-research-agents.cjs +24 -31
  449. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  450. package/scripts/gen-test-timings.cjs +32 -7
  451. package/scripts/lib/cli-exit.cjs +12 -0
  452. package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
  453. package/scripts/lib/ndjson-reporter.cjs +31 -5
  454. package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
  455. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  456. package/scripts/lib/vendor-bundle.cjs +59 -0
  457. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  458. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  459. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  460. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  461. package/scripts/lint-descriptions.cjs +7 -3
  462. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
  463. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  464. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  465. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  466. package/scripts/lint-phase-arg-assignment.cjs +257 -0
  467. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  468. package/scripts/lint-phase-id-drift.cjs +319 -5
  469. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  470. package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
  471. package/scripts/lint-response-language-coverage.cjs +3 -0
  472. package/scripts/lint-retired-runtime-name.cjs +619 -0
  473. package/scripts/lint-skill-deps.cjs +7 -3
  474. package/scripts/lint-state-write-path-drift.cjs +93 -0
  475. package/scripts/lint-test-file-count.allowlist.json +38 -9
  476. package/scripts/lint-test-file-count.cjs +34 -1
  477. package/scripts/lint-vendored-deps.cjs +41 -5
  478. package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
  479. package/scripts/mutation-matrix.cjs +50 -5
  480. package/scripts/prompt-injection-scan.sh +4 -0
  481. package/scripts/release-tarball-smoke.cjs +194 -1
  482. package/scripts/require-issue-link-policy.cjs +6 -2
  483. package/scripts/sync-runtime-launcher.cjs +184 -2
  484. package/scripts/verify-npm-publish.cjs +76 -20
  485. package/skills/gsd-add-tests/SKILL.md +6 -1
  486. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  487. package/skills/gsd-audit-fix/SKILL.md +5 -0
  488. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  489. package/skills/gsd-autonomous/SKILL.md +7 -2
  490. package/skills/gsd-capture/SKILL.md +9 -5
  491. package/skills/gsd-code-review/SKILL.md +7 -2
  492. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  493. package/skills/gsd-config/SKILL.md +8 -4
  494. package/skills/gsd-debug/SKILL.md +11 -7
  495. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  496. package/skills/gsd-docs-update/SKILL.md +12 -7
  497. package/skills/gsd-eval-review/SKILL.md +6 -1
  498. package/skills/gsd-execute-phase/SKILL.md +12 -7
  499. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  500. package/skills/gsd-fast/SKILL.md +4 -0
  501. package/skills/gsd-forensics/SKILL.md +5 -1
  502. package/skills/gsd-graphify/SKILL.md +10 -6
  503. package/skills/gsd-health/SKILL.md +5 -0
  504. package/skills/gsd-help/SKILL.md +7 -2
  505. package/skills/gsd-import/SKILL.md +7 -3
  506. package/skills/gsd-inbox/SKILL.md +5 -0
  507. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  508. package/skills/gsd-manager/SKILL.md +6 -1
  509. package/skills/gsd-map-codebase/SKILL.md +7 -3
  510. package/skills/gsd-mempalace-capture/SKILL.md +12 -4
  511. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  512. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  513. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  514. package/skills/gsd-new-milestone/SKILL.md +6 -1
  515. package/skills/gsd-new-project/SKILL.md +5 -0
  516. package/skills/gsd-next/SKILL.md +6 -1
  517. package/skills/gsd-ns-context/SKILL.md +4 -0
  518. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  519. package/skills/gsd-ns-manage/SKILL.md +4 -0
  520. package/skills/gsd-ns-project/SKILL.md +4 -0
  521. package/skills/gsd-ns-review/SKILL.md +4 -0
  522. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  523. package/skills/gsd-onboard/SKILL.md +6 -1
  524. package/skills/gsd-pause-work/SKILL.md +5 -1
  525. package/skills/gsd-phase/SKILL.md +8 -4
  526. package/skills/gsd-plan-phase/SKILL.md +6 -1
  527. package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
  528. package/skills/gsd-pr-branch/SKILL.md +4 -0
  529. package/skills/gsd-profile-user/SKILL.md +5 -1
  530. package/skills/gsd-progress/SKILL.md +7 -2
  531. package/skills/gsd-quick/SKILL.md +16 -10
  532. package/skills/gsd-quick-batch/SKILL.md +21 -9
  533. package/skills/gsd-review/SKILL.md +7 -4
  534. package/skills/gsd-review-backlog/SKILL.md +3 -2
  535. package/skills/gsd-secure-phase/SKILL.md +6 -1
  536. package/skills/gsd-ship/SKILL.md +5 -0
  537. package/skills/gsd-sketch/SKILL.md +7 -2
  538. package/skills/gsd-spec-phase/SKILL.md +5 -1
  539. package/skills/gsd-spike/SKILL.md +8 -3
  540. package/skills/gsd-surface/SKILL.md +5 -1
  541. package/skills/gsd-thread/SKILL.md +4 -0
  542. package/skills/gsd-ui-phase/SKILL.md +6 -1
  543. package/skills/gsd-ui-review/SKILL.md +6 -1
  544. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  545. package/skills/gsd-undo/SKILL.md +5 -1
  546. package/skills/gsd-update/SKILL.md +6 -2
  547. package/skills/gsd-validate-phase/SKILL.md +6 -1
  548. package/skills/gsd-verify-work/SKILL.md +6 -1
  549. package/skills/gsd-workspace/SKILL.md +7 -3
  550. package/skills/gsd-workstreams/SKILL.md +6 -6
  551. package/vscode/package.json +1 -1
@@ -21,22 +21,23 @@
21
21
  const fs = require('fs');
22
22
  const path = require('path');
23
23
  const os = require('os');
24
+ const capabilityRegistry = require('./capability-registry.cjs');
25
+ const { hostBehaviorsFor } = require('./runtime-name-policy.cjs');
26
+ const { resolveConfigHomeFromDescriptor } = require('./runtime-homes.cjs');
27
+ const { resolveActiveRuntime } = require('./runtime-slash.cjs');
24
28
 
25
29
  /**
26
- * Runtimes whose agent config is static frontmatter/TOML baked at install time.
27
- * MUST stay in sync with the bake paths in bin/install.js. The parity test in
28
- * tests/stale-bake-guard.test.cjs asserts this matches the runtimes that
29
- * actually emit a baked model: line id #2256 (opencode), #49/#2256 (codex),
30
- * and #2093 (kilo).
30
+ * Runtimes whose agent config is static frontmatter/TOML baked at install time,
31
+ * DERIVED from the runtime descriptors (`hostBehaviors.bakesStaticAgentModel`,
32
+ * #5169) instead of a hand-kept list: line id #2256 (opencode), #49/#2256
33
+ * (codex), and #2093 (kilo) declare it, and a new baking runtime does too.
31
34
  */
32
- const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(['codex', 'kilo', 'opencode']);
35
+ const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(
36
+ Object.keys(capabilityRegistry.runtimes)
37
+ .filter((id) => hostBehaviorsFor(id).bakesStaticAgentModel === true)
38
+ .sort(),
39
+ );
33
40
 
34
- /** Per-runtime `gsd install` flag, for the remediation hint in the warning. */
35
- const INSTALL_FLAG_BY_RUNTIME = Object.freeze({
36
- codex: '--codex',
37
- opencode: '--opencode',
38
- kilo: '--kilo',
39
- });
40
41
 
41
42
  const _warnedKeys = new Set();
42
43
 
@@ -64,7 +65,7 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
64
65
  const signal = detectStaleBake({ runtime, configMtimeMs, agentMtimeMs });
65
66
  if (!signal) return '';
66
67
  const configDate = new Date(configMtimeMs).toISOString();
67
- const installFlag = INSTALL_FLAG_BY_RUNTIME[runtime] || `--${runtime}`;
68
+ const installFlag = `--${runtime}`;
68
69
  return [
69
70
  `gsd: model config in ${configPath} changed since agents were last baked (${configDate}).`,
70
71
  ` Static-frontmatter runtime '${runtime}' ignores the new model_overrides`,
@@ -74,44 +75,27 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
74
75
  }
75
76
 
76
77
  /**
77
- * Pure: resolve the active runtime id from a parsed config object.
78
- * Returns the runtime string, or `'claude'` when unset (the spawn-time default
79
- * for which the guard is a no-op).
78
+ * Resolve the active runtime id for the guard: the SAME chain every consumer of
79
+ * "which runtime is this install" reads — GSD_RUNTIME → config.runtime →
80
+ * per-install `.gsd-runtime` marker → `'claude'` (#5169, #4690). Returns
81
+ * `'claude'` when nothing is declared (the spawn-time default for which the
82
+ * guard is a no-op).
80
83
  */
81
- function resolveRuntimeFromConfig(config) {
82
- if (config && typeof config === 'object'
83
- && typeof config.runtime === 'string' && config.runtime) {
84
- return config.runtime;
85
- }
86
- return 'claude';
84
+ function resolveRuntimeFromConfig(config, env = process.env) {
85
+ return resolveActiveRuntime(config, env);
87
86
  }
88
87
 
89
88
  /**
90
- * Resolve the install root for a runtime's agent files, honoring the same env
91
- * vars the installer does (CODEX_HOME, OPENCODE_CONFIG_DIR, KILO_CONFIG_DIR).
92
- * Returns the absolute directory or `null` for unsupported runtimes.
89
+ * Resolve the install root for a runtime's agent files from the runtime
90
+ * descriptor's `configHome` (the same resolution the installer uses), then
91
+ * append `agents` — the installer writes agents to `<configHome>/agents`
92
+ * (plural; #2093). Returns the absolute directory or `null` for runtimes that
93
+ * do not bake a static agent model.
93
94
  */
94
95
  function resolveAgentDir(runtime, { env = process.env, homedir = os.homedir } = {}) {
95
- if (runtime === 'opencode') {
96
- const base = (env.OPENCODE_CONFIG_DIR && String(env.OPENCODE_CONFIG_DIR).trim()) || path.join(homedir(), '.config', 'opencode');
97
- // #2093 fix: the installer writes agents to `<base>/agents` (plural — see
98
- // bin/install.js's universal `agentsDest = path.join(targetDir, 'agents')`,
99
- // verified against a live `--opencode --global` install). The prior
100
- // singular `agent` never matched the real install output, so this guard's
101
- // `findOldestAgentMtime` always hit ENOENT and warnIfStaleBake was a
102
- // silent no-op for opencode in production — discovered while wiring the
103
- // parallel kilo entry below (same bake mechanism, #2093).
104
- return path.join(base, 'agents');
105
- }
106
- if (runtime === 'kilo') {
107
- const base = (env.KILO_CONFIG_DIR && String(env.KILO_CONFIG_DIR).trim()) || path.join(homedir(), '.config', 'kilo');
108
- return path.join(base, 'agents');
109
- }
110
- if (runtime === 'codex') {
111
- const base = (env.CODEX_HOME && String(env.CODEX_HOME).trim()) || path.join(homedir(), '.codex');
112
- return path.join(base, 'agents');
113
- }
114
- return null;
96
+ if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return null;
97
+ const configHome = capabilityRegistry.runtimes[runtime].runtime.configHome;
98
+ return path.join(resolveConfigHomeFromDescriptor(configHome, { env, home: homedir() }), 'agents');
115
99
  }
116
100
 
117
101
  /**
@@ -168,8 +152,8 @@ function findOldestAgentMtime(runtime, { env = process.env, homedir = os.homedir
168
152
  for (const entry of entries) {
169
153
  if (!entry.isFile()) continue;
170
154
  if (!entry.name.startsWith('gsd-')) continue;
171
- const isAgentFile = ((runtime === 'opencode' || runtime === 'kilo') && entry.name.endsWith('.md'))
172
- || (runtime === 'codex' && (entry.name.endsWith('.toml') || entry.name.endsWith('.md')));
155
+ const bakedExts = hostBehaviorsFor(runtime).bakedAgentFileExtensions;
156
+ const isAgentFile = Array.isArray(bakedExts) && bakedExts.some((ext) => entry.name.endsWith(ext));
173
157
  if (!isAgentFile) continue;
174
158
  try {
175
159
  const st = fsStatSync(path.join(dir, entry.name));
@@ -209,7 +193,7 @@ function warnIfStaleBake(cwd, options = {}) {
209
193
  } = options;
210
194
  try {
211
195
  const resolvedConfig = config || _readRuntimeConfig(cwd, { fsStatSync });
212
- const runtime = resolveRuntimeFromConfig(resolvedConfig);
196
+ const runtime = resolveRuntimeFromConfig(resolvedConfig, env);
213
197
  if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return false;
214
198
 
215
199
  const dedupKey = `${runtime}::${path.resolve(cwd || '.')}`;
@@ -73,6 +73,12 @@ exports.buildStateContract = buildStateContract;
73
73
  exports.publishStateContract = publishStateContract;
74
74
  const node_path_1 = __importDefault(require("node:path"));
75
75
  const node_fs_1 = __importDefault(require("node:fs"));
76
+ // #5060: `phase-status.cjs` is a LOAD-TIME LEAF — no top-level requires of
77
+ // its own (verification.cjs/plan-scan.cjs are required lazily, only inside
78
+ // `phaseStatus()`) — so importing it here at top level does not reopen the
79
+ // documented `state.cjs -> state-contract.cjs -> smart-entry.cjs -> state.cjs`
80
+ // require cycle the file header warns about.
81
+ const phase_status_cjs_1 = require("./phase-status.cjs");
76
82
  // ─── Public wire vocabulary ────────────────────────────────────────────────
77
83
  exports.STATE_CONTRACT_VERSION = '1.0.0';
78
84
  exports.STATE_CONTRACT_FLAVOR = 'core';
@@ -80,12 +86,14 @@ exports.STATE_CONTRACT_FLAVOR = 'core';
80
86
  exports.CONTRACT_KEY_ORDER = Object.freeze(['contract', 'flavor', 'milestone', 'phases', 'next', 'updated_at']);
81
87
  /** Key order of each emitted phase object — an observable, pinned by test. */
82
88
  exports.PHASE_KEY_ORDER = Object.freeze(['number', 'name', 'status']);
83
- /** Frozen three-value phase status vocabulary. Conservative in what we send (Postel's Law). */
84
- exports.PHASE_STATUS = Object.freeze({
85
- COMPLETE: 'complete',
86
- IN_PROGRESS: 'in_progress',
87
- PENDING: 'pending',
88
- });
89
+ /**
90
+ * Frozen three-value phase status vocabulary. Conservative in what we send
91
+ * (Postel's Law). #5060: identity-pinned to the Phase Status Module's own
92
+ * `WIRE_STATUS` — this is not a copy, it IS that frozen object, so
93
+ * `state-contract`'s `PHASE_STATUS` and `phase-status.cjs`'s `WIRE_STATUS`
94
+ * can never independently drift.
95
+ */
96
+ exports.PHASE_STATUS = phase_status_cjs_1.WIRE_STATUS;
89
97
  /** Frozen `publishStateContract` result reasons. */
90
98
  exports.PUBLISH_REASON = Object.freeze({
91
99
  PUBLISHED: 'published',
@@ -146,17 +154,6 @@ function buildMilestone(cwd) {
146
154
  }
147
155
  // ─── phases: Progress-table (primary) enumerator ───────────────────────────
148
156
  const PHASE_CELL_RE = /^(\d+(?:\.\d+)*)\s*[.:)–—-]?\s*(.*)$/;
149
- function statusFromProgressCell(raw) {
150
- const normalized = (raw ?? '').trim().toLowerCase().replace(/\s+/g, ' ');
151
- if (normalized === 'complete')
152
- return exports.PHASE_STATUS.COMPLETE;
153
- if (normalized === 'in progress')
154
- return exports.PHASE_STATUS.IN_PROGRESS;
155
- // Everything else — 'not started', 'deferred' (design row 12, lossy by
156
- // design), '', and any unrecognized word — folds to pending. An
157
- // unrecognized status must never reach the wire as a 4th value.
158
- return exports.PHASE_STATUS.PENDING;
159
- }
160
157
  function phasesFromProgressTable(table) {
161
158
  const { isSentinelPhaseId } = owners();
162
159
  const phases = [];
@@ -169,7 +166,7 @@ function phasesFromProgressTable(table) {
169
166
  const m = PHASE_CELL_RE.exec(cell);
170
167
  const number = m ? m[1] : cell;
171
168
  const name = m && m[2].trim().length > 0 ? m[2].trim() : null;
172
- phases.push({ number, name, status: statusFromProgressCell(row['Status']) });
169
+ phases.push({ number, name, status: (0, phase_status_cjs_1.parseRoadmapStatusCell)(row['Status']) });
173
170
  }
174
171
  return phases;
175
172
  }
@@ -30,6 +30,7 @@ const markdown_table_cjs_1 = require("./markdown-table.cjs");
30
30
  const phase_lifecycle_cjs_1 = require("./phase-lifecycle.cjs");
31
31
  const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
32
32
  const pattern_cjs_1 = require("./pattern.cjs");
33
+ const planning_document_cjs_1 = require("./planning-document.cjs");
33
34
  // eslint-disable-next-line @typescript-eslint/no-require-imports -- planning-scope.cjs is an export= CommonJS module
34
35
  const planningScopeMod = require("./planning-scope.cjs");
35
36
  const { SCOPE } = planningScopeMod;
@@ -536,29 +537,106 @@ function joinFieldReplacement(prefix, newValue) {
536
537
  function stateReplaceField(content, fieldName, newValue) {
537
538
  const escaped = (0, pattern_cjs_1.escapeRegex)(fieldName);
538
539
  // Bold inline format: **FieldName:** value
539
- // The label-to-value gap is same-line whitespace only (`[ \t]*`, mirroring the
540
- // read side at stateExtractField). `\s*` here matched `\n`, so on an empty field
541
- // `(.*)` captured the following line and the rebuild discarded it — the #4010
542
- // data-loss. ADR-3180 §7.7 makes stateExtractField the same-line-confined owner;
543
- // this aligns the writer to it.
544
540
  //
545
- // #4243: the bold form is also ANCHORED to line start, with same-line leading
546
- // whitespace only. The pre-fix pattern carried no `^` and no `m` flag, so a
547
- // bold label quoted MID-SENTENCE inside prose — an Accumulated Context bullet
548
- // mentioning `**Status:**` — captured the rewrite and destroyed the rest of
549
- // its line, silently, whenever a whole-body caller fed this function every
550
- // section (beginPhaseCore's tryField, advancePlanCore's Status/Current Plan
551
- // writes). The plain branch below was always line-anchored; only the bold
552
- // branch lagged. Anchoring reuses #4010's same-line confinement idiom (the
553
- // leading class is `[ \t]*`, deliberately NOT the `\s*` the issue suggested —
554
- // `^\s*\*\*` can consume the newlines before the label into the match and
555
- // drop them on rebuild) and #4186's recognition-by-anchoring discipline: a
556
- // write target must BE the whole declared line shape, never a substring
557
- // guess inside prose. `$` is explicit-and-inert (`.` never crosses line
558
- // terminators) and documents that the match ends at end-of-line.
559
- const boldPattern = new RegExp(`^([ \\t]*\\*\\*${escaped}:\\*\\*[ \\t]*)(.*)$`, 'im');
560
- if (boldPattern.test(content)) {
561
- return content.replace(boldPattern, (_match, prefix) => joinFieldReplacement(prefix, newValue));
541
+ // #5007 (Phase 6 / ADR-4910 amendment): migrated off the hand-rolled
542
+ // `^([ \t]*\*\*${escaped}:\*\*[ \t]*)(.*)$` regex (which, per #4010/#4243
543
+ // below, already existed to fix real same-line-confinement and mid-prose
544
+ // data-loss bugs) onto `parsePlanningDoc` for LOCATING the field — same-
545
+ // line confinement AND fence/frontmatter exclusion (parseBoldFieldLine
546
+ // never matches inside a fenced block or frontmatter, which the removed
547
+ // regex could not tell apart from prose) — so this migration keeps
548
+ // #4010/#4243's fix and extends it, rather than replacing it with a
549
+ // weaker check.
550
+ //
551
+ // This does NOT go through the seam's `setFieldValue`/`serialize` write
552
+ // path. An earlier version of this migration did, via a since-removed
553
+ // `setFieldValue({ allowSeparator: true })` option (#5007) — that option
554
+ // spliced the caller's value across the FULL rest-of-line span
555
+ // (`valueSpan.start`..`trailingSpan.end`) to permit a value containing the
556
+ // grammar's ` — ` trailing-separator token (needed here: see the
557
+ // `${currentPhase} — COMPLETE` value below). It was removed after a
558
+ // failing-first reproduction proved it only avoided the write-time
559
+ // refusal: the bytes it writes are correct, but `parseBoldFieldLine`
560
+ // splits on ` — ` unconditionally on every read, with no escaping
561
+ // convention in this grammar to tell "atomic value containing the token"
562
+ // apart from "value plus hand-annotation". So the NEXT fresh
563
+ // `parsePlanningDoc` of that exact text — not the in-memory doc the
564
+ // option's own tests checked — silently re-truncates the value and
565
+ // demotes the rest to `trailingSpan`, with `findField`/`readNode`
566
+ // reporting a confident, wrong `ok: true` and no error. That is exactly
567
+ // the #4917 finding-2 corruption `setFieldValue`'s round-trip check
568
+ // exists to prevent, just moved one parse cycle downstream. This call
569
+ // site never reads STATE.md fields back through `parsePlanningDoc`/
570
+ // `findField` (reads go through `stateExtractField`'s own non-splitting
571
+ // regex, below), so it is safe HERE — but making that a shared, public
572
+ // option on the seam's `setFieldValue` was an attractive nuisance for any
573
+ // future `findField`/`readNode` caller (this same module already serves
574
+ // ROADMAP.md's `Plans`/`Depends on` fields that way). The full-rest-of-
575
+ // line splice is done locally, directly against `content`, instead —
576
+ // `parsePlanningDoc` is used only to locate the field's spans.
577
+ //
578
+ // Two deliberate deviations from a bare findField() call, both
579
+ // PRESERVING this function's own prior contract rather than adopting the
580
+ // seam's stricter defaults:
581
+ //
582
+ // 1. Label lookup here is case-INSENSITIVE (not findField's exact
583
+ // match), mirroring the removed regex's `i` flag: callers in
584
+ // state.cts/state-transition.cts pass a fieldName spelling that can
585
+ // differ only in case from what a given template actually has (the
586
+ // explicit 'Last Activity' / 'Last activity' fallback-call pairs at
587
+ // those call sites), so a case-sensitive lookup would silently miss
588
+ // matches the removed regex used to find.
589
+ // 2. Every write below replaces the FULL rest-of-line span
590
+ // (`valueSpan.start`..`trailingSpan.end`) UNCONDITIONALLY, not only
591
+ // when `newValue` contains the grammar's ` — ` separator token,
592
+ // because `joinFieldReplacement` always discarded the OLD regex's
593
+ // entire captured tail (`(.*)$` — both what the seam calls
594
+ // `valueSpan` AND `trailingSpan`) and replaced it wholesale with the
595
+ // new value. This call site never had a "preserve a hand-written
596
+ // trailing annotation" contract, so writing anything narrower than
597
+ // the full rest-of-line span here would be a NEW, untested behavior
598
+ // this migration must not introduce as a side effect.
599
+ //
600
+ // Matching BOTH bold-placement spellings (`**Label:**` and `**Label**:`,
601
+ // `BOLD_FIELD_RE`) where the removed regex recognized only `**Label:**`
602
+ // is the same, already-precedented widening as the "Depends on"
603
+ // migration (src/phase.cts) — intentional, not scope creep.
604
+ //
605
+ // A parse failure, an absent/case-mismatched label, or a value containing
606
+ // a line break (\r/\n — would forge sibling structure on splice, the same
607
+ // hazard `setFieldValue` refuses unconditionally at #4917/ADR-4910
608
+ // Decision 2 & 4; this local splice has no seam call to inherit that
609
+ // refusal from, so it is re-checked here) falls through to the
610
+ // plain/pipe-table branches below unchanged — the same silent
611
+ // per-occurrence no-op-on-no-match contract the removed regex had for any
612
+ // input it didn't match.
613
+ const parsed = (0, planning_document_cjs_1.parsePlanningDoc)(content, 'STATE.md');
614
+ if (parsed.ok) {
615
+ let boldField = null;
616
+ for (const node of parsed.value.nodes) {
617
+ if (node.kind !== 'boldField')
618
+ continue;
619
+ if (node.label.toLowerCase() !== fieldName.toLowerCase())
620
+ continue;
621
+ boldField = node;
622
+ break;
623
+ }
624
+ if (boldField) {
625
+ // Replicates joinFieldReplacement's own `` `${newValue}` `` coercion
626
+ // (a caller may pass a non-string, e.g. a number, at the JS boundary
627
+ // even though the type signature says `string`) before the
628
+ // missing-separator normalization below: insert a single space when
629
+ // the existing label-to-value gap has none, so `**Status:**value`
630
+ // still becomes `**Status:** value` rather than gluing the two
631
+ // together.
632
+ const spacingText = parsed.value.source.slice(boldField.labelSpan.end, boldField.valueSpan.start);
633
+ const newValueStr = `${newValue}`;
634
+ const needsSeparator = newValueStr.length > 0 && !/[ \t]$/.test(spacingText);
635
+ const writeValue = `${needsSeparator ? ' ' : ''}${newValueStr}`;
636
+ if (!/[\r\n]/.test(writeValue)) {
637
+ return (content.slice(0, boldField.valueSpan.start) + writeValue + content.slice(boldField.trailingSpan.end));
638
+ }
639
+ }
562
640
  }
563
641
  // Plain line-start format: FieldName: value (same same-line confinement as above)
564
642
  const plainPattern = new RegExp(`(^${escaped}:[ \\t]*)(.*)`, 'im');
@@ -25,6 +25,7 @@ exports.getFieldClassification = getFieldClassification;
25
25
  exports.getPreserveWhenUnchangedFields = getPreserveWhenUnchangedFields;
26
26
  exports.openStateTransaction = openStateTransaction;
27
27
  exports.rebuildStateTransaction = rebuildStateTransaction;
28
+ exports.createStateWriteIntent = createStateWriteIntent;
28
29
  exports.applyPreserveWhenUnchanged = applyPreserveWhenUnchanged;
29
30
  exports.applyStatePreservation = applyStatePreservation;
30
31
  exports.transitionCore = transitionCore;
@@ -401,6 +402,28 @@ function openStateTransaction(init) {
401
402
  function rebuildStateTransaction(init) {
402
403
  return createStateTransaction('rebuild', init, 'rebuildStateTransaction');
403
404
  }
405
+ /**
406
+ * Extend an existing StateTransaction into a StateWriteIntent. The base
407
+ * transaction is REQUIRED — an absent base is a construction failure, mirroring
408
+ * `createStateTransaction`'s ADR-3473 §8.6 posture (do not tolerate null). `scope`
409
+ * defaults to the conservative `'narrow'`; `assertions` defaults to none. Frozen
410
+ * so an intent, like a transaction, cannot be mutated after construction.
411
+ */
412
+ function createStateWriteIntent(transaction, init = {}) {
413
+ if (transaction === null || typeof transaction !== 'object' || Array.isArray(transaction)) {
414
+ const err = new Error('createStateWriteIntent: a base StateTransaction is required (build it with ' +
415
+ 'openStateTransaction / rebuildStateTransaction first). Per ADR-4629 §8.1, an absent ' +
416
+ 'transaction is a construction failure — do not tolerate null.');
417
+ err.code = 'STATE_WRITE_INTENT_TRANSACTION_REQUIRED';
418
+ throw err;
419
+ }
420
+ const assertions = Object.freeze((init.assertions ?? []).map((a) => Object.freeze({ field: a.field, requirement: a.requirement })));
421
+ return Object.freeze({
422
+ ...transaction,
423
+ assertions,
424
+ scope: init.scope ?? 'narrow',
425
+ });
426
+ }
404
427
  /**
405
428
  * ADR-3408 §8.2: an unenforced `preserve-when-unchanged` row throws. Both
406
429
  * ends of this invariant are gsd-core's own source — a declared row the
@@ -1648,8 +1671,22 @@ function completePhaseCore(content, intent, deps) {
1648
1671
  body = statusAfter;
1649
1672
  updated.push('Status');
1650
1673
  }
1651
- // Current Plan — reset for the next phase.
1652
- const planAfter = (0, state_document_cjs_1.stateReplaceFieldWithFallback)(body, 'Current Plan', 'Plan', 'Not started');
1674
+ // Current Plan — reset for the next phase. #4823: when a Current Position
1675
+ // section exists (the canonical layout, #2956 locator), the reset is scoped
1676
+ // to it — the whole-body fallback 'Plan' run matched any hard-wrapped prose
1677
+ // line starting with `plan:` anywhere in the document and rewrote it to
1678
+ // 'Not started', silently destroying narrative. Legacy sectionless layouts
1679
+ // (fields at top level, no section) keep the whole-body behavior unchanged:
1680
+ // there is no section to scope to, and their fields are the intended
1681
+ // targets.
1682
+ let planAfter;
1683
+ const positionScope = (0, state_document_cjs_1.stateCurrentPositionSlice)(body);
1684
+ if (positionScope !== null) {
1685
+ planAfter = (0, markdown_sectionizer_cjs_1.withSection)(body, (h) => (h.level === 2 || h.level === 3) && h.text.trim().toLowerCase() === 'current position', (sectionBody) => (0, state_document_cjs_1.stateReplaceFieldWithFallback)(sectionBody, 'Current Plan', 'Plan', 'Not started'), { levelBounded: true });
1686
+ }
1687
+ else {
1688
+ planAfter = (0, state_document_cjs_1.stateReplaceFieldWithFallback)(body, 'Current Plan', 'Plan', 'Not started');
1689
+ }
1653
1690
  if (planAfter !== body) {
1654
1691
  body = planAfter;
1655
1692
  updated.push('Current Plan');