@opengsd/gsd-core 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (551) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +85 -5
  4. package/README.ja-JP.md +3 -3
  5. package/README.ko-KR.md +3 -3
  6. package/README.pt-BR.md +3 -3
  7. package/README.zh-CN.md +3 -3
  8. package/agents/gsd-code-fixer.compact.md +7 -6
  9. package/agents/gsd-code-fixer.md +9 -8
  10. package/agents/gsd-code-reviewer.compact.md +5 -3
  11. package/agents/gsd-code-reviewer.md +8 -6
  12. package/agents/gsd-debug-session-manager.compact.md +17 -2
  13. package/agents/gsd-debug-session-manager.md +17 -2
  14. package/agents/gsd-debugger.md +3 -3
  15. package/agents/gsd-eval-auditor.compact.md +1 -1
  16. package/agents/gsd-eval-auditor.md +1 -1
  17. package/agents/gsd-executor.md +17 -12
  18. package/agents/gsd-intel-updater.compact.md +1 -1
  19. package/agents/gsd-intel-updater.md +1 -1
  20. package/agents/gsd-mempalace-curator.md +2 -2
  21. package/agents/gsd-phase-researcher.md +19 -11
  22. package/agents/gsd-plan-checker.md +15 -9
  23. package/agents/gsd-planner.md +15 -11
  24. package/agents/gsd-project-researcher.compact.md +1 -1
  25. package/agents/gsd-project-researcher.md +1 -1
  26. package/agents/gsd-research-synthesizer.compact.md +1 -1
  27. package/agents/gsd-research-synthesizer.md +1 -1
  28. package/agents/gsd-ui-auditor.compact.md +21 -30
  29. package/agents/gsd-ui-auditor.md +166 -37
  30. package/agents/gsd-ui-researcher.compact.md +1 -1
  31. package/agents/gsd-ui-researcher.md +1 -1
  32. package/agents/gsd-verifier.md +37 -14
  33. package/bin/install.js +764 -287
  34. package/commands/gsd/add-tests.md +6 -1
  35. package/commands/gsd/ai-integration-phase.md +6 -1
  36. package/commands/gsd/audit-fix.md +5 -0
  37. package/commands/gsd/audit-milestone.md +6 -1
  38. package/commands/gsd/autonomous.md +7 -2
  39. package/commands/gsd/capture.md +9 -5
  40. package/commands/gsd/code-review.md +7 -2
  41. package/commands/gsd/complete-milestone.md +4 -0
  42. package/commands/gsd/config.md +7 -3
  43. package/commands/gsd/debug.md +11 -7
  44. package/commands/gsd/discuss-phase.md +7 -3
  45. package/commands/gsd/docs-update.md +12 -7
  46. package/commands/gsd/eval-review.md +6 -1
  47. package/commands/gsd/execute-phase.md +12 -7
  48. package/commands/gsd/extract-learnings.md +5 -0
  49. package/commands/gsd/fast.md +4 -0
  50. package/commands/gsd/forensics.md +5 -1
  51. package/commands/gsd/graphify.md +10 -6
  52. package/commands/gsd/health.md +5 -0
  53. package/commands/gsd/help.md +7 -2
  54. package/commands/gsd/import.md +7 -3
  55. package/commands/gsd/inbox.md +5 -0
  56. package/commands/gsd/ingest-docs.md +5 -1
  57. package/commands/gsd/manager.md +6 -1
  58. package/commands/gsd/map-codebase.md +7 -3
  59. package/commands/gsd/mempalace-capture.md +12 -4
  60. package/commands/gsd/mempalace-recall.md +5 -1
  61. package/commands/gsd/milestone-summary.md +5 -1
  62. package/commands/gsd/mvp-phase.md +8 -3
  63. package/commands/gsd/new-milestone.md +6 -1
  64. package/commands/gsd/new-project.md +5 -0
  65. package/commands/gsd/next.md +6 -1
  66. package/commands/gsd/ns-context.md +4 -0
  67. package/commands/gsd/ns-ideate.md +4 -0
  68. package/commands/gsd/ns-manage.md +4 -0
  69. package/commands/gsd/ns-project.md +4 -0
  70. package/commands/gsd/ns-review.md +4 -0
  71. package/commands/gsd/ns-workflow.md +4 -0
  72. package/commands/gsd/onboard.md +6 -1
  73. package/commands/gsd/pause-work.md +5 -1
  74. package/commands/gsd/phase.md +8 -4
  75. package/commands/gsd/plan-phase.md +6 -1
  76. package/commands/gsd/plan-review-convergence.md +11 -7
  77. package/commands/gsd/pr-branch.md +4 -0
  78. package/commands/gsd/profile-user.md +5 -1
  79. package/commands/gsd/progress.md +7 -2
  80. package/commands/gsd/quick-batch.md +21 -9
  81. package/commands/gsd/quick.md +12 -7
  82. package/commands/gsd/review.md +7 -4
  83. package/commands/gsd/secure-phase.md +6 -1
  84. package/commands/gsd/ship.md +5 -0
  85. package/commands/gsd/sketch.md +7 -2
  86. package/commands/gsd/spec-phase.md +5 -1
  87. package/commands/gsd/spike.md +8 -3
  88. package/commands/gsd/surface.md +5 -1
  89. package/commands/gsd/thread.md +4 -0
  90. package/commands/gsd/ui-phase.md +6 -1
  91. package/commands/gsd/ui-review.md +6 -1
  92. package/commands/gsd/ultraplan-phase.md +5 -1
  93. package/commands/gsd/undo.md +5 -1
  94. package/commands/gsd/update.md +6 -2
  95. package/commands/gsd/validate-phase.md +6 -1
  96. package/commands/gsd/verify-work.md +6 -1
  97. package/commands/gsd/workspace.md +7 -3
  98. package/gsd-core/bin/gsd-tools.cjs +477 -78
  99. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  100. package/gsd-core/bin/lib/adr-parser.cjs +3 -1
  101. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  102. package/gsd-core/bin/lib/audit.cjs +144 -42
  103. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  104. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  105. package/gsd-core/bin/lib/capability-registry.cjs +197 -222
  106. package/gsd-core/bin/lib/capability-validator.cjs +16 -1
  107. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  108. package/gsd-core/bin/lib/check-command-router.cjs +164 -1625
  109. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  110. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  111. package/gsd-core/bin/lib/codex-agent-toml.cjs +32 -33
  112. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  113. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  114. package/gsd-core/bin/lib/commands.cjs +343 -207
  115. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  116. package/gsd-core/bin/lib/config-loader.cjs +65 -4
  117. package/gsd-core/bin/lib/config.cjs +76 -19
  118. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  119. package/gsd-core/bin/lib/coverage.cjs +4 -8
  120. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  121. package/gsd-core/bin/lib/decisions.cjs +30 -14
  122. package/gsd-core/bin/lib/drift.cjs +177 -42
  123. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  124. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  125. package/gsd-core/bin/lib/frontmatter.cjs +426 -234
  126. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  127. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  128. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  129. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  130. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  131. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  132. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  133. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  134. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  135. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  136. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  137. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  138. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  139. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  140. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  141. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  142. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  143. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  144. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  145. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  146. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  147. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  148. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  149. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  150. package/gsd-core/bin/lib/graphify.cjs +10 -2
  151. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  152. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  153. package/gsd-core/bin/lib/host-runtime-detection.cjs +9 -0
  154. package/gsd-core/bin/lib/init.cjs +364 -132
  155. package/gsd-core/bin/lib/install-engine.cjs +30 -33
  156. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  157. package/gsd-core/bin/lib/installer-migrations.cjs +8 -1
  158. package/gsd-core/bin/lib/io.cjs +122 -3
  159. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  160. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  161. package/gsd-core/bin/lib/milestone.cjs +37 -6
  162. package/gsd-core/bin/lib/model-resolver.cjs +171 -62
  163. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  164. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  165. package/gsd-core/bin/lib/pattern.cjs +10 -0
  166. package/gsd-core/bin/lib/phase-command-router.cjs +20 -5
  167. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  168. package/gsd-core/bin/lib/phase-id-card.cjs +32 -0
  169. package/gsd-core/bin/lib/phase-id-display.cjs +78 -0
  170. package/gsd-core/bin/lib/phase-id.cjs +110 -8
  171. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  172. package/gsd-core/bin/lib/phase-locator.cjs +29 -10
  173. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  174. package/gsd-core/bin/lib/phase.cjs +489 -88
  175. package/gsd-core/bin/lib/plan-document.cjs +142 -20
  176. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  177. package/gsd-core/bin/lib/planning-document.cjs +692 -0
  178. package/gsd-core/bin/lib/planning-inspect.cjs +60 -9
  179. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  180. package/gsd-core/bin/lib/planning-workspace.cjs +83 -55
  181. package/gsd-core/bin/lib/pr-branch-patterns.cjs +57 -0
  182. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  183. package/gsd-core/bin/lib/probe-core.cjs +7 -1
  184. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  185. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  186. package/gsd-core/bin/lib/project-root.cjs +41 -2
  187. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  188. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  189. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  190. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  191. package/gsd-core/bin/lib/review-lane-descriptor.cjs +10 -30
  192. package/gsd-core/bin/lib/review-reviewer-selection.cjs +2 -2
  193. package/gsd-core/bin/lib/roadmap-command-router.cjs +25 -19
  194. package/gsd-core/bin/lib/roadmap-parser.cjs +242 -15
  195. package/gsd-core/bin/lib/roadmap-upgrade.cjs +1653 -65
  196. package/gsd-core/bin/lib/roadmap.cjs +405 -88
  197. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +373 -187
  198. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +5 -2
  199. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  200. package/gsd-core/bin/lib/runtime-homes.cjs +14 -7
  201. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +522 -624
  202. package/gsd-core/bin/lib/runtime-name-policy.cjs +246 -21
  203. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  204. package/gsd-core/bin/lib/shell-command-projection.cjs +47 -8
  205. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  206. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  207. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  208. package/gsd-core/bin/lib/state-document.cjs +100 -22
  209. package/gsd-core/bin/lib/state-transition.cjs +39 -2
  210. package/gsd-core/bin/lib/state.cjs +256 -105
  211. package/gsd-core/bin/lib/surface.cjs +19 -2
  212. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -79
  213. package/gsd-core/bin/lib/uat-predicate.cjs +359 -38
  214. package/gsd-core/bin/lib/uat.cjs +432 -7
  215. package/gsd-core/bin/lib/ui-consideration-probe.cjs +15 -2
  216. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +167 -40
  217. package/gsd-core/bin/lib/undo-commit-selection.cjs +131 -0
  218. package/gsd-core/bin/lib/vendor/README.md +31 -9
  219. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  220. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  221. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  222. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  223. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  224. package/gsd-core/bin/lib/verification.cjs +1378 -274
  225. package/gsd-core/bin/lib/verify-command-grounding.cjs +46 -2
  226. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  227. package/gsd-core/bin/lib/verify.cjs +357 -531
  228. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  229. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  230. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  231. package/gsd-core/bin/lib/workstream.cjs +11 -2
  232. package/gsd-core/bin/lib/worktree-base-ref.cjs +482 -73
  233. package/gsd-core/bin/lib/worktree-safety.cjs +784 -51
  234. package/gsd-core/bin/shared/config-defaults.manifest.json +8 -0
  235. package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
  236. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  237. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  238. package/gsd-core/references/checkpoints.md +5 -3
  239. package/gsd-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +28 -3
  240. package/gsd-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +37 -4
  241. package/gsd-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +28 -3
  242. package/gsd-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +28 -3
  243. package/gsd-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +37 -4
  244. package/gsd-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +37 -4
  245. package/gsd-core/references/edge-probe.md +195 -21
  246. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  247. package/gsd-core/references/execute-phase-between-wave-reset.md +10 -6
  248. package/gsd-core/references/execute-phase-response-language.md +1 -1
  249. package/gsd-core/references/execute-phase-wave-guard.md +22 -11
  250. package/gsd-core/references/gsd-run-resolver.md +1 -1
  251. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  252. package/gsd-core/references/model-profiles.md +1 -1
  253. package/gsd-core/references/offer-next.md +1 -1
  254. package/gsd-core/references/phase-argument-parsing.md +9 -7
  255. package/gsd-core/references/phase-id-convention.md +28 -0
  256. package/gsd-core/references/planner-gap-closure.md +2 -0
  257. package/gsd-core/references/planner-load-graph-context.md +24 -13
  258. package/gsd-core/references/planner-verify-command-grounding.md +14 -0
  259. package/gsd-core/references/planning-config.md +12 -3
  260. package/gsd-core/references/spidr-splitting.md +1 -1
  261. package/gsd-core/references/tdd.md +37 -8
  262. package/gsd-core/references/ui-consideration-probe.md +10 -5
  263. package/gsd-core/references/verifier-phase-gates.md +5 -2
  264. package/gsd-core/references/verify-command-path-resolvability.md +10 -2
  265. package/gsd-core/references/verify-mvp-mode.md +2 -2
  266. package/gsd-core/references/workstream-flag.md +33 -3
  267. package/gsd-core/references/worktree-path-safety.md +321 -0
  268. package/gsd-core/templates/README.md +1 -1
  269. package/gsd-core/templates/UAT.md +17 -1
  270. package/gsd-core/templates/config.json +2 -11
  271. package/gsd-core/templates/verification-report.md +1 -1
  272. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  273. package/gsd-core/workflows/add-backlog.md +1 -1
  274. package/gsd-core/workflows/add-phase.md +8 -7
  275. package/gsd-core/workflows/add-tests.md +4 -3
  276. package/gsd-core/workflows/add-todo.md +6 -5
  277. package/gsd-core/workflows/ai-integration-phase.md +13 -4
  278. package/gsd-core/workflows/audit-fix.md +1 -1
  279. package/gsd-core/workflows/audit-milestone.md +4 -3
  280. package/gsd-core/workflows/audit-uat.md +1 -1
  281. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +9 -18
  282. package/gsd-core/workflows/autonomous.md +43 -23
  283. package/gsd-core/workflows/check-todos.md +7 -6
  284. package/gsd-core/workflows/cleanup.md +2 -2
  285. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +4 -3
  286. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  287. package/gsd-core/workflows/code-review-fix.md +112 -25
  288. package/gsd-core/workflows/code-review.md +146 -135
  289. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  290. package/gsd-core/workflows/complete-milestone.md +13 -8
  291. package/gsd-core/workflows/debug.md +32 -7
  292. package/gsd-core/workflows/diagnose-issues.md +3 -2
  293. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  294. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  295. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  296. package/gsd-core/workflows/discuss-phase.md +4 -3
  297. package/gsd-core/workflows/do.md +2 -2
  298. package/gsd-core/workflows/docs-update.md +6 -5
  299. package/gsd-core/workflows/edit-phase.md +4 -3
  300. package/gsd-core/workflows/eval-review.md +14 -5
  301. package/gsd-core/workflows/execute-phase/detail/elaboration.md +2 -2
  302. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +1019 -0
  303. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  304. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  305. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +37 -3
  306. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  307. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  308. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  309. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  310. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +46 -9
  311. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  312. package/gsd-core/workflows/execute-phase/steps/ready-wave-gate.md +37 -0
  313. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  314. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  315. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  316. package/gsd-core/workflows/execute-phase/steps/threat-id-gate.md +28 -0
  317. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  318. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  319. package/gsd-core/workflows/execute-phase/steps/worktree-base-check.md +25 -0
  320. package/gsd-core/workflows/execute-phase.md +96 -178
  321. package/gsd-core/workflows/execute-plan.md +18 -23
  322. package/gsd-core/workflows/explore.md +4 -4
  323. package/gsd-core/workflows/extract-learnings.md +4 -2
  324. package/gsd-core/workflows/fast.md +1 -1
  325. package/gsd-core/workflows/forensics.md +1 -1
  326. package/gsd-core/workflows/graduation.md +1 -1
  327. package/gsd-core/workflows/health.md +3 -2
  328. package/gsd-core/workflows/help/modes/full.compact.md +3 -3
  329. package/gsd-core/workflows/help/modes/full.md +5 -5
  330. package/gsd-core/workflows/help/modes/topic.md +15 -5
  331. package/gsd-core/workflows/import.md +4 -3
  332. package/gsd-core/workflows/inbox.md +2 -2
  333. package/gsd-core/workflows/ingest-docs.md +3 -3
  334. package/gsd-core/workflows/insert-phase.md +4 -3
  335. package/gsd-core/workflows/list-seeds.md +1 -1
  336. package/gsd-core/workflows/list-workspaces.md +1 -1
  337. package/gsd-core/workflows/manager.md +6 -4
  338. package/gsd-core/workflows/map-codebase.md +5 -4
  339. package/gsd-core/workflows/milestone-summary.md +3 -2
  340. package/gsd-core/workflows/mvp-phase.md +14 -14
  341. package/gsd-core/workflows/new-milestone.md +11 -11
  342. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +3 -3
  343. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +1 -1
  344. package/gsd-core/workflows/new-project.md +7 -7
  345. package/gsd-core/workflows/new-workspace.md +2 -2
  346. package/gsd-core/workflows/next.md +1 -1
  347. package/gsd-core/workflows/note.md +1 -1
  348. package/gsd-core/workflows/onboard.md +1 -1
  349. package/gsd-core/workflows/pause-work.md +2 -2
  350. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  351. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +17 -5
  352. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  353. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  354. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +23 -5
  355. package/gsd-core/workflows/plan-phase.md +50 -24
  356. package/gsd-core/workflows/plan-review-convergence.md +21 -5
  357. package/gsd-core/workflows/plant-seed.md +62 -20
  358. package/gsd-core/workflows/pr-branch.md +113 -13
  359. package/gsd-core/workflows/profile-user.md +2 -2
  360. package/gsd-core/workflows/progress.md +19 -49
  361. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +27 -0
  362. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  363. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  364. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  365. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  366. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  367. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  368. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  369. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  370. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  371. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  372. package/gsd-core/workflows/quick-batch.md +15 -10
  373. package/gsd-core/workflows/quick.md +62 -39
  374. package/gsd-core/workflows/reapply-patches.md +9 -3
  375. package/gsd-core/workflows/remove-phase.md +3 -2
  376. package/gsd-core/workflows/remove-workspace.md +2 -2
  377. package/gsd-core/workflows/resume-project.md +3 -2
  378. package/gsd-core/workflows/review.md +33 -17
  379. package/gsd-core/workflows/scan.md +3 -2
  380. package/gsd-core/workflows/secure-phase.md +13 -13
  381. package/gsd-core/workflows/settings-advanced.md +30 -10
  382. package/gsd-core/workflows/settings-integrations.md +2 -3
  383. package/gsd-core/workflows/settings.md +4 -4
  384. package/gsd-core/workflows/ship.md +14 -13
  385. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  386. package/gsd-core/workflows/sketch.md +1 -1
  387. package/gsd-core/workflows/smart-entry.md +2 -2
  388. package/gsd-core/workflows/spec-phase.md +15 -5
  389. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  390. package/gsd-core/workflows/spike.md +1 -1
  391. package/gsd-core/workflows/stats.md +1 -1
  392. package/gsd-core/workflows/sync-skills.md +5 -5
  393. package/gsd-core/workflows/thread.md +2 -2
  394. package/gsd-core/workflows/transition.md +13 -23
  395. package/gsd-core/workflows/ui-phase.md +48 -11
  396. package/gsd-core/workflows/ui-review.md +21 -6
  397. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  398. package/gsd-core/workflows/undo.md +339 -20
  399. package/gsd-core/workflows/update.md +7 -7
  400. package/gsd-core/workflows/validate-phase.md +12 -13
  401. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  402. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  403. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  404. package/gsd-core/workflows/verify-work.md +129 -55
  405. package/hooks/dist/gsd-agent-isolation-guard.js +32 -0
  406. package/hooks/dist/gsd-check-update-worker.js +8 -0
  407. package/hooks/dist/gsd-check-update.js +8 -0
  408. package/hooks/dist/gsd-context-monitor.js +31 -8
  409. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  410. package/hooks/dist/gsd-secret-read-guard.js +161 -4
  411. package/hooks/dist/gsd-statusline.js +85 -20
  412. package/hooks/dist/gsd-update-banner.js +8 -0
  413. package/hooks/dist/gsd-validate-commit.sh +63 -4
  414. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  415. package/hooks/dist/gsd-workflow-guard.js +5 -4
  416. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  417. package/hooks/dist/lib/cli-exit.js +12 -0
  418. package/hooks/dist/lib/git-probe.js +17 -1
  419. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  420. package/hooks/gsd-agent-isolation-guard.js +32 -0
  421. package/hooks/gsd-check-update-worker.js +8 -0
  422. package/hooks/gsd-check-update.js +8 -0
  423. package/hooks/gsd-context-monitor.js +31 -8
  424. package/hooks/gsd-cursor-subagent-start.js +8 -0
  425. package/hooks/gsd-secret-read-guard.js +161 -4
  426. package/hooks/gsd-statusline.js +85 -20
  427. package/hooks/gsd-update-banner.js +8 -0
  428. package/hooks/gsd-validate-commit.sh +63 -4
  429. package/hooks/gsd-windsurf-pre-write.js +11 -2
  430. package/hooks/gsd-workflow-guard.js +5 -4
  431. package/hooks/gsd-worktree-path-guard.js +6 -2
  432. package/hooks/hooks.json +5 -5
  433. package/hooks/lib/cli-exit.js +12 -0
  434. package/hooks/lib/git-probe.js +17 -1
  435. package/hooks/lib/isolation-sentinel.js +2 -2
  436. package/package.json +22 -4
  437. package/scripts/build-hooks.js +15 -6
  438. package/scripts/changeset/parse.cjs +52 -4
  439. package/scripts/check-contract-drift.cjs +127 -11
  440. package/scripts/ci-timeout-report.cjs +770 -4
  441. package/scripts/command-contract-helpers.cjs +15 -8
  442. package/scripts/docs-guard-registry.cjs +34 -0
  443. package/scripts/gen-features.cjs +13 -8
  444. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  445. package/scripts/gen-loop-host-contract.cjs +79 -1
  446. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  447. package/scripts/gen-plugin-skills.cjs +87 -1
  448. package/scripts/gen-research-agents.cjs +24 -31
  449. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  450. package/scripts/gen-test-timings.cjs +32 -7
  451. package/scripts/lib/cli-exit.cjs +12 -0
  452. package/scripts/lib/macos-conformance-tier.generated.cjs +34 -2
  453. package/scripts/lib/ndjson-reporter.cjs +31 -5
  454. package/scripts/lib/platform-conformance-tier.generated.cjs +45 -5
  455. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  456. package/scripts/lib/vendor-bundle.cjs +59 -0
  457. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  458. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  459. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  460. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  461. package/scripts/lint-descriptions.cjs +7 -3
  462. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +38 -1
  463. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  464. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  465. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  466. package/scripts/lint-phase-arg-assignment.cjs +257 -0
  467. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  468. package/scripts/lint-phase-id-drift.cjs +319 -5
  469. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  470. package/scripts/lint-pr-branch-pattern-drift.cjs +148 -0
  471. package/scripts/lint-response-language-coverage.cjs +3 -0
  472. package/scripts/lint-retired-runtime-name.cjs +619 -0
  473. package/scripts/lint-skill-deps.cjs +7 -3
  474. package/scripts/lint-state-write-path-drift.cjs +93 -0
  475. package/scripts/lint-test-file-count.allowlist.json +38 -9
  476. package/scripts/lint-test-file-count.cjs +34 -1
  477. package/scripts/lint-vendored-deps.cjs +41 -5
  478. package/scripts/lint-workflow-shellcheck-baseline.json +25 -10
  479. package/scripts/mutation-matrix.cjs +50 -5
  480. package/scripts/prompt-injection-scan.sh +4 -0
  481. package/scripts/release-tarball-smoke.cjs +194 -1
  482. package/scripts/require-issue-link-policy.cjs +6 -2
  483. package/scripts/sync-runtime-launcher.cjs +184 -2
  484. package/scripts/verify-npm-publish.cjs +76 -20
  485. package/skills/gsd-add-tests/SKILL.md +6 -1
  486. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  487. package/skills/gsd-audit-fix/SKILL.md +5 -0
  488. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  489. package/skills/gsd-autonomous/SKILL.md +7 -2
  490. package/skills/gsd-capture/SKILL.md +9 -5
  491. package/skills/gsd-code-review/SKILL.md +7 -2
  492. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  493. package/skills/gsd-config/SKILL.md +8 -4
  494. package/skills/gsd-debug/SKILL.md +11 -7
  495. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  496. package/skills/gsd-docs-update/SKILL.md +12 -7
  497. package/skills/gsd-eval-review/SKILL.md +6 -1
  498. package/skills/gsd-execute-phase/SKILL.md +12 -7
  499. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  500. package/skills/gsd-fast/SKILL.md +4 -0
  501. package/skills/gsd-forensics/SKILL.md +5 -1
  502. package/skills/gsd-graphify/SKILL.md +10 -6
  503. package/skills/gsd-health/SKILL.md +5 -0
  504. package/skills/gsd-help/SKILL.md +7 -2
  505. package/skills/gsd-import/SKILL.md +7 -3
  506. package/skills/gsd-inbox/SKILL.md +5 -0
  507. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  508. package/skills/gsd-manager/SKILL.md +6 -1
  509. package/skills/gsd-map-codebase/SKILL.md +7 -3
  510. package/skills/gsd-mempalace-capture/SKILL.md +12 -4
  511. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  512. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  513. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  514. package/skills/gsd-new-milestone/SKILL.md +6 -1
  515. package/skills/gsd-new-project/SKILL.md +5 -0
  516. package/skills/gsd-next/SKILL.md +6 -1
  517. package/skills/gsd-ns-context/SKILL.md +4 -0
  518. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  519. package/skills/gsd-ns-manage/SKILL.md +4 -0
  520. package/skills/gsd-ns-project/SKILL.md +4 -0
  521. package/skills/gsd-ns-review/SKILL.md +4 -0
  522. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  523. package/skills/gsd-onboard/SKILL.md +6 -1
  524. package/skills/gsd-pause-work/SKILL.md +5 -1
  525. package/skills/gsd-phase/SKILL.md +8 -4
  526. package/skills/gsd-plan-phase/SKILL.md +6 -1
  527. package/skills/gsd-plan-review-convergence/SKILL.md +10 -6
  528. package/skills/gsd-pr-branch/SKILL.md +4 -0
  529. package/skills/gsd-profile-user/SKILL.md +5 -1
  530. package/skills/gsd-progress/SKILL.md +7 -2
  531. package/skills/gsd-quick/SKILL.md +16 -10
  532. package/skills/gsd-quick-batch/SKILL.md +21 -9
  533. package/skills/gsd-review/SKILL.md +7 -4
  534. package/skills/gsd-review-backlog/SKILL.md +3 -2
  535. package/skills/gsd-secure-phase/SKILL.md +6 -1
  536. package/skills/gsd-ship/SKILL.md +5 -0
  537. package/skills/gsd-sketch/SKILL.md +7 -2
  538. package/skills/gsd-spec-phase/SKILL.md +5 -1
  539. package/skills/gsd-spike/SKILL.md +8 -3
  540. package/skills/gsd-surface/SKILL.md +5 -1
  541. package/skills/gsd-thread/SKILL.md +4 -0
  542. package/skills/gsd-ui-phase/SKILL.md +6 -1
  543. package/skills/gsd-ui-review/SKILL.md +6 -1
  544. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  545. package/skills/gsd-undo/SKILL.md +5 -1
  546. package/skills/gsd-update/SKILL.md +6 -2
  547. package/skills/gsd-validate-phase/SKILL.md +6 -1
  548. package/skills/gsd-verify-work/SKILL.md +6 -1
  549. package/skills/gsd-workspace/SKILL.md +7 -3
  550. package/skills/gsd-workstreams/SKILL.md +6 -6
  551. package/vscode/package.json +1 -1
@@ -7,7 +7,7 @@
7
7
  * word boundary, so a phase section naming the repo `dashboard-financeiro` matches
8
8
  * the token `dashboard` exactly like the real UI compound `micro-frontend` does.
9
9
  * That boundary rule is intentional (#3718) and must not be weakened — instead,
10
- * the plan gate (`computeUiPlanGate` in check-command-router.cjs) corroborates the
10
+ * the plan gate (`computeUiPlanGate` in gate-ui-plan.cjs) corroborates the
11
11
  * token match against the static repo tree before blocking.
12
12
  *
13
13
  * This mirrors what the sibling post-wave gate (`computeUiSafetyGate`) already
@@ -19,23 +19,58 @@
19
19
  * of file layout;
20
20
  * (b) any `*.tsx` / `*.jsx` / `*.vue` / `*.svelte` file in the tree — the
21
21
  * component-framework subset of `UI_FILE_EXTENSIONS_RE`
22
- * (check-command-router.cjs). The weaker members of that list (css, scss,
22
+ * (gate-ui-safety.cjs). The weaker members of that list (css, scss,
23
23
  * html, ...) are deliberately NOT static evidence: docs sites and
24
24
  * markdown/bash/config repos routinely carry stray `.html`/`.css`, which
25
25
  * is precisely the false-positive class #3312 reports.
26
+ * (c) any `*.xaml` file, or a `*.swift` / `*.kt` / `*.dart` file whose
27
+ * content carries its ecosystem's UI-framework import marker
28
+ * (`import SwiftUI` / `import UIKit`, `androidx.compose`,
29
+ * `package:flutter`) (#4658). Native UI projects (SwiftUI, Jetpack
30
+ * Compose, Flutter, .NET MAUI) carry neither (a) nor (b), which made the
31
+ * gate structurally unreachable for them. Source files match on the
32
+ * IMPORT, not the extension alone — the same unambiguity bar that
33
+ * justifies (b)'s subset and excludes (css, scss, html): a non-UI Swift
34
+ * package (a CLI, a server) imports Foundation, not SwiftUI, and must
35
+ * stay silent. `.xaml` is extension-alone for the same reason `.tsx` is —
36
+ * the extension itself is unambiguous. Marker matching is case-sensitive
37
+ * (imports are case-sensitive in all four ecosystems); extension
38
+ * matching is case-insensitive, mirroring `UI_COMPONENT_FILE_RE`.
26
39
  *
27
- * All I/O failures degrade to `false` (no evidence) — never throw.
40
+ * #5170 (ADR-5057 §4): the detector reads typed evidence. An affirmative finding is
41
+ * `found`; a walk that completed without one is `none`; a `package.json` that exists but cannot be
42
+ * read or parsed, a directory that cannot be listed or a native source file that cannot be opened
43
+ * is `unreadable` WHEN no affirmative evidence was found — the gate that consumes this must not
44
+ * certify "no frontend" over a tree it could not look at. Never throws.
28
45
  */
29
46
  var __importDefault = (this && this.__importDefault) || function (mod) {
30
47
  return (mod && mod.__esModule) ? mod : { "default": mod };
31
48
  };
32
49
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.UI_COMPONENT_FILE_RE = void 0;
50
+ exports.NATIVE_UI_CONTENT_MARKERS = exports.NATIVE_UI_XAML_RE = exports.NATIVE_UI_SOURCE_RE = exports.UI_COMPONENT_FILE_RE = void 0;
51
+ exports.readStaticFrontendEvidence = readStaticFrontendEvidence;
34
52
  exports.hasStaticFrontendEvidence = hasStaticFrontendEvidence;
35
53
  const node_fs_1 = __importDefault(require("node:fs"));
36
54
  const node_path_1 = __importDefault(require("node:path"));
55
+ const gate_evidence_cjs_1 = require("./gate-evidence.cjs");
37
56
  /** Component-framework file extensions — the static-evidence subset of UI_FILE_EXTENSIONS_RE. */
38
57
  exports.UI_COMPONENT_FILE_RE = /\.(tsx|jsx|vue|svelte)$/i;
58
+ /** Native UI source files whose CONTENT is scanned for an import marker (#4658). */
59
+ exports.NATIVE_UI_SOURCE_RE = /\.(swift|kt|dart)$/i;
60
+ /** Native UI files that are evidence by extension alone — `.xaml`, the `.tsx` analogue. */
61
+ exports.NATIVE_UI_XAML_RE = /\.xaml$/i;
62
+ /**
63
+ * Per-extension UI-framework import markers for `NATIVE_UI_SOURCE_RE` files
64
+ * (#4658). Every marker embeds its ecosystem's import keyword, so a bare
65
+ * framework-name mention in prose or a comment is not evidence; the Dart
66
+ * marker carries both legal quote styles. Case-sensitive: imports are
67
+ * case-sensitive in Swift, Kotlin and Dart.
68
+ */
69
+ exports.NATIVE_UI_CONTENT_MARKERS = {
70
+ '.swift': ['import SwiftUI', 'import UIKit'],
71
+ '.kt': ['import androidx.compose'],
72
+ '.dart': ["import 'package:flutter", 'import "package:flutter'],
73
+ };
39
74
  /**
40
75
  * UI-framework package.json dependencies (dependencies OR devDependencies).
41
76
  * Component frameworks/renderers only — deliberately excludes meta tooling
@@ -82,23 +117,23 @@ const SKIP_DIRS = new Set([
82
117
  ]);
83
118
  /** Walk safety cap — beyond this the tree is treated as scanned (evidence decided by then). */
84
119
  const MAX_WALK_ENTRIES = 10_000;
85
- function packageJsonHasUiFramework(projectDir) {
86
- let raw;
87
- try {
88
- raw = node_fs_1.default.readFileSync(node_path_1.default.join(projectDir, 'package.json'), 'utf8');
89
- }
90
- catch {
91
- return false; // no/unreadable package.json → no evidence from this signal
92
- }
120
+ /** The first read failure of the package.json signal: `unreadable`, or `none` (absent), or `found`. */
121
+ function packageJsonEvidence(projectDir) {
122
+ const read = (0, gate_evidence_cjs_1.readTextEvidence)(node_path_1.default.join(projectDir, 'package.json'));
123
+ if (read.kind === 'none')
124
+ return (0, gate_evidence_cjs_1.evidenceNone)();
125
+ if (read.kind === 'unreadable')
126
+ return (0, gate_evidence_cjs_1.evidenceUnreadable)(read.reason, read.span);
93
127
  let parsed;
94
128
  try {
95
- parsed = JSON.parse(raw);
129
+ parsed = JSON.parse(read.value);
96
130
  }
97
- catch {
98
- return false; // malformed package.json → no evidence from this signal
131
+ catch (err) {
132
+ // A package.json that exists but is not valid JSON could not be read: unreadable, not "no deps".
133
+ return (0, gate_evidence_cjs_1.evidenceFromError)(err, 'package.json');
99
134
  }
100
135
  if (parsed === null || typeof parsed !== 'object')
101
- return false;
136
+ return (0, gate_evidence_cjs_1.evidenceNone)();
102
137
  const pkg = parsed;
103
138
  for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) {
104
139
  const deps = pkg[field];
@@ -106,52 +141,144 @@ function packageJsonHasUiFramework(projectDir) {
106
141
  continue;
107
142
  for (const name of Object.keys(deps)) {
108
143
  if (UI_FRAMEWORK_DEPS.has(name))
109
- return true;
144
+ return (0, gate_evidence_cjs_1.evidenceFound)(true);
110
145
  }
111
146
  }
112
- return false;
147
+ return (0, gate_evidence_cjs_1.evidenceNone)();
113
148
  }
114
- function treeHasComponentFile(projectDir) {
115
- // Iterative BFS — bounded by MAX_WALK_ENTRIES so a pathological tree cannot
116
- // stall the gate. Symlinks are never followed (withFileTypes + isDirectory).
149
+ /**
150
+ * Shared bounded BFS over the project tree — the single home of the walk
151
+ * semantics both evidence walks depend on: SKIP_DIRS pruning, the
152
+ * MAX_WALK_ENTRIES entry cap (cap-hit → not found: the tree is treated as
153
+ * scanned and evidence stays undecided), symlinks never followed
154
+ * (withFileTypes Dirents). `visit` is called for every regular file with its
155
+ * name, full path and a `note` for a read failure it met; returning `true`
156
+ * stops the walk with `found`. A directory that cannot be listed is NOT
157
+ * silently skipped: it is noted, the walk goes on, and the caller learns that
158
+ * part of the tree was never seen (an absent directory is just skipped).
159
+ */
160
+ function walkProjectFiles(projectDir, visit) {
161
+ let unreadable = null;
162
+ const note = (reason) => {
163
+ unreadable = unreadable ?? reason;
164
+ };
117
165
  const queue = [projectDir];
118
166
  let visited = 0;
119
167
  while (queue.length > 0 && visited < MAX_WALK_ENTRIES) {
120
168
  const dir = queue.shift();
121
- let entries;
122
- try {
123
- entries = node_fs_1.default.readdirSync(dir, { withFileTypes: true });
124
- }
125
- catch {
126
- continue; // unreadable directory → skip it
169
+ const listing = (0, gate_evidence_cjs_1.readDirEntriesEvidence)(dir);
170
+ if (listing.kind === 'unreadable') {
171
+ note(listing.reason);
172
+ continue;
127
173
  }
128
- for (const entry of entries) {
174
+ if (listing.kind === 'none')
175
+ continue; // vanished since it was queued: nothing to see
176
+ for (const entry of listing.value) {
129
177
  visited++;
130
178
  if (visited >= MAX_WALK_ENTRIES)
131
- return false;
179
+ return { found: false, unreadable };
132
180
  if (entry.isDirectory()) {
133
181
  if (!SKIP_DIRS.has(entry.name))
134
182
  queue.push(node_path_1.default.join(dir, entry.name));
135
183
  }
136
- else if (entry.isFile() && exports.UI_COMPONENT_FILE_RE.test(entry.name)) {
137
- return true;
184
+ else if (entry.isFile() && visit(entry.name, node_path_1.default.join(dir, entry.name), note)) {
185
+ return { found: true, unreadable };
138
186
  }
139
187
  }
140
188
  }
141
- return false;
189
+ return { found: false, unreadable };
190
+ }
191
+ function treeComponentFileEvidence(projectDir) {
192
+ return walkProjectFiles(projectDir, (name) => exports.UI_COMPONENT_FILE_RE.test(name));
193
+ }
194
+ /**
195
+ * Read at most the first 64 KiB of `file` as evidence (#4658). Import sections live at
196
+ * the top of a source file, so a bounded prefix read keeps the gate's plan-time cost
197
+ * profile without reading generated monsters in full.
198
+ */
199
+ function readPrefixEvidence(file) {
200
+ let fd;
201
+ try {
202
+ fd = node_fs_1.default.openSync(file, 'r');
203
+ }
204
+ catch (err) {
205
+ return (0, gate_evidence_cjs_1.evidenceFromError)(err, file);
206
+ }
207
+ try {
208
+ const bytes = Buffer.alloc(64 * 1024);
209
+ const read = node_fs_1.default.readSync(fd, bytes, 0, bytes.length, 0);
210
+ return (0, gate_evidence_cjs_1.evidenceFound)(bytes.toString('utf8', 0, read));
211
+ }
212
+ catch (err) {
213
+ return (0, gate_evidence_cjs_1.evidenceFromError)(err, file);
214
+ }
215
+ finally {
216
+ try {
217
+ node_fs_1.default.closeSync(fd);
218
+ }
219
+ catch {
220
+ // already closed — the evidence was read (or its failure returned) above
221
+ }
222
+ }
223
+ }
224
+ /**
225
+ * Native-UI walk over the shared bounded BFS (#4658): `.xaml` is evidence by
226
+ * extension alone; `.swift`/`.kt`/`.dart` are evidence only when the file's
227
+ * content carries its ecosystem's import marker.
228
+ */
229
+ function treeNativeUiEvidence(projectDir) {
230
+ return walkProjectFiles(projectDir, (name, fullPath, note) => {
231
+ if (exports.NATIVE_UI_XAML_RE.test(name))
232
+ return true;
233
+ if (exports.NATIVE_UI_SOURCE_RE.test(name)) {
234
+ const markers = exports.NATIVE_UI_CONTENT_MARKERS[node_path_1.default.extname(name).toLowerCase()];
235
+ if (markers == null)
236
+ return false;
237
+ const prefix = readPrefixEvidence(fullPath);
238
+ if (prefix.kind === 'unreadable') {
239
+ note(prefix.reason);
240
+ return false;
241
+ }
242
+ return prefix.kind === 'found' && markers.some((m) => prefix.value.includes(m));
243
+ }
244
+ return false;
245
+ });
142
246
  }
143
247
  /**
144
248
  * Does the project tree carry static evidence of a frontend?
145
249
  *
146
250
  * @param projectDir - Absolute path to the project root (the gate's cwd).
147
- * @returns true when package.json declares a UI-framework dependency or the
148
- * tree contains a component-framework file; false otherwise (including
149
- * on any I/O failure — evidence must be affirmative).
251
+ * @returns `found` when package.json declares a UI-framework dependency, the tree
252
+ * contains a component-framework file, or the tree contains native UI
253
+ * evidence (a `.xaml` file, or a `.swift`/`.kt`/`.dart` file carrying
254
+ * its ecosystem's UI import marker — #4658); otherwise `unreadable` when
255
+ * any part of the tree or manifest could not be read (the absence of
256
+ * evidence is then not established), else `none`. Affirmative evidence
257
+ * always wins over a read failure elsewhere.
150
258
  */
151
- function hasStaticFrontendEvidence(projectDir) {
259
+ function readStaticFrontendEvidence(projectDir) {
152
260
  if (typeof projectDir !== 'string' || projectDir === '')
153
- return false;
154
- if (packageJsonHasUiFramework(projectDir))
155
- return true;
156
- return treeHasComponentFile(projectDir);
261
+ return (0, gate_evidence_cjs_1.evidenceNone)();
262
+ let unreadable = null;
263
+ const manifest = packageJsonEvidence(projectDir);
264
+ if (manifest.kind === 'found')
265
+ return manifest;
266
+ if (manifest.kind === 'unreadable')
267
+ unreadable = manifest.reason;
268
+ const components = treeComponentFileEvidence(projectDir);
269
+ if (components.found)
270
+ return (0, gate_evidence_cjs_1.evidenceFound)(true);
271
+ unreadable = unreadable ?? components.unreadable;
272
+ const native = treeNativeUiEvidence(projectDir);
273
+ if (native.found)
274
+ return (0, gate_evidence_cjs_1.evidenceFound)(true);
275
+ unreadable = unreadable ?? native.unreadable;
276
+ return unreadable === null ? (0, gate_evidence_cjs_1.evidenceNone)() : (0, gate_evidence_cjs_1.evidenceUnreadable)(unreadable, projectDir);
277
+ }
278
+ /**
279
+ * The boolean projection of {@link readStaticFrontendEvidence}: true only on affirmative evidence. It
280
+ * reads nothing itself; a gate that must tell "no frontend" from "could not look" uses the evidence.
281
+ */
282
+ function hasStaticFrontendEvidence(projectDir) {
283
+ return readStaticFrontendEvidence(projectDir).kind === 'found';
157
284
  }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * Undo Commit Selection — issue #4661 (absorbed into epic #4906, Phase 5).
4
+ *
5
+ * Pure scope-matching logic for `/gsd:undo --phase N` / `--plan N-M`, replacing
6
+ * the two hand-rolled `git log --oneline | grep -E ...` pipelines that used to
7
+ * live in `gsd-core/workflows/undo.md`. Those greps were unanchored substring
8
+ * matches against a live regex built from unvalidated user input — four
9
+ * documented bug classes (see #4661):
10
+ *
11
+ * 1. The id was interpolated raw into an ERE: `.` and `+` are live
12
+ * metacharacters there, so a malformed or merely differently-shaped id
13
+ * silently matched the WRONG phase.
14
+ * 2. The grep was unanchored, so a commit that only MENTIONS a scope
15
+ * (`docs(99-01): explain feat(03-01): commit convention`) was wrongly
16
+ * selected as a DECLARATION of it.
17
+ * 3. Phase-mode's `\):` suffix and plan-mode's missing suffix disagreed on
18
+ * the same commit (`feat(03-01)!: breaking change`).
19
+ * 4. The "obvious" fix — anchoring `git log --oneline`'s record start —
20
+ * is a trap: it silently drops `fixup! ...` / `Revert "..."` wrapper
21
+ * commits (a worse failure, a silent partial revert) and returns zero
22
+ * matches under `color.ui=always` (ANSI codes precede the sha).
23
+ *
24
+ * This module closes all four by parsing each commit subject through the
25
+ * SAME anchored conventional-commit grammar the changelog/PR-title gate uses
26
+ * (`HEADER_RE`, reused verbatim from `scripts/release-notes/conventional-title.cjs`
27
+ * — see the require() below), then comparing the extracted scope to the
28
+ * caller-supplied target id by exact STRING EQUALITY. No regex is built from
29
+ * user input at any point past `validatePhaseNumber` (src/security.cts),
30
+ * which the CLI caller (`gsd-tools.cjs query select-revert-commits`) runs
31
+ * BEFORE this module ever sees the id.
32
+ *
33
+ * Deliberately no `fs`/`child_process` in this file: it operates purely on
34
+ * `{sha, subject}` records the caller already fetched (e.g. via `git log
35
+ * --format=%H%x00%s`), so it is unit-testable without touching git or the
36
+ * filesystem.
37
+ *
38
+ * KNOWN LIMIT (documented, not a defect): `unwrapSubject` unwraps ONE level
39
+ * of a `fixup! `/`squash! `/`Revert "..."` wrapper. A doubly-wrapped subject
40
+ * (e.g. `Revert "fixup! feat(03-01): work"`) is treated as unparseable (no
41
+ * declared scope) after that single unwrap — it is NOT selected, never
42
+ * mis-selected. This bounds the module to the wrapper shapes git itself
43
+ * produces (`fixup!`/`squash!` from `--fixup`/`--squash`, `Revert "..."` from
44
+ * `git revert`), each of which wraps a single ordinary commit subject, not
45
+ * another wrapper.
46
+ */
47
+ var __importDefault = (this && this.__importDefault) || function (mod) {
48
+ return (mod && mod.__esModule) ? mod : { "default": mod };
49
+ };
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.selectCommitsByDeclaredScope = selectCommitsByDeclaredScope;
52
+ const node_path_1 = __importDefault(require("node:path"));
53
+ // Reuse the exact HEADER_RE the changelog classifier and PR-title CI gate
54
+ // already depend on (#1549) — never fork a second copy of this grammar. A
55
+ // bare `require()` (not a TS `import ... = require(...)`) is used
56
+ // deliberately: `scripts/` sits outside this build's `rootDir` ("src", see
57
+ // tsconfig.build.json) and carries no `.d.ts`, so a type-checked import-equals
58
+ // would fail module resolution (TS7016) under `strict`/`noImplicitAny`. A
59
+ // plain `require()` resolves through Node's ambient `NodeRequire` type
60
+ // (`(id: string) => any`) instead, sidestepping that check entirely — the
61
+ // cast below is the only place the resulting shape is asserted.
62
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
63
+ const conventionalTitle = require(node_path_1.default.resolve(__dirname, '..', '..', '..', 'scripts', 'release-notes', 'conventional-title.cjs'));
64
+ const { HEADER_RE } = conventionalTitle;
65
+ // ─── Subject unwrapping (Known limit: exactly ONE level) ──────────────────
66
+ const FIXUP_PREFIX = 'fixup! ';
67
+ const SQUASH_PREFIX = 'squash! ';
68
+ const REVERT_RE = /^Revert "(.*)"$/;
69
+ /**
70
+ * Strip exactly one `fixup! `/`squash! `/`Revert "..."` wrapper layer off a
71
+ * commit subject, returning the (possibly) unwrapped remainder. Never
72
+ * recurses — a doubly-wrapped subject is returned with only its outermost
73
+ * layer removed, which is intentionally still unparseable by `HEADER_RE` (see
74
+ * module doc comment).
75
+ */
76
+ function unwrapSubject(subject) {
77
+ if (subject.startsWith(FIXUP_PREFIX))
78
+ return subject.slice(FIXUP_PREFIX.length);
79
+ if (subject.startsWith(SQUASH_PREFIX))
80
+ return subject.slice(SQUASH_PREFIX.length);
81
+ const revertMatch = REVERT_RE.exec(subject);
82
+ if (revertMatch)
83
+ return revertMatch[1];
84
+ return subject;
85
+ }
86
+ /**
87
+ * Parse a (possibly wrapped) commit subject into its declared conventional-
88
+ * commit scope, or `null` when the subject carries no parseable scope: no
89
+ * clean `type[(scope)][!]:` header at all, or a header with no `(scope)`
90
+ * group. Never regex-matches against untrusted `targetId` — this function
91
+ * only ever consumes the commit's OWN subject text.
92
+ */
93
+ function parseDeclaredScope(subject) {
94
+ const unwrapped = unwrapSubject(subject);
95
+ const m = HEADER_RE.exec(unwrapped);
96
+ if (!m)
97
+ return null;
98
+ const scopeWithParens = m[2]; // e.g. "(03-01)" — includes parens, or undefined
99
+ if (!scopeWithParens)
100
+ return null;
101
+ // HEADER_RE's scope group is `\([^)]*\)` — always at least the two paren
102
+ // characters when present, so slicing them off is safe unconditionally.
103
+ return scopeWithParens.slice(1, -1);
104
+ }
105
+ /**
106
+ * Select commits whose DECLARED conventional-commit scope identifies
107
+ * `targetId`, by exact string equality (`'plan'` mode) or exact-or-phase-
108
+ * prefixed equality (`'phase'` mode). `targetId` is assumed ALREADY
109
+ * VALIDATED/NORMALIZED by the caller (e.g. via `validatePhaseNumber` from
110
+ * `src/security.cts`) — this function performs no validation of its own, and
111
+ * never builds a regex from it (string equality / `startsWith` only), so a
112
+ * malformed or metacharacter-laden `targetId` cannot cause a wildcard-style
113
+ * over-match the way the retired grep pipelines could.
114
+ */
115
+ function selectCommitsByDeclaredScope(commits, targetId, mode = 'plan') {
116
+ const phasePrefix = `${targetId}-`;
117
+ const classified = commits.map(({ sha, subject }) => {
118
+ const parsedScope = parseDeclaredScope(subject);
119
+ let matched = false;
120
+ if (parsedScope !== null) {
121
+ matched = mode === 'phase'
122
+ ? parsedScope === targetId || parsedScope.startsWith(phasePrefix)
123
+ : parsedScope === targetId;
124
+ }
125
+ return { sha, subject, parsedScope, matched };
126
+ });
127
+ const selected = classified
128
+ .filter((c) => c.matched)
129
+ .map(({ sha, subject }) => ({ sha, subject }));
130
+ return { selected, classified };
131
+ }
@@ -1,7 +1,7 @@
1
1
  # vendor/
2
2
 
3
- This directory holds **verbatim, unmodified** copies of third-party build
4
- artifacts that `gsd-core/bin/**` needs at runtime.
3
+ This directory holds third-party artifacts that `gsd-core/bin/**` needs at
4
+ runtime: verbatim upstream builds or reproducible bundles of unmodified upstream code.
5
5
 
6
6
  ## Why
7
7
 
@@ -15,6 +15,19 @@ in-tree instead of depending on it being installed as an npm package.
15
15
 
16
16
  ## Contents
17
17
 
18
+ - `tap-parser.cjs` and `saxes.cjs` — standalone CJS bundles built with pinned
19
+ esbuild from the exact devDependency versions and their lockfile dependencies.
20
+ The TAP and JUnit adapters use these for report grammar and diagnostics.
21
+ `scripts/lib/vendor-bundle.cjs` rejects external imports other than Node
22
+ builtins; `lint-vendored-deps.cjs` rebuilds in memory and byte-compares both
23
+ code and companion `.LICENSE.txt` notices. Refresh with
24
+ `npm run lint:vendored-deps -- --fix`.
25
+ `tap-parser`'s npm metadata says BlueOak-1.0.0 while its shipped LICENSE says
26
+ MIT; the notices preserve both the metadata and the actual license text.
27
+ saxes 6.0.0 omits LICENSE from npm, so the tagged upstream license is preserved
28
+ verbatim in `scripts/lib/vendor-licenses/saxes-6.0.0.txt` and included in the
29
+ generated notices. Neither package's source is patched.
30
+
18
31
  - `re2js.cjs` — verbatim copy of `node_modules/re2js/build/index.cjs`
19
32
  (upstream package `re2js`, pinned version see `package.json`
20
33
  `devDependencies.re2js`). Used by `src/pattern.cts` (compiled to
@@ -30,12 +43,19 @@ in-tree instead of depending on it being installed as an npm package.
30
43
  `require()` calls of its own, and exposes `load`/`dump`/`FAILSAFE_SCHEMA`/
31
44
  `YAMLException`.
32
45
 
33
- ## Two kinds of type twin
46
+ ## Type twins
47
+
48
+ The bundled parsers use **upstream-reference** twins: declaration-only
49
+ `export * from '<package>';` files under `src/vendor/`. TypeScript reads the
50
+ actual upstream declarations during the build, with no hand-maintained API
51
+ copy and no bare runtime import. The vendoring guard checks the exact forwarding
52
+ declaration. The installed runtime needs only the bundled JavaScript.
34
53
 
35
54
  Each vendored package needs a `.d.cts` under `src/vendor/` so TypeScript can
36
55
  resolve types for a relative `./vendor/<pkg>.cjs` import from `src/**`
37
56
  (module resolution for a `.cts` source is relative to `src/`, not the
38
- compiled output dir). There are two kinds:
57
+ compiled output dir). Besides the upstream-reference twins above, the prebuilt
58
+ upstream artifacts use one of two kinds:
39
59
 
40
60
  - **upstream-verbatim** (`re2js.d.cts`) — a byte-for-byte copy of an
41
61
  upstream `.d.cts`/`.d.ts` that ships with the package. Both the
@@ -54,8 +74,8 @@ compiled output dir). There are two kinds:
54
74
 
55
75
  ## Do not hand-edit
56
76
 
57
- These files are **verbatim** copies of upstream build output. Never edit
58
- them directly — refresh them from `node_modules` instead:
77
+ Never edit these artifacts directly. Refresh bundled packages through the
78
+ vendoring command above. Refresh the prebuilt upstream artifacts as follows:
59
79
 
60
80
  ```
61
81
  cp node_modules/re2js/build/index.cjs gsd-core/bin/lib/vendor/re2js.cjs
@@ -68,8 +88,10 @@ cp node_modules/js-yaml/dist/js-yaml.js gsd-core/bin/lib/vendor/js-yaml.cjs
68
88
  ```
69
89
 
70
90
  `node scripts/lint-vendored-deps.cjs` fails CI if any vendored copy drifts
71
- byte-for-byte from its `node_modules` upstream, from its own source-side
72
- type twin (upstream-verbatim twins only), or from the version pinned in
91
+ byte-for-byte from its `node_modules` upstream (for a bundled package: from
92
+ an in-memory rebuild of the bundle and its license notices), from its own
93
+ source-side type twin (upstream-verbatim twins only; an upstream-reference
94
+ twin must be the exact forwarding declaration), or from the version pinned in
73
95
  `package.json` `devDependencies`. It is table-driven (`VENDORED` in that
74
- script) — adding a third vendored package means adding a row, not a second
96
+ script) — adding a vendored package means adding a row, not another
75
97
  hardcoded check block (ADR-3473 §8.3, "one implementation per rule").