@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
@@ -15,9 +15,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15
15
  return (mod && mod.__esModule) ? mod : { "default": mod };
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.NO_LOCAL_CONFIG_DIR_SENTINEL = exports.RetiredRuntimeError = exports.RETIRED_RUNTIME_IDS = void 0;
18
+ exports.NO_LOCAL_CONFIG_DIR_SENTINEL = exports.FALLBACK_HOST_BEHAVIORS = exports.LEGACY_NON_REGISTRY_RUNTIME_IDS = exports.LEGACY_NON_REGISTRY_RUNTIME_HOMES = exports.RetiredRuntimeError = exports.UnknownRuntimeError = exports.RETIRED_RUNTIME_IDS = void 0;
19
19
  exports.isRetiredRuntimeId = isRetiredRuntimeId;
20
20
  exports.assertNotRetiredRuntime = assertNotRetiredRuntime;
21
+ exports.isKnownRuntimeId = isKnownRuntimeId;
22
+ exports.assertKnownRuntime = assertKnownRuntime;
23
+ exports.hostBehaviorsFor = hostBehaviorsFor;
21
24
  exports.canonicalizeRuntimeName = canonicalizeRuntimeName;
22
25
  exports.resolveRuntimeNameFromCandidates = resolveRuntimeNameFromCandidates;
23
26
  exports.getProjectInstructionFile = getProjectInstructionFile;
@@ -25,7 +28,6 @@ exports.getDirName = getDirName;
25
28
  exports.getRuntimeLabel = getRuntimeLabel;
26
29
  exports.getGlobalConfigHomeFragment = getGlobalConfigHomeFragment;
27
30
  exports.runtimeFlags = runtimeFlags;
28
- exports.getRuntimeNewProjectCommand = getRuntimeNewProjectCommand;
29
31
  const node_fs_1 = __importDefault(require("node:fs"));
30
32
  const node_path_1 = __importDefault(require("node:path"));
31
33
  /**
@@ -92,6 +94,22 @@ const RETIRED_RUNTIME_SPELLINGS = new Map(Array.from(RETIRED_RUNTIME_DETAILS.key
92
94
  * with like.
93
95
  */
94
96
  exports.RETIRED_RUNTIME_IDS = new Set(RETIRED_RUNTIME_DETAILS.keys());
97
+ /**
98
+ * Error thrown when a non-empty runtime id that is neither registered nor a
99
+ * known non-registry host reaches a descriptor accessor (ADR-5057 §5, #5169).
100
+ * Before this, such an id silently resolved to Claude Code's values.
101
+ */
102
+ class UnknownRuntimeError extends Error {
103
+ code = 'GSD_UNKNOWN_RUNTIME';
104
+ runtimeId;
105
+ constructor(runtimeId) {
106
+ super(`Runtime "${runtimeId}" is not registered in the capability registry. `
107
+ + 'Refusing to resolve it, because the previous behaviour silently returned Claude Code\'s values.');
108
+ this.name = 'UnknownRuntimeError';
109
+ this.runtimeId = runtimeId;
110
+ }
111
+ }
112
+ exports.UnknownRuntimeError = UnknownRuntimeError;
95
113
  /** Error thrown when a retired runtime id reaches a resolution accessor. */
96
114
  class RetiredRuntimeError extends Error {
97
115
  code = 'GSD_RETIRED_RUNTIME';
@@ -127,6 +145,120 @@ function assertNotRetiredRuntime(runtime) {
127
145
  return;
128
146
  throw new RetiredRuntimeError(id, detail);
129
147
  }
148
+ /**
149
+ * Legacy runtime ids that have a genuine, dedicated resolution branch in
150
+ * `runtime-homes.cts` but no capability-registry descriptor (#3024). They are
151
+ * KNOWN ids: every accessor resolves them rather than refusing. Enumerated by
152
+ * hand and MUST stay in lockstep with `getGlobalConfigDir`'s hardcoded
153
+ * branches — add an id only after confirming it has a real dedicated branch.
154
+ */
155
+ exports.LEGACY_NON_REGISTRY_RUNTIME_HOMES = Object.freeze({
156
+ // Grok's agents home: `GROK_AGENTS_HOME`, else `~/.agents` (dir = path segments under $HOME).
157
+ grok: Object.freeze({ env: 'GROK_AGENTS_HOME', dir: Object.freeze(['.agents']) }),
158
+ });
159
+ exports.LEGACY_NON_REGISTRY_RUNTIME_IDS = new Set(Object.keys(exports.LEGACY_NON_REGISTRY_RUNTIME_HOMES));
160
+ /** The capability registry's `runtimes` map, or `null` when it fails to load. */
161
+ function loadRegistryRuntimes() {
162
+ try {
163
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
164
+ const reg = require('./capability-registry.cjs');
165
+ return (reg && reg.runtimes) || null;
166
+ }
167
+ catch {
168
+ return null;
169
+ }
170
+ }
171
+ /**
172
+ * True when `runtime` is a registered runtime id (own property of the registry
173
+ * `runtimes` map — never an inherited key such as `__proto__`/`constructor`)
174
+ * or one of {@link LEGACY_NON_REGISTRY_RUNTIME_IDS}. Raw-id match: no trimming,
175
+ * no case folding, no alias expansion.
176
+ */
177
+ function isKnownRuntimeId(runtime) {
178
+ if (typeof runtime !== 'string' || runtime.length === 0)
179
+ return false;
180
+ const runtimes = loadRegistryRuntimes();
181
+ if (runtimes && Object.prototype.hasOwnProperty.call(runtimes, runtime))
182
+ return true;
183
+ return exports.LEGACY_NON_REGISTRY_RUNTIME_IDS.has(runtime);
184
+ }
185
+ /**
186
+ * The ONE refusal every descriptor accessor shares (ADR-5057 §5, #5169).
187
+ * No-op for an absent id (`''`, non-string): that is the documented
188
+ * "no runtime selected" generic path. A retired id throws
189
+ * {@link RetiredRuntimeError}; any other non-empty id that is not known throws
190
+ * {@link UnknownRuntimeError} instead of silently resolving to Claude Code's
191
+ * values. When the registry itself failed to load, unknown-ness cannot be
192
+ * proven, so the check degrades to a no-op (the #338 floor in
193
+ * {@link hostBehaviorsFor} still protects the reference host).
194
+ */
195
+ function assertKnownRuntime(runtime) {
196
+ if (typeof runtime !== 'string' || runtime.length === 0)
197
+ return;
198
+ assertNotRetiredRuntime(runtime);
199
+ if (loadRegistryRuntimes() === null)
200
+ return;
201
+ if (!isKnownRuntimeId(runtime))
202
+ throw new UnknownRuntimeError(runtime);
203
+ }
204
+ /**
205
+ * The #338-privacy fail-safe floor: host behaviors for the two hosts whose
206
+ * generic fallthrough would be WRONG if the registry failed to load. Moved
207
+ * here from `bin/install.js` so the registry-load-failure degrade lives in the
208
+ * single host-behaviors accessor instead of one of three copies (#5169).
209
+ */
210
+ exports.FALLBACK_HOST_BEHAVIORS = Object.freeze({
211
+ claude: Object.freeze({
212
+ settingsFileByScope: Object.freeze({ local: 'settings.local.json', global: 'settings.json' }),
213
+ permissionsSchema: 'claude',
214
+ sourceMarkerFile: '.gsd-source',
215
+ hyphenNameAgentBody: true,
216
+ legacyCommandsGsdInstallMigration: true,
217
+ legacyCommandsGsdUninstall: 'global',
218
+ }),
219
+ // antigravity's global config dir is resolved dynamically (env-overridable,
220
+ // multi-segment); this floor keeps that routing intact if the registry fails
221
+ // to load instead of falling through to the wrong '.claude' fragment (#2096).
222
+ antigravity: Object.freeze({ globalDirResolver: 'antigravity' }),
223
+ });
224
+ /**
225
+ * The single accessor for a runtime's host behaviors
226
+ * (capabilities/<runtime>/capability.json -> runtime.hostBehaviors). Replaces
227
+ * the three private `_hostBehaviors` copies in `bin/install.js`,
228
+ * `install-engine.cts` and `runtime-artifact-conversion.cts`.
229
+ *
230
+ * - absent id (`''`, non-string) → `{}` (generic path).
231
+ * - registered id → the descriptor's `hostBehaviors` (or `{}` when it declares
232
+ * none).
233
+ * - known non-registry id (`grok`) → `{}`.
234
+ * - registry failed to load → the #338 floor for the ids it covers, else `{}`.
235
+ * - any other id (unregistered, retired, a prototype key) → `{}`: no declared
236
+ * behaviors, which is the GENERIC path — never Claude Code's behaviors.
237
+ *
238
+ * Unlike the path/label accessors (`getDirName`, `getGlobalConfigDir`, …), whose
239
+ * fallthrough answer is Claude Code's value and therefore a silent wrong answer
240
+ * (#4632), an absent behavior is the correct answer for a label GSD does not
241
+ * know — and this accessor is read by guard and hook code on user-supplied
242
+ * runtime labels (stale config, a retired id), where a throw would crash the
243
+ * session rather than skip a behavior. ADR-5057 §5 Phase 10 amendment.
244
+ *
245
+ * `registry` is injectable so the load-failure branch is unit-testable.
246
+ */
247
+ function hostBehaviorsFor(runtime, registry) {
248
+ if (typeof runtime !== 'string' || runtime.length === 0)
249
+ return {};
250
+ const floor = () => Object.prototype.hasOwnProperty.call(exports.FALLBACK_HOST_BEHAVIORS, runtime)
251
+ ? exports.FALLBACK_HOST_BEHAVIORS[runtime]
252
+ : {};
253
+ const runtimes = registry === undefined ? loadRegistryRuntimes() : (registry && registry.runtimes) || null;
254
+ if (runtimes === null)
255
+ return floor();
256
+ if (Object.prototype.hasOwnProperty.call(runtimes, runtime)) {
257
+ const declared = runtimes[runtime]?.runtime?.hostBehaviors;
258
+ return declared ? declared : floor();
259
+ }
260
+ return {};
261
+ }
130
262
  const FALLBACK_ALIASES = {
131
263
  claude: ['claude', 'claude-code', 'claude-cli'],
132
264
  opencode: ['opencode', 'open-code', 'opencode-cli'],
@@ -302,7 +434,7 @@ exports.NO_LOCAL_CONFIG_DIR_SENTINEL = '(no-local-config-dir)';
302
434
  function getDirName(runtime) {
303
435
  // Same silent-wrong-answer class as the four accessors AC#1 names: this
304
436
  // returned '.claude' for a retired id, and it feeds runtimeConfigDir.
305
- assertNotRetiredRuntime(runtime);
437
+ assertKnownRuntime(runtime);
306
438
  if (!runtime)
307
439
  return '.claude';
308
440
  // eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -373,7 +505,7 @@ const RUNTIME_LABELS = {
373
505
  * 'Claude Code'. Sibling to `getDirName`; pure (no I/O).
374
506
  */
375
507
  function getRuntimeLabel(runtime) {
376
- assertNotRetiredRuntime(runtime);
508
+ assertKnownRuntime(runtime);
377
509
  if (!runtime)
378
510
  return 'Claude Code';
379
511
  const label = RUNTIME_LABELS[runtime];
@@ -429,7 +561,7 @@ const GLOBAL_CONFIG_HOME_FRAGMENTS = {
429
561
  * dynamically). Pure: no I/O. Sibling to `getDirName` / `getRuntimeLabel`.
430
562
  */
431
563
  function getGlobalConfigHomeFragment(runtime) {
432
- assertNotRetiredRuntime(runtime);
564
+ assertKnownRuntime(runtime);
433
565
  if (!runtime)
434
566
  return DEFAULT_CONFIG_HOME_FRAGMENT;
435
567
  const frag = GLOBAL_CONFIG_HOME_FRAGMENTS[runtime];
@@ -475,25 +607,8 @@ function runtimeFlags(runtime) {
475
607
  }
476
608
  return Object.freeze(flags);
477
609
  }
478
- /**
479
- * The `/gsd-new-project` invocation syntax per runtime — the post-install
480
- * "next step" command string. Most runtimes use the default `/gsd-new-project`;
481
- * a few hosts need a different surface syntax. Collapses the 14-line
482
- * `if (runtime === 'x') command = ...` chain in bin/install.js's next-step
483
- * message (ADR-1239 Phase B / #1679 AC2). Pure: no I/O.
484
- */
485
- const DEFAULT_NEW_PROJECT_COMMAND = '/gsd-new-project';
486
- const RUNTIME_NEW_PROJECT_COMMANDS = {
487
- codex: '$gsd-new-project',
488
- cursor: 'gsd-new-project (mention the skill name)',
489
- kimi: '/skill:gsd-new-project',
490
- };
491
- function getRuntimeNewProjectCommand(runtime) {
492
- // Deliberately NOT retirement-guarded: this value does not vary by runtime
493
- // in a way that makes a retired id a WRONG answer, so throwing here would
494
- // cost callers a crash without correcting anything.
495
- if (!runtime)
496
- return DEFAULT_NEW_PROJECT_COMMAND;
497
- const c = RUNTIME_NEW_PROJECT_COMMANDS[runtime];
498
- return typeof c === 'string' && c.length > 0 ? c : DEFAULT_NEW_PROJECT_COMMAND;
499
- }
610
+ // The `/gsd-new-project` next-step command is no longer a per-runtime table
611
+ // here: it is generated from the runtime's registered trigger surface by
612
+ // `resolveAdvertisedNewProject` (runtime-artifact-layout.cts, #5215, ADR-5057
613
+ // §5 Phase 12), so what the installer advertises cannot differ from what a
614
+ // runtime registered.
@@ -34,6 +34,7 @@ exports._setInstallRuntimeMarkerForTests = _setInstallRuntimeMarkerForTests;
34
34
  exports._resetInstallRuntimeMarkerCacheForTests = _resetInstallRuntimeMarkerCacheForTests;
35
35
  exports.resolveExplicitRuntime = resolveExplicitRuntime;
36
36
  exports.resolveRuntime = resolveRuntime;
37
+ exports.resolveActiveRuntime = resolveActiveRuntime;
37
38
  exports.formatGsdSlashFor = formatGsdSlashFor;
38
39
  const node_fs_1 = __importDefault(require("node:fs"));
39
40
  const node_path_1 = __importDefault(require("node:path"));
@@ -148,31 +149,36 @@ function resolveExplicitRuntime(projectDir, env = process.env) {
148
149
  const envRuntime = (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(env['GSD_RUNTIME']);
149
150
  if (envRuntime)
150
151
  return envRuntime;
151
- if (projectDir) {
152
- try {
153
- // Read config.json directly (not via loadConfig). loadConfig has a side
154
- // effect of normalizing and re-writing legacy keys back to disk, which
155
- // would mutate the project file just to read the runtime name. We only
156
- // need the literal `runtime:` value, so a plain JSON read is sufficient
157
- // and side-effect-free.
158
- const configPath = node_path_1.default.join(projectDir, '.planning', 'config.json');
159
- if (node_fs_1.default.existsSync(configPath)) {
160
- const raw = node_fs_1.default.readFileSync(configPath, 'utf-8');
161
- const parsed = JSON.parse(raw);
162
- if (parsed && typeof parsed === 'object' && 'runtime' in parsed) {
163
- const configRuntime = (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(parsed['runtime']);
164
- if (configRuntime)
165
- return configRuntime;
166
- }
167
- }
168
- }
169
- catch {
170
- // Fall through to default — a missing/broken config must not crash
171
- // runtime output formatting.
172
- }
173
- }
152
+ const config = readProjectConfig(projectDir);
153
+ const configRuntime = (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(config ? config['runtime'] : undefined);
154
+ if (configRuntime)
155
+ return configRuntime;
174
156
  return null;
175
157
  }
158
+ /**
159
+ * Read `<projectDir>/.planning/config.json` as a plain object, or `null` when
160
+ * there is no project, no file, or it is unreadable or not an object.
161
+ *
162
+ * Read directly (not via loadConfig). loadConfig has a side effect of
163
+ * normalizing and re-writing legacy keys back to disk, which would mutate the
164
+ * project file just to read the runtime name. A plain JSON read is sufficient
165
+ * and side-effect-free. A missing or broken config must not crash runtime
166
+ * output formatting, so every failure degrades to `null`.
167
+ */
168
+ function readProjectConfig(projectDir) {
169
+ if (!projectDir)
170
+ return null;
171
+ try {
172
+ const configPath = node_path_1.default.join(projectDir, '.planning', 'config.json');
173
+ if (!node_fs_1.default.existsSync(configPath))
174
+ return null;
175
+ const parsed = JSON.parse(node_fs_1.default.readFileSync(configPath, 'utf-8'));
176
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
177
+ }
178
+ catch {
179
+ return null;
180
+ }
181
+ }
176
182
  /**
177
183
  * Resolve the effective runtime for a project directory.
178
184
  *
@@ -195,13 +201,24 @@ function resolveExplicitRuntime(projectDir, env = process.env) {
195
201
  * @returns the resolved runtime name
196
202
  */
197
203
  function resolveRuntime(projectDir) {
198
- const explicit = resolveExplicitRuntime(projectDir);
199
- if (explicit)
200
- return explicit;
201
- const markerRuntime = (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(readInstallRuntimeMarker());
202
- if (markerRuntime)
203
- return markerRuntime;
204
- return 'claude';
204
+ // The same chain `resolveActiveRuntime` owns, fed by a project directory:
205
+ // one implementation, so the two entry points cannot drift (#5169).
206
+ return resolveActiveRuntime(readProjectConfig(projectDir));
207
+ }
208
+ /**
209
+ * Resolve the effective runtime from an ALREADY-LOADED config object — the one
210
+ * chain every consumer of "which runtime is this install" shares (#5169,
211
+ * ADR-5057 §5, #4690):
212
+ *
213
+ * env.GSD_RUNTIME > config.runtime > install marker > 'claude'
214
+ *
215
+ * Canonicalized, so an alias or case variant (`claude-code`, `Claude`) cannot
216
+ * defeat a downstream comparison. `resolveRuntime` above is the same chain for
217
+ * callers that hold a project directory rather than a parsed config; the marker
218
+ * is read through `readInstallRuntimeMarker` in both.
219
+ */
220
+ function resolveActiveRuntime(config, env = process.env) {
221
+ return (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(env['GSD_RUNTIME'], config ? config['runtime'] : undefined, readInstallRuntimeMarker()) || 'claude';
205
222
  }
206
223
  /**
207
224
  * Convenience: format using the runtime resolved from a project directory.
@@ -64,6 +64,8 @@ const node_fs_1 = __importDefault(require("node:fs"));
64
64
  // at load time and become un-mockable.
65
65
  const node_child_process_1 = __importDefault(require("node:child_process"));
66
66
  const pattern_cjs_1 = require("./pattern.cjs");
67
+ const frontmatter_fence_cjs_1 = require("./frontmatter-fence.cjs");
68
+ const runtime_name_policy_cjs_1 = require("./runtime-name-policy.cjs");
67
69
  /**
68
70
  * Convert a filesystem path to POSIX form (forward slashes) by translating the
69
71
  * platform-native separator. Single seam for native→POSIX conversion.
@@ -146,7 +148,10 @@ function formatHookCommandForRuntime(command, opts = {}) {
146
148
  // path missed this guard and reintroduced the #166/#377 failure (#580).
147
149
  function shellHookOmitsBashRunner({ platform, runtime = 'generic', isShellHook = false } = {}) {
148
150
  const p = platform ?? process.platform;
149
- return p === 'win32' && runtime === 'claude' && isShellHook;
151
+ // #5169: descriptor-declared (`hostBehaviors.omitBashRunnerOnWindows`). The
152
+ // `'generic'` default and any other non-registered label declares nothing, so
153
+ // it never omits the runner, exactly as before.
154
+ return p === 'win32' && isShellHook && (0, runtime_name_policy_cjs_1.hostBehaviorsFor)(runtime).omitBashRunnerOnWindows === true;
150
155
  }
151
156
  // Builds the command string for a local-install managed `.sh` hook. Mirrors the
152
157
  // global buildHookCommand path but uses the $CLAUDE_PROJECT_DIR-anchored prefix
@@ -1033,16 +1038,39 @@ function probeTty(opts = {}) {
1033
1038
  }
1034
1039
  }
1035
1040
  // ─── Platform file I/O ────────────────────────────────────────────────────────
1041
+ /**
1042
+ * How many leading lines of LF-only `text` are its closed YAML frontmatter block (opening
1043
+ * fence through closing fence), or 0 when there is none (an unterminated block is not
1044
+ * frontmatter). The fence is `locateFrontmatterFence`'s — the one owner the frontmatter reader
1045
+ * and writer (`frontmatter.cts`) also read — so the normalizer skips exactly the block every
1046
+ * reader sees (found while implementing #5105: this was a private mirror of the reader's
1047
+ * fence rule, because `frontmatter.cts` imports this module, and the two drifted).
1048
+ */
1049
+ function leadingFrontmatterLineCount(text) {
1050
+ const fence = (0, frontmatter_fence_cjs_1.locateFrontmatterFence)(text);
1051
+ if (!fence || !fence.closed)
1052
+ return 0;
1053
+ // The lines before the closing fence, plus the closing fence line itself.
1054
+ return text.slice(0, fence.closingStart).split('\n').length;
1055
+ }
1036
1056
  function _normalizeMd(content) {
1037
1057
  if (!content || typeof content !== 'string')
1038
1058
  return content;
1039
1059
  let text = content.replace(/\r\n/g, '\n');
1040
1060
  const lines = text.split('\n');
1061
+ // The frontmatter block is YAML, not markdown: its lines are published exactly as written.
1062
+ // A `# comment` is not a heading, and a blank line inserted into a multi-line quoted scalar
1063
+ // or removed from a block scalar changes the value (found while implementing #5105).
1064
+ const frontmatterLines = leadingFrontmatterLineCount(text);
1041
1065
  const result = [];
1042
1066
  const fenceRegex = /^```/;
1043
1067
  const insideFence = new Array(lines.length);
1044
1068
  let fenceOpen = false;
1045
1069
  for (let i = 0; i < lines.length; i++) {
1070
+ if (i < frontmatterLines) {
1071
+ insideFence[i] = false;
1072
+ continue;
1073
+ }
1046
1074
  if (fenceRegex.test(lines[i].trimEnd())) {
1047
1075
  if (fenceOpen) {
1048
1076
  insideFence[i] = false;
@@ -1059,6 +1087,10 @@ function _normalizeMd(content) {
1059
1087
  }
1060
1088
  for (let i = 0; i < lines.length; i++) {
1061
1089
  const line = lines[i];
1090
+ if (i < frontmatterLines) {
1091
+ result.push(line);
1092
+ continue;
1093
+ }
1062
1094
  const prev = i > 0 ? lines[i - 1] : '';
1063
1095
  const prevTrimmed = prev.trimEnd();
1064
1096
  const trimmed = line.trimEnd();
@@ -1089,8 +1121,11 @@ function _normalizeMd(content) {
1089
1121
  result.push('');
1090
1122
  }
1091
1123
  }
1124
+ // The frontmatter lines are `result`'s first entries, unchanged; the blank-run collapse
1125
+ // applies from the line ending that closes the block onward.
1126
+ const head = result.slice(0, frontmatterLines).join('\n');
1092
1127
  text = result.join('\n');
1093
- text = text.replace(/\n{3,}/g, '\n\n');
1128
+ text = head + text.slice(head.length).replace(/\n{3,}/g, '\n\n');
1094
1129
  text = text.replace(/\n*$/, '\n');
1095
1130
  return text;
1096
1131
  }
@@ -55,7 +55,7 @@ const planningWorkspace = require("./planning-workspace.cjs");
55
55
  const { planningPaths } = planningWorkspace;
56
56
  // eslint-disable-next-line @typescript-eslint/no-require-imports
57
57
  const frontmatter = require("./frontmatter.cjs");
58
- const { extractFrontmatter } = frontmatter;
58
+ const { extractFrontmatter, frontmatterBlock } = frontmatter;
59
59
  // eslint-disable-next-line @typescript-eslint/no-require-imports -- phase-lifecycle.cjs is an export= CommonJS module
60
60
  const phaseLifecycle = require("./phase-lifecycle.cjs");
61
61
  const { deriveProgressFromRoadmap } = phaseLifecycle;
@@ -71,6 +71,10 @@ const { readStateHeadFreshness } = stateMod;
71
71
  // eslint-disable-next-line @typescript-eslint/no-require-imports
72
72
  const unusableInput = require("./unusable-input.cjs");
73
73
  const { warnUnusableInput, UNUSABLE_REASON } = unusableInput;
74
+ // #5118: the verification-status owner's frontmatter-only report check.
75
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
76
+ const verificationMod = require("./verification.cjs");
77
+ const { findVerificationStatusError } = verificationMod;
74
78
  // ─── Constants ────────────────────────────────────────────────────────────────
75
79
  /**
76
80
  * Staleness threshold for idle-stranded detection. A clean tree whose last
@@ -285,11 +289,20 @@ function detectVerifyFailed(cwd, currentPhaseRaw) {
285
289
  catch {
286
290
  return false;
287
291
  }
292
+ // #5118: this phase's VERIFICATION report `status` is judged by its owner
293
+ // (src/verification.cts, the same frontmatter-only, containment-checked
294
+ // locator every reader shares) — an out-of-set value is the owner's hard
295
+ // error here as at every other reader, never a silent "not failed". The
296
+ // body `STATUS:` marker scan below is this probe's own signal.
297
+ const statusError = findVerificationStatusError([latestDir]);
298
+ if (statusError)
299
+ throw statusError;
288
300
  const candidates = files.filter((f) => /summary|verif(?:y|ication)|uat/i.test(f));
289
301
  for (const name of candidates) {
290
302
  let content = '';
303
+ const filePath = node_path_1.default.join(latestDir, name);
291
304
  try {
292
- content = node_fs_1.default.readFileSync(node_path_1.default.join(latestDir, name), 'utf-8');
305
+ content = node_fs_1.default.readFileSync(filePath, 'utf-8');
293
306
  }
294
307
  catch {
295
308
  continue;
@@ -311,7 +324,10 @@ function readStateFile(statePath) {
311
324
  return null;
312
325
  }
313
326
  const fm = extractFrontmatter(content, statePath);
314
- const body = content.replace(/^---[\s\S]*?---\s*/, '');
327
+ // The body starts after the block `extractFrontmatter` just read (the one fence owner), so a
328
+ // `---` inside a value, a BOM, or an adjacent empty block cannot cut it somewhere else.
329
+ const block = frontmatterBlock(content);
330
+ const body = block ? block.rest.replace(/^\s+/, '') : content;
315
331
  return { fm, body };
316
332
  }
317
333
  /** Collect the full signal set from disk for `cwd`. Exported for unit tests. */
@@ -21,22 +21,23 @@
21
21
  const fs = require('fs');
22
22
  const path = require('path');
23
23
  const os = require('os');
24
+ const capabilityRegistry = require('./capability-registry.cjs');
25
+ const { hostBehaviorsFor } = require('./runtime-name-policy.cjs');
26
+ const { resolveConfigHomeFromDescriptor } = require('./runtime-homes.cjs');
27
+ const { resolveActiveRuntime } = require('./runtime-slash.cjs');
24
28
 
25
29
  /**
26
- * Runtimes whose agent config is static frontmatter/TOML baked at install time.
27
- * MUST stay in sync with the bake paths in bin/install.js. The parity test in
28
- * tests/stale-bake-guard.test.cjs asserts this matches the runtimes that
29
- * actually emit a baked model: line id #2256 (opencode), #49/#2256 (codex),
30
- * and #2093 (kilo).
30
+ * Runtimes whose agent config is static frontmatter/TOML baked at install time,
31
+ * DERIVED from the runtime descriptors (`hostBehaviors.bakesStaticAgentModel`,
32
+ * #5169) instead of a hand-kept list: line id #2256 (opencode), #49/#2256
33
+ * (codex), and #2093 (kilo) declare it, and a new baking runtime does too.
31
34
  */
32
- const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(['codex', 'kilo', 'opencode']);
35
+ const STATIC_FRONTMATTER_RUNTIMES = Object.freeze(
36
+ Object.keys(capabilityRegistry.runtimes)
37
+ .filter((id) => hostBehaviorsFor(id).bakesStaticAgentModel === true)
38
+ .sort(),
39
+ );
33
40
 
34
- /** Per-runtime `gsd install` flag, for the remediation hint in the warning. */
35
- const INSTALL_FLAG_BY_RUNTIME = Object.freeze({
36
- codex: '--codex',
37
- opencode: '--opencode',
38
- kilo: '--kilo',
39
- });
40
41
 
41
42
  const _warnedKeys = new Set();
42
43
 
@@ -64,7 +65,7 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
64
65
  const signal = detectStaleBake({ runtime, configMtimeMs, agentMtimeMs });
65
66
  if (!signal) return '';
66
67
  const configDate = new Date(configMtimeMs).toISOString();
67
- const installFlag = INSTALL_FLAG_BY_RUNTIME[runtime] || `--${runtime}`;
68
+ const installFlag = `--${runtime}`;
68
69
  return [
69
70
  `gsd: model config in ${configPath} changed since agents were last baked (${configDate}).`,
70
71
  ` Static-frontmatter runtime '${runtime}' ignores the new model_overrides`,
@@ -74,44 +75,27 @@ function formatStaleBakeWarning({ runtime, configPath, configMtimeMs, agentMtime
74
75
  }
75
76
 
76
77
  /**
77
- * Pure: resolve the active runtime id from a parsed config object.
78
- * Returns the runtime string, or `'claude'` when unset (the spawn-time default
79
- * for which the guard is a no-op).
78
+ * Resolve the active runtime id for the guard: the SAME chain every consumer of
79
+ * "which runtime is this install" reads — GSD_RUNTIME → config.runtime →
80
+ * per-install `.gsd-runtime` marker → `'claude'` (#5169, #4690). Returns
81
+ * `'claude'` when nothing is declared (the spawn-time default for which the
82
+ * guard is a no-op).
80
83
  */
81
- function resolveRuntimeFromConfig(config) {
82
- if (config && typeof config === 'object'
83
- && typeof config.runtime === 'string' && config.runtime) {
84
- return config.runtime;
85
- }
86
- return 'claude';
84
+ function resolveRuntimeFromConfig(config, env = process.env) {
85
+ return resolveActiveRuntime(config, env);
87
86
  }
88
87
 
89
88
  /**
90
- * Resolve the install root for a runtime's agent files, honoring the same env
91
- * vars the installer does (CODEX_HOME, OPENCODE_CONFIG_DIR, KILO_CONFIG_DIR).
92
- * Returns the absolute directory or `null` for unsupported runtimes.
89
+ * Resolve the install root for a runtime's agent files from the runtime
90
+ * descriptor's `configHome` (the same resolution the installer uses), then
91
+ * append `agents` — the installer writes agents to `<configHome>/agents`
92
+ * (plural; #2093). Returns the absolute directory or `null` for runtimes that
93
+ * do not bake a static agent model.
93
94
  */
94
95
  function resolveAgentDir(runtime, { env = process.env, homedir = os.homedir } = {}) {
95
- if (runtime === 'opencode') {
96
- const base = (env.OPENCODE_CONFIG_DIR && String(env.OPENCODE_CONFIG_DIR).trim()) || path.join(homedir(), '.config', 'opencode');
97
- // #2093 fix: the installer writes agents to `<base>/agents` (plural — see
98
- // bin/install.js's universal `agentsDest = path.join(targetDir, 'agents')`,
99
- // verified against a live `--opencode --global` install). The prior
100
- // singular `agent` never matched the real install output, so this guard's
101
- // `findOldestAgentMtime` always hit ENOENT and warnIfStaleBake was a
102
- // silent no-op for opencode in production — discovered while wiring the
103
- // parallel kilo entry below (same bake mechanism, #2093).
104
- return path.join(base, 'agents');
105
- }
106
- if (runtime === 'kilo') {
107
- const base = (env.KILO_CONFIG_DIR && String(env.KILO_CONFIG_DIR).trim()) || path.join(homedir(), '.config', 'kilo');
108
- return path.join(base, 'agents');
109
- }
110
- if (runtime === 'codex') {
111
- const base = (env.CODEX_HOME && String(env.CODEX_HOME).trim()) || path.join(homedir(), '.codex');
112
- return path.join(base, 'agents');
113
- }
114
- return null;
96
+ if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return null;
97
+ const configHome = capabilityRegistry.runtimes[runtime].runtime.configHome;
98
+ return path.join(resolveConfigHomeFromDescriptor(configHome, { env, home: homedir() }), 'agents');
115
99
  }
116
100
 
117
101
  /**
@@ -168,8 +152,8 @@ function findOldestAgentMtime(runtime, { env = process.env, homedir = os.homedir
168
152
  for (const entry of entries) {
169
153
  if (!entry.isFile()) continue;
170
154
  if (!entry.name.startsWith('gsd-')) continue;
171
- const isAgentFile = ((runtime === 'opencode' || runtime === 'kilo') && entry.name.endsWith('.md'))
172
- || (runtime === 'codex' && (entry.name.endsWith('.toml') || entry.name.endsWith('.md')));
155
+ const bakedExts = hostBehaviorsFor(runtime).bakedAgentFileExtensions;
156
+ const isAgentFile = Array.isArray(bakedExts) && bakedExts.some((ext) => entry.name.endsWith(ext));
173
157
  if (!isAgentFile) continue;
174
158
  try {
175
159
  const st = fsStatSync(path.join(dir, entry.name));
@@ -209,7 +193,7 @@ function warnIfStaleBake(cwd, options = {}) {
209
193
  } = options;
210
194
  try {
211
195
  const resolvedConfig = config || _readRuntimeConfig(cwd, { fsStatSync });
212
- const runtime = resolveRuntimeFromConfig(resolvedConfig);
196
+ const runtime = resolveRuntimeFromConfig(resolvedConfig, env);
213
197
  if (!STATIC_FRONTMATTER_RUNTIMES.includes(runtime)) return false;
214
198
 
215
199
  const dedupKey = `${runtime}::${path.resolve(cwd || '.')}`;
@@ -73,6 +73,12 @@ exports.buildStateContract = buildStateContract;
73
73
  exports.publishStateContract = publishStateContract;
74
74
  const node_path_1 = __importDefault(require("node:path"));
75
75
  const node_fs_1 = __importDefault(require("node:fs"));
76
+ // #5060: `phase-status.cjs` is a LOAD-TIME LEAF — no top-level requires of
77
+ // its own (verification.cjs/plan-scan.cjs are required lazily, only inside
78
+ // `phaseStatus()`) — so importing it here at top level does not reopen the
79
+ // documented `state.cjs -> state-contract.cjs -> smart-entry.cjs -> state.cjs`
80
+ // require cycle the file header warns about.
81
+ const phase_status_cjs_1 = require("./phase-status.cjs");
76
82
  // ─── Public wire vocabulary ────────────────────────────────────────────────
77
83
  exports.STATE_CONTRACT_VERSION = '1.0.0';
78
84
  exports.STATE_CONTRACT_FLAVOR = 'core';
@@ -80,12 +86,14 @@ exports.STATE_CONTRACT_FLAVOR = 'core';
80
86
  exports.CONTRACT_KEY_ORDER = Object.freeze(['contract', 'flavor', 'milestone', 'phases', 'next', 'updated_at']);
81
87
  /** Key order of each emitted phase object — an observable, pinned by test. */
82
88
  exports.PHASE_KEY_ORDER = Object.freeze(['number', 'name', 'status']);
83
- /** Frozen three-value phase status vocabulary. Conservative in what we send (Postel's Law). */
84
- exports.PHASE_STATUS = Object.freeze({
85
- COMPLETE: 'complete',
86
- IN_PROGRESS: 'in_progress',
87
- PENDING: 'pending',
88
- });
89
+ /**
90
+ * Frozen three-value phase status vocabulary. Conservative in what we send
91
+ * (Postel's Law). #5060: identity-pinned to the Phase Status Module's own
92
+ * `WIRE_STATUS` — this is not a copy, it IS that frozen object, so
93
+ * `state-contract`'s `PHASE_STATUS` and `phase-status.cjs`'s `WIRE_STATUS`
94
+ * can never independently drift.
95
+ */
96
+ exports.PHASE_STATUS = phase_status_cjs_1.WIRE_STATUS;
89
97
  /** Frozen `publishStateContract` result reasons. */
90
98
  exports.PUBLISH_REASON = Object.freeze({
91
99
  PUBLISHED: 'published',
@@ -146,17 +154,6 @@ function buildMilestone(cwd) {
146
154
  }
147
155
  // ─── phases: Progress-table (primary) enumerator ───────────────────────────
148
156
  const PHASE_CELL_RE = /^(\d+(?:\.\d+)*)\s*[.:)–—-]?\s*(.*)$/;
149
- function statusFromProgressCell(raw) {
150
- const normalized = (raw ?? '').trim().toLowerCase().replace(/\s+/g, ' ');
151
- if (normalized === 'complete')
152
- return exports.PHASE_STATUS.COMPLETE;
153
- if (normalized === 'in progress')
154
- return exports.PHASE_STATUS.IN_PROGRESS;
155
- // Everything else — 'not started', 'deferred' (design row 12, lossy by
156
- // design), '', and any unrecognized word — folds to pending. An
157
- // unrecognized status must never reach the wire as a 4th value.
158
- return exports.PHASE_STATUS.PENDING;
159
- }
160
157
  function phasesFromProgressTable(table) {
161
158
  const { isSentinelPhaseId } = owners();
162
159
  const phases = [];
@@ -169,7 +166,7 @@ function phasesFromProgressTable(table) {
169
166
  const m = PHASE_CELL_RE.exec(cell);
170
167
  const number = m ? m[1] : cell;
171
168
  const name = m && m[2].trim().length > 0 ? m[2].trim() : null;
172
- phases.push({ number, name, status: statusFromProgressCell(row['Status']) });
169
+ phases.push({ number, name, status: (0, phase_status_cjs_1.parseRoadmapStatusCell)(row['Status']) });
173
170
  }
174
171
  return phases;
175
172
  }