@opengsd/gsd-core 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +85 -5
  4. package/README.ja-JP.md +3 -3
  5. package/README.ko-KR.md +3 -3
  6. package/README.pt-BR.md +3 -3
  7. package/README.zh-CN.md +3 -3
  8. package/agents/gsd-code-fixer.compact.md +7 -6
  9. package/agents/gsd-code-fixer.md +9 -8
  10. package/agents/gsd-code-reviewer.compact.md +5 -3
  11. package/agents/gsd-code-reviewer.md +8 -6
  12. package/agents/gsd-debug-session-manager.compact.md +17 -2
  13. package/agents/gsd-debug-session-manager.md +17 -2
  14. package/agents/gsd-debugger.md +3 -3
  15. package/agents/gsd-eval-auditor.compact.md +1 -1
  16. package/agents/gsd-eval-auditor.md +1 -1
  17. package/agents/gsd-executor.md +17 -12
  18. package/agents/gsd-intel-updater.compact.md +1 -1
  19. package/agents/gsd-intel-updater.md +1 -1
  20. package/agents/gsd-mempalace-curator.md +2 -2
  21. package/agents/gsd-phase-researcher.md +19 -11
  22. package/agents/gsd-plan-checker.md +15 -9
  23. package/agents/gsd-planner.md +15 -11
  24. package/agents/gsd-project-researcher.compact.md +1 -1
  25. package/agents/gsd-project-researcher.md +1 -1
  26. package/agents/gsd-research-synthesizer.compact.md +1 -1
  27. package/agents/gsd-research-synthesizer.md +1 -1
  28. package/agents/gsd-ui-auditor.compact.md +21 -30
  29. package/agents/gsd-ui-auditor.md +166 -37
  30. package/agents/gsd-ui-researcher.compact.md +1 -1
  31. package/agents/gsd-ui-researcher.md +1 -1
  32. package/agents/gsd-verifier.md +37 -14
  33. package/bin/install.js +764 -287
  34. package/commands/gsd/add-tests.md +6 -1
  35. package/commands/gsd/ai-integration-phase.md +6 -1
  36. package/commands/gsd/audit-fix.md +5 -0
  37. package/commands/gsd/audit-milestone.md +6 -1
  38. package/commands/gsd/autonomous.md +7 -2
  39. package/commands/gsd/capture.md +9 -5
  40. package/commands/gsd/code-review.md +7 -2
  41. package/commands/gsd/complete-milestone.md +4 -0
  42. package/commands/gsd/config.md +7 -3
  43. package/commands/gsd/debug.md +11 -7
  44. package/commands/gsd/discuss-phase.md +7 -3
  45. package/commands/gsd/docs-update.md +12 -7
  46. package/commands/gsd/eval-review.md +6 -1
  47. package/commands/gsd/execute-phase.md +12 -7
  48. package/commands/gsd/extract-learnings.md +5 -0
  49. package/commands/gsd/fast.md +4 -0
  50. package/commands/gsd/forensics.md +5 -1
  51. package/commands/gsd/graphify.md +10 -6
  52. package/commands/gsd/health.md +5 -0
  53. package/commands/gsd/help.md +7 -2
  54. package/commands/gsd/import.md +7 -3
  55. package/commands/gsd/inbox.md +5 -0
  56. package/commands/gsd/ingest-docs.md +5 -1
  57. package/commands/gsd/manager.md +6 -1
  58. package/commands/gsd/map-codebase.md +7 -3
  59. package/commands/gsd/mempalace-capture.md +12 -4
  60. package/commands/gsd/mempalace-recall.md +5 -1
  61. package/commands/gsd/milestone-summary.md +5 -1
  62. package/commands/gsd/mvp-phase.md +8 -3
  63. package/commands/gsd/new-milestone.md +6 -1
  64. package/commands/gsd/new-project.md +5 -0
  65. package/commands/gsd/next.md +6 -1
  66. package/commands/gsd/ns-context.md +4 -0
  67. package/commands/gsd/ns-ideate.md +4 -0
  68. package/commands/gsd/ns-manage.md +4 -0
  69. package/commands/gsd/ns-project.md +4 -0
  70. package/commands/gsd/ns-review.md +4 -0
  71. package/commands/gsd/ns-workflow.md +4 -0
  72. package/commands/gsd/onboard.md +6 -1
  73. package/commands/gsd/pause-work.md +5 -1
  74. package/commands/gsd/phase.md +8 -4
  75. package/commands/gsd/plan-phase.md +6 -1
  76. package/commands/gsd/plan-review-convergence.md +11 -7
  77. package/commands/gsd/pr-branch.md +4 -0
  78. package/commands/gsd/profile-user.md +5 -1
  79. package/commands/gsd/progress.md +7 -2
  80. package/commands/gsd/quick-batch.md +21 -9
  81. package/commands/gsd/quick.md +12 -7
  82. package/commands/gsd/review.md +7 -4
  83. package/commands/gsd/secure-phase.md +6 -1
  84. package/commands/gsd/ship.md +5 -0
  85. package/commands/gsd/sketch.md +7 -2
  86. package/commands/gsd/spec-phase.md +5 -1
  87. package/commands/gsd/spike.md +8 -3
  88. package/commands/gsd/surface.md +5 -1
  89. package/commands/gsd/thread.md +4 -0
  90. package/commands/gsd/ui-phase.md +6 -1
  91. package/commands/gsd/ui-review.md +6 -1
  92. package/commands/gsd/ultraplan-phase.md +5 -1
  93. package/commands/gsd/undo.md +5 -1
  94. package/commands/gsd/update.md +6 -2
  95. package/commands/gsd/validate-phase.md +6 -1
  96. package/commands/gsd/verify-work.md +6 -1
  97. package/commands/gsd/workspace.md +7 -3
  98. package/gsd-core/bin/gsd-tools.cjs +477 -78
  99. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  100. package/gsd-core/bin/lib/adr-parser.cjs +3 -1
  101. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  102. package/gsd-core/bin/lib/audit.cjs +144 -42
  103. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  104. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  105. package/gsd-core/bin/lib/capability-registry.cjs +197 -222
  106. package/gsd-core/bin/lib/capability-validator.cjs +16 -1
  107. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  108. package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
  109. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  110. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  111. package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
  112. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  113. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  114. package/gsd-core/bin/lib/commands.cjs +343 -207
  115. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  116. package/gsd-core/bin/lib/config-loader.cjs +65 -4
  117. package/gsd-core/bin/lib/config.cjs +76 -19
  118. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  119. package/gsd-core/bin/lib/coverage.cjs +4 -8
  120. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  121. package/gsd-core/bin/lib/decisions.cjs +30 -14
  122. package/gsd-core/bin/lib/drift.cjs +177 -42
  123. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  124. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  125. package/gsd-core/bin/lib/frontmatter.cjs +426 -234
  126. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  127. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  128. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  129. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  130. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  131. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  132. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  133. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  134. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  135. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  136. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  137. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  138. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  139. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  140. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  141. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  142. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  143. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  144. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  145. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  146. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  147. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  148. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  149. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  150. package/gsd-core/bin/lib/graphify.cjs +10 -2
  151. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  152. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  153. package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
  154. package/gsd-core/bin/lib/init.cjs +364 -132
  155. package/gsd-core/bin/lib/install-engine.cjs +30 -33
  156. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  157. package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
  158. package/gsd-core/bin/lib/io.cjs +122 -3
  159. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  160. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  161. package/gsd-core/bin/lib/milestone.cjs +37 -6
  162. package/gsd-core/bin/lib/model-resolver.cjs +171 -62
  163. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  164. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  165. package/gsd-core/bin/lib/pattern.cjs +10 -0
  166. package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
  167. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  168. package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
  169. package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
  170. package/gsd-core/bin/lib/phase-id.cjs +110 -8
  171. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  172. package/gsd-core/bin/lib/phase-locator.cjs +29 -10
  173. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  174. package/gsd-core/bin/lib/phase.cjs +489 -88
  175. package/gsd-core/bin/lib/plan-document.cjs +142 -20
  176. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  177. package/gsd-core/bin/lib/planning-document.cjs +692 -0
  178. package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
  179. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  180. package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
  181. package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
  182. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  183. package/gsd-core/bin/lib/probe-core.cjs +7 -1
  184. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  185. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  186. package/gsd-core/bin/lib/project-root.cjs +41 -2
  187. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  188. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  189. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  190. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  191. package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
  192. package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
  193. package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
  194. package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
  195. package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
  196. package/gsd-core/bin/lib/roadmap.cjs +405 -88
  197. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
  198. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
  199. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  200. package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
  201. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
  202. package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
  203. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  204. package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
  205. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  206. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  207. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  208. package/gsd-core/bin/lib/state-document.cjs +100 -22
  209. package/gsd-core/bin/lib/state-transition.cjs +39 -2
  210. package/gsd-core/bin/lib/state.cjs +256 -105
  211. package/gsd-core/bin/lib/surface.cjs +19 -2
  212. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
  213. package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
  214. package/gsd-core/bin/lib/uat.cjs +432 -7
  215. package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
  216. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
  217. package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
  218. package/gsd-core/bin/lib/vendor/README.md +31 -9
  219. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  220. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  221. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  222. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  223. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  224. package/gsd-core/bin/lib/verification.cjs +1378 -274
  225. package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
  226. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  227. package/gsd-core/bin/lib/verify.cjs +357 -531
  228. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  229. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  230. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  231. package/gsd-core/bin/lib/workstream.cjs +11 -2
  232. package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
  233. package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
  234. package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
  235. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  236. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  237. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  238. package/gsd-core/references/checkpoints.md +5 -3
  239. package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
  240. package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
  241. package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
  242. package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
  243. package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
  244. package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
  245. package/gsd-core/references/edge-probe.md +195 -21
  246. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  247. package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
  248. package/gsd-core/references/execute-phase-response-language.md +1 -1
  249. package/gsd-core/references/execute-phase-wave-guard.md +22 -11
  250. package/gsd-core/references/gsd-run-resolver.md +1 -1
  251. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  252. package/gsd-core/references/model-profiles.md +1 -1
  253. package/gsd-core/references/offer-next.md +1 -1
  254. package/gsd-core/references/phase-argument-parsing.md +9 -7
  255. package/gsd-core/references/phase-id-convention.md +28 -0
  256. package/gsd-core/references/planner-gap-closure.md +2 -0
  257. package/gsd-core/references/planner-load-graph-context.md +24 -13
  258. package/gsd-core/references/planner-verify-command-grounding.md +14 -0
  259. package/gsd-core/references/planning-config.md +12 -3
  260. package/gsd-core/references/spidr-splitting.md +1 -1
  261. package/gsd-core/references/tdd.md +37 -8
  262. package/gsd-core/references/ui-consideration-probe.md +10 -5
  263. package/gsd-core/references/verifier-phase-gates.md +5 -2
  264. package/gsd-core/references/verify-command-path-resolvability.md +10 -2
  265. package/gsd-core/references/verify-mvp-mode.md +2 -2
  266. package/gsd-core/references/workstream-flag.md +33 -3
  267. package/gsd-core/references/worktree-path-safety.md +321 -0
  268. package/gsd-core/templates/README.md +1 -1
  269. package/gsd-core/templates/UAT.md +17 -1
  270. package/gsd-core/templates/config.json +2 -11
  271. package/gsd-core/templates/verification-report.md +1 -1
  272. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  273. package/gsd-core/workflows/add-backlog.md +1 -1
  274. package/gsd-core/workflows/add-phase.md +8 -7
  275. package/gsd-core/workflows/add-tests.md +4 -3
  276. package/gsd-core/workflows/add-todo.md +6 -5
  277. package/gsd-core/workflows/ai-integration-phase.md +13 -4
  278. package/gsd-core/workflows/audit-fix.md +1 -1
  279. package/gsd-core/workflows/audit-milestone.md +4 -3
  280. package/gsd-core/workflows/audit-uat.md +1 -1
  281. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
  282. package/gsd-core/workflows/autonomous.md +43 -23
  283. package/gsd-core/workflows/check-todos.md +7 -6
  284. package/gsd-core/workflows/cleanup.md +2 -2
  285. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
  286. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  287. package/gsd-core/workflows/code-review-fix.md +112 -25
  288. package/gsd-core/workflows/code-review.md +146 -135
  289. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  290. package/gsd-core/workflows/complete-milestone.md +13 -8
  291. package/gsd-core/workflows/debug.md +32 -7
  292. package/gsd-core/workflows/diagnose-issues.md +3 -2
  293. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  294. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  295. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  296. package/gsd-core/workflows/discuss-phase.md +4 -3
  297. package/gsd-core/workflows/do.md +2 -2
  298. package/gsd-core/workflows/docs-update.md +6 -5
  299. package/gsd-core/workflows/edit-phase.md +4 -3
  300. package/gsd-core/workflows/eval-review.md +14 -5
  301. package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
  302. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
  303. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  304. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  305. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
  306. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  307. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  308. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  309. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  310. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
  311. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  312. package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
  313. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  314. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  315. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  316. package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
  317. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  318. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  319. package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
  320. package/gsd-core/workflows/execute-phase.md +96 -178
  321. package/gsd-core/workflows/execute-plan.md +18 -23
  322. package/gsd-core/workflows/explore.md +4 -4
  323. package/gsd-core/workflows/extract-learnings.md +4 -2
  324. package/gsd-core/workflows/fast.md +1 -1
  325. package/gsd-core/workflows/forensics.md +1 -1
  326. package/gsd-core/workflows/graduation.md +1 -1
  327. package/gsd-core/workflows/health.md +3 -2
  328. package/gsd-core/workflows/help/modes/full.compact.md +3 -3
  329. package/gsd-core/workflows/help/modes/full.md +5 -5
  330. package/gsd-core/workflows/help/modes/topic.md +15 -5
  331. package/gsd-core/workflows/import.md +4 -3
  332. package/gsd-core/workflows/inbox.md +2 -2
  333. package/gsd-core/workflows/ingest-docs.md +3 -3
  334. package/gsd-core/workflows/insert-phase.md +4 -3
  335. package/gsd-core/workflows/list-seeds.md +1 -1
  336. package/gsd-core/workflows/list-workspaces.md +1 -1
  337. package/gsd-core/workflows/manager.md +6 -4
  338. package/gsd-core/workflows/map-codebase.md +5 -4
  339. package/gsd-core/workflows/milestone-summary.md +3 -2
  340. package/gsd-core/workflows/mvp-phase.md +14 -14
  341. package/gsd-core/workflows/new-milestone.md +11 -11
  342. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
  343. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
  344. package/gsd-core/workflows/new-project.md +7 -7
  345. package/gsd-core/workflows/new-workspace.md +2 -2
  346. package/gsd-core/workflows/next.md +1 -1
  347. package/gsd-core/workflows/note.md +1 -1
  348. package/gsd-core/workflows/onboard.md +1 -1
  349. package/gsd-core/workflows/pause-work.md +2 -2
  350. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  351. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
  352. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  353. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  354. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
  355. package/gsd-core/workflows/plan-phase.md +50 -24
  356. package/gsd-core/workflows/plan-review-convergence.md +21 -5
  357. package/gsd-core/workflows/plant-seed.md +62 -20
  358. package/gsd-core/workflows/pr-branch.md +113 -13
  359. package/gsd-core/workflows/profile-user.md +2 -2
  360. package/gsd-core/workflows/progress.md +19 -49
  361. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
  362. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  363. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  364. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  365. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  366. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  367. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  368. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  369. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  370. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  371. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  372. package/gsd-core/workflows/quick-batch.md +15 -10
  373. package/gsd-core/workflows/quick.md +62 -39
  374. package/gsd-core/workflows/reapply-patches.md +9 -3
  375. package/gsd-core/workflows/remove-phase.md +3 -2
  376. package/gsd-core/workflows/remove-workspace.md +2 -2
  377. package/gsd-core/workflows/resume-project.md +3 -2
  378. package/gsd-core/workflows/review.md +33 -17
  379. package/gsd-core/workflows/scan.md +3 -2
  380. package/gsd-core/workflows/secure-phase.md +13 -13
  381. package/gsd-core/workflows/settings-advanced.md +30 -10
  382. package/gsd-core/workflows/settings-integrations.md +2 -3
  383. package/gsd-core/workflows/settings.md +4 -4
  384. package/gsd-core/workflows/ship.md +14 -13
  385. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  386. package/gsd-core/workflows/sketch.md +1 -1
  387. package/gsd-core/workflows/smart-entry.md +2 -2
  388. package/gsd-core/workflows/spec-phase.md +15 -5
  389. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  390. package/gsd-core/workflows/spike.md +1 -1
  391. package/gsd-core/workflows/stats.md +1 -1
  392. package/gsd-core/workflows/sync-skills.md +5 -5
  393. package/gsd-core/workflows/thread.md +2 -2
  394. package/gsd-core/workflows/transition.md +13 -23
  395. package/gsd-core/workflows/ui-phase.md +48 -11
  396. package/gsd-core/workflows/ui-review.md +21 -6
  397. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  398. package/gsd-core/workflows/undo.md +339 -20
  399. package/gsd-core/workflows/update.md +7 -7
  400. package/gsd-core/workflows/validate-phase.md +12 -13
  401. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  402. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  403. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  404. package/gsd-core/workflows/verify-work.md +129 -55
  405. package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
  406. package/hooks/dist/gsd-check-update-worker.js +8 -0
  407. package/hooks/dist/gsd-check-update.js +8 -0
  408. package/hooks/dist/gsd-context-monitor.js +31 -8
  409. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  410. package/hooks/dist/gsd-secret-read-guard.js +161 -4
  411. package/hooks/dist/gsd-statusline.js +85 -20
  412. package/hooks/dist/gsd-update-banner.js +8 -0
  413. package/hooks/dist/gsd-validate-commit.sh +63 -4
  414. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  415. package/hooks/dist/gsd-workflow-guard.js +5 -4
  416. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  417. package/hooks/dist/lib/cli-exit.js +12 -0
  418. package/hooks/dist/lib/git-probe.js +17 -1
  419. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  420. package/hooks/gsd-agent-isolation-guard.js +32 -0
  421. package/hooks/gsd-check-update-worker.js +8 -0
  422. package/hooks/gsd-check-update.js +8 -0
  423. package/hooks/gsd-context-monitor.js +31 -8
  424. package/hooks/gsd-cursor-subagent-start.js +8 -0
  425. package/hooks/gsd-secret-read-guard.js +161 -4
  426. package/hooks/gsd-statusline.js +85 -20
  427. package/hooks/gsd-update-banner.js +8 -0
  428. package/hooks/gsd-validate-commit.sh +63 -4
  429. package/hooks/gsd-windsurf-pre-write.js +11 -2
  430. package/hooks/gsd-workflow-guard.js +5 -4
  431. package/hooks/gsd-worktree-path-guard.js +6 -2
  432. package/hooks/hooks.json +5 -5
  433. package/hooks/lib/cli-exit.js +12 -0
  434. package/hooks/lib/git-probe.js +17 -1
  435. package/hooks/lib/isolation-sentinel.js +2 -2
  436. package/package.json +22 -4
  437. package/scripts/build-hooks.js +15 -6
  438. package/scripts/changeset/parse.cjs +52 -4
  439. package/scripts/check-contract-drift.cjs +127 -11
  440. package/scripts/ci-timeout-report.cjs +770 -4
  441. package/scripts/command-contract-helpers.cjs +15 -8
  442. package/scripts/docs-guard-registry.cjs +34 -0
  443. package/scripts/gen-features.cjs +13 -8
  444. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  445. package/scripts/gen-loop-host-contract.cjs +79 -1
  446. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  447. package/scripts/gen-plugin-skills.cjs +87 -1
  448. package/scripts/gen-research-agents.cjs +24 -31
  449. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  450. package/scripts/gen-test-timings.cjs +32 -7
  451. package/scripts/lib/cli-exit.cjs +12 -0
  452. package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
  453. package/scripts/lib/ndjson-reporter.cjs +31 -5
  454. package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
  455. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  456. package/scripts/lib/vendor-bundle.cjs +59 -0
  457. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  458. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  459. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  460. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  461. package/scripts/lint-descriptions.cjs +7 -3
  462. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
  463. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  464. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  465. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  466. package/scripts/lint-phase-arg-assignment.cjs +257 -0
  467. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  468. package/scripts/lint-phase-id-drift.cjs +319 -5
  469. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  470. package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
  471. package/scripts/lint-response-language-coverage.cjs +3 -0
  472. package/scripts/lint-retired-runtime-name.cjs +619 -0
  473. package/scripts/lint-skill-deps.cjs +7 -3
  474. package/scripts/lint-state-write-path-drift.cjs +93 -0
  475. package/scripts/lint-test-file-count.allowlist.json +38 -9
  476. package/scripts/lint-test-file-count.cjs +34 -1
  477. package/scripts/lint-vendored-deps.cjs +41 -5
  478. package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
  479. package/scripts/mutation-matrix.cjs +50 -5
  480. package/scripts/prompt-injection-scan.sh +4 -0
  481. package/scripts/release-tarball-smoke.cjs +194 -1
  482. package/scripts/require-issue-link-policy.cjs +6 -2
  483. package/scripts/sync-runtime-launcher.cjs +184 -2
  484. package/scripts/verify-npm-publish.cjs +76 -20
  485. package/skills/gsd-add-tests/SKILL.md +6 -1
  486. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  487. package/skills/gsd-audit-fix/SKILL.md +5 -0
  488. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  489. package/skills/gsd-autonomous/SKILL.md +7 -2
  490. package/skills/gsd-capture/SKILL.md +9 -5
  491. package/skills/gsd-code-review/SKILL.md +7 -2
  492. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  493. package/skills/gsd-config/SKILL.md +8 -4
  494. package/skills/gsd-debug/SKILL.md +11 -7
  495. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  496. package/skills/gsd-docs-update/SKILL.md +12 -7
  497. package/skills/gsd-eval-review/SKILL.md +6 -1
  498. package/skills/gsd-execute-phase/SKILL.md +12 -7
  499. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  500. package/skills/gsd-fast/SKILL.md +4 -0
  501. package/skills/gsd-forensics/SKILL.md +5 -1
  502. package/skills/gsd-graphify/SKILL.md +10 -6
  503. package/skills/gsd-health/SKILL.md +5 -0
  504. package/skills/gsd-help/SKILL.md +7 -2
  505. package/skills/gsd-import/SKILL.md +7 -3
  506. package/skills/gsd-inbox/SKILL.md +5 -0
  507. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  508. package/skills/gsd-manager/SKILL.md +6 -1
  509. package/skills/gsd-map-codebase/SKILL.md +7 -3
  510. package/skills/gsd-mempalace-capture/SKILL.md +12 -4
  511. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  512. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  513. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  514. package/skills/gsd-new-milestone/SKILL.md +6 -1
  515. package/skills/gsd-new-project/SKILL.md +5 -0
  516. package/skills/gsd-next/SKILL.md +6 -1
  517. package/skills/gsd-ns-context/SKILL.md +4 -0
  518. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  519. package/skills/gsd-ns-manage/SKILL.md +4 -0
  520. package/skills/gsd-ns-project/SKILL.md +4 -0
  521. package/skills/gsd-ns-review/SKILL.md +4 -0
  522. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  523. package/skills/gsd-onboard/SKILL.md +6 -1
  524. package/skills/gsd-pause-work/SKILL.md +5 -1
  525. package/skills/gsd-phase/SKILL.md +8 -4
  526. package/skills/gsd-plan-phase/SKILL.md +6 -1
  527. package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
  528. package/skills/gsd-pr-branch/SKILL.md +4 -0
  529. package/skills/gsd-profile-user/SKILL.md +5 -1
  530. package/skills/gsd-progress/SKILL.md +7 -2
  531. package/skills/gsd-quick/SKILL.md +16 -10
  532. package/skills/gsd-quick-batch/SKILL.md +21 -9
  533. package/skills/gsd-review/SKILL.md +7 -4
  534. package/skills/gsd-review-backlog/SKILL.md +3 -2
  535. package/skills/gsd-secure-phase/SKILL.md +6 -1
  536. package/skills/gsd-ship/SKILL.md +5 -0
  537. package/skills/gsd-sketch/SKILL.md +7 -2
  538. package/skills/gsd-spec-phase/SKILL.md +5 -1
  539. package/skills/gsd-spike/SKILL.md +8 -3
  540. package/skills/gsd-surface/SKILL.md +5 -1
  541. package/skills/gsd-thread/SKILL.md +4 -0
  542. package/skills/gsd-ui-phase/SKILL.md +6 -1
  543. package/skills/gsd-ui-review/SKILL.md +6 -1
  544. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  545. package/skills/gsd-undo/SKILL.md +5 -1
  546. package/skills/gsd-update/SKILL.md +6 -2
  547. package/skills/gsd-validate-phase/SKILL.md +6 -1
  548. package/skills/gsd-verify-work/SKILL.md +6 -1
  549. package/skills/gsd-workspace/SKILL.md +7 -3
  550. package/skills/gsd-workstreams/SKILL.md +6 -6
  551. package/vscode/package.json +1 -1
@@ -162,6 +162,12 @@ const REASON = Object.freeze({
162
162
  // Axis 2 (§8.6, retained): a raw `fs.writeFileSync(` call targeting the
163
163
  // state path — see `findRawStateWrites`.
164
164
  RAW_STATE_WRITE: 'raw_state_write',
165
+ // ADR-4629 §8.1 (epic #4629, C1): a residual `readModifyWriteStateMd(path,
166
+ // (content) => …)` call whose transform is an inline anonymous arrow/function
167
+ // — the opaque shape §8.1 replaces with a declared StateWriteIntent. Recognized
168
+ // by `findOpaqueStateTransforms`; a CAPABILITY in C1 (not wired into collect()),
169
+ // wired terminal in C2 as the residual callers migrate (ADR-3408 §6 phasing).
170
+ OPAQUE_STATE_TRANSFORM: 'opaque_state_transform',
165
171
  // Axis 4 (§8.3, Decision 4(d)): prompt-layer prose shelling out to a
166
172
  // write-side `gsd-tools` subcommand — see `findPromptSeamUses`.
167
173
  PROMPT_LAYER_STATE_WRITE: 'prompt_layer_state_write',
@@ -645,6 +651,91 @@ function findRawStateWrites(rel, text) {
645
651
  return out;
646
652
  }
647
653
 
654
+ // ADR-4629 §8.1 (epic #4629, C1) — OPAQUE-TRANSFORM RECOGNITION.
655
+ //
656
+ // A residual `readModifyWriteStateMd(path, (content) => …)` call whose transform
657
+ // (2nd) argument is an inline anonymous arrow / function expression is the opaque
658
+ // shape §8.1 replaces with a declared StateWriteIntent: `readModifyWriteStateMd`
659
+ // goes THROUGH the seam (it is NOT a raw-write bypass — Axis 2's concern), but its
660
+ // opaque body transform is neither verified (§8.2) nor bounded (§8.3). This
661
+ // function RECOGNIZES that shape.
662
+ //
663
+ // C1 ships recognition as a CAPABILITY: it is exported and unit-tested (positive
664
+ // control on a seeded fixture) but is DELIBERATELY NOT wired into `collect()`'s
665
+ // failing scan. §8.1's caller-side rule is *Required — Phase 2*; wiring it now
666
+ // would turn the ~16 residual callers red at once, and ADR-3473 §8.6 retired the
667
+ // ratchet that would otherwise be needed to absorb them. C2 wires this terminal as
668
+ // the verifying executor lands and the callers migrate under ADR-3408 §6 phasing.
669
+ //
670
+ // String match, never an AST — same over-report-safe posture as every axis here.
671
+ const OPAQUE_RMW_CALL_RE = /\breadModifyWriteStateMd\s*\(/g;
672
+ // The transform arg is OPAQUE when it BEGINS an inline anonymous function: an
673
+ // arrow (`(…) =>`, `ident =>`, optionally `async`) or a `function` expression. A
674
+ // bare identifier / object (a declared StateWriteIntent, Phase 2+) is NOT opaque.
675
+ const ANON_TRANSFORM_RE =
676
+ /^\s*(?:async\s+)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>|^\s*(?:async\s+)?function\b/;
677
+
678
+ /**
679
+ * Capture the top-level, comma-separated argument list of a call, starting at
680
+ * `startIdx` (the index just AFTER the opening `(`) — across newlines and
681
+ * string-aware, tracking `()[]{}` depth. Returns the raw arg strings, or null if
682
+ * the parens never balance (a truncated arg list is never flagged). Generalizes
683
+ * `captureFirstArg`'s depth/inStr bookkeeping to every argument.
684
+ */
685
+ function captureCallArgList(text, startIdx) {
686
+ let depth = 0;
687
+ let inStr = null;
688
+ const args = [];
689
+ let cur = '';
690
+ for (let i = startIdx; i < text.length; i++) {
691
+ const ch = text[i];
692
+ if (inStr) {
693
+ cur += ch;
694
+ if (ch === inStr && text[i - 1] !== '\\') inStr = null;
695
+ continue;
696
+ }
697
+ if (ch === '"' || ch === "'" || ch === '`') { inStr = ch; cur += ch; continue; }
698
+ if (ch === '(' || ch === '[' || ch === '{') { depth++; cur += ch; continue; }
699
+ if (ch === ')' || ch === ']' || ch === '}') {
700
+ if (ch === ')' && depth === 0) {
701
+ if (cur.trim() !== '' || args.length) args.push(cur);
702
+ return args;
703
+ }
704
+ depth--; cur += ch; continue;
705
+ }
706
+ if (ch === ',' && depth === 0) { args.push(cur); cur = ''; continue; }
707
+ cur += ch;
708
+ }
709
+ return null; // parens never balanced
710
+ }
711
+
712
+ /**
713
+ * Recognize residual opaque-transform STATE.md writes (ADR-4629 §8.1). Returns a
714
+ * finding per `readModifyWriteStateMd(` call whose 2nd argument is an inline
715
+ * anonymous transform. CAPABILITY only in C1 — not called by `collect()`.
716
+ */
717
+ function findOpaqueStateTransforms(rel, text) {
718
+ const rawLines = text.split('\n');
719
+ const stripped = stripComments(text).join('\n');
720
+ const out = [];
721
+ let m;
722
+ OPAQUE_RMW_CALL_RE.lastIndex = 0;
723
+ while ((m = OPAQUE_RMW_CALL_RE.exec(stripped)) !== null) {
724
+ const args = captureCallArgList(stripped, m.index + m[0].length);
725
+ if (!args || args.length < 2) continue;
726
+ if (!ANON_TRANSFORM_RE.test(args[1])) continue;
727
+ const lineNo = stripped.slice(0, m.index).split('\n').length;
728
+ out.push({
729
+ reason: REASON.OPAQUE_STATE_TRANSFORM,
730
+ axis: 'opaque-transform',
731
+ file: sanitizeForReport(rel),
732
+ line: lineNo,
733
+ source: sanitizeForReport((rawLines[lineNo - 1] || '').trim()),
734
+ });
735
+ }
736
+ return out;
737
+ }
738
+
648
739
  // The two write-seam STAGE functions, matched only as CALLS (`\(`
649
740
  // immediately after, modulo whitespace) — never as bare mentions of the
650
741
  // name. `writeStateMd(` is deliberately NOT included here (that arm is
@@ -941,6 +1032,8 @@ module.exports = {
941
1032
  nearestPrecedingAssignment,
942
1033
  findRawStateWrites,
943
1034
  targetsStatePath,
1035
+ findOpaqueStateTransforms,
1036
+ captureCallArgList,
944
1037
  findCompositionBypasses,
945
1038
  findPromptSeamUses,
946
1039
  isInsideCodeSpan,
@@ -1,6 +1,15 @@
1
1
  {
2
- "_doc": "Baseline of modules currently exceeding the 2-test-file limit. Each entry locks in TODAY's exact test filenames as the allowlisted set (identity ratchet). Adding a NEW test file to a capped module fails (novel). Removing one requires pruning this list (stale, ratchet-down). When a cluster drops to \u2264 2, remove its entry entirely. New entries require justification in PR description.",
2
+ "_doc": "Baseline of modules currently exceeding the 2-test-file limit. Each entry locks in TODAY's exact test filenames as the allowlisted set (identity ratchet). Adding a NEW test file to a capped module fails (novel). Removing one requires pruning this list (stale, ratchet-down). When a cluster drops to ≤ 2, remove its entry entirely. New entries require justification in PR description.",
3
3
  "modules": {
4
+ "ui-consideration-probe": {
5
+ "files": [
6
+ "ui-consideration-probe-docs-fixtures.test.cjs",
7
+ "ui-consideration-probe-ui-phase-contract.test.cjs",
8
+ "ui-consideration-probe.test.cjs"
9
+ ],
10
+ "issue": "4657",
11
+ "justification": "The ui-consideration-probe cluster gains its workflow-prose contract file (tests/ui-consideration-probe-ui-phase-contract.test.cjs, #4657), mirroring the edge probe's split (edge-probe.test.cjs / edge-probe-docs-fixtures.test.cjs / edge-probe-spec-phase-contract.test.cjs). The contract file reads shipped gsd-core/workflows/ui-phase.md under the source-text-is-the-product exception, which the unit file deliberately does not carry (it asserts typed returns only)."
12
+ },
4
13
  "adr-parser": {
5
14
  "files": [
6
15
  "adr-parser.property.test.cjs",
@@ -40,7 +49,7 @@
40
49
  "frontmatter.unit.test.cjs"
41
50
  ],
42
51
  "issue": "3881",
43
- "justification": "Grandfathered by #3227 for the original 4-file cluster (pre-existing over-cap, not new sprawl). #3881 (ADR-3473 \u00a78.1, the js-yaml parser migration) adds two more: frontmatter-golden-parity.test.cjs (D-series golden-corpus diff against the legacy parser, ~900 real documents \u2014 cannot be folded into an existing file without losing its independent-of-current-parser provenance) and frontmatter-roundtrip.property.test.cjs (fast-check property coverage the migration's bijective-contract rule requires). Both are migration-specific, not incidental sprawl."
52
+ "justification": "Grandfathered by #3227 for the original 4-file cluster (pre-existing over-cap, not new sprawl). #3881 (ADR-3473 §8.1, the js-yaml parser migration) adds two more: frontmatter-golden-parity.test.cjs (D-series golden-corpus diff against the legacy parser, ~900 real documents — cannot be folded into an existing file without losing its independent-of-current-parser provenance) and frontmatter-roundtrip.property.test.cjs (fast-check property coverage the migration's bijective-contract rule requires). Both are migration-specific, not incidental sprawl."
44
53
  },
45
54
  "graphify": {
46
55
  "files": [
@@ -133,14 +142,16 @@
133
142
  "files": [
134
143
  "verify-archive-dirs-live-path.test.cjs",
135
144
  "verify-health.test.cjs",
145
+ "verify-lifecycle-writes-e2e.test.cjs",
136
146
  "verify-mvp-uat.test.cjs",
137
147
  "verify-npm-publish.test.cjs",
138
148
  "verify-test-quality.test.cjs",
139
149
  "verify-work-auto-transition.test.cjs",
150
+ "verify-work-deferred-promotion.test.cjs",
140
151
  "verify.test.cjs"
141
152
  ],
142
- "issue": "#3813 \u2014 the live-path #1883 suite drives buildPlanningSnapshot in-process with an fs fault; the verify module suites are CLI-driving and cannot host an fs monkeypatch",
143
- "justification": "verify-command-grounding added by #2401/#3678; allowlist follow-up landed with #3606 (base was red on this lane)."
153
+ "issue": "#3813 — the live-path #1883 suite drives buildPlanningSnapshot in-process with an fs fault; the verify module suites are CLI-driving and cannot host an fs monkeypatch",
154
+ "justification": "verify-command-grounding added by #2401/#3678; allowlist follow-up landed with #3606 (base was red on this lane). #4546 adds verify-work-deferred-promotion (deferred-follow-up promotion writer contract + parity). #5105 adds verify-lifecycle-writes-e2e.test.cjs (Phase 3 of #5056: end-to-end fixture proving the fixed post-fingerprint verbs leave an unchanged re-run fresh, plus its own pre-fix CONTROL — a distinct end-to-end concern from the existing per-verb unit suites)."
144
155
  },
145
156
  "install": {
146
157
  "files": [
@@ -154,7 +165,7 @@
154
165
  "install-write-confinement.test.cjs",
155
166
  "install.test.cjs"
156
167
  ],
157
- "issue": "#3798 \u2014 the profile-closure spawn test reads the real repo surface (commands+workflows+agents); consolidating it into install.test.cjs would put a whole-repo scan behind the suite's heaviest file"
168
+ "issue": "#3798 — the profile-closure spawn test reads the real repo surface (commands+workflows+agents); consolidating it into install.test.cjs would put a whole-repo scan behind the suite's heaviest file"
158
169
  },
159
170
  "edge-probe": {
160
171
  "files": [
@@ -252,8 +263,8 @@
252
263
  "docs-state-md-locale-parity.test.cjs",
253
264
  "docs-update.test.cjs"
254
265
  ],
255
- "issue": "3873 | #3839 \u2014 the hook-event parity suite cross-checks the four docs hook tables against src/runtime-hooks-surface.cts registrations; a generated-docs concern distinct from content freshness and registry parity",
256
- "justification": "ADR-3473 \u00a78.8 makes docs/reference/state-md.md and its four locale siblings generated-and-committed and adds the repo's first locale-parity check (verified: no locale-parity lint precedent exists here). That check is a distinct concern from docs-update (content freshness) and docs-parity-live-registry (registry parity); folding it into either would place an unrelated subject inside them purely to satisfy a count. The section it guards is absent from all four translations today and documents the status enum behind #3853."
266
+ "issue": "3873 | #3839 — the hook-event parity suite cross-checks the four docs hook tables against src/runtime-hooks-surface.cts registrations; a generated-docs concern distinct from content freshness and registry parity",
267
+ "justification": "ADR-3473 §8.8 makes docs/reference/state-md.md and its four locale siblings generated-and-committed and adds the repo's first locale-parity check (verified: no locale-parity lint precedent exists here). That check is a distinct concern from docs-update (content freshness) and docs-parity-live-registry (registry parity); folding it into either would place an unrelated subject inside them purely to satisfy a count. The section it guards is absent from all four translations today and documents the status enum behind #3853."
257
268
  },
258
269
  "audit": {
259
270
  "files": [
@@ -265,7 +276,7 @@
265
276
  "audit-uat-summary-segmentation.test.cjs",
266
277
  "audit-workstream-layouts.test.cjs"
267
278
  ],
268
- "issue": "#3804/#3805 \u2014 audit-layout and acknowledged-marker suites drive the real audit-uat CLI against on-disk fixtures | #3817 \u2014 regression suite proving countReal counts the truncation remainder marker instead of treating it as one phantom item | #3783 \u2014 dedicated suite for the summary.current_milestone/archived segmentation, matching this module's one-file-per-feature-slice precedent (e.g. audit-uat-acknowledged.test.cjs) rather than growing the unrelated 6900+ line tests/uat.test.cjs (a different module, keyed off uat.cjs)"
279
+ "issue": "#3804/#3805 — audit-layout and acknowledged-marker suites drive the real audit-uat CLI against on-disk fixtures | #3817 — regression suite proving countReal counts the truncation remainder marker instead of treating it as one phantom item | #3783 — dedicated suite for the summary.current_milestone/archived segmentation, matching this module's one-file-per-feature-slice precedent (e.g. audit-uat-acknowledged.test.cjs) rather than growing the unrelated 6900+ line tests/uat.test.cjs (a different module, keyed off uat.cjs)"
269
280
  },
270
281
  "shell-command-projection": {
271
282
  "files": [
@@ -273,7 +284,25 @@
273
284
  "shell-command-projection-md-normalize.test.cjs",
274
285
  "shell-command-projection-path-sep.test.cjs"
275
286
  ],
276
- "issue": "#3854 \u2014 the tight-list suite pins the markdown write-normalizer's blank-line policy through the exported normalizeContent/platformWriteSync seam; a distinct concern from dispatch routing and path separation"
287
+ "issue": "#3854 — the tight-list suite pins the markdown write-normalizer's blank-line policy through the exported normalizeContent/platformWriteSync seam; a distinct concern from dispatch routing and path separation"
288
+ },
289
+ "ui-consideration-probe": {
290
+ "files": [
291
+ "ui-consideration-probe-docs-fixtures.test.cjs",
292
+ "ui-consideration-probe-ui-phase-contract.test.cjs",
293
+ "ui-consideration-probe.test.cjs"
294
+ ],
295
+ "issue": "4657",
296
+ "justification": "The ui-consideration-probe cluster gains its workflow-prose contract file (tests/ui-consideration-probe-ui-phase-contract.test.cjs, #4657), mirroring the edge probe's split (edge-probe.test.cjs / edge-probe-docs-fixtures.test.cjs / edge-probe-spec-phase-contract.test.cjs). The contract file reads shipped gsd-core/workflows/ui-phase.md under the source-text-is-the-product exception, which the unit file deliberately does not carry (it asserts typed returns only)."
297
+ },
298
+ "verification": {
299
+ "files": [
300
+ "verification-append-audit.test.cjs",
301
+ "verification-overrides.test.cjs",
302
+ "verification-status.test.cjs"
303
+ ],
304
+ "issue": "5105",
305
+ "justification": "#5105 (Phase 3 of #5056) adds verification-append-audit.test.cjs for the new `verification.append-audit` verb (deny-by-default audit-block append/no-op, #4887) — a distinct concern from verification-status.test.cjs's status/fingerprint suite and verification-overrides.test.cjs's override handling."
277
306
  }
278
307
  }
279
308
  }
@@ -141,6 +141,38 @@ function buildTestMap(prodPrefixes, allTestFiles) {
141
141
  return map;
142
142
  }
143
143
 
144
+ // #5074: a `<stem>.platform.test.cjs` alongside `<stem>.test.cjs` (or
145
+ // `.test.ts`) in the SAME directory is the other half of that primary file —
146
+ // the platform-sensitive slice extracted so the Windows CI selector runs
147
+ // only the small sibling — not an additional test file. Exclude it from the
148
+ // per-module count and from the allowlist identity comparison. A
149
+ // `.platform.test.cjs` with no base file in the same directory counts
150
+ // normally, so the rule cannot be used to smuggle in new standalone files.
151
+ // An empty stem (bare `platform.test.cjs`) is never treated as a sibling.
152
+ const PLATFORM_SIBLING_RE = /^(.+)\.platform\.test\.(cjs|ts)$/;
153
+
154
+ function isSplitSibling(fileBasename, siblingBasenamesInDir) {
155
+ const m = fileBasename.match(PLATFORM_SIBLING_RE);
156
+ if (!m) return false;
157
+ const stem = m[1];
158
+ if (!stem) return false;
159
+ return siblingBasenamesInDir.includes(`${stem}.test.cjs`) ||
160
+ siblingBasenamesInDir.includes(`${stem}.test.ts`);
161
+ }
162
+
163
+ function excludeSplitSiblings(testFiles) {
164
+ const basenamesByDir = new Map();
165
+ for (const f of testFiles) {
166
+ const dir = path.dirname(f);
167
+ if (!basenamesByDir.has(dir)) basenamesByDir.set(dir, []);
168
+ basenamesByDir.get(dir).push(path.basename(f));
169
+ }
170
+ return testFiles.filter(f => {
171
+ const dir = path.dirname(f);
172
+ return !isSplitSibling(path.basename(f), basenamesByDir.get(dir));
173
+ });
174
+ }
175
+
144
176
  function loadAllowlist() {
145
177
  try { return JSON.parse(fs.readFileSync(ALLOWLIST_PATH, 'utf-8')).modules || {}; }
146
178
  catch (_) { return {}; }
@@ -160,6 +192,7 @@ function loadAllowlist() {
160
192
  * Returns { verdict, prefix, count, knownFiles, novel, stale, files }
161
193
  */
162
194
  function evaluateLint({ prefix, testFiles, allowlist }) {
195
+ testFiles = excludeSplitSiblings(testFiles);
163
196
  const count = testFiles.length;
164
197
  const entry = allowlist[prefix];
165
198
  const currentNames = testFiles.map(f => path.basename(f));
@@ -258,7 +291,7 @@ function run() {
258
291
  }
259
292
 
260
293
  module.exports = {
261
- Verdict, evaluateLint, testEffectivePrefix, prodPrefix,
294
+ Verdict, evaluateLint, testEffectivePrefix, prodPrefix, isSplitSibling,
262
295
  _collectProdPrefixes: collectProdPrefixes,
263
296
  _collectAllTestFiles: collectAllTestFiles,
264
297
  _buildTestMap: buildTestMap,
@@ -57,6 +57,7 @@
57
57
  const fs = require('node:fs');
58
58
  const path = require('node:path');
59
59
  const { ExitError, runMain } = require('./lib/cli-exit.cjs');
60
+ const { buildVendorBundle } = require('./lib/vendor-bundle.cjs');
60
61
 
61
62
  const ROOT = path.join(__dirname, '..');
62
63
 
@@ -89,16 +90,29 @@ function resolvePath(p) {
89
90
  * or null when there is no bin-side type twin
90
91
  * @property {string|null} srcTwin path under src/vendor/ to the source-side type twin tsc
91
92
  * resolves for a relative import from src/**, or null
92
- * @property {'upstream-verbatim'|'hand-authored'} twinKind
93
+ * @property {boolean} [bundle] Reproducibly bundle upstream and its locked dependencies.
94
+ * @property {'upstream-verbatim'|'upstream-reference'|'hand-authored'} twinKind
93
95
  * 'upstream-verbatim': srcTwin/vendoredDts are byte-compared
94
96
  * against upstream and each other.
95
97
  * 'hand-authored': no upstream counterpart exists, so the
96
98
  * twin is excluded from the byte-compare (checks 2 and 3
97
99
  * above are skipped for this row).
100
+ * 'upstream-reference': srcTwin must be exactly
101
+ * `export * from '<name>';` (bundled rows).
98
102
  */
99
103
 
100
104
  /** @type {VendoredPackage[]} */
101
105
  const VENDORED = [
106
+ ...['tap-parser', 'saxes'].map((name) => ({
107
+ name,
108
+ upstreamCjs: name === 'tap-parser' ? 'node_modules/tap-parser/dist/commonjs/index.js' : 'node_modules/saxes/saxes.js',
109
+ vendoredCjs: `gsd-core/bin/lib/vendor/${name}.cjs`,
110
+ upstreamDts: null,
111
+ vendoredDts: null,
112
+ srcTwin: `src/vendor/${name}.d.cts`,
113
+ twinKind: 'upstream-reference',
114
+ bundle: true,
115
+ })),
102
116
  {
103
117
  name: 're2js',
104
118
  upstreamCjs: 'node_modules/re2js/build/index.cjs',
@@ -127,6 +141,7 @@ const VENDORED = [
127
141
  * @returns {string}
128
142
  */
129
143
  function buildRefreshCommand(row) {
144
+ if (row.bundle) return 'npm run lint:vendored-deps -- --fix';
130
145
  const parts = [`cp ${row.upstreamCjs} ${row.vendoredCjs}`];
131
146
  if (row.twinKind === 'upstream-verbatim' && row.upstreamDts) {
132
147
  if (row.vendoredDts) parts.push(`cp ${row.upstreamDts} ${row.vendoredDts}`);
@@ -135,7 +150,8 @@ function buildRefreshCommand(row) {
135
150
  return parts.join(' && ');
136
151
  }
137
152
 
138
- const REFRESH_COMMAND = VENDORED.map(buildRefreshCommand).join(' && ');
153
+ // Bundled rows share one refresh command; list it once.
154
+ const REFRESH_COMMAND = [...new Set(VENDORED.map(buildRefreshCommand))].join(' && ');
139
155
 
140
156
  /**
141
157
  * Compare two files byte-for-byte. Returns null when equal, or a short
@@ -263,8 +279,17 @@ function readPinState(row, pkgRoot = ROOT) {
263
279
  function checkRow(row, pkgRoot = ROOT) {
264
280
  const findings = [];
265
281
 
266
- const cjsDrift = compareFiles(row.vendoredCjs, row.upstreamCjs);
267
- if (cjsDrift) findings.push(cjsDrift);
282
+ if (row.bundle) {
283
+ const built = buildVendorBundle(pkgRoot, row.upstreamCjs);
284
+ for (const [file, expected] of [[row.vendoredCjs, built.code], [`${row.vendoredCjs}.LICENSE.txt`, built.notices]]) {
285
+ if (!fs.existsSync(resolvePath(file)) || !fs.readFileSync(resolvePath(file)).equals(expected)) {
286
+ findings.push(`${file} != reproducible upstream bundle (including license notices)`);
287
+ }
288
+ }
289
+ } else {
290
+ const cjsDrift = compareFiles(row.vendoredCjs, row.upstreamCjs);
291
+ if (cjsDrift) findings.push(cjsDrift);
292
+ }
268
293
 
269
294
  if (row.twinKind === 'upstream-verbatim') {
270
295
  if (row.upstreamDts && row.vendoredDts) {
@@ -277,6 +302,11 @@ function checkRow(row, pkgRoot = ROOT) {
277
302
  }
278
303
  } else if (row.twinKind === 'hand-authored') {
279
304
  findings.push(...checkHandAuthoredTwin(row));
305
+ } else if (row.twinKind === 'upstream-reference') {
306
+ const expected = `export * from '${row.name}';\n`;
307
+ if (!row.srcTwin || !fs.existsSync(resolvePath(row.srcTwin)) || fs.readFileSync(resolvePath(row.srcTwin), 'utf8') !== expected) {
308
+ findings.push(`${row.name}: type twin must forward the upstream declarations verbatim`);
309
+ }
280
310
  }
281
311
 
282
312
  const { pinnedSpec, installedVersion } = readPinState(row, pkgRoot);
@@ -318,7 +348,13 @@ function checkRow(row, pkgRoot = ROOT) {
318
348
  * @returns {string[]} findings remaining after the fix (empty when fully resolved)
319
349
  */
320
350
  function fixRow(row, pkgRoot = ROOT) {
321
- fs.copyFileSync(resolvePath(row.upstreamCjs), resolvePath(row.vendoredCjs));
351
+ if (row.bundle) {
352
+ const built = buildVendorBundle(pkgRoot, row.upstreamCjs);
353
+ fs.writeFileSync(resolvePath(row.vendoredCjs), built.code);
354
+ fs.writeFileSync(resolvePath(`${row.vendoredCjs}.LICENSE.txt`), built.notices);
355
+ } else {
356
+ fs.copyFileSync(resolvePath(row.upstreamCjs), resolvePath(row.vendoredCjs));
357
+ }
322
358
 
323
359
  if (row.twinKind === 'upstream-verbatim' && row.upstreamDts) {
324
360
  if (row.vendoredDts) fs.copyFileSync(resolvePath(row.upstreamDts), resolvePath(row.vendoredDts));
@@ -354,11 +354,6 @@
354
354
  "code": "2012",
355
355
  "message": "Use find instead of ls to better handle non-alphanumeric filenames."
356
356
  },
357
- {
358
- "file": "gsd-core/workflows/execute-phase.md",
359
- "code": "2012",
360
- "message": "Use find instead of ls to better handle non-alphanumeric filenames."
361
- },
362
357
  {
363
358
  "file": "gsd-core/workflows/execute-phase.md",
364
359
  "code": "2016",
@@ -384,11 +379,6 @@
384
379
  "code": "2086",
385
380
  "message": "Double quote to prevent globbing and word splitting."
386
381
  },
387
- {
388
- "file": "gsd-core/workflows/execute-phase.md",
389
- "code": "2086",
390
- "message": "Double quote to prevent globbing and word splitting."
391
- },
392
382
  {
393
383
  "file": "gsd-core/workflows/execute-phase/detail/elaboration.md",
394
384
  "code": "2086",
@@ -414,6 +404,16 @@
414
404
  "code": "2086",
415
405
  "message": "Double quote to prevent globbing and word splitting."
416
406
  },
407
+ {
408
+ "file": "gsd-core/workflows/execute-phase/steps/verify-phase-goal.md",
409
+ "code": "2012",
410
+ "message": "Use find instead of ls to better handle non-alphanumeric filenames."
411
+ },
412
+ {
413
+ "file": "gsd-core/workflows/execute-phase/steps/verify-phase-goal.md",
414
+ "code": "2086",
415
+ "message": "Double quote to prevent globbing and word splitting."
416
+ },
417
417
  {
418
418
  "file": "gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
419
419
  "code": "2086",
@@ -1108,5 +1108,20 @@
1108
1108
  "file": "gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",
1109
1109
  "code": "2086",
1110
1110
  "message": "Double quote to prevent globbing and word splitting."
1111
+ },
1112
+ {
1113
+ "file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
1114
+ "code": "2317",
1115
+ "message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
1116
+ },
1117
+ {
1118
+ "file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
1119
+ "code": "2317",
1120
+ "message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
1121
+ },
1122
+ {
1123
+ "file": "gsd-core/workflows/execute-phase/steps/code-review-disposition.md",
1124
+ "code": "2317",
1125
+ "message": "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
1111
1126
  }
1112
1127
  ]
@@ -402,11 +402,22 @@ const COVERED = {
402
402
  // extraTests above) rather than deleted, so the mutants they kill stay killed.
403
403
  // frontmatter.test.cjs itself is UNCHANGED and keeps running in the normal
404
404
  // (non-mutation) suite — only the mutation shard drops it.
405
+ // - frontmatter-splice.property.test.cjs (#5105): the writer's own property suite,
406
+ // moved out of frontmatter.property.test.cjs when spliceFrontmatter moved to
407
+ // frontmatter-splice.cts. It requires frontmatter.cjs only as the read-back oracle and
408
+ // matches this module's "frontmatter-" prefix, so the derivation would pull it in here;
409
+ // it runs in the frontmatter-splice shard instead. Keeping it out of this shard is the
410
+ // point of the split: the frontmatter shard was cancelled at its 20-minute cap on PR
411
+ // #5114 (1149/1749 mutants tested) with these splice-heavy properties re-run for every
412
+ // parser mutant they happened to cover.
405
413
  excludeTests: [
406
414
  'frontmatter-cli.test.cjs',
415
+ 'frontmatter-splice.property.test.cjs',
407
416
  'frontmatter.test.cjs',
408
417
  ],
409
- minScore: 65,
418
+ // 87.72% in CI run 36590493522 on PR #5114 (#5105 added in-process command tests).
419
+ // Floor = floor(87.72) - 1 = 86.
420
+ minScore: 86,
410
421
  // MEASUREMENT, not a projection. Under the tap runner with coverageAnalysis: 'perTest'
411
422
  // (#3915), Stryker now re-runs only the test files that cover each mutated line instead
412
423
  // of all six files for every one of ~1900 mutants. Measured result: the frontmatter shard
@@ -428,6 +439,37 @@ const COVERED = {
428
439
  // The prior audit's 'none' vs 'process' comparison (recorded here before this change)
429
440
  // is moot: there is nothing left to opt in or out of.
430
441
  },
442
+ // frontmatter-splice: net-new module from #5105 — the frontmatter WRITER (spliceFrontmatter
443
+ // and its layout slicing, comment classification, parse budget, key quoting and read-back
444
+ // check), split out of frontmatter.cts by module ownership. Before the split the writer grew
445
+ // frontmatter.cjs from 1249 to 1749 mutants and the frontmatter shard was cancelled at its
446
+ // 20-minute cap (PR #5114, run 36577087588, job 109435636296: 1149/1749 tested at ~1.34
447
+ // s/covered mutant). Stryker's instrumenter counts 1267 mutants in frontmatter.cjs and 498 in
448
+ // frontmatter-splice.cjs after the split. Registered here so the writer is scored at all —
449
+ // mutation coverage does not migrate with relocated code (the context-composer precedent).
450
+ //
451
+ // Tests: frontmatter-splice.property.test.cjs is auto-derived (requires this module, matches
452
+ // the naming rule). extraTests are the other files that drive spliceFrontmatter directly —
453
+ // they are named after frontmatter, so the derivation cannot find them for this module:
454
+ // - frontmatter.unit.test.cjs: the #1572/#1660/#3257/#3742/#4802 splice cases.
455
+ // - frontmatter.property.test.cjs: the #644 prohibitions parse -> splice -> re-parse
456
+ // bijection.
457
+ // - frontmatter-fence.test.cjs: the writer's BOM / CRLF / empty-block fence cases.
458
+ //
459
+ // minScore 62: the module was first registered with a provisional floor of 50 (the minimum
460
+ // the ratchet test permits, tests/mutation-matrix-ratchet.test.cjs:107-116) because the shard
461
+ // cannot run locally (see HOW TO UPDATE above). The first CI measurement was 63.82% (CI run
462
+ // 36586350120, PR #5114), so the floor is set to floor(63.82) - 1 = 62, following this file's
463
+ // convention, together with its RATCHET_BASELINE entry.
464
+ 'frontmatter-splice': {
465
+ cjs: 'gsd-core/bin/lib/frontmatter-splice.cjs',
466
+ extraTests: [
467
+ 'frontmatter-fence.test.cjs',
468
+ 'frontmatter.property.test.cjs',
469
+ 'frontmatter.unit.test.cjs',
470
+ ],
471
+ minScore: 62,
472
+ },
431
473
  // adr-parser / config-schema / active-workstream-store / core-utils: derivation reproduces
432
474
  // their prior hand lists exactly (every constraining file's own name already matched the
433
475
  // "<module>*" rule) — no extraTests/excludeTests needed. Note config-schema in particular:
@@ -456,7 +498,10 @@ const COVERED = {
456
498
  },
457
499
  'core-utils': {
458
500
  cjs: 'gsd-core/bin/lib/core-utils.cjs',
459
- minScore: 75, // measured 77.52% (2026-06-14, issue #1187); floor = 77 - 2
501
+ // measured 77.52% (2026-06-14, issue #1187); floor = 77 - 2.
502
+ // CI job 109435636183 (PR #5114, #5105): measured 81.13%. Floor =
503
+ // floor(81.13) - 1 = 80.
504
+ minScore: 80,
460
505
  },
461
506
  // planning-inspect / plan-document / planning-command-router: net-new modules
462
507
  // added by #2790. Registered here so the Stryker gate stops SKIPPING them
@@ -484,7 +529,7 @@ const COVERED = {
484
529
  // PASSED — not a local run; mutation shards run `node --test`, hard-blocked
485
530
  // in this repo's local environment):
486
531
  // planning-command-router 95.65% → floor 94 (already exceeds TARGET_MUTATION_SCORE (80))
487
- // plan-document 76.58% → floor 75
532
+ // plan-document 76.58% → floor 75; then 81.16% → floor 80 (#5026 parity tests)
488
533
  // planning-inspect 57.03% → floor 56 (well below TARGET (80) — ratchet
489
534
  // candidate; comfortably clears its own floor but has real room to grow.
490
535
  // Raise as its tests improve, never lower it.)
@@ -507,7 +552,7 @@ const COVERED = {
507
552
  'planning-inspect': {
508
553
  cjs: 'gsd-core/bin/lib/planning-inspect.cjs',
509
554
  excludeTests: ['planning-inspect.test.cjs'],
510
- minScore: 56,
555
+ minScore: 72, // #5118: 73.70% in CI run 36676296090; floor(73.70) - 1
511
556
  },
512
557
  // plan-document / planning-command-router: their own names never appear in any test
513
558
  // filename (the shared dedicated unit file is named after planning-inspect, the module
@@ -516,7 +561,7 @@ const COVERED = {
516
561
  'plan-document': {
517
562
  cjs: 'gsd-core/bin/lib/plan-document.cjs',
518
563
  extraTests: ['planning-inspect.unit.test.cjs'],
519
- minScore: 75,
564
+ minScore: 80,
520
565
  },
521
566
  'planning-command-router': {
522
567
  cjs: 'gsd-core/bin/lib/planning-command-router.cjs',
@@ -171,6 +171,10 @@ ALLOWLIST=(
171
171
  # allowlist cannot reach it either, because the literal `child_process` is
172
172
  # not adjacent to `.exec`. See the note at the pattern itself.
173
173
  'tests/continuation-grammar-parity.test.cjs'
174
+ # #4906 Phase 5 — regex.exec('### Phase 03: ...') fixtures.
175
+ # Same DEFECT.PROMPT-INJECTION-SCAN-COLLISION class as above:
176
+ # RegExp.prototype.exec, not code execution.
177
+ 'tests/phase-id.test.cjs'
174
178
  # #3676 row 11b — quick-batch's task-list parser must treat a
175
179
  # prompt-injection-shaped task description as inert data, never
176
180
  # interpreted. The fixture has to be a real "ignore all previous