@opengsd/gsd-core 1.15.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 (487) 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/agents/gsd-code-fixer.compact.md +1 -1
  5. package/agents/gsd-code-fixer.md +1 -1
  6. package/agents/gsd-code-reviewer.compact.md +5 -3
  7. package/agents/gsd-code-reviewer.md +8 -6
  8. package/agents/gsd-debug-session-manager.compact.md +1 -1
  9. package/agents/gsd-debug-session-manager.md +1 -1
  10. package/agents/gsd-debugger.md +2 -2
  11. package/agents/gsd-eval-auditor.compact.md +1 -1
  12. package/agents/gsd-eval-auditor.md +1 -1
  13. package/agents/gsd-executor.md +4 -4
  14. package/agents/gsd-intel-updater.compact.md +1 -1
  15. package/agents/gsd-intel-updater.md +1 -1
  16. package/agents/gsd-mempalace-curator.md +2 -2
  17. package/agents/gsd-phase-researcher.md +1 -1
  18. package/agents/gsd-plan-checker.md +7 -2
  19. package/agents/gsd-planner.md +3 -3
  20. package/agents/gsd-project-researcher.compact.md +1 -1
  21. package/agents/gsd-project-researcher.md +1 -1
  22. package/agents/gsd-research-synthesizer.compact.md +1 -1
  23. package/agents/gsd-research-synthesizer.md +1 -1
  24. package/agents/gsd-ui-auditor.compact.md +21 -30
  25. package/agents/gsd-ui-auditor.md +42 -51
  26. package/agents/gsd-ui-researcher.compact.md +1 -1
  27. package/agents/gsd-ui-researcher.md +1 -1
  28. package/agents/gsd-verifier.md +31 -9
  29. package/bin/install.js +126 -196
  30. package/commands/gsd/add-tests.md +6 -1
  31. package/commands/gsd/ai-integration-phase.md +6 -1
  32. package/commands/gsd/audit-fix.md +5 -0
  33. package/commands/gsd/audit-milestone.md +6 -1
  34. package/commands/gsd/autonomous.md +5 -0
  35. package/commands/gsd/capture.md +8 -4
  36. package/commands/gsd/code-review.md +7 -2
  37. package/commands/gsd/complete-milestone.md +4 -0
  38. package/commands/gsd/config.md +7 -3
  39. package/commands/gsd/debug.md +11 -7
  40. package/commands/gsd/discuss-phase.md +7 -3
  41. package/commands/gsd/docs-update.md +12 -7
  42. package/commands/gsd/eval-review.md +6 -1
  43. package/commands/gsd/execute-phase.md +12 -7
  44. package/commands/gsd/extract-learnings.md +5 -0
  45. package/commands/gsd/fast.md +4 -0
  46. package/commands/gsd/forensics.md +5 -1
  47. package/commands/gsd/graphify.md +10 -6
  48. package/commands/gsd/health.md +5 -0
  49. package/commands/gsd/help.md +7 -2
  50. package/commands/gsd/import.md +7 -3
  51. package/commands/gsd/inbox.md +5 -0
  52. package/commands/gsd/ingest-docs.md +5 -1
  53. package/commands/gsd/manager.md +6 -1
  54. package/commands/gsd/map-codebase.md +7 -3
  55. package/commands/gsd/mempalace-capture.md +5 -1
  56. package/commands/gsd/mempalace-recall.md +5 -1
  57. package/commands/gsd/milestone-summary.md +5 -1
  58. package/commands/gsd/mvp-phase.md +8 -3
  59. package/commands/gsd/new-milestone.md +6 -1
  60. package/commands/gsd/new-project.md +5 -0
  61. package/commands/gsd/next.md +6 -1
  62. package/commands/gsd/ns-context.md +4 -0
  63. package/commands/gsd/ns-ideate.md +4 -0
  64. package/commands/gsd/ns-manage.md +4 -0
  65. package/commands/gsd/ns-project.md +4 -0
  66. package/commands/gsd/ns-review.md +4 -0
  67. package/commands/gsd/ns-workflow.md +4 -0
  68. package/commands/gsd/onboard.md +6 -1
  69. package/commands/gsd/pause-work.md +5 -1
  70. package/commands/gsd/phase.md +8 -4
  71. package/commands/gsd/plan-phase.md +6 -1
  72. package/commands/gsd/plan-review-convergence.md +5 -1
  73. package/commands/gsd/pr-branch.md +4 -0
  74. package/commands/gsd/profile-user.md +5 -1
  75. package/commands/gsd/progress.md +6 -1
  76. package/commands/gsd/quick-batch.md +20 -8
  77. package/commands/gsd/quick.md +12 -7
  78. package/commands/gsd/review.md +5 -1
  79. package/commands/gsd/secure-phase.md +6 -1
  80. package/commands/gsd/ship.md +5 -0
  81. package/commands/gsd/sketch.md +7 -2
  82. package/commands/gsd/spec-phase.md +5 -1
  83. package/commands/gsd/spike.md +8 -3
  84. package/commands/gsd/surface.md +5 -1
  85. package/commands/gsd/thread.md +4 -0
  86. package/commands/gsd/ui-phase.md +6 -1
  87. package/commands/gsd/ui-review.md +6 -1
  88. package/commands/gsd/ultraplan-phase.md +5 -1
  89. package/commands/gsd/undo.md +5 -1
  90. package/commands/gsd/update.md +6 -2
  91. package/commands/gsd/validate-phase.md +6 -1
  92. package/commands/gsd/verify-work.md +6 -1
  93. package/commands/gsd/workspace.md +7 -3
  94. package/gsd-core/bin/gsd-tools.cjs +142 -56
  95. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  96. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  97. package/gsd-core/bin/lib/audit.cjs +78 -44
  98. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  99. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  100. package/gsd-core/bin/lib/capability-registry.cjs +183 -103
  101. package/gsd-core/bin/lib/capability-validator.cjs +16 -0
  102. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  103. package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
  104. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  105. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  106. package/gsd-core/bin/lib/codex-agent-toml.cjs +11 -8
  107. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  108. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  109. package/gsd-core/bin/lib/commands.cjs +173 -170
  110. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  111. package/gsd-core/bin/lib/config.cjs +43 -12
  112. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  113. package/gsd-core/bin/lib/coverage.cjs +4 -8
  114. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  115. package/gsd-core/bin/lib/drift.cjs +177 -42
  116. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  117. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  118. package/gsd-core/bin/lib/frontmatter.cjs +413 -234
  119. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  120. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  121. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  122. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  123. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  124. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  125. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  126. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  127. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  128. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  129. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  130. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  131. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  132. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  133. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  134. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  135. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  136. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  137. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  138. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  139. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  140. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  141. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  142. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  143. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  144. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  145. package/gsd-core/bin/lib/init.cjs +162 -96
  146. package/gsd-core/bin/lib/install-engine.cjs +19 -35
  147. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  148. package/gsd-core/bin/lib/io.cjs +122 -3
  149. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  150. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  151. package/gsd-core/bin/lib/milestone.cjs +19 -1
  152. package/gsd-core/bin/lib/model-resolver.cjs +18 -18
  153. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  154. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  155. package/gsd-core/bin/lib/pattern.cjs +10 -0
  156. package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
  157. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  158. package/gsd-core/bin/lib/phase-id.cjs +1 -1
  159. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  160. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  161. package/gsd-core/bin/lib/phase.cjs +280 -80
  162. package/gsd-core/bin/lib/plan-document.cjs +93 -19
  163. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  164. package/gsd-core/bin/lib/planning-document.cjs +273 -40
  165. package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
  166. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  167. package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
  168. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  169. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  170. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  171. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  172. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  173. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  174. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  175. package/gsd-core/bin/lib/roadmap-command-router.cjs +13 -15
  176. package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
  177. package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
  178. package/gsd-core/bin/lib/roadmap.cjs +169 -72
  179. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +91 -157
  180. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
  181. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  182. package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
  183. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +307 -591
  184. package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
  185. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  186. package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
  187. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  188. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  189. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  190. package/gsd-core/bin/lib/state-document.cjs +100 -22
  191. package/gsd-core/bin/lib/state.cjs +214 -105
  192. package/gsd-core/bin/lib/surface.cjs +2 -1
  193. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
  194. package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
  195. package/gsd-core/bin/lib/uat.cjs +424 -7
  196. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
  197. package/gsd-core/bin/lib/vendor/README.md +31 -9
  198. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  199. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  200. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  201. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  202. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  203. package/gsd-core/bin/lib/verification.cjs +1165 -314
  204. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  205. package/gsd-core/bin/lib/verify.cjs +286 -567
  206. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  207. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  208. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  209. package/gsd-core/bin/lib/workstream.cjs +11 -2
  210. package/gsd-core/bin/shared/config-defaults.manifest.json +5 -0
  211. package/gsd-core/bin/shared/config-schema.manifest.json +4 -0
  212. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  213. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  214. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  215. package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
  216. package/gsd-core/references/execute-phase-response-language.md +1 -1
  217. package/gsd-core/references/gsd-run-resolver.md +1 -1
  218. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  219. package/gsd-core/references/offer-next.md +1 -1
  220. package/gsd-core/references/planning-config.md +1 -1
  221. package/gsd-core/references/spidr-splitting.md +1 -1
  222. package/gsd-core/references/tdd.md +10 -4
  223. package/gsd-core/references/verifier-phase-gates.md +5 -2
  224. package/gsd-core/references/verify-mvp-mode.md +2 -2
  225. package/gsd-core/references/workstream-flag.md +33 -3
  226. package/gsd-core/templates/README.md +1 -1
  227. package/gsd-core/templates/UAT.md +17 -1
  228. package/gsd-core/templates/config.json +2 -11
  229. package/gsd-core/templates/verification-report.md +1 -1
  230. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  231. package/gsd-core/workflows/add-backlog.md +1 -1
  232. package/gsd-core/workflows/add-phase.md +8 -7
  233. package/gsd-core/workflows/add-tests.md +3 -2
  234. package/gsd-core/workflows/add-todo.md +4 -3
  235. package/gsd-core/workflows/ai-integration-phase.md +3 -2
  236. package/gsd-core/workflows/audit-fix.md +1 -1
  237. package/gsd-core/workflows/audit-milestone.md +4 -3
  238. package/gsd-core/workflows/audit-uat.md +1 -1
  239. package/gsd-core/workflows/autonomous.md +28 -18
  240. package/gsd-core/workflows/check-todos.md +6 -5
  241. package/gsd-core/workflows/cleanup.md +1 -1
  242. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  243. package/gsd-core/workflows/code-review-fix.md +5 -4
  244. package/gsd-core/workflows/code-review.md +84 -90
  245. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  246. package/gsd-core/workflows/complete-milestone.md +12 -7
  247. package/gsd-core/workflows/debug.md +30 -5
  248. package/gsd-core/workflows/diagnose-issues.md +3 -2
  249. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  250. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  252. package/gsd-core/workflows/discuss-phase.md +4 -3
  253. package/gsd-core/workflows/do.md +1 -1
  254. package/gsd-core/workflows/docs-update.md +4 -3
  255. package/gsd-core/workflows/edit-phase.md +4 -3
  256. package/gsd-core/workflows/eval-review.md +5 -3
  257. package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
  258. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
  259. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  260. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  261. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  263. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  264. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  265. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  266. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
  267. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  268. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  269. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  270. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  271. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  272. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  273. package/gsd-core/workflows/execute-phase.md +78 -170
  274. package/gsd-core/workflows/execute-plan.md +13 -19
  275. package/gsd-core/workflows/explore.md +2 -2
  276. package/gsd-core/workflows/extract-learnings.md +3 -2
  277. package/gsd-core/workflows/fast.md +1 -1
  278. package/gsd-core/workflows/forensics.md +1 -1
  279. package/gsd-core/workflows/graduation.md +1 -1
  280. package/gsd-core/workflows/health.md +2 -1
  281. package/gsd-core/workflows/import.md +3 -2
  282. package/gsd-core/workflows/inbox.md +1 -1
  283. package/gsd-core/workflows/ingest-docs.md +1 -1
  284. package/gsd-core/workflows/insert-phase.md +4 -3
  285. package/gsd-core/workflows/list-seeds.md +1 -1
  286. package/gsd-core/workflows/list-workspaces.md +1 -1
  287. package/gsd-core/workflows/manager.md +5 -3
  288. package/gsd-core/workflows/map-codebase.md +4 -3
  289. package/gsd-core/workflows/milestone-summary.md +3 -2
  290. package/gsd-core/workflows/mvp-phase.md +14 -14
  291. package/gsd-core/workflows/new-milestone.md +10 -10
  292. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  293. package/gsd-core/workflows/new-project.md +1 -1
  294. package/gsd-core/workflows/new-workspace.md +1 -1
  295. package/gsd-core/workflows/next.md +1 -1
  296. package/gsd-core/workflows/pause-work.md +2 -2
  297. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  298. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
  299. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  300. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  301. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +1 -1
  302. package/gsd-core/workflows/plan-phase.md +27 -18
  303. package/gsd-core/workflows/plan-review-convergence.md +1 -1
  304. package/gsd-core/workflows/plant-seed.md +1 -1
  305. package/gsd-core/workflows/pr-branch.md +1 -1
  306. package/gsd-core/workflows/profile-user.md +1 -1
  307. package/gsd-core/workflows/progress.md +19 -49
  308. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
  309. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  310. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  311. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  312. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  313. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  314. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  315. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  316. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  317. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  318. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  319. package/gsd-core/workflows/quick-batch.md +15 -10
  320. package/gsd-core/workflows/quick.md +42 -31
  321. package/gsd-core/workflows/remove-phase.md +3 -2
  322. package/gsd-core/workflows/remove-workspace.md +1 -1
  323. package/gsd-core/workflows/resume-project.md +3 -2
  324. package/gsd-core/workflows/review.md +3 -2
  325. package/gsd-core/workflows/scan.md +3 -2
  326. package/gsd-core/workflows/secure-phase.md +11 -12
  327. package/gsd-core/workflows/settings-advanced.md +1 -1
  328. package/gsd-core/workflows/settings-integrations.md +1 -1
  329. package/gsd-core/workflows/settings.md +1 -1
  330. package/gsd-core/workflows/ship.md +12 -12
  331. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  332. package/gsd-core/workflows/sketch.md +1 -1
  333. package/gsd-core/workflows/smart-entry.md +1 -1
  334. package/gsd-core/workflows/spec-phase.md +1 -1
  335. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  336. package/gsd-core/workflows/spike.md +1 -1
  337. package/gsd-core/workflows/stats.md +1 -1
  338. package/gsd-core/workflows/sync-skills.md +1 -1
  339. package/gsd-core/workflows/thread.md +2 -2
  340. package/gsd-core/workflows/transition.md +13 -23
  341. package/gsd-core/workflows/ui-phase.md +5 -4
  342. package/gsd-core/workflows/ui-review.md +4 -3
  343. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  344. package/gsd-core/workflows/undo.md +1 -1
  345. package/gsd-core/workflows/validate-phase.md +10 -12
  346. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  347. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  348. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  349. package/gsd-core/workflows/verify-work.md +68 -59
  350. package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
  351. package/hooks/dist/gsd-check-update-worker.js +8 -0
  352. package/hooks/dist/gsd-check-update.js +8 -0
  353. package/hooks/dist/gsd-context-monitor.js +31 -8
  354. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  355. package/hooks/dist/gsd-secret-read-guard.js +147 -16
  356. package/hooks/dist/gsd-statusline.js +15 -7
  357. package/hooks/dist/gsd-update-banner.js +8 -0
  358. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  359. package/hooks/dist/gsd-workflow-guard.js +5 -4
  360. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  361. package/hooks/dist/lib/cli-exit.js +12 -0
  362. package/hooks/dist/lib/git-probe.js +17 -1
  363. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  364. package/hooks/gsd-agent-isolation-guard.js +8 -0
  365. package/hooks/gsd-check-update-worker.js +8 -0
  366. package/hooks/gsd-check-update.js +8 -0
  367. package/hooks/gsd-context-monitor.js +31 -8
  368. package/hooks/gsd-cursor-subagent-start.js +8 -0
  369. package/hooks/gsd-secret-read-guard.js +147 -16
  370. package/hooks/gsd-statusline.js +15 -7
  371. package/hooks/gsd-update-banner.js +8 -0
  372. package/hooks/gsd-windsurf-pre-write.js +11 -2
  373. package/hooks/gsd-workflow-guard.js +5 -4
  374. package/hooks/gsd-worktree-path-guard.js +6 -2
  375. package/hooks/hooks.json +5 -5
  376. package/hooks/lib/cli-exit.js +12 -0
  377. package/hooks/lib/git-probe.js +17 -1
  378. package/hooks/lib/isolation-sentinel.js +2 -2
  379. package/package.json +21 -4
  380. package/scripts/changeset/parse.cjs +52 -4
  381. package/scripts/ci-timeout-report.cjs +770 -4
  382. package/scripts/command-contract-helpers.cjs +12 -8
  383. package/scripts/docs-guard-registry.cjs +6 -0
  384. package/scripts/gen-features.cjs +13 -8
  385. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  386. package/scripts/gen-loop-host-contract.cjs +10 -1
  387. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  388. package/scripts/gen-plugin-skills.cjs +87 -1
  389. package/scripts/gen-research-agents.cjs +24 -31
  390. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  391. package/scripts/gen-test-timings.cjs +32 -7
  392. package/scripts/lib/cli-exit.cjs +12 -0
  393. package/scripts/lib/macos-conformance-tier.generated.cjs +20 -2
  394. package/scripts/lib/ndjson-reporter.cjs +28 -3
  395. package/scripts/lib/platform-conformance-tier.generated.cjs +34 -5
  396. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  397. package/scripts/lib/vendor-bundle.cjs +59 -0
  398. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  399. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  400. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  401. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  402. package/scripts/lint-descriptions.cjs +7 -3
  403. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +10 -0
  404. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  405. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  406. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  407. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  408. package/scripts/lint-phase-id-drift.cjs +29 -0
  409. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  410. package/scripts/lint-response-language-coverage.cjs +3 -0
  411. package/scripts/lint-skill-deps.cjs +7 -3
  412. package/scripts/lint-test-file-count.allowlist.json +11 -1
  413. package/scripts/lint-test-file-count.cjs +34 -1
  414. package/scripts/lint-vendored-deps.cjs +41 -5
  415. package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
  416. package/scripts/mutation-matrix.cjs +50 -5
  417. package/scripts/require-issue-link-policy.cjs +6 -2
  418. package/scripts/sync-runtime-launcher.cjs +184 -2
  419. package/scripts/verify-npm-publish.cjs +76 -20
  420. package/skills/gsd-add-tests/SKILL.md +6 -1
  421. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  422. package/skills/gsd-audit-fix/SKILL.md +5 -0
  423. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  424. package/skills/gsd-autonomous/SKILL.md +5 -0
  425. package/skills/gsd-capture/SKILL.md +8 -4
  426. package/skills/gsd-code-review/SKILL.md +7 -2
  427. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  428. package/skills/gsd-config/SKILL.md +8 -4
  429. package/skills/gsd-debug/SKILL.md +11 -7
  430. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  431. package/skills/gsd-docs-update/SKILL.md +12 -7
  432. package/skills/gsd-eval-review/SKILL.md +6 -1
  433. package/skills/gsd-execute-phase/SKILL.md +12 -7
  434. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  435. package/skills/gsd-fast/SKILL.md +4 -0
  436. package/skills/gsd-forensics/SKILL.md +5 -1
  437. package/skills/gsd-graphify/SKILL.md +10 -6
  438. package/skills/gsd-health/SKILL.md +5 -0
  439. package/skills/gsd-help/SKILL.md +7 -2
  440. package/skills/gsd-import/SKILL.md +7 -3
  441. package/skills/gsd-inbox/SKILL.md +5 -0
  442. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  443. package/skills/gsd-manager/SKILL.md +6 -1
  444. package/skills/gsd-map-codebase/SKILL.md +7 -3
  445. package/skills/gsd-mempalace-capture/SKILL.md +5 -1
  446. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  447. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  448. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  449. package/skills/gsd-new-milestone/SKILL.md +6 -1
  450. package/skills/gsd-new-project/SKILL.md +5 -0
  451. package/skills/gsd-next/SKILL.md +6 -1
  452. package/skills/gsd-ns-context/SKILL.md +4 -0
  453. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  454. package/skills/gsd-ns-manage/SKILL.md +4 -0
  455. package/skills/gsd-ns-project/SKILL.md +4 -0
  456. package/skills/gsd-ns-review/SKILL.md +4 -0
  457. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  458. package/skills/gsd-onboard/SKILL.md +6 -1
  459. package/skills/gsd-pause-work/SKILL.md +5 -1
  460. package/skills/gsd-phase/SKILL.md +8 -4
  461. package/skills/gsd-plan-phase/SKILL.md +6 -1
  462. package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
  463. package/skills/gsd-pr-branch/SKILL.md +4 -0
  464. package/skills/gsd-profile-user/SKILL.md +5 -1
  465. package/skills/gsd-progress/SKILL.md +6 -1
  466. package/skills/gsd-quick/SKILL.md +16 -10
  467. package/skills/gsd-quick-batch/SKILL.md +20 -8
  468. package/skills/gsd-review/SKILL.md +5 -1
  469. package/skills/gsd-review-backlog/SKILL.md +3 -2
  470. package/skills/gsd-secure-phase/SKILL.md +6 -1
  471. package/skills/gsd-ship/SKILL.md +5 -0
  472. package/skills/gsd-sketch/SKILL.md +7 -2
  473. package/skills/gsd-spec-phase/SKILL.md +5 -1
  474. package/skills/gsd-spike/SKILL.md +8 -3
  475. package/skills/gsd-surface/SKILL.md +5 -1
  476. package/skills/gsd-thread/SKILL.md +4 -0
  477. package/skills/gsd-ui-phase/SKILL.md +6 -1
  478. package/skills/gsd-ui-review/SKILL.md +6 -1
  479. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  480. package/skills/gsd-undo/SKILL.md +5 -1
  481. package/skills/gsd-update/SKILL.md +6 -2
  482. package/skills/gsd-validate-phase/SKILL.md +6 -1
  483. package/skills/gsd-verify-work/SKILL.md +6 -1
  484. package/skills/gsd-workspace/SKILL.md +7 -3
  485. package/skills/gsd-workstreams/SKILL.md +6 -6
  486. package/vscode/package.json +1 -1
  487. package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
@@ -34,6 +34,9 @@ const coreUtilsMod = require("./core-utils.cjs");
34
34
  const markdownSectionizerMod = require("./markdown-sectionizer.cjs");
35
35
  // eslint-disable-next-line @typescript-eslint/no-require-imports
36
36
  const planScanMod = require("./plan-scan.cjs");
37
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
38
+ const stateMod = require("./state.cjs");
39
+ const planning_document_cjs_1 = require("./planning-document.cjs");
37
40
  const { planningDir } = planningWorkspace;
38
41
  const { listAllPhaseDirs } = phaseLocatorMod;
39
42
  const { SCOPE } = planningScopeMod;
@@ -41,7 +44,22 @@ const { SCOPE } = planningScopeMod;
41
44
  // (src/frontmatter.cts) rather than a bespoke YAML touch — `spliceFrontmatter`
42
45
  // already solves "change exactly one key, preserve every other key's raw text
43
46
  // byte-for-byte", which is exactly the contract a `depends_on` rewrite needs.
44
- const { extractFrontmatter, spliceFrontmatter } = frontmatterMod;
47
+ const { extractFrontmatter, spliceFrontmatter, isFrontmatterWriteRefusal } = frontmatterMod;
48
+ /**
49
+ * The migration's fail-closed error for a phase artifact whose frontmatter the shared
50
+ * writer refuses to rewrite: it names the artifact's full path and, for a write refusal,
51
+ * the refusal code (also set as `code` on the error) — so the user can find the file and
52
+ * see why (found while implementing #5105).
53
+ */
54
+ function frontmatterRewriteError(what, filePath, sourceToken, targetToken, err) {
55
+ const code = isFrontmatterWriteRefusal(err) ? err.code : undefined;
56
+ const rewriteErr = new Error(`Cannot rewrite ${what} in ${JSON.stringify(filePath)} for phase token change `
57
+ + `${JSON.stringify(sourceToken)} -> ${JSON.stringify(targetToken)}`
58
+ + `${code ? ` [${code}]` : ''}: ${err.message}`);
59
+ if (code)
60
+ rewriteErr.code = code;
61
+ return rewriteErr;
62
+ }
45
63
  const { milestoneSections, isPhaseHeadingText } = roadmapParserMod;
46
64
  const { normalizeDependencyToken } = phaseMod;
47
65
  // #4144 round 5 Blocker 3: the single owner of the canonical short-alias
@@ -51,7 +69,11 @@ const { extractCanonicalPlanId } = coreUtilsMod;
51
69
  // #4144 round 5 Blocker 4: the readers' own fence-scanning engine
52
70
  // (tokenizeHeadings is built on this same seam) — reused here instead of a
53
71
  // third independent fence parser.
54
- const { scanFencedBlocks } = markdownSectionizerMod;
72
+ const { scanFencedBlocks, updateBullet, updateHeading } = markdownSectionizerMod;
73
+ // ADR-5057 §6 (Phase 13, #5217): every mutation of a planning artifact goes
74
+ // through its seam — headings/bullets through the sectionizer, PROJECT.md
75
+ // prose through PlanningDoc, STATE.md through its own write seam.
76
+ const { readModifyWriteStateMd } = stateMod;
55
77
  // #4144 round 5 follow-up (lint-plan-count-drift): the plan-scan owner's own
56
78
  // root-plan-file predicate (src/plan-scan.cts) — reused in
57
79
  // computeDependsOnRewrites instead of a private `/-PLAN\.md$/i` filename
@@ -113,7 +135,7 @@ const PROJECT_CODE_RE = new RegExp(`^${BRACKET_PROJECT_CODE_SRC}$`);
113
135
  // `.` never matches `\r` (it is its own LineTerminator, ECMA-262), so a CRLF
114
136
  // roadmap's `\r` sat just past the `(.*)` group's end — present in the LINE
115
137
  // but absent from `headingTail`, which the heading rebuild below is built
116
- // from. Since `applyRoadmapEdits` replaces a touched line's FULL text with
138
+ // from. Since the roadmap rewrite (`rewriteRoadmapLines`) replaces a touched line's FULL text with
117
139
  // the rebuilt one, every converted heading silently lost its `\r` while
118
140
  // every untouched line (and every checklist bullet, whose rewrite instead
119
141
  // slices the line's own remainder rather than reassembling captured groups)
@@ -698,8 +720,7 @@ function computeDependsOnRewrites(oldDirPath, sourceToken, targetToken, fileRena
698
720
  // must never be silently dropped — refuse before any write, the same
699
721
  // contract every other unrepresentable case in this file already
700
722
  // follows (e.g. computeArtifactRenames' collision refusal above).
701
- throw new Error(`Cannot rewrite depends_on in ${JSON.stringify(entry.name)} for phase token change `
702
- + `${JSON.stringify(sourceToken)} -> ${JSON.stringify(targetToken)}: ${err.message}`);
723
+ throw frontmatterRewriteError('depends_on', filePath, sourceToken, targetToken, err);
703
724
  }
704
725
  rewrites.push({
705
726
  oldName: entry.name,
@@ -800,8 +821,7 @@ function computePhaseFrontmatterRewrites(oldDirPath, dirName, sourceToken, targe
800
821
  catch (err) {
801
822
  // Same refuse-before-any-write contract every other unrepresentable
802
823
  // frontmatter rewrite in this file already follows.
803
- throw new Error(`Cannot rewrite phase frontmatter in ${JSON.stringify(entry.name)} for phase token change `
804
- + `${JSON.stringify(sourceToken)} -> ${JSON.stringify(targetToken)}: ${err.message}`);
824
+ throw frontmatterRewriteError('phase frontmatter', filePath, sourceToken, targetToken, err);
805
825
  }
806
826
  const finalName = renameByOldName.get(entry.name) ?? entry.name;
807
827
  if (existing) {
@@ -1817,40 +1837,71 @@ function computeMigrationPlan(cwd, options = {}) {
1817
1837
  crossRefEdits,
1818
1838
  };
1819
1839
  }
1840
+ // ─── Seam-routed planning writes (ADR-5057 §6, Phase 13, #5217) ───────────────
1820
1841
  /**
1821
- * Apply roadmap line edits via character-offset splicing against the
1822
- * ORIGINAL content string — never a full split/rejoin (#3413). `lineIndex`
1823
- * boundaries are found by scanning for the next bare `\n`, exactly matching
1824
- * how computeMigrationPlan() itself indexes lines (`roadmapContent.split('\n')`)
1825
- * — both sides must agree on line indexing for `lineText === edit.from` to
1826
- * match, and this keeps a `\r` that precedes a `\n` as part of the LINE text
1827
- * rather than a separately-normalized terminator. Only a line whose text
1828
- * exactly equals an edit's `from` is replaced; every other character —
1829
- * including every line's own terminator, touched or not — is copied
1830
- * byte-for-byte from the original, so a mixed-EOL ROADMAP.md never has its
1831
- * untouched lines silently flattened to one dominant style.
1842
+ * Apply the plan's ROADMAP.md line edits through the sectionizer seam: a
1843
+ * heading edit through `updateHeading`, a checklist edit through
1844
+ * `updateBullet`. Both match on the plan's own `lineIndex` AND exact line text
1845
+ * (`split('\n')` indexing, a trailing `\r` is part of the line), so two
1846
+ * headings with identical text in different milestones stay distinct, a stale
1847
+ * edit is left untouched, and every untouched byte is copied verbatim.
1848
+ *
1849
+ * An edit whose target line is still its `from` text after both seams ran was
1850
+ * refused by the seam (a line the sectionizer does not read as a heading or
1851
+ * bullet — fenced, or not CommonMark-shaped). That is thrown, never skipped:
1852
+ * a silently-skipped edit leaves ROADMAP.md half-migrated, and the mixed-state
1853
+ * guard then refuses every retry. `applyMigration` rolls back on the throw.
1832
1854
  */
1833
- function applyRoadmapEdits(content, edits) {
1834
- const editByLine = new Map();
1835
- for (const edit of edits)
1836
- editByLine.set(edit.lineIndex, edit);
1837
- let result = '';
1838
- let pos = 0;
1839
- let lineIndex = 0;
1840
- for (;;) {
1841
- const nlIdx = content.indexOf('\n', pos);
1842
- const lineEnd = nlIdx === -1 ? content.length : nlIdx;
1843
- const lineText = content.slice(pos, lineEnd);
1844
- const edit = editByLine.get(lineIndex);
1845
- result += edit && lineText === edit.from ? edit.to : lineText;
1846
- if (nlIdx === -1)
1847
- break;
1848
- result += '\n';
1849
- pos = nlIdx + 1;
1850
- lineIndex++;
1855
+ function rewriteRoadmapLines(content, plannedEdits) {
1856
+ // The planner reads raw lines, so it also plans edits for phase-shaped lines
1857
+ // inside a fenced example block. Fenced content is never a heading or a
1858
+ // bullet (the sectionizer's own view), so those edits are dropped here —
1859
+ // not thrown: a fenced example must neither be rewritten nor block the
1860
+ // migration.
1861
+ const fencedLines = new Set();
1862
+ const physicalLines = content.split('\n');
1863
+ for (const block of scanFencedBlocks(physicalLines)) {
1864
+ const last = block.closeLineIdx === -1 ? physicalLines.length - 1 : block.closeLineIdx;
1865
+ for (let i = block.openLineIdx; i <= last; i++)
1866
+ fencedLines.add(i);
1867
+ }
1868
+ const edits = plannedEdits.filter((edit) => !fencedLines.has(edit.lineIndex));
1869
+ let result = content;
1870
+ for (const edit of edits) {
1871
+ const atTarget = (rawLine, lineIndex) => lineIndex === edit.lineIndex && rawLine === edit.from;
1872
+ const swap = () => edit.to;
1873
+ result = updateHeading(result, (_heading, rawLine, lineIndex) => atTarget(rawLine, lineIndex), swap);
1874
+ result = updateBullet(result, (_text, rawLine, lineIndex) => atTarget(rawLine, lineIndex), swap);
1875
+ }
1876
+ const lines = result.split('\n');
1877
+ for (const edit of edits) {
1878
+ if (edit.from !== edit.to && lines[edit.lineIndex] === edit.from) {
1879
+ throw new Error(`ROADMAP.md line ${edit.lineIndex + 1} (${JSON.stringify(edit.from)}) is not a heading or checklist `
1880
+ + 'line the planning seam can rewrite');
1881
+ }
1851
1882
  }
1852
1883
  return result;
1853
1884
  }
1885
+ /**
1886
+ * Apply the cross-reference substitutions to one planning artifact's content
1887
+ * through `PlanningDoc` (`replaceProse`), in plan order. A document the seam
1888
+ * cannot read (an unterminated frontmatter fence) is refused — thrown, so the
1889
+ * migration rolls back — rather than rewritten blind.
1890
+ */
1891
+ function substituteCrossRefs(content, fileName, edits) {
1892
+ const parsed = (0, planning_document_cjs_1.parsePlanningDoc)(content, fileName);
1893
+ if (!parsed.ok) {
1894
+ throw new Error(`${fileName} cannot be read as a planning document: ${parsed.reason}`);
1895
+ }
1896
+ let doc = parsed.value;
1897
+ for (const edit of edits) {
1898
+ const next = (0, planning_document_cjs_1.replaceProse)(doc, edit.from, edit.to);
1899
+ if (!next.ok)
1900
+ throw new Error(`${fileName} cross-reference rewrite refused: ${next.reason}`);
1901
+ doc = next.value;
1902
+ }
1903
+ return doc.source;
1904
+ }
1854
1905
  // ─── applyMigration ───────────────────────────────────────────────────────────
1855
1906
  /**
1856
1907
  * Apply the migration plan computed by computeMigrationPlan().
@@ -1944,6 +1995,18 @@ function applyMigration(cwd, plan, options = {}) {
1944
1995
  const currentPath = node_path_1.default.join(newPath, rewrite.finalName);
1945
1996
  if (node_fs_1.default.existsSync(currentPath)) {
1946
1997
  const originalPath = node_path_1.default.join(oldPath, rewrite.oldName);
1998
+ // `rewrite.to` is the frontmatter seam's own output
1999
+ // (`spliceFrontmatter`, computed in computeDependsOnRewrites); it is
2000
+ // only persisted over the exact content it was computed from, so a
2001
+ // plan file edited since the plan was made is refused, never
2002
+ // clobbered with a stale whole-file image. The check runs BEFORE
2003
+ // the backup is recorded: the backup holds `rewrite.from`, which is
2004
+ // only the file's real content once this check has passed — recording
2005
+ // it first would make the rollback restore stale content over the
2006
+ // edited file.
2007
+ if (node_fs_1.default.readFileSync(currentPath, 'utf8') !== rewrite.from) {
2008
+ throw new Error(`${JSON.stringify(node_path_1.default.join('phases', phaseEntry.newDir, rewrite.finalName))} changed since the migration plan was computed`);
2009
+ }
1947
2010
  if (!fileBackups.has(originalPath)) {
1948
2011
  fileBackups.set(originalPath, { existed: true, content: rewrite.from });
1949
2012
  }
@@ -1956,36 +2019,36 @@ function applyMigration(cwd, plan, options = {}) {
1956
2019
  // 2. Rewrite ROADMAP.md phase headings
1957
2020
  if (plan.roadmapEdits.length > 0) {
1958
2021
  const roadmapContent = node_fs_1.default.readFileSync(roadmapPath, 'utf8');
1959
- const newRoadmapContent = applyRoadmapEdits(roadmapContent, plan.roadmapEdits);
2022
+ const newRoadmapContent = rewriteRoadmapLines(roadmapContent, plan.roadmapEdits);
1960
2023
  snapshotFile(roadmapPath);
1961
2024
  node_fs_1.default.writeFileSync(roadmapPath, newRoadmapContent, 'utf8');
1962
2025
  editedFiles.push('ROADMAP.md');
1963
2026
  }
1964
2027
  // 3. Rewrite cross-refs in STATE.md and PROJECT.md
1965
- const crossRefsByFile = new Map();
1966
- for (const edit of plan.crossRefEdits) {
1967
- if (!crossRefsByFile.has(edit.file)) {
1968
- crossRefsByFile.set(edit.file, []);
2028
+ // Two targets, two writes, one per seam (ADR-5057 §6): PROJECT.md's
2029
+ // content is rewritten by PlanningDoc, STATE.md goes through its own
2030
+ // read-modify-write seam (ADR-3408: lock, frontmatter sync and
2031
+ // preservation; body-only edit).
2032
+ const crossRefsFor = (fileName) => plan.crossRefEdits.filter((edit) => edit.file === fileName);
2033
+ const projectEdits = crossRefsFor('PROJECT.md');
2034
+ const projectPath = node_path_1.default.join(pDir, 'PROJECT.md');
2035
+ if (projectEdits.length > 0 && node_fs_1.default.existsSync(projectPath)) {
2036
+ const original = node_fs_1.default.readFileSync(projectPath, 'utf8');
2037
+ const rewritten = substituteCrossRefs(original, 'PROJECT.md', projectEdits);
2038
+ if (rewritten !== original) {
2039
+ snapshotFile(projectPath);
2040
+ node_fs_1.default.writeFileSync(projectPath, rewritten, 'utf8');
2041
+ editedFiles.push('PROJECT.md');
1969
2042
  }
1970
- crossRefsByFile.get(edit.file).push(edit);
1971
2043
  }
1972
- for (const [fileName, edits] of crossRefsByFile) {
1973
- const filePath = node_path_1.default.join(pDir, fileName);
1974
- if (!node_fs_1.default.existsSync(filePath))
1975
- continue;
1976
- let content = node_fs_1.default.readFileSync(filePath, 'utf8');
1977
- let changed = false;
1978
- for (const edit of edits) {
1979
- if (content.includes(edit.from)) {
1980
- // Replace all occurrences
1981
- content = content.split(edit.from).join(edit.to);
1982
- changed = true;
1983
- }
1984
- }
1985
- if (changed) {
1986
- snapshotFile(filePath);
1987
- node_fs_1.default.writeFileSync(filePath, content, 'utf8');
1988
- editedFiles.push(fileName);
2044
+ const stateEdits = crossRefsFor('STATE.md');
2045
+ const stateMdPath = node_path_1.default.join(pDir, 'STATE.md');
2046
+ if (stateEdits.length > 0 && node_fs_1.default.existsSync(stateMdPath)) {
2047
+ const original = node_fs_1.default.readFileSync(stateMdPath, 'utf8');
2048
+ if (substituteCrossRefs(original, 'STATE.md', stateEdits) !== original) {
2049
+ snapshotFile(stateMdPath);
2050
+ readModifyWriteStateMd(stateMdPath, (current) => substituteCrossRefs(current, 'STATE.md', stateEdits), cwd, { resync: false });
2051
+ editedFiles.push('STATE.md');
1989
2052
  }
1990
2053
  }
1991
2054
  // 4. Update config.json to the convention named by this plan — but only
@@ -2051,10 +2114,9 @@ module.exports = {
2051
2114
  computeMigrationPlan,
2052
2115
  applyMigration,
2053
2116
  computeDependsOnRewrites,
2054
- // #4698 review round 28: exported for the property test that drives the REAL
2055
- // roadmap transform (the same function applyMigration writes through) rather
2056
- // than a hand-rolled line-replacer stand-in, per ADR-1508's precedent of
2057
- // exporting an internal solely to satisfy RULESET.TESTS.property-based-testing.
2058
- // Not a new production seam: applyMigration remains its only caller in `src/`.
2059
- applyRoadmapEdits,
2117
+ // #4698 review round 28 precedent (ADR-1508): exported solely so the property
2118
+ // test drives the REAL roadmap transform `applyMigration` writes through —
2119
+ // which is now a composition of sectionizer seams (`updateHeading`,
2120
+ // `updateBullet`), not a line-indexer of its own. Not a new production seam.
2121
+ rewriteRoadmapLines,
2060
2122
  };