@opengsd/gsd-core 1.11.0 → 1.12.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 (395) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/agents/gsd-code-fixer.md +1 -1
  4. package/agents/gsd-debug-session-manager.md +1 -1
  5. package/agents/gsd-debugger.md +1 -1
  6. package/agents/gsd-dom-verifier.md +169 -0
  7. package/agents/gsd-eval-auditor.md +1 -1
  8. package/agents/gsd-executor.md +17 -9
  9. package/agents/gsd-framework-selector.md +1 -3
  10. package/agents/gsd-intel-updater.md +1 -1
  11. package/agents/gsd-mempalace-curator.md +0 -1
  12. package/agents/gsd-pattern-mapper.md +11 -0
  13. package/agents/gsd-phase-researcher.md +3 -1
  14. package/agents/gsd-plan-checker.md +15 -55
  15. package/agents/gsd-planner.md +6 -4
  16. package/agents/gsd-project-researcher.md +1 -1
  17. package/agents/gsd-research-synthesizer.md +2 -2
  18. package/agents/gsd-roadmapper.md +15 -11
  19. package/agents/gsd-ui-checker.md +63 -4
  20. package/agents/gsd-ui-researcher.md +41 -3
  21. package/agents/gsd-verifier.md +1 -1
  22. package/bin/install.js +609 -134
  23. package/commands/gsd/discuss-phase.md +1 -1
  24. package/commands/gsd/import.md +1 -1
  25. package/commands/gsd/quick.md +8 -4
  26. package/gsd-core/bin/gsd-tools.cjs +567 -51
  27. package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
  28. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  29. package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
  30. package/gsd-core/bin/lib/api-coverage.cjs +30 -9
  31. package/gsd-core/bin/lib/artifacts.cjs +2 -0
  32. package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
  33. package/gsd-core/bin/lib/audit.cjs +163 -41
  34. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  35. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  36. package/gsd-core/bin/lib/capability-registry.cjs +336 -95
  37. package/gsd-core/bin/lib/capability-state.cjs +18 -3
  38. package/gsd-core/bin/lib/capability-validator.cjs +205 -18
  39. package/gsd-core/bin/lib/check-command-router.cjs +145 -5
  40. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  41. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  42. package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
  43. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  44. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  45. package/gsd-core/bin/lib/commands.cjs +543 -44
  46. package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
  47. package/gsd-core/bin/lib/config-loader.cjs +118 -29
  48. package/gsd-core/bin/lib/config.cjs +92 -2
  49. package/gsd-core/bin/lib/configuration.cjs +129 -37
  50. package/gsd-core/bin/lib/core-utils.cjs +84 -7
  51. package/gsd-core/bin/lib/edge-probe.cjs +9 -1
  52. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  53. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  54. package/gsd-core/bin/lib/frontmatter.cjs +840 -305
  55. package/gsd-core/bin/lib/gap-checker.cjs +27 -3
  56. package/gsd-core/bin/lib/git-base-branch.cjs +174 -39
  57. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
  58. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +6 -3
  59. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
  60. package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
  61. package/gsd-core/bin/lib/host-integration.cjs +39 -6
  62. package/gsd-core/bin/lib/init-command-router.cjs +118 -21
  63. package/gsd-core/bin/lib/init.cjs +120 -41
  64. package/gsd-core/bin/lib/install-engine.cjs +68 -3
  65. package/gsd-core/bin/lib/install-model-override-resolver.cjs +33 -1
  66. package/gsd-core/bin/lib/install-profiles.cjs +78 -4
  67. package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
  68. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  69. package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
  70. package/gsd-core/bin/lib/intel.cjs +101 -26
  71. package/gsd-core/bin/lib/io.cjs +160 -15
  72. package/gsd-core/bin/lib/learnings.cjs +85 -14
  73. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  74. package/gsd-core/bin/lib/markdown-table.cjs +52 -4
  75. package/gsd-core/bin/lib/milestone.cjs +90 -5
  76. package/gsd-core/bin/lib/model-catalog.cjs +177 -19
  77. package/gsd-core/bin/lib/model-resolver.cjs +10 -28
  78. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  79. package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
  80. package/gsd-core/bin/lib/phase-id.cjs +70 -4
  81. package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
  82. package/gsd-core/bin/lib/phase-locator.cjs +138 -17
  83. package/gsd-core/bin/lib/phase.cjs +405 -84
  84. package/gsd-core/bin/lib/plan-document.cjs +263 -0
  85. package/gsd-core/bin/lib/plan-scan.cjs +13 -2
  86. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  87. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  88. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -14
  89. package/gsd-core/bin/lib/planning-workspace.cjs +56 -0
  90. package/gsd-core/bin/lib/probe-core.cjs +4 -1
  91. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  92. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  93. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  94. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
  95. package/gsd-core/bin/lib/review-lane-descriptor.cjs +9 -9
  96. package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
  97. package/gsd-core/bin/lib/roadmap-parser.cjs +79 -16
  98. package/gsd-core/bin/lib/roadmap.cjs +74 -19
  99. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +96 -8
  100. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +34 -1
  101. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +287 -55
  102. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  103. package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
  104. package/gsd-core/bin/lib/shell-command-projection.cjs +71 -8
  105. package/gsd-core/bin/lib/smart-entry.cjs +12 -22
  106. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  107. package/gsd-core/bin/lib/state-command-router.cjs +47 -18
  108. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  109. package/gsd-core/bin/lib/state-document.cjs +186 -0
  110. package/gsd-core/bin/lib/state-md-schema.cjs +221 -0
  111. package/gsd-core/bin/lib/state-transition.cjs +517 -101
  112. package/gsd-core/bin/lib/state.cjs +946 -163
  113. package/gsd-core/bin/lib/surface.cjs +10 -2
  114. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  115. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  116. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  117. package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
  118. package/gsd-core/bin/lib/uat.cjs +1376 -125
  119. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  120. package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
  121. package/gsd-core/bin/lib/unusable-input.cjs +13 -0
  122. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  123. package/gsd-core/bin/lib/vendor/README.md +43 -5
  124. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  125. package/gsd-core/bin/lib/verification.cjs +14 -1
  126. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  127. package/gsd-core/bin/lib/verify.cjs +95 -40
  128. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  129. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  130. package/gsd-core/bin/lib/worktree-safety.cjs +177 -21
  131. package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
  132. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  133. package/gsd-core/bin/shared/exit-codes.json +8 -0
  134. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  135. package/gsd-core/bin/shared/model-catalog.json +8 -1
  136. package/gsd-core/references/agent-contracts.md +3 -2
  137. package/gsd-core/references/api-coverage.md +24 -2
  138. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  139. package/gsd-core/references/checkpoints.md +37 -19
  140. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  141. package/gsd-core/references/edge-probe.md +8 -0
  142. package/gsd-core/references/execute-mvp-tdd.md +1 -3
  143. package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
  144. package/gsd-core/references/execute-phase-wave-guard.md +11 -9
  145. package/gsd-core/references/failing-direction.md +78 -0
  146. package/gsd-core/references/gate-prompts.md +1 -1
  147. package/gsd-core/references/git-integration.md +5 -5
  148. package/gsd-core/references/git-planning-commit.md +3 -3
  149. package/gsd-core/references/gsd-run-resolver.md +1 -1
  150. package/gsd-core/references/loop-hook-dispatch.md +22 -0
  151. package/gsd-core/references/model-profiles.md +1 -1
  152. package/gsd-core/references/nyquist-compliance.md +74 -0
  153. package/gsd-core/references/offer-next.md +3 -5
  154. package/gsd-core/references/phase-argument-parsing.md +3 -3
  155. package/gsd-core/references/planner-failing-direction.md +53 -0
  156. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  157. package/gsd-core/references/planner-revision.md +1 -1
  158. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  159. package/gsd-core/references/planning-config.md +37 -8
  160. package/gsd-core/references/reviewer-instances.md +31 -0
  161. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  162. package/gsd-core/references/tdd.md +1 -3
  163. package/gsd-core/references/ui-brand.md +65 -21
  164. package/gsd-core/references/ui-consideration-probe.md +1 -1
  165. package/gsd-core/references/universal-anti-patterns.md +2 -2
  166. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  167. package/gsd-core/references/verify-mvp-mode.md +1 -1
  168. package/gsd-core/references/workstream-flag.md +11 -11
  169. package/gsd-core/templates/README.md +1 -1
  170. package/gsd-core/templates/SECURITY.md +3 -3
  171. package/gsd-core/templates/UI-SPEC.md +25 -3
  172. package/gsd-core/templates/VALIDATION.md +3 -3
  173. package/gsd-core/templates/phase-prompt.md +3 -0
  174. package/gsd-core/templates/state.md +7 -0
  175. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  176. package/gsd-core/workflows/add-backlog.md +1 -1
  177. package/gsd-core/workflows/add-phase.md +3 -3
  178. package/gsd-core/workflows/add-tests.md +3 -8
  179. package/gsd-core/workflows/add-todo.md +1 -1
  180. package/gsd-core/workflows/ai-integration-phase.md +4 -9
  181. package/gsd-core/workflows/audit-fix.md +12 -3
  182. package/gsd-core/workflows/audit-milestone.md +9 -9
  183. package/gsd-core/workflows/audit-uat.md +17 -2
  184. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  185. package/gsd-core/workflows/autonomous.md +10 -26
  186. package/gsd-core/workflows/check-todos.md +1 -1
  187. package/gsd-core/workflows/cleanup.md +2 -2
  188. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +1 -1
  189. package/gsd-core/workflows/code-review-fix.md +1 -1
  190. package/gsd-core/workflows/code-review.md +121 -40
  191. package/gsd-core/workflows/complete-milestone.md +15 -10
  192. package/gsd-core/workflows/debug.md +5 -3
  193. package/gsd-core/workflows/diagnose-issues.md +12 -6
  194. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  195. package/gsd-core/workflows/discuss-phase/modes/chain.md +3 -7
  196. package/gsd-core/workflows/discuss-phase/modes/text.md +1 -1
  197. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  198. package/gsd-core/workflows/discuss-phase-assumptions.md +2 -2
  199. package/gsd-core/workflows/discuss-phase.md +1 -1
  200. package/gsd-core/workflows/do.md +3 -6
  201. package/gsd-core/workflows/docs-update.md +5 -4
  202. package/gsd-core/workflows/edit-phase.md +1 -1
  203. package/gsd-core/workflows/eval-review.md +4 -9
  204. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
  205. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +113 -11
  206. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  207. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  208. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  209. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +22 -4
  210. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  211. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  212. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -2
  213. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  214. package/gsd-core/workflows/execute-phase.md +38 -54
  215. package/gsd-core/workflows/execute-plan.md +17 -12
  216. package/gsd-core/workflows/explore.md +1 -1
  217. package/gsd-core/workflows/extract-learnings.md +1 -1
  218. package/gsd-core/workflows/fast.md +2 -2
  219. package/gsd-core/workflows/forensics.md +1 -1
  220. package/gsd-core/workflows/graduation.md +5 -5
  221. package/gsd-core/workflows/health.md +3 -6
  222. package/gsd-core/workflows/import.md +14 -11
  223. package/gsd-core/workflows/inbox.md +4 -5
  224. package/gsd-core/workflows/ingest-docs.md +44 -11
  225. package/gsd-core/workflows/insert-phase.md +5 -5
  226. package/gsd-core/workflows/list-seeds.md +5 -3
  227. package/gsd-core/workflows/list-workspaces.md +1 -1
  228. package/gsd-core/workflows/manager.md +12 -23
  229. package/gsd-core/workflows/map-codebase.md +1 -1
  230. package/gsd-core/workflows/milestone-summary.md +1 -1
  231. package/gsd-core/workflows/mvp-phase.md +2 -2
  232. package/gsd-core/workflows/new-milestone.md +9 -21
  233. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  234. package/gsd-core/workflows/new-project.md +12 -26
  235. package/gsd-core/workflows/new-workspace.md +1 -1
  236. package/gsd-core/workflows/next.md +2 -2
  237. package/gsd-core/workflows/pause-work.md +1 -1
  238. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  239. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
  240. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -4
  241. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +3 -3
  242. package/gsd-core/workflows/plan-phase.md +121 -42
  243. package/gsd-core/workflows/plan-review-convergence.md +46 -9
  244. package/gsd-core/workflows/plant-seed.md +2 -2
  245. package/gsd-core/workflows/pr-branch.md +187 -51
  246. package/gsd-core/workflows/profile-user.md +16 -14
  247. package/gsd-core/workflows/progress.md +27 -12
  248. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  249. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -3
  250. package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
  251. package/gsd-core/workflows/quick/steps/research-phase.md +2 -4
  252. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  253. package/gsd-core/workflows/quick.md +20 -29
  254. package/gsd-core/workflows/remove-phase.md +4 -4
  255. package/gsd-core/workflows/remove-workspace.md +2 -2
  256. package/gsd-core/workflows/resume-project.md +8 -12
  257. package/gsd-core/workflows/review.md +193 -15
  258. package/gsd-core/workflows/scan.md +1 -1
  259. package/gsd-core/workflows/secure-phase.md +2 -2
  260. package/gsd-core/workflows/settings-advanced.md +7 -9
  261. package/gsd-core/workflows/settings-integrations.md +64 -31
  262. package/gsd-core/workflows/settings.md +3 -5
  263. package/gsd-core/workflows/ship.md +12 -6
  264. package/gsd-core/workflows/sketch-wrap-up.md +11 -17
  265. package/gsd-core/workflows/sketch.md +12 -18
  266. package/gsd-core/workflows/smart-entry.md +3 -5
  267. package/gsd-core/workflows/spec-phase.md +23 -1
  268. package/gsd-core/workflows/spike-wrap-up.md +7 -11
  269. package/gsd-core/workflows/spike.md +20 -31
  270. package/gsd-core/workflows/stats.md +2 -2
  271. package/gsd-core/workflows/sync-skills.md +1 -1
  272. package/gsd-core/workflows/thread.md +11 -7
  273. package/gsd-core/workflows/transition.md +5 -5
  274. package/gsd-core/workflows/ui-phase.md +10 -16
  275. package/gsd-core/workflows/ui-review.md +6 -10
  276. package/gsd-core/workflows/ultraplan-phase.md +5 -13
  277. package/gsd-core/workflows/undo.md +8 -16
  278. package/gsd-core/workflows/update.md +6 -10
  279. package/gsd-core/workflows/validate-phase.md +2 -2
  280. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  281. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  282. package/gsd-core/workflows/verify-work.md +57 -18
  283. package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
  284. package/hooks/dist/gsd-config-reload.js +18 -12
  285. package/hooks/dist/gsd-context-monitor.js +19 -10
  286. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  287. package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
  288. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  289. package/hooks/dist/gsd-cursor-stop.js +2 -1
  290. package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
  291. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
  292. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  293. package/hooks/dist/gsd-graphify-update.sh +22 -18
  294. package/hooks/dist/gsd-node-runner.sh +76 -0
  295. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  296. package/hooks/dist/gsd-prompt-guard.js +16 -7
  297. package/hooks/dist/gsd-read-guard.js +16 -7
  298. package/hooks/dist/gsd-read-injection-scanner.js +17 -8
  299. package/hooks/dist/gsd-session-state.sh +1 -0
  300. package/hooks/dist/gsd-statusline.js +215 -26
  301. package/hooks/dist/gsd-validate-commit.sh +80 -6
  302. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  303. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  304. package/hooks/dist/gsd-workflow-guard.js +34 -16
  305. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  306. package/hooks/dist/gsd-write-guard.js +35 -25
  307. package/hooks/dist/lib/cli-exit.js +560 -0
  308. package/hooks/dist/lib/exit-code-registry.js +98 -0
  309. package/hooks/dist/lib/git-probe.js +84 -0
  310. package/hooks/dist/lib/hook-exit.js +81 -0
  311. package/hooks/dist/managed-hooks-registry.cjs +3 -0
  312. package/hooks/gsd-agent-isolation-guard.js +77 -38
  313. package/hooks/gsd-config-reload.js +18 -12
  314. package/hooks/gsd-context-monitor.js +19 -10
  315. package/hooks/gsd-cursor-post-tool.js +3 -1
  316. package/hooks/gsd-cursor-pre-tool.js +3 -1
  317. package/hooks/gsd-cursor-session-start.js +2 -1
  318. package/hooks/gsd-cursor-stop.js +2 -1
  319. package/hooks/gsd-cursor-subagent-start.js +28 -23
  320. package/hooks/gsd-cursor-subagent-stop.js +3 -1
  321. package/hooks/gsd-ensure-canonical-path.js +2 -1
  322. package/hooks/gsd-graphify-update.sh +22 -18
  323. package/hooks/gsd-node-runner.sh +76 -0
  324. package/hooks/gsd-phase-boundary.sh +1 -0
  325. package/hooks/gsd-prompt-guard.js +16 -7
  326. package/hooks/gsd-read-guard.js +16 -7
  327. package/hooks/gsd-read-injection-scanner.js +17 -8
  328. package/hooks/gsd-session-state.sh +1 -0
  329. package/hooks/gsd-statusline.js +215 -26
  330. package/hooks/gsd-validate-commit.sh +80 -6
  331. package/hooks/gsd-windsurf-pre-command.js +16 -11
  332. package/hooks/gsd-windsurf-pre-write.js +22 -13
  333. package/hooks/gsd-workflow-guard.js +34 -16
  334. package/hooks/gsd-worktree-path-guard.js +36 -21
  335. package/hooks/gsd-write-guard.js +35 -25
  336. package/hooks/lib/cli-exit.js +560 -0
  337. package/hooks/lib/exit-code-registry.js +98 -0
  338. package/hooks/lib/git-probe.js +84 -0
  339. package/hooks/lib/hook-exit.js +81 -0
  340. package/hooks/managed-hooks-registry.cjs +3 -0
  341. package/package.json +12 -7
  342. package/scripts/base64-scan.sh +74 -12
  343. package/scripts/build-hooks.js +5 -0
  344. package/scripts/check-glossary-refs.cjs +77 -15
  345. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  346. package/scripts/ci-check-job-near-cap.cjs +49 -0
  347. package/scripts/ci-pr-mergeability.cjs +262 -0
  348. package/scripts/ci-test-scope.cjs +45 -12
  349. package/scripts/ci-timeout-report.cjs +230 -0
  350. package/scripts/docs-guard-registry.cjs +396 -0
  351. package/scripts/gen-capability-registry.cjs +8 -6
  352. package/scripts/gen-exit-code-docs.cjs +318 -0
  353. package/scripts/gen-exit-code-registry.cjs +891 -0
  354. package/scripts/gen-features.cjs +836 -0
  355. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  356. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  357. package/scripts/gen-loop-host-contract.cjs +134 -1
  358. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  359. package/scripts/gen-state-md-docs.cjs +727 -0
  360. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  361. package/scripts/lib/ci-job-timing.cjs +72 -0
  362. package/scripts/lib/cli-exit.cjs +546 -44
  363. package/scripts/lib/drift-scan.cjs +32 -2
  364. package/scripts/lib/exit-code-registry.cjs +98 -0
  365. package/scripts/lib/ndjson-reporter.cjs +119 -0
  366. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  367. package/scripts/lint-docs-guard-registration.cjs +495 -0
  368. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +193 -0
  369. package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
  370. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  371. package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
  372. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  373. package/scripts/lint-phase-enumeration-drift.cjs +21 -8
  374. package/scripts/lint-planning-prompt-drift.cjs +38 -1
  375. package/scripts/lint-removed-but-needed.cjs +184 -16
  376. package/scripts/lint-seam-enforcement.cjs +182 -0
  377. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  378. package/scripts/lint-source-test-name-collision.cjs +241 -0
  379. package/scripts/lint-state-write-path-drift.cjs +337 -432
  380. package/scripts/lint-test-file-count.allowlist.json +122 -4
  381. package/scripts/lint-test-file-count.cjs +25 -3
  382. package/scripts/lint-unreachable-guard-drift.cjs +51 -64
  383. package/scripts/lint-vendored-deps.cjs +208 -35
  384. package/scripts/mutation-matrix.cjs +599 -50
  385. package/scripts/prompt-injection-scan.sh +75 -14
  386. package/scripts/secret-scan.sh +75 -13
  387. package/scripts/select-docs-guards.cjs +56 -0
  388. package/scripts/sync-runtime-launcher.cjs +22 -3
  389. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  390. package/skills/gsd-import/SKILL.md +1 -1
  391. package/skills/gsd-quick/SKILL.md +8 -4
  392. package/vscode/package.json +1 -1
  393. package/bin/lib/ui-safety-gate.cjs +0 -109
  394. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  395. package/scripts/state-write-path-drift-baseline.json +0 -19
@@ -61,17 +61,43 @@ const SKIP_DIR_NAMES = new Set(['node_modules', 'dist', '.git']);
61
61
  * previous regex silently MISSED every re-derivation using a
62
62
  * cross-platform path-separator class for exactly this reason.
63
63
  */
64
+ // Deterministic regression seam for the MAJOR-2 bound (issue #3951/#3987): a
65
+ // counter of how many characters this tokenizer has actually examined, so a
66
+ // test can assert the bound HOLDS (total work stays a small linear multiple
67
+ // of the number of scan attempts × MAX_REGEX_LITERAL_LEN) without resorting
68
+ // to a wall-clock elapsed-time assertion, which this repo's test rules ban
69
+ // ("Clock Seams: Do not assert on wall-clock time.") and which is exactly
70
+ // what flaked on a slow shared CI runner. `resetRegexScanStats`/
71
+ // `getRegexScanStats` are read-modify-reset around a single scan under test;
72
+ // they are process-global and NOT safe under concurrent scans, which is fine
73
+ // for this synchronous, single-threaded CLI tool and its tests.
74
+ let regexScanStats = { calls: 0, charsExamined: 0 };
75
+
76
+ function resetRegexScanStats() {
77
+ regexScanStats = { calls: 0, charsExamined: 0 };
78
+ }
79
+
80
+ function getRegexScanStats() {
81
+ return { ...regexScanStats };
82
+ }
83
+
64
84
  function readRegexLiteralAt(line, start) {
65
85
  if (line[start] !== '/') return null;
86
+ regexScanStats.calls++;
66
87
  const limit = Math.min(line.length, start + MAX_REGEX_LITERAL_LEN);
67
88
  let inClass = false;
68
- for (let i = start + 1; i < limit; i++) {
89
+ let i = start + 1;
90
+ for (; i < limit; i++) {
69
91
  const ch = line[i];
70
92
  if (ch === '\\') {
71
93
  i++; // escape consumes the next character, whatever it is
72
94
  continue;
73
95
  }
74
- if (ch === '\r' || ch === '\n') return null; // a literal cannot span lines
96
+ if (ch === '\r' || ch === '\n') {
97
+ // a literal cannot span lines
98
+ regexScanStats.charsExamined += i - start;
99
+ return null;
100
+ }
75
101
  if (ch === '[') {
76
102
  inClass = true;
77
103
  } else if (ch === ']') {
@@ -83,9 +109,11 @@ function readRegexLiteralAt(line, start) {
83
109
  // MAX_REGEX_LITERAL_LEN either.
84
110
  let end = i + 1;
85
111
  while (end < limit && line[end] >= 'a' && line[end] <= 'z') end++;
112
+ regexScanStats.charsExamined += end - start;
86
113
  return { text: line.slice(start, end), end };
87
114
  }
88
115
  }
116
+ regexScanStats.charsExamined += limit - start;
89
117
  return null;
90
118
  }
91
119
 
@@ -275,4 +303,6 @@ module.exports = {
275
303
  MAX_REGEX_LITERAL_LEN,
276
304
  sanitizeForReport,
277
305
  scanTree,
306
+ resetRegexScanStats,
307
+ getRegexScanStats,
278
308
  };
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+
3
+ // GENERATED FILE — DO NOT EDIT BY HAND.
4
+ // Source of truth: gsd-core/bin/shared/exit-codes.json. Regenerate with:
5
+ // node scripts/gen-exit-code-registry.cjs --write
6
+ // This exact content is emitted to THREE locations — gsd-core/bin/lib/exit-code-registry.cjs,
7
+ // scripts/lib/exit-code-registry.cjs, and hooks/lib/exit-code-registry.js (the latter two
8
+ // committed so scripts/ and hooks/ consumers work on an unbuilt clone) — all byte-compared by
9
+ // `npm run lint:generated-sync` (#3905 ADR-3889 Phase 1; #3906 Phase 2 added the second copy;
10
+ // #3911 ADR-3889 Phase 7 added the hooks/lib/ copy).
11
+ //
12
+ // exitCodeFor(name) / nameForExitCode(code) are pure and total over this
13
+ // closed table — each throws for anything not registered here.
14
+
15
+ const EXIT_CODES = Object.freeze([
16
+ Object.freeze({
17
+ code: 2,
18
+ name: "HOOK_DENY",
19
+ meaning: "Hook protocol deny — the harness blocks the tool call",
20
+ owner: "hook-adapter",
21
+ authorizedBy: "ADR-3889",
22
+ }),
23
+ Object.freeze({
24
+ code: 64,
25
+ name: "USAGE",
26
+ meaning: "Caller error — bad argv, unknown subcommand, missing argument",
27
+ owner: "generic",
28
+ authorizedBy: "ADR-3889",
29
+ }),
30
+ Object.freeze({
31
+ code: 66,
32
+ name: "NO_INPUT",
33
+ meaning: "Ran; zero units were in scope, and that emptiness is known to be genuine",
34
+ owner: "generic",
35
+ authorizedBy: "ADR-3889",
36
+ }),
37
+ Object.freeze({
38
+ code: 69,
39
+ name: "UNAVAILABLE",
40
+ meaning: "Could not run — prerequisite absent, input unreadable, scope unestablished",
41
+ owner: "generic",
42
+ authorizedBy: "ADR-3889",
43
+ }),
44
+ Object.freeze({
45
+ code: 70,
46
+ name: "INTERNAL",
47
+ meaning: "Self-failure — crash, timeout, killed subprocess",
48
+ owner: "generic",
49
+ authorizedBy: "ADR-3889",
50
+ }),
51
+ Object.freeze({
52
+ code: 80,
53
+ name: "DEGRADED",
54
+ meaning: "Ran to completion and is reporting a condition through its result payload rather than as a process failure",
55
+ owner: "gsd-tools",
56
+ authorizedBy: "ADR-3889 + ADR-2980",
57
+ })
58
+ ]);
59
+
60
+ const NAME_TO_CODE = new Map(EXIT_CODES.map((entry) => [entry.name, entry.code]));
61
+ const CODE_TO_NAME = new Map(EXIT_CODES.map((entry) => [entry.code, entry.name]));
62
+
63
+ /**
64
+ * Resolve the registered exit code for a symbolic name. Pure, total: throws
65
+ * for anything not an exact, registered, exact-case key — including
66
+ * non-strings, the empty string, untrimmed strings, wrong case, and
67
+ * prototype-chain names like `__proto__`/`constructor`/`toString` (a Map
68
+ * lookup never touches the prototype chain, so these are indistinguishable
69
+ * from any other unregistered name).
70
+ *
71
+ * @param {string} name
72
+ * @returns {number}
73
+ */
74
+ function exitCodeFor(name) {
75
+ if (typeof name !== 'string' || name.length === 0) {
76
+ throw new Error(`exitCodeFor: name must be a non-empty string, received ${JSON.stringify(name)}`);
77
+ }
78
+ if (!NAME_TO_CODE.has(name)) {
79
+ throw new Error(`exitCodeFor: unregistered exit code name: ${JSON.stringify(name)}`);
80
+ }
81
+ return NAME_TO_CODE.get(name);
82
+ }
83
+
84
+ /**
85
+ * Reverse of exitCodeFor: resolve the symbolic name for a registered exit
86
+ * code. Pure, total: throws for anything not an exact, registered code.
87
+ *
88
+ * @param {number} code
89
+ * @returns {string}
90
+ */
91
+ function nameForExitCode(code) {
92
+ if (!CODE_TO_NAME.has(code)) {
93
+ throw new Error(`nameForExitCode: unregistered exit code: ${JSON.stringify(code)}`);
94
+ }
95
+ return CODE_TO_NAME.get(code);
96
+ }
97
+
98
+ module.exports = { EXIT_CODES, exitCodeFor, nameForExitCode };
@@ -0,0 +1,119 @@
1
+ 'use strict';
2
+
3
+ // Machine-readable companion reporter for scripts/run-tests.cjs (#3889).
4
+ //
5
+ // node:test's built-in reporters (spec/tap) are human-formatted and
6
+ // scripts/run-tests.cjs spawns the child with `stdio: 'inherit'` — by design,
7
+ // per #3597/#1051, to avoid the maxBuffer and live-output risks of piping —
8
+ // so the parent process has no way to see WHICH file was executing when a
9
+ // per-chunk timeout kills the child. This reporter runs ALONGSIDE the normal
10
+ // human reporter (a second `--test-reporter` on the same invocation, per
11
+ // Node's documented multi-reporter pairing) and appends one JSON object per
12
+ // line to a path supplied via the GSD_RUN_TESTS_EVENTS_FILE env var. On a
13
+ // timeout, run-tests.cjs reads that file back to name the file(s) still
14
+ // in flight (a `test:dequeue` with no matching `test:pass`/`test:fail`).
15
+ //
16
+ // Durability, not `--test-reporter-destination` (#3889 root cause): a
17
+ // reporter that YIELDS strings has them piped by Node into a
18
+ // `fs.WriteStream` targeting the destination path, and that stream buffers.
19
+ // The parent's `execFileSync` timeout SIGKILLs the child on a hang, and
20
+ // SIGKILL is uncatchable and gives the process zero chance to flush — so a
21
+ // yield-based reporter can lose every event still sitting in the stream's
22
+ // buffer, which is exactly the case this feature exists to diagnose (proven
23
+ // live: a chunk killed at 2006ms produced a `killed after 2006ms` line from
24
+ // the TIMER, which lives in the parent, but zero usable events from the
25
+ // reporter, which lives in the child and never flushed). Writing each event
26
+ // with `fs.appendFileSync` — synchronous and unbuffered — makes it durable
27
+ // the instant it happens, before the process can be killed out from under
28
+ // it. The reporter therefore yields NOTHING; it is a pure side-effecting
29
+ // sink. Node still requires a `--test-reporter-destination` to pair with
30
+ // this `--test-reporter` (see run-tests.cjs's reporterArgsFor), but that
31
+ // destination is a throwaway sink that stays empty by design — the durable
32
+ // path is GSD_RUN_TESTS_EVENTS_FILE, not the destination Node manages.
33
+ //
34
+ // Contract targeted: Node's "Custom reporters" contract
35
+ // (https://nodejs.org/api/test.html#custom-reporters) — a reporter module's
36
+ // default export is a function receiving the test runner's event stream (an
37
+ // AsyncIterable of `{ type, data }` objects). Node feeds that function to
38
+ // `stream.compose` as the stream's "body". When the body is an async
39
+ // FUNCTION (not an `async function*` generator), `stream.compose`'s own
40
+ // contract (https://nodejs.org/api/stream.html#streamcomposestreams)
41
+ // requires it to return nully (undefined/null) — returning anything else,
42
+ // including an array, throws `ERR_INVALID_RETURN_VALUE` ("Expected nully to
43
+ // be returned from the 'body' function but got an instance of Array")
44
+ // exactly once the promise resolves. Verified directly against
45
+ // `stream.compose` in this repo's Node: calling it with a body that
46
+ // `return`s `[]` reproduces that same TypeError. A generator form
47
+ // (`async function*`) is the one that yields an iterable; the plain
48
+ // `async function` form used here is the one that must return nully. This
49
+ // repo's `engines.node` requires >=24.0.0 (package.json), where both
50
+ // contracts have been stable since Node 20.
51
+ //
52
+ // Kept intentionally tiny: only the five event types run-tests.cjs needs are
53
+ // handled — `test:enqueue`/`test:dequeue` (emitted by the RUNNER as it queues
54
+ // and begins each spawned test-file child, independent of whether anything
55
+ // inside that file ever completes) plus `test:start`/`test:pass`/`test:fail`
56
+ // (emitted per-subtest, once the child reports it). `test:dequeue` is the
57
+ // event that actually means "in flight": a subtest inside a file that hangs
58
+ // forever never reaches `test:start`/`test:pass`/`test:fail` at all, because
59
+ // node:test only surfaces those to the parent once the child COMPLETES that
60
+ // test — a hang, by definition, never completes. Recording `test:dequeue`
61
+ // closes that gap: it fires the moment the runner begins the file, so a
62
+ // killed hang still leaves a durable "this file was running" record.
63
+ // Everything else (diagnostics, plans, coverage) is ignored so a truncated
64
+ // events file (the process is SIGKILLed mid-`appendFileSync` on timeout — an
65
+ // individual write is unbuffered but not atomic, so the OS can still
66
+ // interleave a partial write with the kill) never leaves more than one
67
+ // dangling unparsable trailing line.
68
+ module.exports = async function ndjsonEventReporter(source) {
69
+ const eventsPath = process.env.GSD_RUN_TESTS_EVENTS_FILE;
70
+ // #3889: an init marker, written as this reporter's FIRST action — before
71
+ // the `for await` loop even begins consuming the event stream — so the
72
+ // events file's mere existence (and its exact contents) can distinguish
73
+ // "the reporter module never loaded in the child at all" (file absent)
74
+ // from "it loaded fine but no test:start reached it before the kill"
75
+ // (file contains only this one line) from "it's working" (file contains
76
+ // more than this line). Same appendFileSync durability rationale as every
77
+ // other write in this file: synchronous and unbuffered, so it survives an
78
+ // uncatchable SIGKILL landing a moment later.
79
+ if (eventsPath) {
80
+ try {
81
+ require('fs').appendFileSync(eventsPath, `${JSON.stringify({ type: 'reporter:init', ts: Date.now() })}\n`);
82
+ } catch {
83
+ // Best-effort, same as every other write below — must never crash the
84
+ // test run this reporter is only observing.
85
+ }
86
+ }
87
+ for await (const event of source) {
88
+ if (!eventsPath) continue; // no destination configured — nothing to record
89
+ if (
90
+ event.type === 'test:enqueue' ||
91
+ event.type === 'test:dequeue' ||
92
+ event.type === 'test:start' ||
93
+ event.type === 'test:pass' ||
94
+ event.type === 'test:fail'
95
+ ) {
96
+ const { file, name, nesting, testNumber } = event.data || {};
97
+ const line = `${JSON.stringify({
98
+ type: event.type,
99
+ file,
100
+ name,
101
+ nesting,
102
+ testNumber,
103
+ ts: Date.now(),
104
+ })}\n`;
105
+ try {
106
+ require('fs').appendFileSync(eventsPath, line);
107
+ } catch {
108
+ // Best-effort: a write failure here (e.g. the events dir vanished)
109
+ // must never crash the test run this reporter is only observing.
110
+ }
111
+ }
112
+ }
113
+ // Falls through to an implicit `return undefined` (nully): this reporter is
114
+ // a pure side-effecting sink (see the durability note above), never a
115
+ // source of reporter OUTPUT, and `stream.compose` requires its async
116
+ // FUNCTION body to return nully — returning an iterable (e.g. `[]`) here
117
+ // raises `ERR_INVALID_RETURN_VALUE` (observed live: this exact `return []`
118
+ // crashed every chunk on the real remote run this regresses).
119
+ };
@@ -1,3 +1,3 @@
1
1
  {
2
- "maxFiles": 280
2
+ "maxFiles": 282
3
3
  }