@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
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Canonical bracket convention card (#3638 / ADR-612 PR-5).
4
+ *
5
+ * This module is the sole editable source of the compact grammar diagram.
6
+ * Render sites import phaseIdCard(); generated documentation is held to the
7
+ * same bytes by tests/phase-id-card.test.cjs. PR-6 can therefore inject the
8
+ * card broadly without inventing another copy.
9
+ */
10
+ const PHASE_ID_CARD = [
11
+ '[GSD.02] 05.03-01',
12
+ ' │ │ │ │ │',
13
+ ' │ │ │ │ └── plan 01',
14
+ ' │ │ │ └────── subphase 03',
15
+ ' │ │ └───────── phase 05',
16
+ ' │ └───────────── milestone 02',
17
+ ' └───────────────── project GSD',
18
+ ].join('\n');
19
+ const PHASE_ID_LEGEND = "milestone = bracket integer; dots = phase-levels; one hyphen = plan; "
20
+ + "no 'Phase' word, no vX.Y";
21
+ function phaseIdCard(options = {}) {
22
+ const parts = [];
23
+ if (options.title)
24
+ parts.push(options.title, '');
25
+ parts.push(PHASE_ID_CARD, '', PHASE_ID_LEGEND);
26
+ return parts.join('\n');
27
+ }
28
+ module.exports = {
29
+ phaseIdCard,
30
+ PHASE_ID_CARD,
31
+ PHASE_ID_LEGEND,
32
+ };
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ /**
3
+ * Phase-ID display adapters (#3638 / ADR-612 PR-5).
4
+ *
5
+ * STATE.md and milestone metadata still expose the legacy `vN.0` marker on
6
+ * this stacked base. Display surfaces need to translate that metadata into a
7
+ * bracket identity without growing another renderer. These pure adapters do
8
+ * only the boundary normalization, then delegate identity parsing/rendering to
9
+ * phase-id.cts's canonical pair.
10
+ */
11
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
12
+ const phaseId = require("./phase-id.cjs");
13
+ const { parsePhaseId, renderMilestoneId, renderPhaseId } = phaseId;
14
+ function canonicalNumeric(value) {
15
+ let offset = 0;
16
+ while (offset < value.length - 1 && value[offset] === '0')
17
+ offset++;
18
+ const stripped = value.slice(offset);
19
+ return stripped.length < 2 ? stripped.padStart(2, '0') : stripped;
20
+ }
21
+ function isDigits(value) {
22
+ return value.length > 0
23
+ && [...value].every(char => char >= '0' && char <= '9');
24
+ }
25
+ function milestoneToken(value) {
26
+ if (typeof value !== 'string' && typeof value !== 'number')
27
+ return null;
28
+ const raw = String(value).replace(/^v/i, '');
29
+ const parts = raw.split('.');
30
+ if (parts.length > 2 || parts.some(part => !isDigits(part)))
31
+ return null;
32
+ return canonicalNumeric(parts[0]);
33
+ }
34
+ function phaseToken(value) {
35
+ if (typeof value !== 'string' && typeof value !== 'number')
36
+ return null;
37
+ const raw = String(value);
38
+ const parts = raw.split('.');
39
+ if (parts.length > 2 || parts.some(part => !isDigits(part)))
40
+ return null;
41
+ return parts.map(canonicalNumeric).join('.');
42
+ }
43
+ /**
44
+ * Render a bracket phase display from legacy milestone metadata.
45
+ * Returns null for incomplete or invalid metadata so cosmetic callers can
46
+ * degrade without breaking a command/statusline render.
47
+ */
48
+ function renderBracketPhaseDisplay(milestone, phase, projectCode) {
49
+ const project = typeof projectCode === 'string' ? projectCode : '';
50
+ const mm = milestoneToken(milestone);
51
+ const pp = phaseToken(phase);
52
+ if (!project || mm === null || pp === null)
53
+ return null;
54
+ try {
55
+ return renderPhaseId(parsePhaseId(`${project}.${mm}-${pp}`));
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ /** Render only the bracket milestone label, still through canonical parsing. */
62
+ function renderBracketMilestoneDisplay(milestone, projectCode) {
63
+ const project = typeof projectCode === 'string' ? projectCode : '';
64
+ const mm = milestoneToken(milestone);
65
+ if (!project || mm === null)
66
+ return null;
67
+ try {
68
+ // The sentinel phase is a validation vehicle, not a rendering artifact.
69
+ return renderMilestoneId(parsePhaseId(`${project}.${mm}-00`));
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ module.exports = {
76
+ renderBracketPhaseDisplay,
77
+ renderBracketMilestoneDisplay,
78
+ };
@@ -59,6 +59,20 @@ const OPTIONAL_PHASE_TAG_SOURCE = '(?:\\s*\\([^)\\n]{0,200}\\))?';
59
59
  // (scripts/lint-phase-id-drift.cjs) fails CI if a literal re-derivation is
60
60
  // introduced outside this module without a `// phase-id-owner:` justification.
61
61
  const PHASE_NUMBER_TOKEN_SOURCE = '\\d+[A-Z]?(?:\\.\\d+)*';
62
+ // #4764: a phase REFERENCE in depends-on PROSE — the token in context, directly
63
+ // following "Phase"/"Phases", with bare-token list continuation ("Phases 1 and 2",
64
+ // "Phase 1, 2, and 3", "Phase 1-3"). Built HERE, beside the token grammar it is
65
+ // anchored on, because two readers consume Depends-on prose (init.manager's
66
+ // dep_phases and planning-inspect's dependencies) and re-deriving the anchored
67
+ // form at each would drift exactly the way PHASE_NUMBER_TOKEN_SOURCE's own
68
+ // anti-divergence rule exists to prevent. A bare digit run is the right shape
69
+ // test for a phase id and the WRONG test for a reference: the whole-field
70
+ // scrape this replaces pulled calendar dates ("2026-09-14" → 2026/09/14), git
71
+ // shas ("8bf403100d" → 8b/403100d/…) and ledger ids (WINDOWS #1843) in as
72
+ // dependencies. The `-` separator deliberately extracts range ENDPOINTS only
73
+ // ("Phase 1-3" → 1, 3) — the pre-#4764 behavior; interior enumeration stays
74
+ // out (a range's middle is not written as a reference).
75
+ const PHASE_DEP_REF_SOURCE = `\\bphases?\\s+(${PHASE_NUMBER_TOKEN_SOURCE}(?:(?:\\s*,\\s*(?:and\\s+)?|\\s+and\\s+|\\s*&\\s*|\\s+(?:to|through)\\s+|\\s*-\\s*)${PHASE_NUMBER_TOKEN_SOURCE})*)`;
62
76
  // #2528 review: the CASE-FLEXIBLE renderings of the two sources above, for call
63
77
  // sites that scan directory names (where a project code or a variant suffix may
64
78
  // legitimately be lowercase) and therefore cannot use a case-sensitive class.
@@ -308,6 +322,30 @@ function phaseHeadingPrefixSrcFor(baseline, convention, capturing = false) {
308
322
  const bracketAlt = `\\[${id}\\][ \\t]*(?:Phase\\s+|(?=\\d))`;
309
323
  return `(?:${bracketAlt}|${base})`;
310
324
  }
325
+ /**
326
+ * The single owner of the "scan a whole document for every phase heading"
327
+ * pattern (#4865 / ADR-4910 §8) — anchored (`^ {0,3}#{2,4}`, so indentation up
328
+ * to 3 spaces is tolerated but a heading is never matched mid-line), global,
329
+ * multiline, convention-aware via `phaseHeadingPrefixSrcFor`. Returns the
330
+ * capture-group layout alongside the regex so a caller never re-derives the
331
+ * bracket-convention offset (`const G = convention === 'bracket' ? 1 : 0`)
332
+ * itself — a second, independently-computed offset is exactly the kind of
333
+ * drift `scripts/lint-phase-id-drift.cjs` exists to catch structurally, not
334
+ * just by pattern text.
335
+ *
336
+ * Distinct from `buildPhaseHeadingRegex` (`src/roadmap.cts`), which searches
337
+ * for ONE already-known phase number (anchored `^`, no `g` flag, phase number
338
+ * interpolated literally) — a different contract for a different question.
339
+ * This function answers "which phases exist in this content", not "does this
340
+ * specific phase exist".
341
+ */
342
+ function buildPhaseHeadingScanRegex(baseline, convention) {
343
+ const bracketGroup = convention === 'bracket' ? 1 : null;
344
+ const phaseNumGroup = bracketGroup ? 2 : 1;
345
+ const phaseNameGroup = phaseNumGroup + 1;
346
+ const regex = new RegExp(`^ {0,3}#{2,4}\\s*${phaseHeadingPrefixSrcFor(baseline, convention, true)}(${PHASE_NUMBER_TOKEN_SOURCE})${OPTIONAL_PHASE_TAG_SOURCE}:\\s*([^\\n]+)`, 'gim');
347
+ return { regex, bracketGroup, phaseNumGroup, phaseNameGroup };
348
+ }
311
349
  function stripProjectCodePrefix(value, caseInsensitive = true) {
312
350
  const input = String(value);
313
351
  const re = caseInsensitive ? PROJECT_CODE_PREFIX_STRIP_RE_I : PROJECT_CODE_PREFIX_STRIP_RE;
@@ -451,10 +489,27 @@ function parsePhaseId(input) {
451
489
  // tokens unchanged.
452
490
  throw new Error(`parsePhaseId: not a bracket phase id: ${JSON.stringify(input)}`);
453
491
  }
492
+ function renderMilestoneId(id) {
493
+ return `[${id.project}.${id.milestone}]`;
494
+ }
454
495
  function renderPhaseId(id) {
455
496
  const sub = id.subphase ? `.${id.subphase}` : '';
456
497
  const plan = id.plan ? `-${id.plan}` : '';
457
- return `[${id.project}.${id.milestone}] ${id.phase}${sub}${plan}`;
498
+ return `${renderMilestoneId(id)} ${id.phase}${sub}${plan}`;
499
+ }
500
+ /** Whether a legacy phase token has a lossless spelling in bracket display grammar. */
501
+ function isBracketPhaseTokenRepresentable(token) {
502
+ try {
503
+ const bracketToken = normalizePhaseName(token)
504
+ .split('.')
505
+ .map((segment) => segment.padStart(2, '0'))
506
+ .join('.');
507
+ parsePhaseId(`[GSD.00] ${bracketToken}`);
508
+ return true;
509
+ }
510
+ catch {
511
+ return false;
512
+ }
458
513
  }
459
514
  // PhaseId is a structural type: nothing forces a caller through parsePhaseId,
460
515
  // so toDir cannot trust project/milestone/phase/subphase are already
@@ -1017,7 +1072,7 @@ function isPhaseArtifact(fileName, phaseDirName, convention) {
1017
1072
  * whichever path produced the candidates, which is what makes a bracket dir
1018
1073
  * read exactly what its legacy twin reads.
1019
1074
  */
1020
- function matchesPhaseTokenCandidates(fileName, rawCandidates) {
1075
+ function expandPhaseTokenCandidates(rawCandidates) {
1021
1076
  // Each reading is compared in BOTH its padded and de-padded form: files are
1022
1077
  // written padded by `normalizePhaseName` (`cmdScaffold`) while directories
1023
1078
  // are often not (`1-unpadded`), and legacy trees carry the reverse pairing.
@@ -1025,9 +1080,19 @@ function matchesPhaseTokenCandidates(fileName, rawCandidates) {
1025
1080
  // sub-phase (`03A`, `03.1`) has no meaningful de-padded form and is left
1026
1081
  // alone, so this only ever ADDS a reading and can never drop one.
1027
1082
  const depad = (t) => (/^\d+$/.test(t) ? String(Number(t)) : t);
1028
- const candidates = new Set(rawCandidates
1083
+ return new Set(rawCandidates
1029
1084
  .flatMap(t => [t, normalizePhaseName(t), depad(t)])
1030
1085
  .map(t => t.toUpperCase()));
1086
+ }
1087
+ function matchesPhaseTokenCandidates(fileName, rawCandidates) {
1088
+ const candidates = expandPhaseTokenCandidates(rawCandidates);
1089
+ if (matchPhaseTokenCandidateSpan(fileName, candidates) !== null)
1090
+ return true;
1091
+ // FIX 2: token-less filename (bare "VERIFICATION.md"/"UAT.md") — containment
1092
+ // in this phase's own directory listing is sufficient.
1093
+ return derivePhaseTokenSegments(fileName).tokenSegments.length === 0;
1094
+ }
1095
+ function matchPhaseTokenCandidateSpan(fileName, candidates) {
1031
1096
  const fileUpper = fileName.toUpperCase();
1032
1097
  for (const candidate of candidates) {
1033
1098
  // A dotted sub-phase segment (e.g. `01.1-CONTEXT.md`) is a legitimate
@@ -1053,11 +1118,43 @@ function matchesPhaseTokenCandidates(fileName, rawCandidates) {
1053
1118
  if (fileUpper.startsWith(`${candidate}-`) ||
1054
1119
  fileUpper.startsWith(`${candidate}.`) ||
1055
1120
  fileUpper.startsWith(`${candidate}_`))
1056
- return true;
1121
+ return { start: 0, end: candidate.length };
1057
1122
  }
1058
- // FIX 2: token-less filename (bare "VERIFICATION.md"/"UAT.md") — containment
1059
- // in this phase's own directory listing is sufficient.
1060
- return derivePhaseTokenSegments(fileName).tokenSegments.length === 0;
1123
+ return null;
1124
+ }
1125
+ /**
1126
+ * Return the exact leading token span by which the phase-artifact reader
1127
+ * attributes a phase-qualified filename to `phaseDirName`.
1128
+ *
1129
+ * Membership is first decided by `isPhaseArtifact`, then the span is selected
1130
+ * from the same padded, de-padded, case-folded candidate set used by
1131
+ * `matchesPhaseTokenCandidates`. Token-less containment fallbacks return null
1132
+ * because there is no phase token in the filename to replace.
1133
+ */
1134
+ function phaseArtifactTokenSpan(fileName, phaseDirName, convention) {
1135
+ if (!isPhaseArtifact(fileName, phaseDirName, convention))
1136
+ return null;
1137
+ if (convention === 'bracket') {
1138
+ const bracketDir = phaseDirName.match(BRACKET_DIR_TOKEN_RE);
1139
+ if (bracketDir) {
1140
+ const qualified = fileName.match(BRACKET_QUALIFIED_KEY_RE);
1141
+ if (qualified && bracketQualifiedKey(fileName, convention) !== null) {
1142
+ return { start: 0, end: qualified[0].length };
1143
+ }
1144
+ const bracketCandidates = expandPhaseTokenCandidates([bracketDir[1]]);
1145
+ return matchPhaseTokenCandidateSpan(fileName, bracketCandidates);
1146
+ }
1147
+ }
1148
+ const { tokenSegments } = derivePhaseTokenSegments(phaseDirName);
1149
+ if (tokenSegments.length === 0)
1150
+ return null;
1151
+ const literalToken = extractPhaseToken(phaseDirName);
1152
+ const strippedDir = stripProjectCodePrefix(phaseDirName);
1153
+ const strippedToken = strippedDir !== phaseDirName ? extractPhaseToken(strippedDir) : literalToken;
1154
+ const leadingRunMatch = strippedDir.match(LEADING_DIGIT_RUN_RE);
1155
+ const rawCandidates = [literalToken, strippedToken, leadingRunMatch?.[1]].filter((token) => Boolean(token));
1156
+ const candidates = expandPhaseTokenCandidates(rawCandidates);
1157
+ return matchPhaseTokenCandidateSpan(fileName, candidates);
1061
1158
  }
1062
1159
  /**
1063
1160
  * #3511: scope `fileNames` to the subset that passes
@@ -1245,7 +1342,7 @@ const unpad = (digits) => digits.replace(/^0+(?=\d)/, '');
1245
1342
  * candidates (#2237).
1246
1343
  *
1247
1344
  * TAKE `matches[0]` — `cmdPhasesList`, `cmdInitManager`, `cmdRoadmapAnalyze`,
1248
- * `cmdVerifySchemaDrift`, `detectVerifyFailed`. Each read a directory to
1345
+ * the schema-drift gate (`resolvePhaseDirByToken`), `detectVerifyFailed`. Each read a directory to
1249
1346
  * DECORATE a row they are already emitting; each used `.find()` before this
1250
1347
  * PR, so first-match is their prior behavior preserved verbatim, and each is
1251
1348
  * order-stable because the directory list is sorted and this function filters
@@ -1538,6 +1635,7 @@ module.exports = {
1538
1635
  OPTIONAL_PROJECT_CODE_PREFIX_SOURCE,
1539
1636
  OPTIONAL_PHASE_TAG_SOURCE,
1540
1637
  PHASE_NUMBER_TOKEN_SOURCE,
1638
+ PHASE_DEP_REF_SOURCE,
1541
1639
  CASE_FLEXIBLE_PROJECT_CODE_PREFIX_SOURCE,
1542
1640
  CASE_FLEXIBLE_PHASE_NUMBER_TOKEN_SOURCE,
1543
1641
  PHASE_CONTINUATION_SEGMENT_SOURCE,
@@ -1554,6 +1652,7 @@ module.exports = {
1554
1652
  BASE_PHASE_LABEL_PREFIX_SRC,
1555
1653
  PHASE_HEADING_BASELINE,
1556
1654
  phaseHeadingPrefixSrcFor,
1655
+ buildPhaseHeadingScanRegex,
1557
1656
  foldBracketId,
1558
1657
  bracketQualifiedKey,
1559
1658
  stripProjectCodePrefix,
@@ -1561,7 +1660,9 @@ module.exports = {
1561
1660
  getMilestoneFromPhaseId,
1562
1661
  getPhaseDirFromPhaseId,
1563
1662
  parsePhaseId,
1663
+ renderMilestoneId,
1564
1664
  renderPhaseId,
1665
+ isBracketPhaseTokenRepresentable,
1565
1666
  toDir,
1566
1667
  SENTINEL_RANGES,
1567
1668
  isSentinelPhaseId,
@@ -1571,6 +1672,7 @@ module.exports = {
1571
1672
  comparePhaseNum,
1572
1673
  extractPhaseToken,
1573
1674
  isPhaseArtifact,
1675
+ phaseArtifactTokenSpan,
1574
1676
  scopeToPhase,
1575
1677
  phaseTokenMatches,
1576
1678
  matchPhaseDirs,
@@ -31,6 +31,9 @@ const markdown_table_cjs_1 = require("./markdown-table.cjs");
31
31
  // eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-id.cjs is an export= CommonJS module
32
32
  const phaseIdMod = require("./phase-id.cjs");
33
33
  const { isSentinelPhaseId } = phaseIdMod;
34
+ // #5060: `phase-status.cjs` is a load-time leaf (no top-level requires), safe
35
+ // to import here for the ROADMAP Status-cell reader.
36
+ const phase_status_cjs_1 = require("./phase-status.cjs");
34
37
  /**
35
38
  * #3227: the single owner of "where is this ROADMAP's Progress table".
36
39
  * Lifted verbatim out of deriveProgressFromRoadmap so `state-contract.cts`
@@ -93,8 +96,6 @@ function deriveProgressFromRoadmap(roadmapContent) {
93
96
  const table = locateProgressTable(roadmapContent);
94
97
  if (table) {
95
98
  const allRows = table.rows;
96
- const completed = allRows.filter((r) => /^complete$/i.test((r['Status'] ?? '').trim())).length;
97
- completedPhases = completed > 0 ? completed : null;
98
99
  // Data rows only (exclude sentinel phases 0 and 999.x).
99
100
  // #3185: canonical sentinel predicate (SENTINEL_RANGES [0,999]) — this was a local 999-only literal that admitted Phase 0.
100
101
  const dataRows = allRows.filter((r) => {
@@ -102,6 +103,12 @@ function deriveProgressFromRoadmap(roadmapContent) {
102
103
  return /^\d/.test(phase) && !isSentinelPhaseId(phase);
103
104
  });
104
105
  totalPhases = dataRows.length > 0 ? dataRows.length : null;
106
+ // #5060: routed through the Phase Status Module's `parseRoadmapStatusCell`
107
+ // owner (rather than a local `/^complete$/i` regex) and counted over
108
+ // `dataRows` (not `allRows`) — a sentinel row's Status cell must never
109
+ // contribute to `completedPhases`.
110
+ const completed = dataRows.filter((r) => (0, phase_status_cjs_1.parseRoadmapStatusCell)(r['Status']) === phase_status_cjs_1.WIRE_STATUS.COMPLETE).length;
111
+ completedPhases = completed > 0 ? completed : null;
105
112
  let totalPlansSum = 0;
106
113
  for (const r of allRows) {
107
114
  const cell = (r['Plans Complete'] ?? '').trim();
@@ -35,7 +35,7 @@ const frontmatterModule = require("./frontmatter.cjs");
35
35
  const { extractFrontmatter } = frontmatterModule;
36
36
  // eslint-disable-next-line @typescript-eslint/no-require-imports
37
37
  const planDependencyGraphModule = require("./plan-dependency-graph.cjs");
38
- const { computeHaltPropagation, buildSummaryFileIndex, isSummaryFileHalted } = planDependencyGraphModule;
38
+ const { computeHaltPropagation, buildSummaryFileIndex, isSummaryFileHalted, isSummaryFileBlocked } = planDependencyGraphModule;
39
39
  // eslint-disable-next-line @typescript-eslint/no-require-imports
40
40
  const roadmapParserModule = require("./roadmap-parser.cjs");
41
41
  const { getMilestonePhaseFilter } = roadmapParserModule;
@@ -146,13 +146,15 @@ function listArchiveVersionDirs(cwd, wsOverride) {
146
146
  }
147
147
  return out;
148
148
  }
149
- function searchPhaseInDir(baseDir, relBase, normalized) {
149
+ function searchPhaseInDir(baseDir, relBase, normalized, convention) {
150
150
  try {
151
151
  const dirs = readSubdirectories(baseDir, true);
152
152
  // #2528: canonical two-pass selection (exact token match, then the
153
153
  // bare-integer leading-digit-run fallback) shared with the find-phase and
154
154
  // phase-plan-index scans — see phase-id.cts::matchPhaseDirs.
155
- const { matches, usedBareFallback } = matchPhaseDirs(dirs, normalized);
155
+ // #4801: the convention is threaded (optional) so bracket-convention
156
+ // consumers get exact token matching here too.
157
+ const { matches, usedBareFallback } = matchPhaseDirs(dirs, normalized, convention);
156
158
  if (matches.length === 0)
157
159
  return null;
158
160
  // #2237: fail loud when multiple directories match the same bare phase
@@ -176,6 +178,7 @@ function searchPhaseInDir(baseDir, relBase, normalized) {
176
178
  halted_plans: [],
177
179
  blocked_by: {},
178
180
  runnable_plans: [],
181
+ ready_plans: [],
179
182
  };
180
183
  }
181
184
  const match = matches[0];
@@ -208,12 +211,19 @@ function searchPhaseInDir(baseDir, relBase, normalized) {
208
211
  const planIds = plans.map(p => p.replace('-PLAN.md', '').replace('PLAN.md', ''));
209
212
  const planIdByLower = new Map(planIds.map(id => [id.toLowerCase(), id]));
210
213
  const canonicalToPlanId = new Map(plans.map((p, i) => [extractCanonicalPlanId(p).toLowerCase(), planIds[i]]));
214
+ // #4628: raw depends_on per plan, so readiness can fail closed on a
215
+ // DROPPED edge (a dep token that resolves to nothing carries no evidence)
216
+ // instead of the resolution silently shrinking the dependency list.
217
+ const rawDeps = plans.map((p) => parsePlanDependsOn(phaseDir, p));
218
+ // #4628: completion evidence excludes status:blocked summaries (#3345) —
219
+ // a failure record is not completion, matching cmdPhasePlanIndex's count.
220
+ const completionEvidence = buildSummaryFileIndex(summaries.filter((f) => !isSummaryFileBlocked(node_path_1.default.join(phaseDir, f))), extractCanonicalPlanId);
211
221
  const haltNodes = plans.map((p, i) => {
212
222
  const planId = planIds[i];
213
223
  const canonical = extractCanonicalPlanId(p);
214
224
  const summaryFile = summaryFileByPlanId.get(planId) ?? summaryFileByPlanId.get(canonical);
215
225
  const halted = summaryFile !== undefined && isSummaryFileHalted(node_path_1.default.join(phaseDir, summaryFile));
216
- const resolvedDependsOn = parsePlanDependsOn(phaseDir, p)
226
+ const resolvedDependsOn = rawDeps[i]
217
227
  .map((dep) => {
218
228
  const lower = dep.toLowerCase();
219
229
  return planIdByLower.get(lower) ?? canonicalToPlanId.get(lower) ?? null;
@@ -226,6 +236,7 @@ function searchPhaseInDir(baseDir, relBase, normalized) {
226
236
  const incompletePlanSet = new Set(incompletePlans);
227
237
  const blockedByFiles = {};
228
238
  const runnablePlans = [];
239
+ const readyPlans = [];
229
240
  for (let i = 0; i < plans.length; i++) {
230
241
  const p = plans[i];
231
242
  if (!incompletePlanSet.has(p))
@@ -233,10 +244,16 @@ function searchPhaseInDir(baseDir, relBase, normalized) {
233
244
  const causes = blockedBy.get(planIds[i]) ?? [];
234
245
  if (causes.length > 0) {
235
246
  blockedByFiles[p] = causes;
247
+ continue;
236
248
  }
237
- else {
238
- runnablePlans.push(p);
239
- }
249
+ runnablePlans.push(p);
250
+ // #4628: DAG-ready on top of runnable — every dependency must have
251
+ // completion evidence (a matching, non-blocked SUMMARY) and no dropped
252
+ // edge: both readers of this contract fail closed identically.
253
+ const depsComplete = rawDeps[i].length === haltNodes[i].resolvedDependsOn.length &&
254
+ haltNodes[i].resolvedDependsOn.every((dep) => completionEvidence.has(dep));
255
+ if (depsComplete)
256
+ readyPlans.push(p);
240
257
  }
241
258
  return {
242
259
  found: true,
@@ -259,19 +276,21 @@ function searchPhaseInDir(baseDir, relBase, normalized) {
259
276
  halted_plans: haltedPlans,
260
277
  blocked_by: blockedByFiles,
261
278
  runnable_plans: runnablePlans,
279
+ ready_plans: readyPlans,
262
280
  };
263
281
  }
264
282
  catch {
265
283
  return null;
266
284
  }
267
285
  }
268
- function findPhaseInternal(cwd, phase) {
286
+ function findPhaseInternal(cwd, phase, convention) {
269
287
  if (!phase)
270
288
  return null;
271
289
  const phasesDir = node_path_1.default.join(planningDir(cwd), 'phases');
272
290
  const normalized = normalizePhaseName(phase);
273
291
  const relPhasesDir = toPosixPath(node_path_1.default.relative(cwd, phasesDir));
274
- const current = searchPhaseInDir(phasesDir, relPhasesDir, normalized);
292
+ // #4801: convention threaded through to the matcher (see searchPhaseInDir).
293
+ const current = searchPhaseInDir(phasesDir, relPhasesDir, normalized, convention);
275
294
  if (current)
276
295
  return current;
277
296
  // #2855: scope the archived-milestone fallback to the SAME workstream as the
@@ -285,7 +304,7 @@ function findPhaseInternal(cwd, phase) {
285
304
  // getArchivedPhaseDirs via listArchiveVersionDirs (see its doc comment).
286
305
  for (const { version, archivePath } of listArchiveVersionDirs(cwd)) {
287
306
  const relBase = toPosixPath(node_path_1.default.relative(cwd, archivePath));
288
- const result = searchPhaseInDir(archivePath, relBase, normalized);
307
+ const result = searchPhaseInDir(archivePath, relBase, normalized, convention);
289
308
  if (result) {
290
309
  result.archived = version;
291
310
  return result;