@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
@@ -1,17 +1,47 @@
1
1
  {
2
2
  "_doc": "Baseline of modules currently exceeding the 2-test-file limit. Each entry locks in TODAY's exact test filenames as the allowlisted set (identity ratchet). Adding a NEW test file to a capped module fails (novel). Removing one requires pruning this list (stale, ratchet-down). When a cluster drops to \u2264 2, remove its entry entirely. New entries require justification in PR description.",
3
3
  "modules": {
4
+ "adr-parser": {
5
+ "files": [
6
+ "adr-parser.property.test.cjs",
7
+ "adr-parser.test.cjs",
8
+ "adr-parser.unit.test.cjs"
9
+ ],
10
+ "issue": "3227",
11
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
12
+ },
4
13
  "config": {
5
14
  "files": [
6
15
  "config-defaults-runtime-exclusion.test.cjs",
7
16
  "config-field-docs.test.cjs",
8
17
  "config-get-default.test.cjs",
9
- "config-schema.property.test.cjs",
18
+ "config-get-raw-guard.test.cjs",
10
19
  "config-validation.test.cjs",
11
20
  "config.test.cjs"
12
21
  ],
13
22
  "issue": "TBD"
14
23
  },
24
+ "context-predicates": {
25
+ "files": [
26
+ "context-predicates-query.test.cjs",
27
+ "context-predicates.property.test.cjs",
28
+ "context-predicates.test.cjs"
29
+ ],
30
+ "issue": "3227",
31
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
32
+ },
33
+ "frontmatter": {
34
+ "files": [
35
+ "frontmatter-cli.test.cjs",
36
+ "frontmatter-golden-parity.test.cjs",
37
+ "frontmatter-roundtrip.property.test.cjs",
38
+ "frontmatter.property.test.cjs",
39
+ "frontmatter.test.cjs",
40
+ "frontmatter.unit.test.cjs"
41
+ ],
42
+ "issue": "3881",
43
+ "justification": "Grandfathered by #3227 for the original 4-file cluster (pre-existing over-cap, not new sprawl). #3881 (ADR-3473 \u00a78.1, the js-yaml parser migration) adds two more: frontmatter-golden-parity.test.cjs (D-series golden-corpus diff against the legacy parser, ~900 real documents \u2014 cannot be folded into an existing file without losing its independent-of-current-parser provenance) and frontmatter-roundtrip.property.test.cjs (fast-check property coverage the migration's bijective-contract rule requires). Both are migration-specific, not incidental sprawl."
44
+ },
15
45
  "graphify": {
16
46
  "files": [
17
47
  "graphify-auto-update.slow.test.cjs",
@@ -51,6 +81,7 @@
51
81
  "phase-dependency-levels.test.cjs",
52
82
  "phase-resolution-parity.test.cjs",
53
83
  "phase-structure.test.cjs",
84
+ "phase-tdd-applicable.test.cjs",
54
85
  "phase.test.cjs"
55
86
  ],
56
87
  "issue": "3186"
@@ -99,6 +130,7 @@
99
130
  },
100
131
  "verify": {
101
132
  "files": [
133
+ "verify-archive-dirs-live-path.test.cjs",
102
134
  "verify-health.test.cjs",
103
135
  "verify-mvp-uat.test.cjs",
104
136
  "verify-npm-publish.test.cjs",
@@ -106,20 +138,22 @@
106
138
  "verify-work-auto-transition.test.cjs",
107
139
  "verify.test.cjs"
108
140
  ],
109
- "issue": "3767"
141
+ "issue": "#3813 \u2014 the live-path #1883 suite drives buildPlanningSnapshot in-process with an fs fault; the verify module suites are CLI-driving and cannot host an fs monkeypatch",
142
+ "justification": "verify-command-grounding added by #2401/#3678; allowlist follow-up landed with #3606 (base was red on this lane)."
110
143
  },
111
144
  "install": {
112
145
  "files": [
113
146
  "install-minimal-hooks.test.cjs",
114
147
  "install-nested-layout.test.cjs",
115
148
  "install-path-detection.test.cjs",
149
+ "install-profile-workflow-spawns.test.cjs",
116
150
  "install-regressions.test.cjs",
117
151
  "install-runtime-artifacts.test.cjs",
118
152
  "install-update-marker.test.cjs",
119
153
  "install-write-confinement.test.cjs",
120
154
  "install.test.cjs"
121
155
  ],
122
- "issue": "1679"
156
+ "issue": "#3798 \u2014 the profile-closure spawn test reads the real repo surface (commands+workflows+agents); consolidating it into install.test.cjs would put a whole-repo scan behind the suite's heaviest file"
123
157
  },
124
158
  "edge-probe": {
125
159
  "files": [
@@ -150,9 +184,95 @@
150
184
  "files": [
151
185
  "prompt-budget-cli.test.cjs",
152
186
  "prompt-budget-parity.test.cjs",
153
- "prompt-budget.test.cjs"
187
+ "prompt-budget.property.test.cjs",
188
+ "prompt-budget.test.cjs",
189
+ "prompt-budget.unit.test.cjs"
154
190
  ],
155
191
  "issue": "2929"
192
+ },
193
+ "mcp-catalog": {
194
+ "files": [
195
+ "mcp-catalog-parity.install.test.cjs",
196
+ "mcp-catalog.property.test.cjs",
197
+ "mcp-catalog.test.cjs"
198
+ ],
199
+ "issue": "3227",
200
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
201
+ },
202
+ "model-catalog": {
203
+ "files": [
204
+ "model-catalog-runtime-defaults.test.cjs",
205
+ "model-catalog-valid-tiers.test.cjs",
206
+ "model-catalog.unit.test.cjs"
207
+ ],
208
+ "issue": "3227",
209
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
210
+ },
211
+ "package-legitimacy": {
212
+ "files": [
213
+ "package-legitimacy-gate.test.cjs",
214
+ "package-legitimacy.property.test.cjs",
215
+ "package-legitimacy.test.cjs"
216
+ ],
217
+ "issue": "3227",
218
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
219
+ },
220
+ "runtime-homes": {
221
+ "files": [
222
+ "runtime-homes-descriptor-drive.test.cjs",
223
+ "runtime-homes-legacy-ids-drift-guard.test.cjs",
224
+ "runtime-homes.property.test.cjs"
225
+ ],
226
+ "issue": "3227",
227
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
228
+ },
229
+ "section-manifest": {
230
+ "files": [
231
+ "section-manifest-init-facts.test.cjs",
232
+ "section-manifest.property.test.cjs",
233
+ "section-manifest.test.cjs"
234
+ ],
235
+ "issue": "3227",
236
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
237
+ },
238
+ "workflow-fragments": {
239
+ "files": [
240
+ "workflow-fragments-emission.install.test.cjs",
241
+ "workflow-fragments.property.test.cjs",
242
+ "workflow-fragments.test.cjs"
243
+ ],
244
+ "issue": "3227",
245
+ "justification": "Grandfathered by #3227 when the testEffectivePrefix() dot/hyphen bucketing fix first made this pre-existing over-cap cluster visible to the gate; not new test sprawl."
246
+ },
247
+ "docs": {
248
+ "files": [
249
+ "docs-hooks-table-parity.test.cjs",
250
+ "docs-parity-live-registry.test.cjs",
251
+ "docs-state-md-locale-parity.test.cjs",
252
+ "docs-update.test.cjs"
253
+ ],
254
+ "issue": "3873 | #3839 \u2014 the hook-event parity suite cross-checks the four docs hook tables against src/runtime-hooks-surface.cts registrations; a generated-docs concern distinct from content freshness and registry parity",
255
+ "justification": "ADR-3473 \u00a78.8 makes docs/reference/state-md.md and its four locale siblings generated-and-committed and adds the repo's first locale-parity check (verified: no locale-parity lint precedent exists here). That check is a distinct concern from docs-update (content freshness) and docs-parity-live-registry (registry parity); folding it into either would place an unrelated subject inside them purely to satisfy a count. The section it guards is absent from all four translations today and documents the status enum behind #3853."
256
+ },
257
+ "audit": {
258
+ "files": [
259
+ "audit-command-cutover.test.cjs",
260
+ "audit-fix-command.test.cjs",
261
+ "audit-milestone-filename-guard.test.cjs",
262
+ "audit-open-remainder-count.test.cjs",
263
+ "audit-uat-acknowledged.test.cjs",
264
+ "audit-uat-summary-segmentation.test.cjs",
265
+ "audit-workstream-layouts.test.cjs"
266
+ ],
267
+ "issue": "#3804/#3805 \u2014 audit-layout and acknowledged-marker suites drive the real audit-uat CLI against on-disk fixtures | #3817 \u2014 regression suite proving countReal counts the truncation remainder marker instead of treating it as one phantom item | #3783 \u2014 dedicated suite for the summary.current_milestone/archived segmentation, matching this module's one-file-per-feature-slice precedent (e.g. audit-uat-acknowledged.test.cjs) rather than growing the unrelated 6900+ line tests/uat.test.cjs (a different module, keyed off uat.cjs)"
268
+ },
269
+ "shell-command-projection": {
270
+ "files": [
271
+ "shell-command-projection-dispatch.test.cjs",
272
+ "shell-command-projection-md-normalize.test.cjs",
273
+ "shell-command-projection-path-sep.test.cjs"
274
+ ],
275
+ "issue": "#3854 \u2014 the tight-list suite pins the markdown write-normalizer's blank-line policy through the exported normalizeContent/platformWriteSync seam; a distinct concern from dispatch routing and path separation"
156
276
  }
157
277
  }
158
278
  }
@@ -74,7 +74,16 @@ function prodPrefix(filename) {
74
74
  function testEffectivePrefix(testName) {
75
75
  const bare = testName
76
76
  .replace(/\.integration\.test\.(ts|cjs)$/, '')
77
- .replace(/\.test\.(ts|cjs)$/, '');
77
+ .replace(/\.test\.(ts|cjs)$/, '')
78
+ // #3227: strip a trailing suite/kind qualifier (`.unit`, `.property`,
79
+ // `.security`, `.slow`, `.install`, `.rule`, `.regression`, `.qa`, ...).
80
+ // A production prefix comes from `prodPrefix`, which strips only the file
81
+ // extension, so it never contains a dot — any surviving trailing `.<word>`
82
+ // is a qualifier. Without this, `frontmatter.property` matched no module at
83
+ // all (65 files counted against nothing repo-wide) and `state-contract.unit`
84
+ // matched the SHORTER `state` module through the `prefix + '-'` rule
85
+ // (9 files mis-bucketed).
86
+ .replace(/\.[a-z0-9]+$/i, '');
78
87
  const m = bare.match(/^(?:feat|bug|enh|fix)-\d+(?:-\d+)*-(.+)$/);
79
88
  return m ? m[1] : bare;
80
89
  }
@@ -109,12 +118,25 @@ function buildTestMap(prodPrefixes, allTestFiles) {
109
118
  const map = new Map([...prodPrefixes.keys()].map(p => [p, []]));
110
119
  for (const tf of allTestFiles) {
111
120
  const ep = testEffectivePrefix(path.basename(tf));
121
+ // fs.readdirSync order (and therefore prodPrefixes' Map insertion order,
122
+ // which is built from it in collectProdPrefixes) is NOT stable across
123
+ // platforms/filesystems — e.g. ext4 hash order on Linux CI differs from
124
+ // HFS+/APFS on macOS. When one module's name is a hyphen-extension of
125
+ // another's (e.g. `verify` and `verify-command-grounding`), first-match-
126
+ // wins bucketing is therefore platform-dependent. Scan every candidate
127
+ // and keep the longest (most specific) matching prefix, so the bucket a
128
+ // test file lands in is decided by specificity, never iteration order.
129
+ let bestPrefix = null;
112
130
  for (const prefix of prodPrefixes.keys()) {
113
131
  if (ep === prefix || ep.startsWith(prefix + '-')) {
114
- map.get(prefix).push(tf);
115
- break;
132
+ if (bestPrefix === null || prefix.length > bestPrefix.length) {
133
+ bestPrefix = prefix;
134
+ }
116
135
  }
117
136
  }
137
+ if (bestPrefix !== null) {
138
+ map.get(bestPrefix).push(tf);
139
+ }
118
140
  }
119
141
  return map;
120
142
  }
@@ -8,37 +8,43 @@
8
8
  * Design: .gsd/phase/feat-3409-unreachable-shell-guard-lint/40-design.md
9
9
  * Test matrix: .gsd/phase/feat-3409-unreachable-shell-guard-lint/50-test-matrix.md
10
10
  *
11
- * `gsd-tools.cjs`'s `--pick <field>` extractor coerces a missing/absent
12
- * field to the empty string and exits **0** (probe-confirmed in
13
- * 40-design.md). So in `$(gsd_run query V --pick F 2>/dev/null || echo D)`
14
- * the `|| echo D` arm can fire only on a typo in the verb name — never on
15
- * the field absence it was written to handle. Three shipped shell guards
16
- * silently relied on that unreachable arm (#3365's Walking Skeleton gate,
17
- * `PHASE_REQ_IDS`, and `complete-milestone.md`'s bare `cat <glob>`, all
18
- * fixed alongside this guard — see `tests/unreachable-shell-guard.test.cjs`,
19
- * which this file does not touch).
11
+ * RETIRED — Detector A (`--pick` + `|| echo` on one line), #3884.
12
+ * `gsd-tools.cjs`'s `--pick <field>` extractor used to coerce a missing/
13
+ * absent field to the empty string and exit **0**, which made the `|| echo D`
14
+ * arm in `$(gsd_run query V --pick F 2>/dev/null || echo D)` unreachable on
15
+ * field absence — the exact defect Detector A existed to flag (this file's
16
+ * own prior header quoted the premise verbatim: "the `|| echo D` arm can
17
+ * fire only on a typo in the verb name, never on the field absence it was
18
+ * written to handle"). ADR-3473 §8.4 ("Failure is a value") makes `--pick`
19
+ * exit **non-zero** on an absent field (see
20
+ * `.gsd/phase/feat-3884-failure-is-a-value/40-design.md` rows B6-B14), so
21
+ * that premise is now FALSE: the `|| echo D` arm is reachable, and the shape
22
+ * Detector A forbade is the CORRECT idiom going forward. Keeping Detector A
23
+ * would forbid the fix, so it is removed rather than updated — see this
24
+ * file's Guard ledger entry in 40-design.md ("net: −1 detector, 0 added").
25
+ * `docs/how-to/resolve-unreachable-guard-findings.md` Shape A was updated in
26
+ * the same change (#3884) to say the same thing. The three shell guards this
27
+ * file's Detector A shipped alongside (#3365's Walking Skeleton gate,
28
+ * `PHASE_REQ_IDS`, `complete-milestone.md`'s bare `cat <glob>`) were fixed
29
+ * under #3409 with remedies that never took the now-retired shape (a bare
30
+ * `--pick` with no fallback, a two-line `X=…`/`X="${X:-D}"` split, and an
31
+ * array expansion, respectively) — see
32
+ * `tests/unreachable-shell-guard.test.cjs`, which this file does not touch
33
+ * and which #3884 confirmed still passes unchanged.
20
34
  *
21
- * TWO detectors, each narrow by design (mirroring the sibling drift guards'
22
- * precedent of a small, specific shape rather than a wide heuristic):
23
- *
24
- * Detector A — a line carrying BOTH a `--pick` token AND a `|| echo`
25
- * fallback. `--pick` is the discriminator: a `|| echo` default WITHOUT
26
- * `--pick` (e.g. `config-get k 2>/dev/null || echo "default"`, ~132 of the
27
- * 141 `$(… || echo …)` lines in the prompt layer) genuinely observes a
28
- * nonzero exit code and is left alone — see 40-design.md's Rejected #2
29
- * ("detect on `gsd_run` + `|| echo`" was tried and reverted for exactly
30
- * this false-positive volume).
35
+ * ONE detector remains, unaffected by the above — its mechanism (nullglob
36
+ * success-on-empty) has nothing to do with `--pick`'s exit code:
31
37
  *
32
38
  * Detector B — `cat` or `ls` invoked in COMMAND POSITION with an operand
33
- * containing an unquoted glob metacharacter (`*` or `?`). Both detectors
34
- * are, at bottom, the SAME shape: a fallback/guard arm that a
35
- * success-on-empty case silently defeats. Detector A is `--pick … ||
36
- * echo`; Detector B-ii below is `ls <glob> … || echo` — the identical
37
- * defect, one level down the stack, with `ls`'s own nullglob-driven
38
- * success-on-empty standing in for `--pick`'s absence-coerced-to-''.
39
- * SCOPED to exactly three fired shapes, per a full measurement across the
40
- * four SCAN_DIRS (measured counts recorded in the PR description; 0 sites
41
- * for B-iii today, by design — see KNOWN LIMITS):
39
+ * containing an unquoted glob metacharacter (`*` or `?`). At bottom the
40
+ * same class of bug Detector A used to catch one level up the stack: a
41
+ * fallback/guard arm that a success-on-empty case silently defeats.
42
+ * Detector B-ii below is `ls <glob> … || echo` — with `ls`'s own
43
+ * nullglob-driven success-on-empty standing in for what used to be
44
+ * `--pick`'s absence-coerced-to-''. SCOPED to exactly three fired shapes,
45
+ * per a full measurement across the four SCAN_DIRS (measured counts
46
+ * recorded in the PR description; 0 sites for B-iii today, by design — see
47
+ * KNOWN LIMITS):
42
48
  *
43
49
  * B-i. `cat <glob>` fires UNCONDITIONALLY. This is the stdin-hang
44
50
  * shape (measured rc=137 at 3s under an unmatched glob +
@@ -96,9 +102,6 @@
96
102
  * `npm run lint:ci` runs CodeQL js/redos over this repo, the same
97
103
  * discipline `lint-planning-prompt-drift.cjs` documents in its own header:
98
104
  *
99
- * - PICK_RE / ECHO_FALLBACK_RE carry only a single bounded `\s*`
100
- * quantifier each, over a fixed literal — no nesting, nothing to
101
- * backtrack.
102
105
  * - CAT_LS_COMMAND_RE's alternation is a FIXED, non-overlapping set (a
103
106
  * handful of literal command-position anchors, then a fixed
104
107
  * `(cat|ls)`), with one `[ \t]*` quantifier between the anchor and the
@@ -171,11 +174,6 @@
171
174
  * SCAN_EXT: `.md` only.
172
175
  *
173
176
  * KNOWN, ACCEPTED limits (same tradeoffs the sibling guards document):
174
- * - A cross-line split defeats Detector A (`--pick` on one line, `|| echo`
175
- * on the next) — left to code review, per-line textual scan only.
176
- * - `|| printf` and other non-`echo` fallbacks are not detected by
177
- * Detector A — narrow by design; widening is a one-line change if a
178
- * site ever appears.
179
177
  * - Detector B's command-position anchor set (line start; `;`, `&`, `|`,
180
178
  * `(`; the keywords `if`/`then`/`elif`/`while`/`do`) is what lets
181
179
  * `$(cat …)` / `$(ls …)` — the dominant real invocation idiom in this
@@ -214,16 +212,6 @@ const path = require('node:path');
214
212
  const driftScan = require('./lib/drift-scan.cjs');
215
213
  const { sanitizeForReport, scanTree } = driftScan;
216
214
 
217
- // ─── Detector A — `--pick` + `|| echo` ────────────────────────────────────
218
- //
219
- // `--pick` is the discriminator (see module header); `|| echo` is the
220
- // unreachable fallback arm it silently defeats. Both must be present on the
221
- // SAME line for the shape to be the exact unreachable-arm defect #3409
222
- // fixes — see the module header for why a bare "`gsd_run` + `|| echo`" rule
223
- // was tried and reverted (Rejected #2).
224
- const PICK_RE = /--pick\b/;
225
- const ECHO_FALLBACK_RE = /\|\|\s*echo\b/;
226
-
227
215
  // ─── Detector B — cat <glob> (B-i), ls <glob> … || <real fallback> (B-ii),
228
216
  // or ls <glob> at the head of if/elif/while (B-iii) ────────────────────────
229
217
  //
@@ -378,22 +366,28 @@ const BASELINE_REL_PATH = path.join('scripts', 'baselines', 'unreachable-guard-d
378
366
 
379
367
  // The tracking issue this guard's own baseline entries are owned by, absent
380
368
  // a more specific site owner named at `--update` time. #3409 is this
381
- // guard's own issue: any site it finds that this PR does not convert is a
382
- // "one careless line from the same class" per 40-design.md's Postel's Law
383
- // section, tracked here until the upstream `--pick` contract fix (#3473)
384
- // or a per-site conversion lands.
369
+ // guard's own issue: any Detector B site it finds that this PR does not
370
+ // convert is a "one careless line from the same class" per 40-design.md's
371
+ // Postel's Law section, tracked here until a per-site conversion lands.
372
+ // (Detector A's own entries, if any had ever existed, would have been
373
+ // tracked the same way until the upstream `--pick` contract fix landed —
374
+ // #3884 — but the baseline shipped with zero Detector A entries; see the
375
+ // retirement note at the top of this file.)
385
376
  const RATCHET_OWNER_ISSUE = '#3409';
386
377
 
387
378
  /**
388
- * Pure: scan `text` (one file's content) for Detector A / Detector B
389
- * violations and malformed escape-marker declarations. `relPath` is the
390
- * repo-relative path (native separators or POSIX, either accepted) —
391
- * normalized via `toPosixRel` and attached as `file` on every result.
379
+ * Pure: scan `text` (one file's content) for Detector B violations and
380
+ * malformed escape-marker declarations. `relPath` is the repo-relative path
381
+ * (native separators or POSIX, either accepted) — normalized via
382
+ * `toPosixRel` and attached as `file` on every result.
392
383
  *
393
384
  * Returns `{ violations, malformed }`:
394
- * - `violations`: `[{ file, line, kind: 'A'|'B', found, text }]` — `text`
395
- * is the TRIMMED source line (the baseline key), `found` names the
396
- * discriminating token (`--pick` for A, `cat`/`ls` for B).
385
+ * - `violations`: `[{ file, line, kind: 'B', found, text }]` — `text` is
386
+ * the TRIMMED source line (the baseline key), `found` names the
387
+ * discriminating command (`cat`/`ls`). `kind` is retained as a field
388
+ * (rather than dropped now that only one detector remains) so the
389
+ * baseline JSON shape and the `--json` report shape are unchanged by
390
+ * Detector A's retirement.
397
391
  * - `malformed`: `[{ file, line, text, reason }]` — an ATTEMPTED
398
392
  * `# gsd-scan-ignore:` declaration whose reason names no issue and no
399
393
  * URL. Checked on EVERY line independent of whether that line also
@@ -428,9 +422,6 @@ function findUnreachableGuardDrift(text, relPath) {
428
422
  }
429
423
  if (exempt) continue;
430
424
 
431
- if (PICK_RE.test(line) && ECHO_FALLBACK_RE.test(line)) {
432
- violations.push({ file, line: lineNo, kind: 'A', found: '--pick', text: line.trim() });
433
- }
434
425
  const globInfo = detectGlobOperand(line);
435
426
  if (globInfo) {
436
427
  violations.push({ file, line: lineNo, kind: 'B', found: globInfo.command, text: line.trim() });
@@ -774,8 +765,6 @@ function main() {
774
765
  if (!json) {
775
766
  if (fresh.length > 0) {
776
767
  process.stderr.write('unreachable-guard-drift: NEW unreachable shell-guard shape(s) found in the prompt layer.\n');
777
- process.stderr.write('Detector A (--pick + || echo): the fallback can never fire on field absence — replace with an\n');
778
- process.stderr.write('explicit -z/empty-string test on the resolved value.\n');
779
768
  process.stderr.write('Detector B (cat/ls over a glob operand): under a nullglob set elsewhere in the same shell\n');
780
769
  process.stderr.write('session, an unmatched glob reads from stdin (cat) or lists the cwd (ls) — use an array\n');
781
770
  process.stderr.write('expansion or an existence test instead.\n');
@@ -825,8 +814,6 @@ module.exports = {
825
814
  dedupeViolationsForBaseline,
826
815
  sortEntries,
827
816
  writeBaseline,
828
- PICK_RE,
829
- ECHO_FALLBACK_RE,
830
817
  CAT_LS_COMMAND_RE,
831
818
  HEREDOC_AFTER_COMMAND_RE,
832
819
  EXIT_TESTING_KEYWORDS,