@opengsd/gsd-core 1.11.0 → 1.13.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 (498) 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 +12 -0
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-debug-session-manager.md +1 -1
  6. package/agents/gsd-debugger.md +1 -1
  7. package/agents/gsd-dom-verifier.md +169 -0
  8. package/agents/gsd-eval-auditor.md +1 -1
  9. package/agents/gsd-executor.md +78 -42
  10. package/agents/gsd-framework-selector.md +1 -3
  11. package/agents/gsd-intel-updater.md +1 -1
  12. package/agents/gsd-mempalace-curator.md +0 -1
  13. package/agents/gsd-pattern-mapper.md +11 -0
  14. package/agents/gsd-phase-researcher.md +3 -1
  15. package/agents/gsd-plan-checker.md +91 -112
  16. package/agents/gsd-planner.md +20 -4
  17. package/agents/gsd-project-researcher.md +1 -1
  18. package/agents/gsd-research-synthesizer.md +2 -2
  19. package/agents/gsd-roadmapper.md +15 -11
  20. package/agents/gsd-ui-checker.md +82 -7
  21. package/agents/gsd-ui-researcher.md +70 -3
  22. package/agents/gsd-verifier.md +24 -2
  23. package/bin/install.js +847 -200
  24. package/commands/gsd/discuss-phase.md +1 -1
  25. package/commands/gsd/execute-phase.md +1 -1
  26. package/commands/gsd/import.md +1 -1
  27. package/commands/gsd/ns-workflow.md +2 -1
  28. package/commands/gsd/phase.md +1 -1
  29. package/commands/gsd/quick-batch.md +105 -0
  30. package/commands/gsd/quick.md +8 -4
  31. package/commands/gsd/surface.md +18 -8
  32. package/gsd-core/bin/gsd-tools.cjs +761 -100
  33. package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
  34. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  35. package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
  36. package/gsd-core/bin/lib/api-coverage.cjs +30 -9
  37. package/gsd-core/bin/lib/artifacts.cjs +2 -0
  38. package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
  39. package/gsd-core/bin/lib/audit.cjs +163 -41
  40. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  41. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  42. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  43. package/gsd-core/bin/lib/capability-registry.cjs +785 -144
  44. package/gsd-core/bin/lib/capability-state.cjs +25 -4
  45. package/gsd-core/bin/lib/capability-validator.cjs +321 -18
  46. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  47. package/gsd-core/bin/lib/check-command-router.cjs +229 -6
  48. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  49. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  50. package/gsd-core/bin/lib/clusters.cjs +1 -0
  51. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  52. package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
  53. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  54. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  55. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  56. package/gsd-core/bin/lib/commands.cjs +877 -54
  57. package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
  58. package/gsd-core/bin/lib/config-loader.cjs +121 -29
  59. package/gsd-core/bin/lib/config.cjs +92 -2
  60. package/gsd-core/bin/lib/configuration.cjs +129 -37
  61. package/gsd-core/bin/lib/core-utils.cjs +118 -14
  62. package/gsd-core/bin/lib/decisions.cjs +213 -1
  63. package/gsd-core/bin/lib/edge-probe.cjs +23 -2
  64. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  65. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  66. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  67. package/gsd-core/bin/lib/frontmatter.cjs +975 -326
  68. package/gsd-core/bin/lib/gap-checker.cjs +41 -8
  69. package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
  71. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  72. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
  73. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
  74. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
  75. package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
  76. package/gsd-core/bin/lib/host-integration.cjs +96 -11
  77. package/gsd-core/bin/lib/init-command-router.cjs +132 -21
  78. package/gsd-core/bin/lib/init.cjs +252 -56
  79. package/gsd-core/bin/lib/install-engine.cjs +252 -15
  80. package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
  81. package/gsd-core/bin/lib/install-profiles.cjs +100 -18
  82. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  83. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  84. package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
  85. package/gsd-core/bin/lib/intel.cjs +101 -26
  86. package/gsd-core/bin/lib/io.cjs +195 -15
  87. package/gsd-core/bin/lib/learnings.cjs +85 -14
  88. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  89. package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
  90. package/gsd-core/bin/lib/markdown-table.cjs +175 -4
  91. package/gsd-core/bin/lib/milestone.cjs +112 -7
  92. package/gsd-core/bin/lib/model-catalog.cjs +177 -19
  93. package/gsd-core/bin/lib/model-resolver.cjs +10 -28
  94. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  95. package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
  96. package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
  97. package/gsd-core/bin/lib/phase-id.cjs +321 -13
  98. package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
  99. package/gsd-core/bin/lib/phase-locator.cjs +138 -17
  100. package/gsd-core/bin/lib/phase.cjs +1175 -115
  101. package/gsd-core/bin/lib/plan-document.cjs +273 -0
  102. package/gsd-core/bin/lib/plan-scan.cjs +13 -2
  103. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  104. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  105. package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
  106. package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
  107. package/gsd-core/bin/lib/probe-core.cjs +4 -1
  108. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  109. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  110. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  111. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  112. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  113. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  114. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
  115. package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
  116. package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
  117. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  118. package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
  119. package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
  120. package/gsd-core/bin/lib/roadmap.cjs +248 -64
  121. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
  122. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
  123. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
  124. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
  125. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  126. package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
  127. package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
  128. package/gsd-core/bin/lib/smart-entry.cjs +19 -31
  129. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  130. package/gsd-core/bin/lib/state-command-router.cjs +47 -18
  131. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  132. package/gsd-core/bin/lib/state-document.cjs +216 -5
  133. package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
  134. package/gsd-core/bin/lib/state-transition.cjs +850 -145
  135. package/gsd-core/bin/lib/state.cjs +1629 -287
  136. package/gsd-core/bin/lib/surface.cjs +33 -10
  137. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  138. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  139. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  140. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  141. package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
  142. package/gsd-core/bin/lib/uat.cjs +2542 -387
  143. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  144. package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
  145. package/gsd-core/bin/lib/unusable-input.cjs +13 -0
  146. package/gsd-core/bin/lib/update-context.cjs +6 -2
  147. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  148. package/gsd-core/bin/lib/validate.cjs +230 -12
  149. package/gsd-core/bin/lib/vendor/README.md +43 -5
  150. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  151. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  152. package/gsd-core/bin/lib/verification.cjs +287 -13
  153. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  154. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  155. package/gsd-core/bin/lib/verify.cjs +441 -56
  156. package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
  157. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  158. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  159. package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
  160. package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
  161. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  162. package/gsd-core/bin/shared/exit-codes.json +8 -0
  163. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  164. package/gsd-core/bin/shared/model-catalog.json +8 -1
  165. package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
  166. package/gsd-core/references/agent-contracts.md +6 -5
  167. package/gsd-core/references/api-coverage.md +24 -2
  168. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  169. package/gsd-core/references/checkpoints.md +37 -19
  170. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  171. package/gsd-core/references/edge-probe.md +17 -5
  172. package/gsd-core/references/execute-mvp-tdd.md +18 -18
  173. package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
  174. package/gsd-core/references/execute-phase-response-language.md +6 -0
  175. package/gsd-core/references/execute-phase-wave-guard.md +11 -9
  176. package/gsd-core/references/executor-examples.md +42 -0
  177. package/gsd-core/references/failing-direction.md +78 -0
  178. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  179. package/gsd-core/references/gate-prompts.md +1 -1
  180. package/gsd-core/references/git-integration.md +5 -5
  181. package/gsd-core/references/git-planning-commit.md +3 -3
  182. package/gsd-core/references/gsd-run-resolver.md +1 -1
  183. package/gsd-core/references/loop-hook-dispatch.md +22 -0
  184. package/gsd-core/references/model-profiles.md +1 -1
  185. package/gsd-core/references/mvp-concepts.md +2 -2
  186. package/gsd-core/references/nyquist-compliance.md +74 -0
  187. package/gsd-core/references/offer-next.md +3 -5
  188. package/gsd-core/references/phase-argument-parsing.md +3 -3
  189. package/gsd-core/references/plan-checker-examples.md +41 -0
  190. package/gsd-core/references/planner-antipatterns.md +25 -0
  191. package/gsd-core/references/planner-chunked.md +5 -1
  192. package/gsd-core/references/planner-coupling.md +42 -0
  193. package/gsd-core/references/planner-failing-direction.md +53 -0
  194. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  195. package/gsd-core/references/planner-quick-batch.md +71 -0
  196. package/gsd-core/references/planner-reviews.md +47 -0
  197. package/gsd-core/references/planner-revision.md +76 -3
  198. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  199. package/gsd-core/references/planning-config.md +39 -9
  200. package/gsd-core/references/response-language-directive.md +9 -0
  201. package/gsd-core/references/reviewer-instances.md +31 -0
  202. package/gsd-core/references/revision-loop.md +118 -11
  203. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  204. package/gsd-core/references/tdd.md +15 -12
  205. package/gsd-core/references/ui-brand.md +65 -21
  206. package/gsd-core/references/ui-consideration-probe.md +1 -1
  207. package/gsd-core/references/universal-anti-patterns.md +2 -2
  208. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  209. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  210. package/gsd-core/references/verify-mvp-mode.md +1 -1
  211. package/gsd-core/references/workstream-flag.md +11 -11
  212. package/gsd-core/templates/README.md +1 -1
  213. package/gsd-core/templates/SECURITY.md +3 -3
  214. package/gsd-core/templates/UI-SPEC.md +25 -3
  215. package/gsd-core/templates/VALIDATION.md +3 -3
  216. package/gsd-core/templates/phase-prompt.md +7 -0
  217. package/gsd-core/templates/state.md +7 -0
  218. package/gsd-core/templates/verification-report.md +5 -0
  219. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  220. package/gsd-core/workflows/add-backlog.md +3 -1
  221. package/gsd-core/workflows/add-phase.md +5 -3
  222. package/gsd-core/workflows/add-tests.md +4 -9
  223. package/gsd-core/workflows/add-todo.md +2 -2
  224. package/gsd-core/workflows/ai-integration-phase.md +5 -10
  225. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  226. package/gsd-core/workflows/audit-fix.md +14 -3
  227. package/gsd-core/workflows/audit-milestone.md +11 -9
  228. package/gsd-core/workflows/audit-uat.md +19 -2
  229. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  230. package/gsd-core/workflows/autonomous.md +12 -26
  231. package/gsd-core/workflows/check-todos.md +2 -2
  232. package/gsd-core/workflows/cleanup.md +3 -3
  233. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
  234. package/gsd-core/workflows/code-review-fix.md +3 -1
  235. package/gsd-core/workflows/code-review.md +192 -69
  236. package/gsd-core/workflows/complete-milestone.md +28 -14
  237. package/gsd-core/workflows/debug.md +6 -4
  238. package/gsd-core/workflows/diagnose-issues.md +17 -7
  239. package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
  240. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  241. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  242. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  243. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  244. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
  245. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  246. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  247. package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
  248. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  249. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  250. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
  252. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  253. package/gsd-core/workflows/discuss-phase.md +2 -2
  254. package/gsd-core/workflows/do.md +46 -19
  255. package/gsd-core/workflows/docs-update.md +6 -5
  256. package/gsd-core/workflows/edit-phase.md +3 -1
  257. package/gsd-core/workflows/eval-review.md +5 -10
  258. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
  259. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
  260. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  261. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  263. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
  264. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  265. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  266. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
  267. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  268. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  269. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  270. package/gsd-core/workflows/execute-phase.md +68 -66
  271. package/gsd-core/workflows/execute-plan.md +25 -20
  272. package/gsd-core/workflows/explore.md +3 -1
  273. package/gsd-core/workflows/extract-learnings.md +3 -1
  274. package/gsd-core/workflows/fast.md +8 -2
  275. package/gsd-core/workflows/forensics.md +3 -1
  276. package/gsd-core/workflows/graduation.md +6 -6
  277. package/gsd-core/workflows/health.md +4 -7
  278. package/gsd-core/workflows/help/modes/brief.md +2 -0
  279. package/gsd-core/workflows/help/modes/default.md +2 -0
  280. package/gsd-core/workflows/help/modes/full.md +12 -0
  281. package/gsd-core/workflows/help/modes/topic.md +2 -0
  282. package/gsd-core/workflows/help.md +2 -0
  283. package/gsd-core/workflows/import.md +17 -14
  284. package/gsd-core/workflows/inbox.md +5 -6
  285. package/gsd-core/workflows/ingest-docs.md +45 -12
  286. package/gsd-core/workflows/insert-phase.md +7 -5
  287. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  288. package/gsd-core/workflows/list-seeds.md +7 -3
  289. package/gsd-core/workflows/list-workspaces.md +3 -1
  290. package/gsd-core/workflows/manager.md +15 -26
  291. package/gsd-core/workflows/map-codebase.md +3 -1
  292. package/gsd-core/workflows/milestone-summary.md +3 -1
  293. package/gsd-core/workflows/mvp-phase.md +3 -3
  294. package/gsd-core/workflows/new-milestone.md +10 -22
  295. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  296. package/gsd-core/workflows/new-project.md +17 -29
  297. package/gsd-core/workflows/new-workspace.md +2 -2
  298. package/gsd-core/workflows/next.md +4 -2
  299. package/gsd-core/workflows/node-repair.md +2 -0
  300. package/gsd-core/workflows/note.md +2 -0
  301. package/gsd-core/workflows/onboard.md +1 -1
  302. package/gsd-core/workflows/pause-work.md +20 -5
  303. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  304. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  305. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
  306. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
  307. package/gsd-core/workflows/plan-phase.md +251 -54
  308. package/gsd-core/workflows/plan-review-convergence.md +148 -19
  309. package/gsd-core/workflows/plant-seed.md +3 -3
  310. package/gsd-core/workflows/pr-branch.md +195 -51
  311. package/gsd-core/workflows/profile-user.md +17 -15
  312. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  313. package/gsd-core/workflows/progress.md +52 -15
  314. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  315. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
  316. package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
  317. package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
  318. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  319. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  320. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  321. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  322. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  323. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  324. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  325. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  326. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  327. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  328. package/gsd-core/workflows/quick-batch.md +203 -0
  329. package/gsd-core/workflows/quick.md +33 -32
  330. package/gsd-core/workflows/reapply-patches.md +2 -0
  331. package/gsd-core/workflows/remove-phase.md +6 -4
  332. package/gsd-core/workflows/remove-workspace.md +3 -3
  333. package/gsd-core/workflows/resume-project.md +14 -14
  334. package/gsd-core/workflows/review.md +404 -21
  335. package/gsd-core/workflows/scan.md +3 -1
  336. package/gsd-core/workflows/section-manifest.json +12 -0
  337. package/gsd-core/workflows/secure-phase.md +3 -3
  338. package/gsd-core/workflows/session-report.md +2 -0
  339. package/gsd-core/workflows/settings-advanced.md +9 -9
  340. package/gsd-core/workflows/settings-integrations.md +66 -32
  341. package/gsd-core/workflows/settings.md +4 -6
  342. package/gsd-core/workflows/ship.md +22 -16
  343. package/gsd-core/workflows/sketch-wrap-up.md +13 -17
  344. package/gsd-core/workflows/sketch.md +13 -19
  345. package/gsd-core/workflows/smart-entry.md +4 -6
  346. package/gsd-core/workflows/spec-phase.md +31 -4
  347. package/gsd-core/workflows/spike-wrap-up.md +9 -11
  348. package/gsd-core/workflows/spike.md +21 -32
  349. package/gsd-core/workflows/stats.md +4 -2
  350. package/gsd-core/workflows/sync-skills.md +13 -5
  351. package/gsd-core/workflows/thread.md +13 -7
  352. package/gsd-core/workflows/transition.md +7 -5
  353. package/gsd-core/workflows/ui-phase.md +36 -21
  354. package/gsd-core/workflows/ui-review.md +7 -11
  355. package/gsd-core/workflows/ultraplan-phase.md +7 -13
  356. package/gsd-core/workflows/undo.md +9 -17
  357. package/gsd-core/workflows/update.md +47 -48
  358. package/gsd-core/workflows/validate-phase.md +3 -3
  359. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  360. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  361. package/gsd-core/workflows/verify-work.md +106 -21
  362. package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
  363. package/hooks/dist/gsd-check-update-worker.js +19 -2
  364. package/hooks/dist/gsd-config-reload.js +18 -12
  365. package/hooks/dist/gsd-context-monitor.js +302 -22
  366. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  367. package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
  368. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  369. package/hooks/dist/gsd-cursor-stop.js +2 -1
  370. package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
  371. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
  372. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  373. package/hooks/dist/gsd-graphify-update.sh +22 -18
  374. package/hooks/dist/gsd-node-runner.sh +77 -0
  375. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  376. package/hooks/dist/gsd-prompt-guard.js +46 -12
  377. package/hooks/dist/gsd-read-guard.js +18 -7
  378. package/hooks/dist/gsd-read-injection-scanner.js +22 -13
  379. package/hooks/dist/gsd-secret-read-guard.js +1079 -0
  380. package/hooks/dist/gsd-session-state.sh +1 -0
  381. package/hooks/dist/gsd-statusline.js +222 -29
  382. package/hooks/dist/gsd-validate-commit.sh +523 -12
  383. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  384. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  385. package/hooks/dist/gsd-workflow-guard.js +36 -17
  386. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  387. package/hooks/dist/gsd-write-guard.js +35 -25
  388. package/hooks/dist/lib/cli-exit.js +560 -0
  389. package/hooks/dist/lib/exit-code-registry.js +98 -0
  390. package/hooks/dist/lib/git-cmd.js +210 -1
  391. package/hooks/dist/lib/git-probe.js +84 -0
  392. package/hooks/dist/lib/hook-exit.js +81 -0
  393. package/hooks/dist/lib/injection-patterns.js +36 -6
  394. package/hooks/dist/managed-hooks-registry.cjs +4 -0
  395. package/hooks/gsd-agent-isolation-guard.js +77 -38
  396. package/hooks/gsd-check-update-worker.js +19 -2
  397. package/hooks/gsd-config-reload.js +18 -12
  398. package/hooks/gsd-context-monitor.js +302 -22
  399. package/hooks/gsd-cursor-post-tool.js +3 -1
  400. package/hooks/gsd-cursor-pre-tool.js +3 -1
  401. package/hooks/gsd-cursor-session-start.js +2 -1
  402. package/hooks/gsd-cursor-stop.js +2 -1
  403. package/hooks/gsd-cursor-subagent-start.js +28 -23
  404. package/hooks/gsd-cursor-subagent-stop.js +3 -1
  405. package/hooks/gsd-ensure-canonical-path.js +2 -1
  406. package/hooks/gsd-graphify-update.sh +22 -18
  407. package/hooks/gsd-node-runner.sh +77 -0
  408. package/hooks/gsd-phase-boundary.sh +1 -0
  409. package/hooks/gsd-prompt-guard.js +46 -12
  410. package/hooks/gsd-read-guard.js +18 -7
  411. package/hooks/gsd-read-injection-scanner.js +22 -13
  412. package/hooks/gsd-secret-read-guard.js +1079 -0
  413. package/hooks/gsd-session-state.sh +1 -0
  414. package/hooks/gsd-statusline.js +222 -29
  415. package/hooks/gsd-validate-commit.sh +523 -12
  416. package/hooks/gsd-windsurf-pre-command.js +16 -11
  417. package/hooks/gsd-windsurf-pre-write.js +22 -13
  418. package/hooks/gsd-workflow-guard.js +36 -17
  419. package/hooks/gsd-worktree-path-guard.js +36 -21
  420. package/hooks/gsd-write-guard.js +35 -25
  421. package/hooks/hooks.json +6 -0
  422. package/hooks/lib/cli-exit.js +560 -0
  423. package/hooks/lib/exit-code-registry.js +98 -0
  424. package/hooks/lib/git-cmd.js +210 -1
  425. package/hooks/lib/git-probe.js +84 -0
  426. package/hooks/lib/hook-exit.js +81 -0
  427. package/hooks/lib/injection-patterns.js +36 -6
  428. package/hooks/managed-hooks-registry.cjs +4 -0
  429. package/package.json +14 -9
  430. package/scripts/base64-scan.sh +74 -12
  431. package/scripts/build-hooks.js +12 -0
  432. package/scripts/check-glossary-refs.cjs +77 -15
  433. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  434. package/scripts/ci-check-job-near-cap.cjs +49 -0
  435. package/scripts/ci-pr-mergeability.cjs +262 -0
  436. package/scripts/ci-test-scope.cjs +52 -12
  437. package/scripts/ci-timeout-report.cjs +230 -0
  438. package/scripts/docs-guard-registry.cjs +406 -0
  439. package/scripts/gen-capability-registry.cjs +8 -6
  440. package/scripts/gen-exit-code-docs.cjs +318 -0
  441. package/scripts/gen-exit-code-registry.cjs +891 -0
  442. package/scripts/gen-features.cjs +836 -0
  443. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  444. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  445. package/scripts/gen-loop-host-contract.cjs +189 -4
  446. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  447. package/scripts/gen-state-md-docs.cjs +727 -0
  448. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  449. package/scripts/lib/ci-job-timing.cjs +72 -0
  450. package/scripts/lib/cli-exit.cjs +546 -44
  451. package/scripts/lib/drift-scan.cjs +32 -2
  452. package/scripts/lib/exit-code-registry.cjs +98 -0
  453. package/scripts/lib/ndjson-reporter.cjs +119 -0
  454. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  455. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  456. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  457. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  458. package/scripts/lint-docs-guard-registration.cjs +495 -0
  459. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
  460. package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
  461. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  462. package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
  463. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  464. package/scripts/lint-phase-enumeration-drift.cjs +45 -14
  465. package/scripts/lint-phase-id-drift.cjs +133 -8
  466. package/scripts/lint-planning-prompt-drift.cjs +38 -1
  467. package/scripts/lint-portable-grep.cjs +176 -0
  468. package/scripts/lint-removed-but-needed.cjs +184 -16
  469. package/scripts/lint-response-language-coverage.cjs +524 -0
  470. package/scripts/lint-seam-enforcement.cjs +182 -0
  471. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  472. package/scripts/lint-source-test-name-collision.cjs +241 -0
  473. package/scripts/lint-state-write-path-drift.cjs +337 -432
  474. package/scripts/lint-test-file-count.allowlist.json +124 -4
  475. package/scripts/lint-test-file-count.cjs +25 -3
  476. package/scripts/lint-unreachable-guard-drift.cjs +51 -64
  477. package/scripts/lint-vendored-deps.cjs +208 -35
  478. package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
  479. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  480. package/scripts/mutation-matrix.cjs +599 -50
  481. package/scripts/npm-audit-baseline.cjs +376 -0
  482. package/scripts/prompt-injection-scan.sh +83 -14
  483. package/scripts/require-issue-link-policy.cjs +16 -1
  484. package/scripts/secret-scan.sh +75 -13
  485. package/scripts/select-docs-guards.cjs +56 -0
  486. package/scripts/sync-runtime-launcher.cjs +22 -3
  487. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  488. package/skills/gsd-execute-phase/SKILL.md +1 -1
  489. package/skills/gsd-import/SKILL.md +1 -1
  490. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  491. package/skills/gsd-phase/SKILL.md +1 -1
  492. package/skills/gsd-quick/SKILL.md +8 -4
  493. package/skills/gsd-quick-batch/SKILL.md +105 -0
  494. package/skills/gsd-surface/SKILL.md +18 -8
  495. package/vscode/package.json +1 -1
  496. package/bin/lib/ui-safety-gate.cjs +0 -109
  497. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  498. package/scripts/state-write-path-drift-baseline.json +0 -19
@@ -180,4 +180,213 @@ function isGitSubcommand(cmd, sub) {
180
180
  return tokens[subIdx] === sub;
181
181
  }
182
182
 
183
- module.exports = { isGitSubcommand, tokenize, extractBranchArgument, skipToSubcommand };
183
+ /**
184
+ * Resolve a `-m` message argument to its SUBJECT — the first line of the commit
185
+ * message — resolving the command-substituted heredoc form to the heredoc
186
+ * BODY's first line.
187
+ *
188
+ * PURE STRING FUNCTION. It deliberately does NOT tokenize or walk the command
189
+ * line: selecting *which* argument is the message stays with the caller, exactly
190
+ * as before, so this cannot change which commands are validated. An earlier
191
+ * revision of this fix did walk tokens and regressed four separate cases —
192
+ * `git commit -- -m WIP` (a pathspec), `git commit --amend && echo -m WIP` (a
193
+ * later command's flag), `-m "" --allow-empty-message` (the scanner drops empty
194
+ * tokens, so the following flag became the subject), and unquoted
195
+ * `git commit -m WIP`. All were allowed upstream and would have started being
196
+ * blocked. Reported in review of #3802.
197
+ *
198
+ * The defect this DOES fix: `gsd-validate-commit.sh` captured the message with
199
+ * `-m[[:space:]]+"([^"]+)"`, and bash `[^"]` matches newlines, so the widely
200
+ * used agent-authored commit idiom
201
+ *
202
+ * git commit -m "$(cat <<'EOF'
203
+ * feat(auth): add login flow
204
+ * EOF
205
+ * )"
206
+ *
207
+ * captured the whole span up to the final quote at `)"`. Taking its first line
208
+ * yielded the literal `$(cat <<'EOF'`, which can never satisfy Conventional
209
+ * Commits, so every heredoc-form commit was blocked regardless of its message.
210
+ *
211
+ * Recognition is anchored at BOTH ends and requires a command substitution, so
212
+ * an ordinary message merely CONTAINING — or ending in — `<<WORD` is not
213
+ * mistaken for an opener. Without the `^\$\(` anchor,
214
+ * `-m "WIP notes <<EOF\nfix: smuggled subject"` resolved to the second line and
215
+ * ALLOWED a non-conforming commit: an enforcement bypass, not just a
216
+ * misclassification (review of #3802).
217
+ *
218
+ * NOT resolved, by design: an UNQUOTED delimiter (`<<EOF`). bash expands `$var`
219
+ * and `$(...)` in that body, so the literal text here is not what git receives.
220
+ * An earlier revision resolved it anyway and called the gap "the same
221
+ * pre-existing limit as expansions in a plain `-m` argument" — that framing was
222
+ * wrong on both halves: on base the whole heredoc form was blocked, so this fix
223
+ * CREATED the path, and it dodged the length gate as well as the format gate.
224
+ * See the expansion guard in the body (review of #3816, round 4).
225
+ *
226
+ * KNOWN LIMIT: the DOUBLE-QUOTED delimiter spelling (`<<"EOF"`) is resolvable
227
+ * here but unreachable through the caller — `gsd-validate-commit.sh`'s
228
+ * double-quoted `-m` capture stops at the first `"`, which in that spelling is
229
+ * the delimiter's own quote, so the resolver only ever sees a truncated opener
230
+ * and the commit stays blocked. Its single-quoted `-m` capture DOES deliver the
231
+ * spelling intact, which is why an earlier revision's claim of unreachability
232
+ * was false; the caller now gates the resolver on the double-quoted arm alone
233
+ * (review of #3816, round 4), so the claim holds again — for that reason, not
234
+ * by luck. That is the pre-fix behaviour for the whole form (fail closed, a
235
+ * false positive on one rare spelling), and widening the bash capture to span
236
+ * inner quotes would change what is captured for EVERY message containing one —
237
+ * a regression class this fix deliberately does not touch (Codex review of
238
+ * #3816). The same capture truncation blocks a `"` in the SUBJECT LINE itself,
239
+ * where it lands inside the line being measured. It does NOT block a `"` on a
240
+ * later body line: the subject is already complete before the truncation point,
241
+ * so that message resolves and is allowed (measured; an earlier revision of this
242
+ * comment and of the changeset claimed a `"` ANYWHERE blocked, which is false —
243
+ * Codex review of #3816, round 4). The truncation guard below is what keeps the
244
+ * unmeasurable half fail-closed. Two more legal-but-unrecognized spellings
245
+ * stay blocked the same fail-closed way: an env-prefixed cat
246
+ * (`$(A=1 cat <<'EOF'`) and an option-terminated cat (`$(cat -- <<'EOF'`) —
247
+ * recognizing either would mean modelling bash prefix words here, cost with
248
+ * no reported user (review of #3816, round 3).
249
+ *
250
+ * @param {string} messageArg - the raw `-m` argument, already selected by the caller
251
+ * @returns {string} the subject to validate
252
+ */
253
+ function resolveCommitSubject(messageArg) {
254
+ // CRLF-tolerant split. With a bare split('\n') every body line kept its \r,
255
+ // so `body.indexOf(delimiter)` never matched on CRLF input: the truncation
256
+ // guard was inert, an empty CRLF message resolved to 'EOF\r' instead of '',
257
+ // and a real 72-char subject measured 73 (review of #3816). Splitting on
258
+ // /\r?\n/ is the repo-wide remedy for this recurring defect class.
259
+ const lines = String(messageArg == null ? '' : messageArg).split(/\r?\n/);
260
+ // The path prefix is a PATH-CHARACTER class, not \S*: `\S*` accepted
261
+ // `id;/bin/cat`, so `$(id;/bin/cat <<'EOF' ...` was resolved to its heredoc
262
+ // body while bash actually runs `id` first and git's real subject is `id`'s
263
+ // OUTPUT — an enforcement bypass (Codex review of #3816). A prefix carrying
264
+ // any shell metacharacter now fails recognition, which falls back to the
265
+ // opener line and the format gate: fail closed, exactly the pre-fix
266
+ // behaviour for the whole form.
267
+ //
268
+ // Whitespace inside the recognition is ASCII space/tab — [ \t], never \s —
269
+ // because JavaScript \s includes Unicode whitespace bash does NOT split on:
270
+ // `$(<NBSP>/bin/cat <<'EOF'` was recognized here while bash reads
271
+ // `<NBSP>/bin/cat` as the executable NAME, so recognition claimed a
272
+ // substitution that does not run cat (Codex review of #3816, round 2). The
273
+ // same ASCII rule as the blank-line skip below, for the same reason.
274
+ // `cat[ \t]*<<`, not `+`: bash accepts `cat<<'EOF'` with no space (review of
275
+ // #3816, round 3), and recognizing it costs nothing — the token before `<<`
276
+ // is still literally `cat`.
277
+ //
278
+ // The path prefix must be ABSOLUTE (Codex review of #3816, round 4). The old
279
+ // `[\w./-]*\/` also accepted `./cat` and `../evil/cat`, so a relative
280
+ // executable that merely ENDS in `cat` was trusted to echo its stdin: with a
281
+ // planted `../evil/cat` printing `WIP injected`, the resolver validated the
282
+ // heredoc body while git's real subject was `WIP injected` (measured
283
+ // base=2 -> head=0 against a real commit). Requiring `/` up front costs
284
+ // nothing real — `/bin/cat` and a bare `cat` both still resolve.
285
+ //
286
+ // AN ABSOLUTE PATH IS NOT AN IDENTITY EITHER (independent review of #3816,
287
+ // round 8). Round 4 stopped at "must be absolute", so any absolute path
288
+ // ENDING in `/cat` was still trusted to echo its stdin — the very thing the
289
+ // round-4 reasoning rejected one spelling earlier. With an executable at
290
+ // `/some/scratch/dir/cat` printing `WIP injected`, the resolver validated
291
+ // the conforming heredoc body while git's real subject was `WIP injected`
292
+ // (measured on bash 3.2.57 and 5.3.15 against a real commit: hook exit 0,
293
+ // `git cat-file -p` subject `WIP injected`, while the same command through
294
+ // `./cat` was already refused). The prefix is now the canonical system
295
+ // locations, which is the only claim a string can support. `/usr/local/bin`
296
+ // is deliberately excluded: it is user-writable on ordinary machines, which
297
+ // is the plantable case this guard exists for.
298
+ //
299
+ // RESIDUAL, not fixable from a string: a bare `cat` shadowed earlier on PATH
300
+ // has the same effect and is indistinguishable here. It is also not a
301
+ // meaningful boundary — anyone who can plant an executable on PATH can run
302
+ // `git commit` directly — so this hook stays an authoring guard, not a
303
+ // security control.
304
+ //
305
+ // The delimiter alternatives are split so the BARE spelling is its own group:
306
+ // `\\(...)` (backslash-quoted) and `(...)` (bare) were one `\\?(...)` branch,
307
+ // which conflated the only two spellings that differ in bash. See the
308
+ // expansion guard below.
309
+ const opener = /^\$\([ \t]*(?:\/(?:usr\/)?bin\/)?cat[ \t]*<<(-?)[ \t]*(?:'([^']+)'|"([^"]+)"|\\([^\s'"();|&<>\\]+)|([^\s'"();|&<>\\]+))[ \t]*$/
310
+ .exec(lines[0]);
311
+ if (!opener) return lines[0];
312
+
313
+ // EXPANSION GUARD (review of #3816, round 4 — BLOCKER). Only `<<'D'`, `<<"D"`
314
+ // and `<<\D` suppress expansion. A BARE `<<D` is expanded by bash, so the body
315
+ // captured here is NOT the text git receives, and measuring it is an
316
+ // enforcement bypass in both gates at once:
317
+ //
318
+ // -m "$(cat <<EOF\nfeat: $UNSET_VAR\nEOF\n)" git gets `feat:` -> format gate dodged
319
+ // -m "$(cat <<EOF\nfeat: ${LONG}\nEOF\n)" git gets any length -> length gate dodged
320
+ //
321
+ // Both measured base=2 -> head=0 against the real hook. This is NOT the
322
+ // pre-existing plain-`-m` expansion limit an earlier revision claimed it was:
323
+ // on base the whole heredoc form was blocked, so no expansion inside a body
324
+ // ever reached an allow — this fix created the path, and closes it here.
325
+ // Same rule every other guard in this function follows: when the real subject
326
+ // cannot be known, fall back to the opener line, which fails the format gate.
327
+ if (opener[5]) return lines[0];
328
+
329
+ // `<<-` strips leading TABS from every body line, including the terminator.
330
+ const stripTabs = opener[1] === '-';
331
+ const delimiter = opener[2] || opener[3] || opener[4];
332
+ const body = lines.slice(1).map((l) => (stripTabs ? l.replace(/^\t+/, '') : l));
333
+
334
+ // TRUNCATION GUARD. The capture that produced this argument stops at the first
335
+ // `"`, so a message containing one arrives here missing its tail — and its
336
+ // terminator. Resolving anyway would hand the length gate a PREFIX of the real
337
+ // subject and let an over-long message through, an enforcement hole that did
338
+ // not exist before this fix (review of #3802). A body with no terminator is
339
+ // therefore not resolved at all: returning the opener line fails the format
340
+ // gate, which is exactly what this whole form did before the fix. The fix
341
+ // applies where the capture is complete and changes nothing where it is not.
342
+ const end = body.indexOf(delimiter);
343
+
344
+ // POST-TERMINATOR GUARD (review of #3816, round 3 — BLOCKER). Everything
345
+ // after the terminator is still part of the real message once bash
346
+ // substitutes: `-m "$(cat <<'EOF'\nfeat: ok\nEOF\n) <200 a's>"` expands to a
347
+ // single 200+ char subject, but discarding the tail measured 8 and DODGED
348
+ // COMMIT_SUBJECT_TOO_LONG — the same prefix-measurement class the truncation
349
+ // guard below exists for, missed on the other side of the terminator. The
350
+ // canonical idiom's tail is exactly one closing-paren line; anything else
351
+ // means the substitution is composed with more text, so fall back to the
352
+ // opener line — blocked, the pre-fix behaviour for the whole form.
353
+ if (end !== -1) {
354
+ const tail = body.slice(end + 1);
355
+ if (tail.length !== 1 || !/^[ \t]*\)[ \t]*$/.test(tail[0])) return lines[0];
356
+ }
357
+
358
+ // git's default `cleanup=whitespace` strips leading blank lines, so the subject
359
+ // is the first NON-EMPTY body line, not blindly the first one. Taking lines[1]
360
+ // returned '' for a body that starts blank and falsely blocked a conforming
361
+ // commit — the very defect class #3802 reports (review of #3802).
362
+ const scan = end === -1 ? body : body.slice(0, end);
363
+ // "Blank" is git's ASCII definition — space and tab — never JavaScript's
364
+ // trim(), whose Unicode whitespace class skips lines git KEEPS: a body whose
365
+ // first line is a NBSP resolved to the SECOND line while git's real subject
366
+ // is the NBSP line — an enforcement bypass (Codex review of #3816, verified
367
+ // against `git stripspace`, which preserves the c2a0 bytes). A Unicode-blank
368
+ // first line is now returned as the subject and fails the format gate: the
369
+ // same fail-closed direction git itself takes.
370
+ const idx = scan.findIndex((l) => !/^[ \t]*$/.test(l));
371
+ if (idx === -1) return end === -1 ? lines[0] : '';
372
+
373
+ // Truncation is only fatal to the line it lands IN. A captured line is complete
374
+ // exactly when another line follows it, because the capture kept its newline.
375
+ // So an unterminated body whose subject line is followed by more text is still
376
+ // measurable; only a subject line that runs to the end of a truncated capture
377
+ // is not, and that one falls back to the opener — which fails the format gate,
378
+ // exactly as this whole form did before the fix. Without this, the length gate
379
+ // measured a PREFIX of the real subject and let an over-long message through
380
+ // (review of #3802).
381
+ if (end === -1 && idx >= body.length - 1) return lines[0];
382
+
383
+ // git's `cleanup=whitespace` strips whitespace at BOTH ends of the line, not
384
+ // just leading blanks. Measuring the raw line rejected `feat: <66 x's>` plus
385
+ // three trailing spaces as 75 chars when git's actual subject is a conforming
386
+ // 72 — a still-blocked conforming commit, the very defect #3802 reports
387
+ // (review of #3816). Trailing only, here: leading blank-LINE handling is the
388
+ // findIndex above, and `<<-` leading-tab stripping already happened.
389
+ return scan[idx].replace(/[ \t]+$/, '');
390
+ }
391
+
392
+ module.exports = { isGitSubcommand, tokenize, extractBranchArgument, skipToSubcommand, resolveCommitSubject };
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+ // hooks/lib/git-probe.js — classify a bounded spawnSync(git, ...) result,
3
+ // distinguishing a GENUINE negative answer (git ran and said "no") from
4
+ // "could not determine" (timeout / spawn failure / signal kill) — #3911.
5
+ //
6
+ // Proven defect: hooks/gsd-worktree-path-guard.js, hooks/gsd-workflow-guard.js,
7
+ // and hooks/gsd-windsurf-pre-write.js each treat spawnSync(git, ..., {timeout})
8
+ // returning a non-zero/empty result as "not applicable" and allow silently.
9
+ // A macOS CI run showed three deny cases land at 2084ms/2112ms/2177ms — just
10
+ // past the 2000ms budget — each returning exit 0 with EMPTY stdout AND EMPTY
11
+ // stderr: a timeout is INDISTINGUISHABLE, at the call site, from git cleanly
12
+ // answering "not a repo" / "not this worktree" unless the spawnSync() result
13
+ // itself is inspected for `error`/`signal`, not just `status`/`stdout`.
14
+ //
15
+ // This module does not change any hook's decision or exit code — it only
16
+ // answers "was this probe's answer real?" so a caller can emit a diagnostic
17
+ // on the undetermined branch while keeping the existing fail-open behavior.
18
+ //
19
+ // Classification mirrors tests/helpers/process-seam.cjs's OUTCOME vocabulary
20
+ // (EXITED vs TIMED_OUT/SPAWN_FAILED/KILLED) — same evidence-over-classification
21
+ // ordering (a populated `status` outranks an attached `error`, since Node can
22
+ // report `error.code === 'ETIMEDOUT'` on a result that also carried a real
23
+ // exit that beat the timer) — so a probe here and a subprocess outcome in the
24
+ // test suite never disagree on the same raw spawnSync() shape.
25
+
26
+ /**
27
+ * @param {{error?: (Error & {code?: string})|null, status: number|null, signal: string|null}} result
28
+ * the raw return value of `spawnSync('git', ...)`.
29
+ * @returns {{determined: true} | {determined: false, reason: string}}
30
+ */
31
+ function classifyGitProbe(result) {
32
+ const error = result && result.error;
33
+ const status = result ? result.status : null;
34
+ const signal = result ? result.signal : null;
35
+
36
+ if (!error && signal === null) {
37
+ // A real exit — status 0 or non-zero is a genuine, trustworthy answer.
38
+ return { determined: true };
39
+ }
40
+ if (status !== null) {
41
+ // `status` is only ever populated by a real exit; it outranks an attached
42
+ // `error` even at the exact timeout boundary (process-seam.cjs's own
43
+ // "evidence over classification" rule).
44
+ return { determined: true };
45
+ }
46
+
47
+ const code = error ? (error.code ?? null) : null;
48
+ let reason;
49
+ if (code === 'ETIMEDOUT' || signal !== null) {
50
+ reason = signal ? `timed out (signal ${signal})` : 'timed out';
51
+ } else if (code) {
52
+ reason = `spawn failed (${code})`;
53
+ } else {
54
+ reason = 'could not run (unknown reason)';
55
+ }
56
+ return { determined: false, reason };
57
+ }
58
+
59
+ /**
60
+ * If `result` could not be determined (timeout / spawn failure / signal
61
+ * kill), write a stderr diagnostic naming the probe and why — never changes
62
+ * any exit code, never throws. A no-op when the probe genuinely ran and
63
+ * answered (status 0 or non-zero with no error/signal).
64
+ *
65
+ * @param {string} hookName - e.g. 'gsd-worktree-path-guard'
66
+ * @param {string} probeLabel - e.g. "git rev-parse --show-toplevel"
67
+ * @param {*} result - the raw spawnSync() return value
68
+ */
69
+ function reportIfUndetermined(hookName, probeLabel, result) {
70
+ const classification = classifyGitProbe(result);
71
+ if (classification.determined) return;
72
+ try {
73
+ process.stderr.write(
74
+ `${hookName}: git probe '${probeLabel}' ${classification.reason} — ` +
75
+ `allowing this call because the probe's answer is unknown, not because ` +
76
+ `git answered "no" (#3911).\n`
77
+ );
78
+ } catch {
79
+ // A stderr write failing (EPIPE, closed fd) must never itself change the
80
+ // hook's fail-open outcome.
81
+ }
82
+ }
83
+
84
+ module.exports = { classifyGitProbe, reportIfUndetermined };
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+ // hooks/lib/hook-exit.js — hand-written, NOT generated. A tiny hook-facing
3
+ // vocabulary layered over hooks/lib/cli-exit.js's terminateNow (ADR-3889 §3),
4
+ // for the 19 enforcement hooks P7/#3911 is migrating off raw process.exit().
5
+ //
6
+ // WHY onCrash is a REQUIRED argument, with no default (this is the entire
7
+ // point of this module): every hook audited for #3911 ended its outer
8
+ // try/catch in ONE of two ways — some `process.exit(0)` (fail open: a hook
9
+ // error must never block a legitimate tool call), others `process.exit(2)`
10
+ // (fail closed: a hook whose whole job is a security/safety denial must not
11
+ // let its own bug wave the denial through). Both are legitimate policies for
12
+ // DIFFERENT hooks — but neither is the "obviously correct" one, and a shared
13
+ // helper that silently defaulted to either would let a future hook inherit
14
+ // the wrong policy by omission, which is exactly the "nothing fails with
15
+ // success" defect ADR-3889 exists to close. Requiring the caller to name its
16
+ // policy at every call site — not just once at module load — makes "I forgot
17
+ // to decide" a load-time/call-time crash instead of a silent behavior. A
18
+ // caller that truly wants "allow on crash" must still write ALLOW; there is
19
+ // no path that reaches terminateNow without a declared choice.
20
+ //
21
+ // crash() itself is total: it does not throw on a bad `onCrash`, because
22
+ // throwing would unwind into the CALLER's own outer catch — the exact
23
+ // fail-open-by-accident hazard this module removes. Instead an unrecognized
24
+ // policy terminates via terminateNow('INTERNAL', ...) with a diagnostic
25
+ // payload naming the offending value, so a typo'd/misspelled policy is
26
+ // debuggable on stderr rather than silently reinterpreted as ALLOW or DENY.
27
+ const { terminateNow } = require('./cli-exit.js');
28
+
29
+ /** Frozen enum of the two declarable crash policies. No third option. */
30
+ const HOOK_ON_CRASH = Object.freeze({
31
+ ALLOW: 'allow',
32
+ DENY: 'deny',
33
+ });
34
+
35
+ /** Terminate with the hook-protocol PASS outcome (exit 0). */
36
+ function allow(payload) {
37
+ terminateNow('PASS', payload);
38
+ }
39
+
40
+ /**
41
+ * Terminate with the hook-protocol deny outcome (exit 2, stdout+stderr).
42
+ *
43
+ * @param {*} payload - JSON-serializable value written to fd 1 (and, when
44
+ * `stderrPayload` is omitted, fd 2 too).
45
+ * @param {*} [stderrPayload] - optional distinct value for fd 2, forwarded
46
+ * verbatim to terminateNow's own `stderrPayload` param — a string is
47
+ * written raw, anything else is JSON-stringified.
48
+ */
49
+ function deny(payload, stderrPayload) {
50
+ terminateNow('HOOK_DENY', payload, stderrPayload);
51
+ }
52
+
53
+ /**
54
+ * Dispatch to allow()/deny() per a DECLARED crash policy. `onCrash` is
55
+ * required — see the module header for why there is no default.
56
+ *
57
+ * @param {'allow'|'deny'} onCrash - one of HOOK_ON_CRASH's two values.
58
+ * @param {*} payload - JSON-serializable value forwarded to terminateNow.
59
+ */
60
+ function crash(onCrash, payload) {
61
+ if (onCrash === HOOK_ON_CRASH.ALLOW) {
62
+ allow(payload);
63
+ return;
64
+ }
65
+ if (onCrash === HOOK_ON_CRASH.DENY) {
66
+ deny(payload);
67
+ return;
68
+ }
69
+ // Never guess a policy and never throw (a throw would unwind into the
70
+ // caller's own outer catch — the fail-open-by-accident defect this module
71
+ // exists to remove). Terminate deterministically with INTERNAL, naming the
72
+ // offending value so a misspelled/omitted policy is diagnosable.
73
+ terminateNow('INTERNAL', {
74
+ error: 'hook-exit: crash() called with an unrecognized onCrash policy',
75
+ receivedOnCrash: onCrash,
76
+ expectedOneOf: [HOOK_ON_CRASH.ALLOW, HOOK_ON_CRASH.DENY],
77
+ originalPayload: payload,
78
+ });
79
+ }
80
+
81
+ module.exports = { HOOK_ON_CRASH, allow, deny, crash };
@@ -26,11 +26,29 @@
26
26
  */
27
27
 
28
28
  const INJECTION_PATTERNS = Object.freeze([
29
- /ignore\s+(all\s+)?previous\s+instructions/i,
30
- /ignore\s+(all\s+)?above\s+instructions/i,
31
- /disregard\s+(all\s+)?previous/i,
32
- /forget\s+(all\s+)?(your\s+)?instructions/i,
33
- /override\s+(system|previous)\s+(prompt|instructions)/i,
29
+ // #4016: ONE filler-tolerant imperative-override pattern. It REPLACES the
30
+ // five narrow verb patterns (ignore x2 / disregard / forget / override) that
31
+ // used to sit here: they tolerated no filler between verb and noun, so a
32
+ // planted "forget all of your ..." phrasing (measured in the wild) matched
33
+ // nothing. A single pattern rather than narrow-plus-combined because both
34
+ // consumers count one finding PER PATTERN toward the severity threshold
35
+ // (3 = HIGH, blockable under security.injection_blocking): overlapping
36
+ // patterns made one sentence count twice and pushed a two-phrasing LOW
37
+ // payload to HIGH (PR #4061 review).
38
+ // verbs ignore|disregard|forget|discard|override. `override` carries
39
+ // the old `override system|previous prompt|instructions` family;
40
+ // `discard` is the synonym seen in the same planted phrasings.
41
+ // fillers at least ONE of all|of|the|your|my|<qualifier> must sit between
42
+ // verb and noun (a lookahead, no repetition). Bare "override
43
+ // rules" / "ignore instructions" are ordinary repo prose
44
+ // (measured: 6 hits across docs and source) and stay unmatched.
45
+ // tails `disregard (all) previous` with no noun, and bare `forget` +
46
+ // `instructions`, are kept verbatim because the old narrow
47
+ // patterns accepted them; the superset is pinned by
48
+ // tests/injection-patterns-parity.security.test.cjs.
49
+ // known FP determined linter-doc prose such as "ignore (the) rules" trips
50
+ // a single-pattern LOW advisory; one pattern can never block.
51
+ /(?:ignore|disregard|forget|discard|override)\s+(?=(?:all|of|the|your|my|system|previous|prior|above|earlier)\s)(?:all\s+)?(?:of\s+)?(?:the\s+|your\s+|my\s+)?(?:(?:system|previous|prior|above|earlier)\s+)?(?:instructions|directives|prompts?|rules)|disregard\s+(?:all\s+)?previous|forget\s+instructions/i,
34
52
  /you\s+are\s+now\s+(?:a|an|the)\s+/i,
35
53
  /act\s+as\s+(?:a|an|the)\s+(?!plan|phase|wave)/i,
36
54
  /pretend\s+(?:you(?:'re| are)\s+|to\s+be\s+)/i,
@@ -42,4 +60,16 @@ const INJECTION_PATTERNS = Object.freeze([
42
60
  /<<\s*SYS\s*>>/i,
43
61
  ]);
44
62
 
45
- module.exports = { INJECTION_PATTERNS };
63
+ // Short single-line label for a matched pattern, used for both the rendered
64
+ // advisory prose and the typed `findings[].match` field in BOTH consumer
65
+ // hooks. The raw regex source is not user-facing: the #4016 superset pattern
66
+ // is ~280 characters, and gsd-prompt-guard.js echoed it verbatim into its
67
+ // advisory (PR #4061 review nit). Byte-identical to the transform
68
+ // gsd-read-injection-scanner.js carried inline since #3523, hoisted here so
69
+ // one finding renders the same way in both hooks. Both hooks already require
70
+ // this module, so this adds no new staging dependency.
71
+ function describePattern(pattern) {
72
+ return pattern.source.replace(/\\s\+/g, '-').replace(/[()\\]/g, '').substring(0, 50);
73
+ }
74
+
75
+ module.exports = { INJECTION_PATTERNS, describePattern };
@@ -29,10 +29,14 @@ const MANAGED_HOOKS = [
29
29
  'gsd-cursor-subagent-stop.js',
30
30
  'gsd-ensure-canonical-path.js',
31
31
  'gsd-graphify-update.sh',
32
+ // #3662: portable node resolver (helper staged in hooks/; managed JS hook
33
+ // commands route through it under --portable-hooks).
34
+ 'gsd-node-runner.sh',
32
35
  'gsd-phase-boundary.sh',
33
36
  'gsd-prompt-guard.js',
34
37
  'gsd-read-guard.js',
35
38
  'gsd-read-injection-scanner.js',
39
+ 'gsd-secret-read-guard.js',
36
40
  'gsd-session-state.sh',
37
41
  'gsd-statusline.js',
38
42
  'gsd-update-banner.js',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengsd/gsd-core",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
5
5
  "main": ".opencode/plugins/gsd-core.js",
6
6
  "bin": {
@@ -66,6 +66,7 @@
66
66
  "devDependencies": {
67
67
  "@eslint/js": "^9.39.4",
68
68
  "@stryker-mutator/core": "^9.6.1",
69
+ "@stryker-mutator/tap-runner": "^9.6.1",
69
70
  "@types/node": "^22.19.19",
70
71
  "c8": "^11.0.0",
71
72
  "eslint": "^9.39.4",
@@ -75,6 +76,7 @@
75
76
  "fast-check": "^4.8.0",
76
77
  "globals": "^16.5.0",
77
78
  "js-yaml": "^4.3.1",
79
+ "mutation-testing-metrics": "^3.7.3",
78
80
  "re2js": "^2.8.6",
79
81
  "typescript": "^6.0.3",
80
82
  "typescript-eslint": "^8.60.0"
@@ -106,7 +108,7 @@
106
108
  "gen:registry": "node scripts/gen-registry.cjs --write",
107
109
  "gen:install-tree": "node scripts/gen-install-tree-fixtures.cjs",
108
110
  "gen:section-manifest": "node scripts/gen-section-manifest.cjs --write",
109
- "regen:derived": "npm run build && npm run gen:registry && node scripts/gen-adr-index.cjs --write && node scripts/gen-capability-matrix.cjs --write && node scripts/gen-inventory-manifest.cjs --write && node scripts/gen-context-index.cjs --write && npm run gen:section-manifest && node scripts/sync-manifest-versions.cjs && npm run gen:install-tree",
111
+ "regen:derived": "npm run build && npm run gen:registry && node scripts/gen-adr-index.cjs --write && node scripts/gen-features.cjs --write && node scripts/gen-capability-matrix.cjs --write && node scripts/gen-inventory-manifest.cjs --write && node scripts/gen-context-index.cjs --write && node scripts/gen-state-md-docs.cjs --write && npm run gen:section-manifest && node scripts/sync-manifest-versions.cjs && npm run gen:install-tree && node scripts/gen-scripts-cli-exit.cjs --write && node scripts/gen-hooks-cli-exit.cjs --write && node scripts/gen-exit-code-registry.cjs --write && node scripts/gen-exit-code-docs.cjs --write",
110
112
  "validate:registry": "node scripts/validate-registry.cjs",
111
113
  "prepack": "npm run build:lib",
112
114
  "prepare": "npm run build:lib",
@@ -119,7 +121,8 @@
119
121
  "lint:table-schema-drift": "node scripts/lint-table-schema-drift.cjs",
120
122
  "lint:frontmatter-scalar-broad-grep": "node scripts/lint-frontmatter-scalar-broad-grep.cjs",
121
123
  "lint:removed-but-needed": "node scripts/lint-removed-but-needed.cjs",
122
- "lint:ci": "npm run lint && npm run lint:skill-deps && npm run lint:generated-sync && node scripts/lint-test-file-count.cjs && node scripts/lint-command-contract.cjs && node scripts/lint-pr-check-project-dir.cjs && npm run lint:legacy-name && node scripts/lint-regression-test-names.cjs && node scripts/lint-allow-test-rule-refs.cjs && node scripts/lint-resolution-provenance.cjs && node scripts/lint-emitted-drift-ack.cjs && node scripts/lint-portable-timeout.cjs && node scripts/validate-registry.cjs && node scripts/lint-table-schema-drift.cjs && node scripts/lint-fix-has-regression-test.cjs && node scripts/lint-example-parser-parity.cjs && node scripts/lint-docs-command-form.cjs && node scripts/lint-plan-count-drift.cjs && node scripts/lint-milestone-window-drift.cjs && node scripts/lint-phase-enumeration-drift.cjs && node scripts/lint-planning-prompt-drift.cjs && node scripts/lint-unreachable-guard-drift.cjs && node scripts/lint-completion-ratio-drift.cjs && node scripts/lint-state-field-drift.cjs && node scripts/lint-state-write-path-drift.cjs && node scripts/lint-completion-predicate-drift.cjs && node scripts/lint-planning-snapshot-bypass-drift.cjs && node scripts/lint-health-diagnostic-rule-table.cjs && node scripts/lint-planning-artifact-writer-drift.cjs && node scripts/lint-frontmatter-scalar-broad-grep.cjs && node scripts/lint-removed-but-needed.cjs && node scripts/lint-no-adhoc-regex-escape.cjs && node scripts/lint-vendored-deps.cjs && npm run lint:hooks-runtime-build-seam && node scripts/check-contract-drift.cjs",
124
+ "lint:response-language": "node scripts/lint-response-language-coverage.cjs",
125
+ "lint:ci": "npm run lint && npm run lint:skill-deps && npm run lint:generated-sync && node scripts/lint-test-file-count.cjs && node scripts/lint-command-contract.cjs && node scripts/lint-pr-check-project-dir.cjs && npm run lint:legacy-name && node scripts/lint-regression-test-names.cjs && node scripts/lint-allow-test-rule-refs.cjs && node scripts/lint-resolution-provenance.cjs && node scripts/lint-portable-timeout.cjs && node scripts/lint-portable-grep.cjs && node scripts/validate-registry.cjs && node scripts/lint-table-schema-drift.cjs && node scripts/lint-fix-has-regression-tests.cjs && node scripts/lint-example-parser-parity.cjs && node scripts/lint-docs-command-form.cjs && node scripts/lint-plan-count-drift.cjs && node scripts/lint-milestone-window-drift.cjs && node scripts/lint-phase-enumeration-drift.cjs && node scripts/lint-planning-prompt-drift.cjs && node scripts/lint-unreachable-guard-drift.cjs && node scripts/lint-completion-ratio-drift.cjs && node scripts/lint-slug-derivation-drift.cjs && node scripts/lint-state-field-drift.cjs && node scripts/lint-state-write-path-drift.cjs && node scripts/lint-completion-predicate-drift.cjs && node scripts/lint-planning-snapshot-bypass-drift.cjs && node scripts/lint-health-diagnostic-rule-table.cjs && node scripts/lint-planning-artifact-writer-drift.cjs && node scripts/lint-frontmatter-scalar-broad-grep.cjs && node scripts/lint-removed-but-needed.cjs && node scripts/lint-no-adhoc-regex-escape.cjs && node scripts/lint-vendored-deps.cjs && node scripts/lint-docs-guard-registration.cjs && node scripts/lint-source-test-name-collision.cjs && npm run lint:hooks-runtime-build-seam && node scripts/check-contract-drift.cjs && node scripts/lint-mutation-test-derivation-drift.cjs && node scripts/lint-seam-enforcement.cjs && node scripts/lint-workflow-shellcheck.cjs && npm run lint:response-language",
123
126
  "lint:allow-test-rule-refs": "node scripts/lint-allow-test-rule-refs.cjs",
124
127
  "lint:regression-names": "node scripts/lint-regression-test-names.cjs",
125
128
  "lint:descriptions": "node scripts/lint-descriptions.cjs",
@@ -127,10 +130,11 @@
127
130
  "lint:test-file-count": "node scripts/lint-test-file-count.cjs",
128
131
  "lint:pr-checks": "node scripts/lint-pr-check-project-dir.cjs",
129
132
  "lint:changeset": "node scripts/changeset/lint.cjs",
130
- "lint:generated-sync": "node scripts/gen-capability-registry.cjs --check && node scripts/gen-loop-host-contract.cjs --check && node scripts/gen-capability-matrix.cjs --check && node scripts/sync-manifest-versions.cjs --check && node scripts/gen-inventory-manifest.cjs --check && node scripts/generate-package-identity.cjs --check && node scripts/gen-plugin-skills.cjs --check && node scripts/gen-registry.cjs --check && node scripts/gen-adr-index.cjs --check && node scripts/check-glossary-refs.cjs --check && node scripts/lint-compiled-artifact-sync.cjs --check && node scripts/gen-context-index.cjs --check && node scripts/gen-section-manifest.cjs --check && node scripts/gen-health-docs.cjs --check",
133
+ "lint:generated-sync": "node scripts/gen-capability-registry.cjs --check && node scripts/gen-loop-host-contract.cjs --check && node scripts/gen-capability-matrix.cjs --check && node scripts/sync-manifest-versions.cjs --check && node scripts/gen-inventory-manifest.cjs --check && node scripts/generate-package-identity.cjs --check && node scripts/gen-plugin-skills.cjs --check && node scripts/gen-registry.cjs --check && node scripts/gen-adr-index.cjs --check && node scripts/gen-features.cjs --check && node scripts/check-glossary-refs.cjs --check && node scripts/lint-compiled-artifact-sync.cjs --check && node scripts/gen-context-index.cjs --check && node scripts/gen-section-manifest.cjs --check && node scripts/gen-health-docs.cjs --check && node scripts/gen-state-md-docs.cjs --check && node scripts/gen-scripts-cli-exit.cjs --check && node scripts/gen-hooks-cli-exit.cjs --check && node scripts/gen-exit-code-registry.cjs --check && node scripts/gen-exit-code-docs.cjs --check",
131
134
  "lint:docs": "node scripts/lint-docs-required.cjs",
132
135
  "lint:qa-smells": "node scripts/qa-smell-ratchet.cjs",
133
136
  "lint:legacy-name": "node scripts/lint-legacy-dir-name.cjs",
137
+ "lint:seam-enforcement": "node scripts/lint-seam-enforcement.cjs",
134
138
  "lint:docs-command-form": "node scripts/lint-docs-command-form.cjs",
135
139
  "lint:hooks-runtime-build-seam": "node scripts/lint-hooks-runtime-build-seam.cjs",
136
140
  "ci:test-scope": "node scripts/ci-test-scope.cjs",
@@ -145,13 +149,14 @@
145
149
  "test:qa": "node scripts/run-tests.cjs --suite qa",
146
150
  "test:affected": "node scripts/run-affected-tests.cjs",
147
151
  "test:coverage": "c8 --check-coverage --lines 70 --branches 60 --reporter text --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs",
148
- "test:coverage:scripts-floor": "c8 check-coverage --lines 55 --include 'scripts/**/*.cjs' --exclude 'tests/**' --all",
149
- "test:coverage:unit": "c8 --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs --suite unit && node scripts/check-coverage-gate.cjs",
150
- "test:coverage:unit:raw": "c8 --reporter none node scripts/run-tests.cjs --suite unit",
151
- "test:coverage:report": "c8 report --reporter text --reporter json-summary --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all && node scripts/check-coverage-gate.cjs",
152
+ "test:coverage:scripts-floor": "c8 report --check-coverage --lines 55 --merge-async --include 'scripts/**/*.cjs' --exclude 'tests/**' --all",
153
+ "test:coverage:unit": "c8 --reporter text --reporter json-summary --merge-async --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all node scripts/run-tests.cjs --suite unit && node scripts/check-coverage-gate.cjs",
154
+ "test:coverage:unit:raw": "c8 --reporter none --merge-async node scripts/run-tests.cjs --suite unit",
155
+ "test:coverage:report": "c8 report --reporter text --reporter json-summary --merge-async --include 'gsd-core/bin/lib/**/*.cjs' --exclude 'tests/**' --all && node scripts/check-coverage-gate.cjs",
152
156
  "test:coverage:all": "npm run test:coverage",
153
157
  "test:mutation": "stryker run",
154
- "test:mutation:since": "stryker run --incremental --since origin/next"
158
+ "gen:features": "node scripts/gen-features.cjs",
159
+ "gen:state-md-docs": "node scripts/gen-state-md-docs.cjs"
155
160
  },
156
161
  "allowScripts": {
157
162
  "fallow@2.70.0": true