@opengsd/gsd-core 1.18.0 → 1.20.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 (308) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -1
  3. package/.opencode/plugins/gsd-core.js +2 -3
  4. package/agents/gsd-code-fixer.compact.md +7 -7
  5. package/agents/gsd-code-fixer.md +13 -7
  6. package/agents/gsd-code-reviewer.compact.md +49 -8
  7. package/agents/gsd-code-reviewer.md +53 -14
  8. package/agents/gsd-executor.md +8 -4
  9. package/agents/gsd-verifier.md +1 -1
  10. package/bin/install.js +422 -103
  11. package/commands/gsd/update.md +5 -2
  12. package/gsd-core/bin/gsd-tools.cjs +179 -30
  13. package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
  14. package/gsd-core/bin/lib/args-terminator.cjs +114 -0
  15. package/gsd-core/bin/lib/broken-windows.cjs +59 -1
  16. package/gsd-core/bin/lib/capability-lifecycle.cjs +1 -12
  17. package/gsd-core/bin/lib/capability-lock.cjs +13 -2
  18. package/gsd-core/bin/lib/capability-registry.cjs +376 -103
  19. package/gsd-core/bin/lib/capability-state.cjs +14 -8
  20. package/gsd-core/bin/lib/capability-validator.cjs +32 -0
  21. package/gsd-core/bin/lib/commands.cjs +27 -17
  22. package/gsd-core/bin/lib/config-loader.cjs +13 -3
  23. package/gsd-core/bin/lib/config.cjs +256 -58
  24. package/gsd-core/bin/lib/core-utils.cjs +45 -0
  25. package/gsd-core/bin/lib/decision-coverage-support.cjs +74 -0
  26. package/gsd-core/bin/lib/frontmatter.cjs +21 -3
  27. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +2 -2
  28. package/gsd-core/bin/lib/gate-context-drift.cjs +9 -4
  29. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +6 -1
  30. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +6 -1
  31. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
  32. package/gsd-core/bin/lib/gate-phase-context.cjs +7 -8
  33. package/gsd-core/bin/lib/gate-schema-drift.cjs +1 -1
  34. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +63 -22
  35. package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
  36. package/gsd-core/bin/lib/git-info-exclude.cjs +52 -0
  37. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +31 -12
  38. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +9 -7
  39. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +3 -3
  40. package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
  41. package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
  42. package/gsd-core/bin/lib/host-integration.cjs +13 -6
  43. package/gsd-core/bin/lib/init.cjs +245 -68
  44. package/gsd-core/bin/lib/install-engine.cjs +246 -32
  45. package/gsd-core/bin/lib/install-profiles.cjs +9 -4
  46. package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
  47. package/gsd-core/bin/lib/io.cjs +6 -0
  48. package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
  49. package/gsd-core/bin/lib/markdown-sectionizer.cjs +147 -1
  50. package/gsd-core/bin/lib/markdown-table.cjs +23 -0
  51. package/gsd-core/bin/lib/mcp-server.cjs +8 -5
  52. package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
  53. package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
  54. package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
  55. package/gsd-core/bin/lib/milestone.cjs +61 -51
  56. package/gsd-core/bin/lib/model-catalog.cjs +8 -0
  57. package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
  58. package/gsd-core/bin/lib/phase-entry-grammar.cjs +119 -0
  59. package/gsd-core/bin/lib/phase-id-display.cjs +2 -0
  60. package/gsd-core/bin/lib/phase-id.cjs +629 -38
  61. package/gsd-core/bin/lib/phase-lifecycle.cjs +12 -44
  62. package/gsd-core/bin/lib/phase-locator.cjs +328 -19
  63. package/gsd-core/bin/lib/phase.cjs +3066 -653
  64. package/gsd-core/bin/lib/planning-document.cjs +26 -5
  65. package/gsd-core/bin/lib/planning-inspect.cjs +27 -35
  66. package/gsd-core/bin/lib/planning-snapshot.cjs +15 -8
  67. package/gsd-core/bin/lib/planning-workspace.cjs +21 -3
  68. package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
  69. package/gsd-core/bin/lib/read-only-git-env.cjs +79 -0
  70. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +2 -2
  71. package/gsd-core/bin/lib/review-lane-descriptor.cjs +57 -2
  72. package/gsd-core/bin/lib/review-lane-invocation.cjs +125 -18
  73. package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
  74. package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +11 -9
  75. package/gsd-core/bin/lib/roadmap-parser.cjs +735 -137
  76. package/gsd-core/bin/lib/roadmap-progress.cjs +136 -0
  77. package/gsd-core/bin/lib/roadmap-upgrade.cjs +47 -7
  78. package/gsd-core/bin/lib/roadmap.cjs +383 -123
  79. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +381 -14
  80. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
  81. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
  82. package/gsd-core/bin/lib/shell-command-projection.cjs +151 -19
  83. package/gsd-core/bin/lib/smart-entry.cjs +35 -11
  84. package/gsd-core/bin/lib/state-contract.cjs +39 -15
  85. package/gsd-core/bin/lib/state-document.cjs +344 -27
  86. package/gsd-core/bin/lib/state-transition.cjs +156 -32
  87. package/gsd-core/bin/lib/state.cjs +527 -186
  88. package/gsd-core/bin/lib/surface.cjs +9 -0
  89. package/gsd-core/bin/lib/task-command-router.cjs +5 -25
  90. package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
  91. package/gsd-core/bin/lib/template.cjs +2 -2
  92. package/gsd-core/bin/lib/validate.cjs +3 -2
  93. package/gsd-core/bin/lib/vendor/re2js.cjs +863 -577
  94. package/gsd-core/bin/lib/vendor/re2js.d.cts +284 -219
  95. package/gsd-core/bin/lib/verification.cjs +96 -9
  96. package/gsd-core/bin/lib/verify.cjs +4 -2
  97. package/gsd-core/bin/lib/workstream-inventory.cjs +26 -20
  98. package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
  99. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  100. package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
  101. package/gsd-core/bin/verify-reapply-patches.cjs +411 -10
  102. package/gsd-core/references/cicd-review-patterns.md +45 -0
  103. package/gsd-core/references/git-integration.md +11 -0
  104. package/gsd-core/references/loop-hook-dispatch.md +13 -6
  105. package/gsd-core/references/necessity-review.md +48 -0
  106. package/gsd-core/references/planning-config.md +2 -0
  107. package/gsd-core/references/tdd.md +2 -2
  108. package/gsd-core/templates/DEBUG.md +16 -0
  109. package/gsd-core/templates/config.json +2 -1
  110. package/gsd-core/templates/verification-report.md +1 -1
  111. package/gsd-core/workflows/audit-fix.md +2 -1
  112. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
  113. package/gsd-core/workflows/code-review-fix.md +46 -5
  114. package/gsd-core/workflows/code-review.md +64 -7
  115. package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
  116. package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
  117. package/gsd-core/workflows/complete-milestone.md +37 -150
  118. package/gsd-core/workflows/diagnose-issues.md +29 -5
  119. package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
  120. package/gsd-core/workflows/discuss-phase-assumptions.md +33 -2
  121. package/gsd-core/workflows/discuss-phase-power.md +19 -2
  122. package/gsd-core/workflows/discuss-phase.md +6 -10
  123. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
  124. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +7 -2
  125. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -1
  126. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +2 -2
  127. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
  128. package/gsd-core/workflows/execute-phase.md +10 -6
  129. package/gsd-core/workflows/execute-plan.md +1 -1
  130. package/gsd-core/workflows/health.md +2 -1
  131. package/gsd-core/workflows/import.md +1 -1
  132. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +2 -2
  133. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +13 -9
  134. package/gsd-core/workflows/plan-phase.md +14 -14
  135. package/gsd-core/workflows/pr-branch.md +2 -0
  136. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
  137. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
  138. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
  139. package/gsd-core/workflows/quick.md +1 -1
  140. package/gsd-core/workflows/reapply-patches.md +104 -0
  141. package/gsd-core/workflows/review.md +70 -154
  142. package/gsd-core/workflows/section-manifest.json +5 -0
  143. package/gsd-core/workflows/secure-phase.md +1 -1
  144. package/gsd-core/workflows/settings-advanced.md +57 -9
  145. package/gsd-core/workflows/settings.md +1 -0
  146. package/gsd-core/workflows/ship.md +15 -4
  147. package/gsd-core/workflows/spec-phase.md +3 -6
  148. package/gsd-core/workflows/verify-work.md +4 -3
  149. package/hooks/dist/gsd-agent-isolation-guard.js +11 -1
  150. package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
  151. package/hooks/dist/gsd-graphify-update.sh +6 -0
  152. package/hooks/dist/gsd-path-export.js +95 -0
  153. package/hooks/dist/gsd-secret-read-guard.js +172 -39
  154. package/hooks/dist/gsd-statusline.js +37 -3
  155. package/hooks/dist/gsd-windsurf-pre-write.js +29 -2
  156. package/hooks/dist/gsd-workflow-guard.js +3 -2
  157. package/hooks/dist/gsd-worktree-path-guard.js +29 -2
  158. package/hooks/dist/lib/git-probe.js +16 -0
  159. package/hooks/dist/lib/isolation-sentinel.js +44 -0
  160. package/hooks/dist/managed-hooks-registry.cjs +1 -0
  161. package/hooks/gsd-agent-isolation-guard.js +11 -1
  162. package/hooks/gsd-cursor-subagent-start.js +6 -2
  163. package/hooks/gsd-graphify-update.sh +6 -0
  164. package/hooks/gsd-path-export.js +95 -0
  165. package/hooks/gsd-secret-read-guard.js +172 -39
  166. package/hooks/gsd-statusline.js +37 -3
  167. package/hooks/gsd-windsurf-pre-write.js +29 -2
  168. package/hooks/gsd-workflow-guard.js +3 -2
  169. package/hooks/gsd-worktree-path-guard.js +29 -2
  170. package/hooks/hooks.json +1 -0
  171. package/hooks/lib/git-probe.js +16 -0
  172. package/hooks/lib/isolation-sentinel.js +44 -0
  173. package/hooks/managed-hooks-registry.cjs +1 -0
  174. package/package.json +15 -8
  175. package/pi/gsd.cjs +1047 -10
  176. package/pi/package-agents/gsd-advisor-researcher.md +113 -0
  177. package/pi/package-agents/gsd-ai-researcher.md +111 -0
  178. package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
  179. package/pi/package-agents/gsd-code-fixer.md +774 -0
  180. package/pi/package-agents/gsd-code-reviewer.md +441 -0
  181. package/pi/package-agents/gsd-codebase-mapper.md +850 -0
  182. package/pi/package-agents/gsd-debug-session-manager.md +416 -0
  183. package/pi/package-agents/gsd-debugger.md +1274 -0
  184. package/pi/package-agents/gsd-doc-classifier.md +269 -0
  185. package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
  186. package/pi/package-agents/gsd-doc-verifier.md +212 -0
  187. package/pi/package-agents/gsd-doc-writer.md +626 -0
  188. package/pi/package-agents/gsd-dom-verifier.md +164 -0
  189. package/pi/package-agents/gsd-domain-researcher.md +144 -0
  190. package/pi/package-agents/gsd-eval-auditor.md +185 -0
  191. package/pi/package-agents/gsd-eval-planner.md +149 -0
  192. package/pi/package-agents/gsd-executor.md +898 -0
  193. package/pi/package-agents/gsd-framework-selector.md +159 -0
  194. package/pi/package-agents/gsd-integration-checker.md +476 -0
  195. package/pi/package-agents/gsd-intel-updater.md +338 -0
  196. package/pi/package-agents/gsd-mempalace-curator.md +49 -0
  197. package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
  198. package/pi/package-agents/gsd-pattern-mapper.md +340 -0
  199. package/pi/package-agents/gsd-phase-researcher.md +897 -0
  200. package/pi/package-agents/gsd-plan-checker.md +1077 -0
  201. package/pi/package-agents/gsd-planner.md +1003 -0
  202. package/pi/package-agents/gsd-project-researcher.md +611 -0
  203. package/pi/package-agents/gsd-research-synthesizer.md +259 -0
  204. package/pi/package-agents/gsd-roadmapper.md +779 -0
  205. package/pi/package-agents/gsd-security-auditor.md +171 -0
  206. package/pi/package-agents/gsd-ui-auditor.md +581 -0
  207. package/pi/package-agents/gsd-ui-checker.md +417 -0
  208. package/pi/package-agents/gsd-ui-researcher.md +469 -0
  209. package/pi/package-agents/gsd-user-profiler.md +174 -0
  210. package/pi/package-agents/gsd-verifier.md +963 -0
  211. package/pi/package-agents/manifest.json +39 -0
  212. package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
  213. package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
  214. package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
  215. package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
  216. package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
  217. package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
  218. package/pi/package-skills/gsd-capture/SKILL.md +68 -0
  219. package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
  220. package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
  221. package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
  222. package/pi/package-skills/gsd-config/SKILL.md +60 -0
  223. package/pi/package-skills/gsd-debug/SKILL.md +64 -0
  224. package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
  225. package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
  226. package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
  227. package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
  228. package/pi/package-skills/gsd-explore/SKILL.md +26 -0
  229. package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
  230. package/pi/package-skills/gsd-fast/SKILL.md +33 -0
  231. package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
  232. package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
  233. package/pi/package-skills/gsd-health/SKILL.md +36 -0
  234. package/pi/package-skills/gsd-help/SKILL.md +37 -0
  235. package/pi/package-skills/gsd-import/SKILL.md +46 -0
  236. package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
  237. package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
  238. package/pi/package-skills/gsd-manager/SKILL.md +46 -0
  239. package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
  240. package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
  241. package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
  242. package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
  243. package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
  244. package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
  245. package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
  246. package/pi/package-skills/gsd-next/SKILL.md +34 -0
  247. package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
  248. package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
  249. package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
  250. package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
  251. package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
  252. package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
  253. package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
  254. package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
  255. package/pi/package-skills/gsd-phase/SKILL.md +61 -0
  256. package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
  257. package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
  258. package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
  259. package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
  260. package/pi/package-skills/gsd-progress/SKILL.md +51 -0
  261. package/pi/package-skills/gsd-quick/SKILL.md +179 -0
  262. package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
  263. package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
  264. package/pi/package-skills/gsd-review/SKILL.md +50 -0
  265. package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
  266. package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
  267. package/pi/package-skills/gsd-settings/SKILL.md +30 -0
  268. package/pi/package-skills/gsd-ship/SKILL.md +27 -0
  269. package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
  270. package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
  271. package/pi/package-skills/gsd-spike/SKILL.md +53 -0
  272. package/pi/package-skills/gsd-stats/SKILL.md +22 -0
  273. package/pi/package-skills/gsd-surface/SKILL.md +177 -0
  274. package/pi/package-skills/gsd-thread/SKILL.md +29 -0
  275. package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
  276. package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
  277. package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
  278. package/pi/package-skills/gsd-undo/SKILL.md +38 -0
  279. package/pi/package-skills/gsd-update/SKILL.md +54 -0
  280. package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
  281. package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
  282. package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
  283. package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
  284. package/scripts/build-hooks.js +4 -0
  285. package/scripts/ci-next-health.cjs +246 -23
  286. package/scripts/command-contract-helpers.cjs +1 -1
  287. package/scripts/docs-guard-registry.cjs +22 -7
  288. package/scripts/gen-features.cjs +14 -2
  289. package/scripts/gen-health-docs.cjs +13 -1
  290. package/scripts/gen-pi-package-skills.cjs +217 -0
  291. package/scripts/lib/drift-scan.cjs +27 -0
  292. package/scripts/lib/macos-conformance-tier.generated.cjs +17 -1
  293. package/scripts/lib/platform-conformance-tier.generated.cjs +37 -1
  294. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
  295. package/scripts/lint-phase-enumeration-drift.cjs +8 -4
  296. package/scripts/lint-retired-runtime-name.cjs +5 -0
  297. package/scripts/lint-roadmap-progress-drift.cjs +421 -0
  298. package/scripts/mutation-matrix.cjs +23 -1
  299. package/scripts/npm-audit-baseline.cjs +41 -7
  300. package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
  301. package/scripts/select-docs-guards.cjs +1 -1
  302. package/scripts/self-test-report-policy.cjs +350 -0
  303. package/scripts/sync-next-version.cjs +38 -6
  304. package/skills/gsd-update/SKILL.md +5 -2
  305. package/vscode/package.json +1 -1
  306. package/scripts/diagnose-validate-commit-in-tier.cjs +0 -270
  307. package/scripts/diagnose-validate-commit-phases.cjs +0 -348
  308. package/scripts/xtrace-phase-timing.cjs +0 -205
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ /**
3
+ * Roadmap Progress Module (#5761, Phase 1 of epic #5692): the single owner of
4
+ * "which table is this ROADMAP's Progress table, and what is its milestone
5
+ * slice".
6
+ *
7
+ * Before this module the question was answered by six locators/scopers that
8
+ * disagreed on `## Progress Tracker`, on a `## Progress` inside a fenced block,
9
+ * and on the headingless fallback. Every READER now asks `locateRoadmapProgress`
10
+ * (or, for the "does this span hold the Progress section" probe,
11
+ * `findProgressSection`); a second hand-written `## Progress` regex or
12
+ * table-locating call in a reader is the DEFECT.GENERATIVE-FIX shape.
13
+ *
14
+ * The rule, defined once:
15
+ * - The Progress section is the first level-2 ATX heading, outside fenced
16
+ * code, whose text starts with the word `Progress` (`## Progress`,
17
+ * `## Progress Tracker`). It runs to the next level-1/2 heading outside
18
+ * fenced code.
19
+ * - The table is the first table in that section whose header is a SUPERSET
20
+ * of the requested column set (ADR-2143 §3: addressed by NAME, never
21
+ * ordinal). A section with no matching table yields no table; it does not
22
+ * fall through to the rest of the document (#2012 decoy avoidance).
23
+ * - A document with no Progress heading is scanned whole (a headingless
24
+ * milestone slice, #1445, keeps resolving).
25
+ * - Two readers had a wider pre-owner reach and ask for it by name, so the
26
+ * rule stays single (#5692: no behavior change for existing ROADMAP.md
27
+ * files): `levels: [1, 2]` for the archive-span probe, which always took a
28
+ * level-1 `# Progress`, and `sectionMiss: 'document'` for the workstream
29
+ * inventory, which always read a table outside a table-less section.
30
+ * - The milestone slice (#5165): when the caller names a milestone and the
31
+ * table carries a `Milestone` column, only that milestone's rows.
32
+ *
33
+ * The writers (`roadmap.cts` update-plan-progress / phase add, `phase.cts`
34
+ * complete / remove) cut their slice with `editRoadmapProgress` (#5762), the
35
+ * write side of the same rule, so a writer edits only the section the readers
36
+ * read. `phase.cts`'s `cmdPhaseComplete` already-complete check still slices
37
+ * the Milestone column itself, with a blank-milestone-matches-nothing rule this
38
+ * owner deliberately does not share.
39
+ */
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.isProgressHeadingTitle = isProgressHeadingTitle;
42
+ exports.normalizeMilestoneToken = normalizeMilestoneToken;
43
+ exports.milestoneVersionOf = milestoneVersionOf;
44
+ exports.findProgressSection = findProgressSection;
45
+ exports.editRoadmapProgress = editRoadmapProgress;
46
+ exports.locateRoadmapProgress = locateRoadmapProgress;
47
+ const markdown_table_cjs_1 = require("./markdown-table.cjs");
48
+ const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
49
+ /** The canonical column set both RoadmapProgress variants carry. */
50
+ const CANONICAL_COLUMNS = ['Phase', 'Plans Complete', 'Status', 'Completed'];
51
+ /**
52
+ * The ONE textual expression of "this heading is titled Progress": the title
53
+ * starts with the word `Progress`, any suffix admitted (`Progress`,
54
+ * `Progress Tracker`, `Progress (v2.1)`), case-insensitive. `findProgressSection`
55
+ * adds the level-2 anchor; the bracket writers (`phase.cts`) reuse the title
56
+ * test at their own levels (#4304).
57
+ */
58
+ function isProgressHeadingTitle(text) {
59
+ return /^Progress\b/i.test(text.trim());
60
+ }
61
+ /**
62
+ * #5165: a milestone token compared by identity, not spelling — `v1.1`, `V1.1`
63
+ * and ` 1.1 ` name one milestone. A hand-decorated Progress cell
64
+ * (`**v1.1**`, `` `v1.1` ``, `v1.1 (current)`) still names its first
65
+ * whitespace-separated token. Absent/blank tokens normalize to `''`.
66
+ */
67
+ function normalizeMilestoneToken(value) {
68
+ // `[v1.1](ROADMAP.md#v11)` names its link text.
69
+ const unlinked = (milestoneVersionOf(value) ?? '').replace(/\[([^\]]*)\]\([^)]*\)/g, '$1');
70
+ const first = unlinked.split(/\s+/)[0] ?? '';
71
+ return first.replace(/^[*_`]+|[*_`:,;]+$/g, '').replace(/^v/i, '').toLowerCase();
72
+ }
73
+ /**
74
+ * #5165: a STATE.md `milestone:` frontmatter value as a trimmed version string,
75
+ * or null when it is absent, blank or not scalar text.
76
+ */
77
+ function milestoneVersionOf(value) {
78
+ if (typeof value !== 'string' && typeof value !== 'number')
79
+ return null;
80
+ const text = String(value).trim();
81
+ return text === '' ? null : text;
82
+ }
83
+ /**
84
+ * The Progress section of `content`: the first level-2 heading (`levels` widens
85
+ * this) outside fenced code whose text starts with the word `Progress`, up to
86
+ * the next level-1/2 heading. Null when the document has no such heading.
87
+ */
88
+ function findProgressSection(content, options = {}) {
89
+ const headings = (0, markdown_sectionizer_cjs_1.tokenizeHeadings)(content);
90
+ const { active, exclude, levels = [2] } = options;
91
+ const isProgress = (h) => levels.includes(h.level) && isProgressHeadingTitle(h.text) && !(exclude && exclude(h.offset));
92
+ // #5553: with an active-milestone range, the first Progress heading INSIDE it wins over an
93
+ // earlier one (a shipped plain section's own table); with none in range, the first overall.
94
+ const inActive = active ? headings.findIndex((h) => isProgress(h) && h.offset >= active.start && h.offset < active.end) : -1;
95
+ const index = inActive !== -1 ? inActive : headings.findIndex(isProgress);
96
+ if (index === -1)
97
+ return null;
98
+ return (0, markdown_sectionizer_cjs_1.headingSliceRange)(content, headings, index, headings[index].level);
99
+ }
100
+ /**
101
+ * The WRITE side of the same rule (#5762): run `edit` on the Progress section
102
+ * `findProgressSection` locates and splice the result back byte-exact, so a
103
+ * writer can only ever edit the section the readers read.
104
+ *
105
+ * A document with no Progress heading is what the readers scan whole;
106
+ * `headingless: 'whole'` (default) gives `edit` that same whole document,
107
+ * `'skip'` leaves it untouched (a destructive writer that must not guess a
108
+ * table by column names alone).
109
+ */
110
+ function editRoadmapProgress(content, edit, options = {}) {
111
+ const section = findProgressSection(content, { active: options.active });
112
+ if (!section)
113
+ return options.headingless === 'skip' ? content : edit(content);
114
+ return (0, markdown_sectionizer_cjs_1.editHeadingSlice)(content, section, edit);
115
+ }
116
+ /** Which table is the Progress table, and what is its milestone slice. */
117
+ function locateRoadmapProgress(content, options = {}) {
118
+ const section = findProgressSection(content);
119
+ const scoped = section ? content.slice(section.start, section.end) : content;
120
+ // `sectionMiss: 'document'` widens each column set's probe from the section to the whole
121
+ // document, set by set, so an earlier set found anywhere still beats a later set in the section.
122
+ const widen = section !== null && options.sectionMiss === 'document';
123
+ let table = null;
124
+ for (const columns of options.columns ?? [CANONICAL_COLUMNS]) {
125
+ table = (0, markdown_table_cjs_1.findTableWithColumns)(scoped, [...columns]) ?? (widen ? (0, markdown_table_cjs_1.findTableWithColumns)(content, [...columns]) : null);
126
+ if (table)
127
+ break;
128
+ }
129
+ if (!table)
130
+ return { table: null, rows: [], section };
131
+ const want = normalizeMilestoneToken(options.milestone);
132
+ const rows = want !== '' && table.columns.includes('Milestone')
133
+ ? table.rows.filter((r) => normalizeMilestoneToken(r['Milestone']) === want)
134
+ : table.rows;
135
+ return { table, rows, section };
136
+ }
@@ -12,8 +12,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  };
13
13
  const node_fs_1 = __importDefault(require("node:fs"));
14
14
  const node_path_1 = __importDefault(require("node:path"));
15
- const node_child_process_1 = require("node:child_process");
16
15
  const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
16
+ const phase_entry_grammar_cjs_1 = require("./phase-entry-grammar.cjs");
17
17
  // eslint-disable-next-line @typescript-eslint/no-require-imports
18
18
  const planningWorkspace = require("./planning-workspace.cjs");
19
19
  // eslint-disable-next-line @typescript-eslint/no-require-imports
@@ -1398,10 +1398,11 @@ function computeBracketPlan(cwd) {
1398
1398
  // bullet stayed legacy after an otherwise-done migration, so the
1399
1399
  // bracket-mode milestone id set carried the stale legacy token alongside
1400
1400
  // the bracket ones.
1401
- const CHECKLIST_BULLET_PREFIX_SRC = '[-*]\\s*\\[[ x]\\]\\s*\\*{0,2}';
1401
+ // #5764: the prefix is the phase-entry grammar's (line-anchored, indent included).
1402
+ const CHECKLIST_BULLET_PREFIX_SRC = (0, phase_entry_grammar_cjs_1.phaseEntryPrefixSrc)();
1402
1403
  const CHECKLIST_PHASE_INTRO_SRC = phaseHeadingPrefixSrcFor(PHASE_HEADING_BASELINE.LABEL_ONLY, undefined, true);
1403
- const mnnChecklistRe = new RegExp(`^(\\s*${CHECKLIST_BULLET_PREFIX_SRC})${CHECKLIST_PHASE_INTRO_SRC}(${MNN_SOURCE_TOKEN_SOURCE})(${OPTIONAL_PHASE_TAG_SOURCE})`, 'i');
1404
- const legacyChecklistRe = new RegExp(`^(\\s*${CHECKLIST_BULLET_PREFIX_SRC})${CHECKLIST_PHASE_INTRO_SRC}(${PHASE_NUMBER_TOKEN_SOURCE})(${OPTIONAL_PHASE_TAG_SOURCE})`, 'i');
1404
+ const mnnChecklistRe = new RegExp(`(${CHECKLIST_BULLET_PREFIX_SRC})${CHECKLIST_PHASE_INTRO_SRC}(${MNN_SOURCE_TOKEN_SOURCE})(${OPTIONAL_PHASE_TAG_SOURCE})`, 'i');
1405
+ const legacyChecklistRe = new RegExp(`(${CHECKLIST_BULLET_PREFIX_SRC})${CHECKLIST_PHASE_INTRO_SRC}(${PHASE_NUMBER_TOKEN_SOURCE})(${OPTIONAL_PHASE_TAG_SOURCE})`, 'i');
1405
1406
  // #4144 round 8 I1: `legacyChecklistRe` above requires nothing at all
1406
1407
  // after the number/tag — deliberately, since Tier 1 (reader-recognized,
1407
1408
  // `isReaderRecognizedBullet` below) must match exactly what the readers'
@@ -1753,7 +1754,8 @@ function computeMigrationPlan(cwd, options = {}) {
1753
1754
  if (roadmapEdits.some(e => e.lineIndex === i))
1754
1755
  continue;
1755
1756
  // Match checklist items: "- [ ] **Phase N:**" or "- [x] Phase N:" (also decimal)
1756
- const checklistMatch = line.match(new RegExp(`^(\\s*-\\s*\\[[ x]\\]\\s*\\*{0,2}Phase\\s+)(${PHASE_NUMBER_TOKEN_SOURCE})(\\s*[:\\s*])`, 'i'));
1757
+ // The entry prefix (marker, box, bold token) is the phase-entry grammar's (#5764).
1758
+ const checklistMatch = line.match(new RegExp(`(${(0, phase_entry_grammar_cjs_1.phaseEntryPrefixSrc)()}Phase[ \\t]+)(${PHASE_NUMBER_TOKEN_SOURCE})(\\s*[:\\s*])`, 'i'));
1757
1759
  if (checklistMatch) {
1758
1760
  const legacyNum = checklistMatch[2];
1759
1761
  const cIntPart = parseInt(legacyNum, 10);
@@ -1779,7 +1781,7 @@ function computeMigrationPlan(cwd, options = {}) {
1779
1781
  newId = found.newId;
1780
1782
  }
1781
1783
  if (newId) {
1782
- const newLine = line.replace(new RegExp(`^(\\s*-\\s*\\[[ x]\\]\\s*\\*{0,2}Phase\\s+)${PHASE_NUMBER_TOKEN_SOURCE}(\\s*[:\\s*])`, 'i'), `$1${newId}$2`);
1784
+ const newLine = line.replace(new RegExp(`(${(0, phase_entry_grammar_cjs_1.phaseEntryPrefixSrc)()}Phase[ \\t]+)${PHASE_NUMBER_TOKEN_SOURCE}(\\s*[:\\s*])`, 'i'), `$1${newId}$2`);
1783
1785
  if (newLine !== line) {
1784
1786
  roadmapEdits.push({ lineIndex: i, from: line, to: newLine });
1785
1787
  }
@@ -1923,7 +1925,45 @@ function applyMigration(cwd, plan, options = {}) {
1923
1925
  // ── Real run: verify clean working tree ───────────────────────────────────
1924
1926
  let gitStatus;
1925
1927
  try {
1926
- gitStatus = (0, node_child_process_1.execSync)('git status --porcelain', { cwd, encoding: 'utf8', windowsHide: true, timeout: 10_000 });
1928
+ // #5048: this is a read-only spawn, but git still refreshes the index under
1929
+ // it and takes the optional `.git/index.lock` to write the refreshed copy
1930
+ // back — which can lose a race against a real `git add` / `git commit` in
1931
+ // the same repo. Routing through the shared execGit seam (CONTEXT.md, OS
1932
+ // Shell Projection) is what gets GIT_OPTIONAL_LOCKS=0 here; a bare execSync
1933
+ // bypassed the seam and therefore the opt-out, so this call site was the one
1934
+ // read-only `git status` the seam change did not reach. shell-free, so no
1935
+ // argv quoting or PATH-resolution policy is introduced.
1936
+ const statusTimeoutMs = 10_000;
1937
+ const result = (0, shell_command_projection_cjs_1.execGit)(['status', '--porcelain'], { cwd, timeout: statusTimeoutMs });
1938
+ // #5048: execSync carried the cause on the thrown error. execGit reports a
1939
+ // timeout, a spawn/buffer failure or a signal through `timedOut`/`error`/
1940
+ // `signal` with an exit code of `status ?? 1` and often an empty stderr.
1941
+ // Order matters: a maxBuffer overflow returns signal SIGTERM *and*
1942
+ // error.code ENOBUFS — check `error` before `signal` so the real cause is
1943
+ // not reported as "killed by SIGTERM". Only a genuine non-zero exit falls
1944
+ // through. (ENOENT is rewritten by `_spawnResult` to exit 127 + stderr.)
1945
+ if (result.timedOut) {
1946
+ throw new Error(`git status timed out after ${statusTimeoutMs} ms`);
1947
+ }
1948
+ if (result.error) {
1949
+ // The cause is not always a failed spawn: ENOBUFS and EPERM reach this
1950
+ // branch with the process already started (a maxBuffer overflow returns
1951
+ // signal SIGTERM *and* error.code ENOBUFS). So the message stays neutral
1952
+ // about starting and names the code instead of inferring a cause from it.
1953
+ const code = result.error.code;
1954
+ const why = code === 'ENOBUFS' ? 'output exceeded the buffer' : code;
1955
+ const detail = why && !result.error.message.includes(why)
1956
+ ? `${result.error.message} (${why})`
1957
+ : result.error.message;
1958
+ throw new Error(detail);
1959
+ }
1960
+ if (result.signal) {
1961
+ throw new Error(`git status was killed by ${result.signal}`);
1962
+ }
1963
+ if (result.exitCode !== 0) {
1964
+ throw new Error(result.stderr || `git exited ${result.exitCode}`);
1965
+ }
1966
+ gitStatus = result.stdout;
1927
1967
  }
1928
1968
  catch (err) {
1929
1969
  throw new Error(`git status failed: ${err.message}`);