@opengsd/gsd-core 1.15.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 (487) 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/agents/gsd-code-fixer.compact.md +1 -1
  5. package/agents/gsd-code-fixer.md +1 -1
  6. package/agents/gsd-code-reviewer.compact.md +5 -3
  7. package/agents/gsd-code-reviewer.md +8 -6
  8. package/agents/gsd-debug-session-manager.compact.md +1 -1
  9. package/agents/gsd-debug-session-manager.md +1 -1
  10. package/agents/gsd-debugger.md +2 -2
  11. package/agents/gsd-eval-auditor.compact.md +1 -1
  12. package/agents/gsd-eval-auditor.md +1 -1
  13. package/agents/gsd-executor.md +4 -4
  14. package/agents/gsd-intel-updater.compact.md +1 -1
  15. package/agents/gsd-intel-updater.md +1 -1
  16. package/agents/gsd-mempalace-curator.md +2 -2
  17. package/agents/gsd-phase-researcher.md +1 -1
  18. package/agents/gsd-plan-checker.md +7 -2
  19. package/agents/gsd-planner.md +3 -3
  20. package/agents/gsd-project-researcher.compact.md +1 -1
  21. package/agents/gsd-project-researcher.md +1 -1
  22. package/agents/gsd-research-synthesizer.compact.md +1 -1
  23. package/agents/gsd-research-synthesizer.md +1 -1
  24. package/agents/gsd-ui-auditor.compact.md +21 -30
  25. package/agents/gsd-ui-auditor.md +42 -51
  26. package/agents/gsd-ui-researcher.compact.md +1 -1
  27. package/agents/gsd-ui-researcher.md +1 -1
  28. package/agents/gsd-verifier.md +31 -9
  29. package/bin/install.js +126 -196
  30. package/commands/gsd/add-tests.md +6 -1
  31. package/commands/gsd/ai-integration-phase.md +6 -1
  32. package/commands/gsd/audit-fix.md +5 -0
  33. package/commands/gsd/audit-milestone.md +6 -1
  34. package/commands/gsd/autonomous.md +5 -0
  35. package/commands/gsd/capture.md +8 -4
  36. package/commands/gsd/code-review.md +7 -2
  37. package/commands/gsd/complete-milestone.md +4 -0
  38. package/commands/gsd/config.md +7 -3
  39. package/commands/gsd/debug.md +11 -7
  40. package/commands/gsd/discuss-phase.md +7 -3
  41. package/commands/gsd/docs-update.md +12 -7
  42. package/commands/gsd/eval-review.md +6 -1
  43. package/commands/gsd/execute-phase.md +12 -7
  44. package/commands/gsd/extract-learnings.md +5 -0
  45. package/commands/gsd/fast.md +4 -0
  46. package/commands/gsd/forensics.md +5 -1
  47. package/commands/gsd/graphify.md +10 -6
  48. package/commands/gsd/health.md +5 -0
  49. package/commands/gsd/help.md +7 -2
  50. package/commands/gsd/import.md +7 -3
  51. package/commands/gsd/inbox.md +5 -0
  52. package/commands/gsd/ingest-docs.md +5 -1
  53. package/commands/gsd/manager.md +6 -1
  54. package/commands/gsd/map-codebase.md +7 -3
  55. package/commands/gsd/mempalace-capture.md +5 -1
  56. package/commands/gsd/mempalace-recall.md +5 -1
  57. package/commands/gsd/milestone-summary.md +5 -1
  58. package/commands/gsd/mvp-phase.md +8 -3
  59. package/commands/gsd/new-milestone.md +6 -1
  60. package/commands/gsd/new-project.md +5 -0
  61. package/commands/gsd/next.md +6 -1
  62. package/commands/gsd/ns-context.md +4 -0
  63. package/commands/gsd/ns-ideate.md +4 -0
  64. package/commands/gsd/ns-manage.md +4 -0
  65. package/commands/gsd/ns-project.md +4 -0
  66. package/commands/gsd/ns-review.md +4 -0
  67. package/commands/gsd/ns-workflow.md +4 -0
  68. package/commands/gsd/onboard.md +6 -1
  69. package/commands/gsd/pause-work.md +5 -1
  70. package/commands/gsd/phase.md +8 -4
  71. package/commands/gsd/plan-phase.md +6 -1
  72. package/commands/gsd/plan-review-convergence.md +5 -1
  73. package/commands/gsd/pr-branch.md +4 -0
  74. package/commands/gsd/profile-user.md +5 -1
  75. package/commands/gsd/progress.md +6 -1
  76. package/commands/gsd/quick-batch.md +20 -8
  77. package/commands/gsd/quick.md +12 -7
  78. package/commands/gsd/review.md +5 -1
  79. package/commands/gsd/secure-phase.md +6 -1
  80. package/commands/gsd/ship.md +5 -0
  81. package/commands/gsd/sketch.md +7 -2
  82. package/commands/gsd/spec-phase.md +5 -1
  83. package/commands/gsd/spike.md +8 -3
  84. package/commands/gsd/surface.md +5 -1
  85. package/commands/gsd/thread.md +4 -0
  86. package/commands/gsd/ui-phase.md +6 -1
  87. package/commands/gsd/ui-review.md +6 -1
  88. package/commands/gsd/ultraplan-phase.md +5 -1
  89. package/commands/gsd/undo.md +5 -1
  90. package/commands/gsd/update.md +6 -2
  91. package/commands/gsd/validate-phase.md +6 -1
  92. package/commands/gsd/verify-work.md +6 -1
  93. package/commands/gsd/workspace.md +7 -3
  94. package/gsd-core/bin/gsd-tools.cjs +142 -56
  95. package/gsd-core/bin/lib/active-workstream-store.cjs +15 -0
  96. package/gsd-core/bin/lib/agent-install-check.cjs +4 -1
  97. package/gsd-core/bin/lib/audit.cjs +78 -44
  98. package/gsd-core/bin/lib/broken-windows.cjs +13 -13
  99. package/gsd-core/bin/lib/capability-activation.cjs +9 -4
  100. package/gsd-core/bin/lib/capability-registry.cjs +183 -103
  101. package/gsd-core/bin/lib/capability-validator.cjs +16 -0
  102. package/gsd-core/bin/lib/check-auto-mode.cjs +35 -0
  103. package/gsd-core/bin/lib/check-command-router.cjs +164 -1712
  104. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +13 -2
  105. package/gsd-core/bin/lib/cli-exit.cjs +12 -0
  106. package/gsd-core/bin/lib/codex-agent-toml.cjs +11 -8
  107. package/gsd-core/bin/lib/command-aliases.cjs +7 -0
  108. package/gsd-core/bin/lib/command-routing-hub.cjs +48 -1
  109. package/gsd-core/bin/lib/commands.cjs +173 -170
  110. package/gsd-core/bin/lib/complexity-trigger.cjs +8 -7
  111. package/gsd-core/bin/lib/config.cjs +43 -12
  112. package/gsd-core/bin/lib/core-utils.cjs +6 -1
  113. package/gsd-core/bin/lib/coverage.cjs +4 -8
  114. package/gsd-core/bin/lib/decision-coverage-support.cjs +259 -0
  115. package/gsd-core/bin/lib/drift.cjs +177 -42
  116. package/gsd-core/bin/lib/frontmatter-fence.cjs +90 -0
  117. package/gsd-core/bin/lib/frontmatter-splice.cjs +494 -0
  118. package/gsd-core/bin/lib/frontmatter.cjs +413 -234
  119. package/gsd-core/bin/lib/gap-checker.cjs +72 -29
  120. package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +381 -0
  121. package/gsd-core/bin/lib/gate-args.cjs +53 -0
  122. package/gsd-core/bin/lib/gate-codebase-drift.cjs +285 -0
  123. package/gsd-core/bin/lib/gate-config.cjs +46 -0
  124. package/gsd-core/bin/lib/gate-context-drift.cjs +141 -0
  125. package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +169 -0
  126. package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +126 -0
  127. package/gsd-core/bin/lib/gate-evaluation-scope.cjs +555 -0
  128. package/gsd-core/bin/lib/gate-evidence.cjs +138 -0
  129. package/gsd-core/bin/lib/gate-exit.cjs +27 -0
  130. package/gsd-core/bin/lib/gate-gap-analysis-plan-post.cjs +61 -0
  131. package/gsd-core/bin/lib/gate-phase-context.cjs +170 -0
  132. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +1 -1
  133. package/gsd-core/bin/lib/gate-predicate.cjs +165 -0
  134. package/gsd-core/bin/lib/gate-prohibition-enforcement.cjs +94 -0
  135. package/gsd-core/bin/lib/gate-schema-drift.cjs +165 -0
  136. package/gsd-core/bin/lib/gate-tdd-red-evidence.cjs +100 -0
  137. package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +182 -0
  138. package/gsd-core/bin/lib/gate-ui-plan.cjs +86 -0
  139. package/gsd-core/bin/lib/gate-ui-safety.cjs +80 -0
  140. package/gsd-core/bin/lib/gate-verdict.cjs +64 -0
  141. package/gsd-core/bin/lib/gate-verify-command-paths.cjs +78 -0
  142. package/gsd-core/bin/lib/gate-verify-failure-directions.cjs +41 -0
  143. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +43 -47
  144. package/gsd-core/bin/lib/health-diagnostic.cjs +45 -8
  145. package/gsd-core/bin/lib/init.cjs +162 -96
  146. package/gsd-core/bin/lib/install-engine.cjs +19 -35
  147. package/gsd-core/bin/lib/install-profiles.cjs +7 -4
  148. package/gsd-core/bin/lib/io.cjs +122 -3
  149. package/gsd-core/bin/lib/loop-resolver.cjs +95 -0
  150. package/gsd-core/bin/lib/markdown-sectionizer.cjs +75 -1
  151. package/gsd-core/bin/lib/milestone.cjs +19 -1
  152. package/gsd-core/bin/lib/model-resolver.cjs +18 -18
  153. package/gsd-core/bin/lib/observability/event.cjs +1 -1
  154. package/gsd-core/bin/lib/observability/logger.cjs +46 -1
  155. package/gsd-core/bin/lib/pattern.cjs +10 -0
  156. package/gsd-core/bin/lib/phase-command-router.cjs +11 -4
  157. package/gsd-core/bin/lib/phase-estimation.cjs +5 -4
  158. package/gsd-core/bin/lib/phase-id.cjs +1 -1
  159. package/gsd-core/bin/lib/phase-lifecycle.cjs +9 -2
  160. package/gsd-core/bin/lib/phase-status.cjs +360 -0
  161. package/gsd-core/bin/lib/phase.cjs +280 -80
  162. package/gsd-core/bin/lib/plan-document.cjs +93 -19
  163. package/gsd-core/bin/lib/plan-drift-guard.cjs +5 -0
  164. package/gsd-core/bin/lib/planning-document.cjs +273 -40
  165. package/gsd-core/bin/lib/planning-inspect.cjs +42 -8
  166. package/gsd-core/bin/lib/planning-snapshot.cjs +18 -0
  167. package/gsd-core/bin/lib/planning-workspace.cjs +76 -53
  168. package/gsd-core/bin/lib/pristine-baseline.cjs +10 -0
  169. package/gsd-core/bin/lib/profile-output.cjs +6 -3
  170. package/gsd-core/bin/lib/prohibition-enforcement.cjs +0 -55
  171. package/gsd-core/bin/lib/quick-batch-command-router.cjs +35 -9
  172. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +11 -8
  173. package/gsd-core/bin/lib/real-home-guard.cjs +9 -1
  174. package/gsd-core/bin/lib/report-parser.cjs +269 -0
  175. package/gsd-core/bin/lib/roadmap-command-router.cjs +13 -15
  176. package/gsd-core/bin/lib/roadmap-parser.cjs +82 -15
  177. package/gsd-core/bin/lib/roadmap-upgrade.cjs +127 -65
  178. package/gsd-core/bin/lib/roadmap.cjs +169 -72
  179. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +91 -157
  180. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +2 -1
  181. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +57 -1
  182. package/gsd-core/bin/lib/runtime-homes.cjs +13 -10
  183. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +307 -591
  184. package/gsd-core/bin/lib/runtime-name-policy.cjs +142 -27
  185. package/gsd-core/bin/lib/runtime-slash.cjs +47 -30
  186. package/gsd-core/bin/lib/shell-command-projection.cjs +37 -2
  187. package/gsd-core/bin/lib/smart-entry.cjs +19 -3
  188. package/gsd-core/bin/lib/stale-bake-guard.cjs +32 -48
  189. package/gsd-core/bin/lib/state-contract.cjs +15 -18
  190. package/gsd-core/bin/lib/state-document.cjs +100 -22
  191. package/gsd-core/bin/lib/state.cjs +214 -105
  192. package/gsd-core/bin/lib/surface.cjs +2 -1
  193. package/gsd-core/bin/lib/tdd-red-evidence.cjs +48 -152
  194. package/gsd-core/bin/lib/uat-predicate.cjs +313 -35
  195. package/gsd-core/bin/lib/uat.cjs +424 -7
  196. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +94 -58
  197. package/gsd-core/bin/lib/vendor/README.md +31 -9
  198. package/gsd-core/bin/lib/vendor/saxes.cjs +1934 -0
  199. package/gsd-core/bin/lib/vendor/saxes.cjs.LICENSE.txt +92 -0
  200. package/gsd-core/bin/lib/vendor/tap-parser.cjs +8927 -0
  201. package/gsd-core/bin/lib/vendor/tap-parser.cjs.LICENSE.txt +152 -0
  202. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  203. package/gsd-core/bin/lib/verification.cjs +1165 -314
  204. package/gsd-core/bin/lib/verify-command-router.cjs +18 -7
  205. package/gsd-core/bin/lib/verify.cjs +286 -567
  206. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +14 -6
  207. package/gsd-core/bin/lib/workstream-inventory.cjs +31 -21
  208. package/gsd-core/bin/lib/workstream-name-policy.cjs +31 -1
  209. package/gsd-core/bin/lib/workstream.cjs +11 -2
  210. package/gsd-core/bin/shared/config-defaults.manifest.json +5 -0
  211. package/gsd-core/bin/shared/config-schema.manifest.json +4 -0
  212. package/gsd-core/references/autonomous-smart-discuss.md +2 -1
  213. package/gsd-core/references/autonomous-ui-design-contract.md +3 -3
  214. package/gsd-core/references/execute-mvp-tdd.md +5 -10
  215. package/gsd-core/references/execute-phase-between-wave-reset.md +3 -0
  216. package/gsd-core/references/execute-phase-response-language.md +1 -1
  217. package/gsd-core/references/gsd-run-resolver.md +1 -1
  218. package/gsd-core/references/loop-hook-dispatch.md +7 -1
  219. package/gsd-core/references/offer-next.md +1 -1
  220. package/gsd-core/references/planning-config.md +1 -1
  221. package/gsd-core/references/spidr-splitting.md +1 -1
  222. package/gsd-core/references/tdd.md +10 -4
  223. package/gsd-core/references/verifier-phase-gates.md +5 -2
  224. package/gsd-core/references/verify-mvp-mode.md +2 -2
  225. package/gsd-core/references/workstream-flag.md +33 -3
  226. package/gsd-core/templates/README.md +1 -1
  227. package/gsd-core/templates/UAT.md +17 -1
  228. package/gsd-core/templates/config.json +2 -11
  229. package/gsd-core/templates/verification-report.md +1 -1
  230. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  231. package/gsd-core/workflows/add-backlog.md +1 -1
  232. package/gsd-core/workflows/add-phase.md +8 -7
  233. package/gsd-core/workflows/add-tests.md +3 -2
  234. package/gsd-core/workflows/add-todo.md +4 -3
  235. package/gsd-core/workflows/ai-integration-phase.md +3 -2
  236. package/gsd-core/workflows/audit-fix.md +1 -1
  237. package/gsd-core/workflows/audit-milestone.md +4 -3
  238. package/gsd-core/workflows/audit-uat.md +1 -1
  239. package/gsd-core/workflows/autonomous.md +28 -18
  240. package/gsd-core/workflows/check-todos.md +6 -5
  241. package/gsd-core/workflows/cleanup.md +1 -1
  242. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +20 -13
  243. package/gsd-core/workflows/code-review-fix.md +5 -4
  244. package/gsd-core/workflows/code-review.md +84 -90
  245. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +4 -3
  246. package/gsd-core/workflows/complete-milestone.md +12 -7
  247. package/gsd-core/workflows/debug.md +30 -5
  248. package/gsd-core/workflows/diagnose-issues.md +3 -2
  249. package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
  250. package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +4 -3
  252. package/gsd-core/workflows/discuss-phase.md +4 -3
  253. package/gsd-core/workflows/do.md +1 -1
  254. package/gsd-core/workflows/docs-update.md +4 -3
  255. package/gsd-core/workflows/edit-phase.md +4 -3
  256. package/gsd-core/workflows/eval-review.md +5 -3
  257. package/gsd-core/workflows/execute-phase/detail/elaboration.md +1 -1
  258. package/gsd-core/workflows/execute-phase/steps/code-review-disposition.md +4 -2
  259. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +15 -4
  260. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +10 -7
  261. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +3 -1
  263. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +2 -2
  264. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  265. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -1
  266. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
  267. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +1 -1
  268. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +1 -1
  269. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +2 -0
  270. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +1 -1
  271. package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +187 -0
  272. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +2 -3
  273. package/gsd-core/workflows/execute-phase.md +78 -170
  274. package/gsd-core/workflows/execute-plan.md +13 -19
  275. package/gsd-core/workflows/explore.md +2 -2
  276. package/gsd-core/workflows/extract-learnings.md +3 -2
  277. package/gsd-core/workflows/fast.md +1 -1
  278. package/gsd-core/workflows/forensics.md +1 -1
  279. package/gsd-core/workflows/graduation.md +1 -1
  280. package/gsd-core/workflows/health.md +2 -1
  281. package/gsd-core/workflows/import.md +3 -2
  282. package/gsd-core/workflows/inbox.md +1 -1
  283. package/gsd-core/workflows/ingest-docs.md +1 -1
  284. package/gsd-core/workflows/insert-phase.md +4 -3
  285. package/gsd-core/workflows/list-seeds.md +1 -1
  286. package/gsd-core/workflows/list-workspaces.md +1 -1
  287. package/gsd-core/workflows/manager.md +5 -3
  288. package/gsd-core/workflows/map-codebase.md +4 -3
  289. package/gsd-core/workflows/milestone-summary.md +3 -2
  290. package/gsd-core/workflows/mvp-phase.md +14 -14
  291. package/gsd-core/workflows/new-milestone.md +10 -10
  292. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  293. package/gsd-core/workflows/new-project.md +1 -1
  294. package/gsd-core/workflows/new-workspace.md +1 -1
  295. package/gsd-core/workflows/next.md +1 -1
  296. package/gsd-core/workflows/pause-work.md +2 -2
  297. package/gsd-core/workflows/plan-phase/detail/elaboration.md +1 -1
  298. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +1 -1
  299. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +1 -1
  300. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
  301. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +1 -1
  302. package/gsd-core/workflows/plan-phase.md +27 -18
  303. package/gsd-core/workflows/plan-review-convergence.md +1 -1
  304. package/gsd-core/workflows/plant-seed.md +1 -1
  305. package/gsd-core/workflows/pr-branch.md +1 -1
  306. package/gsd-core/workflows/profile-user.md +1 -1
  307. package/gsd-core/workflows/progress.md +19 -49
  308. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +4 -2
  309. package/gsd-core/workflows/quick/steps/quick-verification.md +4 -4
  310. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +30 -11
  311. package/gsd-core/workflows/quick-batch/steps/batch-init.md +1 -1
  312. package/gsd-core/workflows/quick-batch/steps/completion.md +1 -1
  313. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +1 -1
  314. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +1 -1
  315. package/gsd-core/workflows/quick-batch/steps/research-phase.md +1 -1
  316. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +1 -1
  317. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +9 -3
  318. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +1 -1
  319. package/gsd-core/workflows/quick-batch.md +15 -10
  320. package/gsd-core/workflows/quick.md +42 -31
  321. package/gsd-core/workflows/remove-phase.md +3 -2
  322. package/gsd-core/workflows/remove-workspace.md +1 -1
  323. package/gsd-core/workflows/resume-project.md +3 -2
  324. package/gsd-core/workflows/review.md +3 -2
  325. package/gsd-core/workflows/scan.md +3 -2
  326. package/gsd-core/workflows/secure-phase.md +11 -12
  327. package/gsd-core/workflows/settings-advanced.md +1 -1
  328. package/gsd-core/workflows/settings-integrations.md +1 -1
  329. package/gsd-core/workflows/settings.md +1 -1
  330. package/gsd-core/workflows/ship.md +12 -12
  331. package/gsd-core/workflows/sketch-wrap-up.md +1 -1
  332. package/gsd-core/workflows/sketch.md +1 -1
  333. package/gsd-core/workflows/smart-entry.md +1 -1
  334. package/gsd-core/workflows/spec-phase.md +1 -1
  335. package/gsd-core/workflows/spike-wrap-up.md +1 -1
  336. package/gsd-core/workflows/spike.md +1 -1
  337. package/gsd-core/workflows/stats.md +1 -1
  338. package/gsd-core/workflows/sync-skills.md +1 -1
  339. package/gsd-core/workflows/thread.md +2 -2
  340. package/gsd-core/workflows/transition.md +13 -23
  341. package/gsd-core/workflows/ui-phase.md +5 -4
  342. package/gsd-core/workflows/ui-review.md +4 -3
  343. package/gsd-core/workflows/ultraplan-phase.md +3 -2
  344. package/gsd-core/workflows/undo.md +1 -1
  345. package/gsd-core/workflows/validate-phase.md +10 -12
  346. package/gsd-core/workflows/verify-work/detail/elaboration.md +43 -3
  347. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +1 -1
  348. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +5 -3
  349. package/gsd-core/workflows/verify-work.md +68 -59
  350. package/hooks/dist/gsd-agent-isolation-guard.js +8 -0
  351. package/hooks/dist/gsd-check-update-worker.js +8 -0
  352. package/hooks/dist/gsd-check-update.js +8 -0
  353. package/hooks/dist/gsd-context-monitor.js +31 -8
  354. package/hooks/dist/gsd-cursor-subagent-start.js +8 -0
  355. package/hooks/dist/gsd-secret-read-guard.js +147 -16
  356. package/hooks/dist/gsd-statusline.js +15 -7
  357. package/hooks/dist/gsd-update-banner.js +8 -0
  358. package/hooks/dist/gsd-windsurf-pre-write.js +11 -2
  359. package/hooks/dist/gsd-workflow-guard.js +5 -4
  360. package/hooks/dist/gsd-worktree-path-guard.js +6 -2
  361. package/hooks/dist/lib/cli-exit.js +12 -0
  362. package/hooks/dist/lib/git-probe.js +17 -1
  363. package/hooks/dist/lib/isolation-sentinel.js +2 -2
  364. package/hooks/gsd-agent-isolation-guard.js +8 -0
  365. package/hooks/gsd-check-update-worker.js +8 -0
  366. package/hooks/gsd-check-update.js +8 -0
  367. package/hooks/gsd-context-monitor.js +31 -8
  368. package/hooks/gsd-cursor-subagent-start.js +8 -0
  369. package/hooks/gsd-secret-read-guard.js +147 -16
  370. package/hooks/gsd-statusline.js +15 -7
  371. package/hooks/gsd-update-banner.js +8 -0
  372. package/hooks/gsd-windsurf-pre-write.js +11 -2
  373. package/hooks/gsd-workflow-guard.js +5 -4
  374. package/hooks/gsd-worktree-path-guard.js +6 -2
  375. package/hooks/hooks.json +5 -5
  376. package/hooks/lib/cli-exit.js +12 -0
  377. package/hooks/lib/git-probe.js +17 -1
  378. package/hooks/lib/isolation-sentinel.js +2 -2
  379. package/package.json +21 -4
  380. package/scripts/changeset/parse.cjs +52 -4
  381. package/scripts/ci-timeout-report.cjs +770 -4
  382. package/scripts/command-contract-helpers.cjs +12 -8
  383. package/scripts/docs-guard-registry.cjs +6 -0
  384. package/scripts/gen-features.cjs +13 -8
  385. package/scripts/gen-hooks-cli-exit.cjs +12 -28
  386. package/scripts/gen-loop-host-contract.cjs +10 -1
  387. package/scripts/gen-platform-conformance-tier.cjs +187 -1
  388. package/scripts/gen-plugin-skills.cjs +87 -1
  389. package/scripts/gen-research-agents.cjs +24 -31
  390. package/scripts/gen-scripts-cli-exit.cjs +30 -3
  391. package/scripts/gen-test-timings.cjs +32 -7
  392. package/scripts/lib/cli-exit.cjs +12 -0
  393. package/scripts/lib/macos-conformance-tier.generated.cjs +20 -2
  394. package/scripts/lib/ndjson-reporter.cjs +28 -3
  395. package/scripts/lib/platform-conformance-tier.generated.cjs +34 -5
  396. package/scripts/lib/registration-ledger-preload.cjs +155 -0
  397. package/scripts/lib/vendor-bundle.cjs +59 -0
  398. package/scripts/lib/vendor-licenses/saxes-6.0.0.txt +64 -0
  399. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  400. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  401. package/scripts/lint-completion-predicate-drift.cjs +18 -19
  402. package/scripts/lint-descriptions.cjs +7 -3
  403. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +10 -0
  404. package/scripts/lint-eslint-glob-coverage.allowlist.json +20 -0
  405. package/scripts/lint-frontmatter-fence-drift.cjs +313 -0
  406. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +122 -16
  407. package/scripts/lint-phase-enumeration-drift.cjs +12 -8
  408. package/scripts/lint-phase-id-drift.cjs +29 -0
  409. package/scripts/lint-planning-document-positive-control.cjs +329 -0
  410. package/scripts/lint-response-language-coverage.cjs +3 -0
  411. package/scripts/lint-skill-deps.cjs +7 -3
  412. package/scripts/lint-test-file-count.allowlist.json +11 -1
  413. package/scripts/lint-test-file-count.cjs +34 -1
  414. package/scripts/lint-vendored-deps.cjs +41 -5
  415. package/scripts/lint-workflow-shellcheck-baseline.json +10 -10
  416. package/scripts/mutation-matrix.cjs +50 -5
  417. package/scripts/require-issue-link-policy.cjs +6 -2
  418. package/scripts/sync-runtime-launcher.cjs +184 -2
  419. package/scripts/verify-npm-publish.cjs +76 -20
  420. package/skills/gsd-add-tests/SKILL.md +6 -1
  421. package/skills/gsd-ai-integration-phase/SKILL.md +6 -1
  422. package/skills/gsd-audit-fix/SKILL.md +5 -0
  423. package/skills/gsd-audit-milestone/SKILL.md +6 -1
  424. package/skills/gsd-autonomous/SKILL.md +5 -0
  425. package/skills/gsd-capture/SKILL.md +8 -4
  426. package/skills/gsd-code-review/SKILL.md +7 -2
  427. package/skills/gsd-complete-milestone/SKILL.md +4 -0
  428. package/skills/gsd-config/SKILL.md +8 -4
  429. package/skills/gsd-debug/SKILL.md +11 -7
  430. package/skills/gsd-discuss-phase/SKILL.md +7 -3
  431. package/skills/gsd-docs-update/SKILL.md +12 -7
  432. package/skills/gsd-eval-review/SKILL.md +6 -1
  433. package/skills/gsd-execute-phase/SKILL.md +12 -7
  434. package/skills/gsd-extract-learnings/SKILL.md +5 -0
  435. package/skills/gsd-fast/SKILL.md +4 -0
  436. package/skills/gsd-forensics/SKILL.md +5 -1
  437. package/skills/gsd-graphify/SKILL.md +10 -6
  438. package/skills/gsd-health/SKILL.md +5 -0
  439. package/skills/gsd-help/SKILL.md +7 -2
  440. package/skills/gsd-import/SKILL.md +7 -3
  441. package/skills/gsd-inbox/SKILL.md +5 -0
  442. package/skills/gsd-ingest-docs/SKILL.md +5 -1
  443. package/skills/gsd-manager/SKILL.md +6 -1
  444. package/skills/gsd-map-codebase/SKILL.md +7 -3
  445. package/skills/gsd-mempalace-capture/SKILL.md +5 -1
  446. package/skills/gsd-mempalace-recall/SKILL.md +5 -1
  447. package/skills/gsd-milestone-summary/SKILL.md +5 -1
  448. package/skills/gsd-mvp-phase/SKILL.md +8 -3
  449. package/skills/gsd-new-milestone/SKILL.md +6 -1
  450. package/skills/gsd-new-project/SKILL.md +5 -0
  451. package/skills/gsd-next/SKILL.md +6 -1
  452. package/skills/gsd-ns-context/SKILL.md +4 -0
  453. package/skills/gsd-ns-ideate/SKILL.md +4 -0
  454. package/skills/gsd-ns-manage/SKILL.md +4 -0
  455. package/skills/gsd-ns-project/SKILL.md +4 -0
  456. package/skills/gsd-ns-review/SKILL.md +4 -0
  457. package/skills/gsd-ns-workflow/SKILL.md +4 -0
  458. package/skills/gsd-onboard/SKILL.md +6 -1
  459. package/skills/gsd-pause-work/SKILL.md +5 -1
  460. package/skills/gsd-phase/SKILL.md +8 -4
  461. package/skills/gsd-plan-phase/SKILL.md +6 -1
  462. package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
  463. package/skills/gsd-pr-branch/SKILL.md +4 -0
  464. package/skills/gsd-profile-user/SKILL.md +5 -1
  465. package/skills/gsd-progress/SKILL.md +6 -1
  466. package/skills/gsd-quick/SKILL.md +16 -10
  467. package/skills/gsd-quick-batch/SKILL.md +20 -8
  468. package/skills/gsd-review/SKILL.md +5 -1
  469. package/skills/gsd-review-backlog/SKILL.md +3 -2
  470. package/skills/gsd-secure-phase/SKILL.md +6 -1
  471. package/skills/gsd-ship/SKILL.md +5 -0
  472. package/skills/gsd-sketch/SKILL.md +7 -2
  473. package/skills/gsd-spec-phase/SKILL.md +5 -1
  474. package/skills/gsd-spike/SKILL.md +8 -3
  475. package/skills/gsd-surface/SKILL.md +5 -1
  476. package/skills/gsd-thread/SKILL.md +4 -0
  477. package/skills/gsd-ui-phase/SKILL.md +6 -1
  478. package/skills/gsd-ui-review/SKILL.md +6 -1
  479. package/skills/gsd-ultraplan-phase/SKILL.md +5 -1
  480. package/skills/gsd-undo/SKILL.md +5 -1
  481. package/skills/gsd-update/SKILL.md +6 -2
  482. package/skills/gsd-validate-phase/SKILL.md +6 -1
  483. package/skills/gsd-verify-work/SKILL.md +6 -1
  484. package/skills/gsd-workspace/SKILL.md +7 -3
  485. package/skills/gsd-workstreams/SKILL.md +6 -6
  486. package/vscode/package.json +1 -1
  487. package/gsd-core/workflows/execute-phase/steps/stale-reverification.md +0 -24
@@ -65,15 +65,40 @@ const BANNER = [
65
65
  '',
66
66
  ].join('\n');
67
67
 
68
- /** Compile the whole project to a throwaway outDir so the work tree is untouched. */
68
+ /**
69
+ * Compile ONLY src/cli-exit.cts (and whatever it imports — tsc follows
70
+ * `./exit-code-registry.cjs` on its own) to a throwaway outDir, so the work
71
+ * tree is untouched. A whole-project `-p tsconfig.build.json` type-checks and
72
+ * emits every .cts file in src/ under a fixed COMPILE_TIMEOUT_MS ceiling; on a
73
+ * CPU-contended shared bench that whole-project compile can exceed the
74
+ * ceiling and get killed even though the one file this script actually needs
75
+ * compiles in a fraction of the time. A throwaway tsconfig that `extends`
76
+ * tsconfig.build.json but overrides `files`/`include` to name only
77
+ * cli-exit.cts keeps every compiler option (target, strict, rootDir, etc.)
78
+ * while scoping the type-check + emit to that file's own import closure.
79
+ */
69
80
  function compileToTemp() {
70
81
  const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-scripts-cli-exit-'));
82
+ const scopedTsconfigPath = path.join(tmp, 'tsconfig.scoped.json');
71
83
  try {
84
+ const scopedTsconfig = {
85
+ extends: path.join(REPO_ROOT, 'tsconfig.build.json'),
86
+ // typeRoots must be pinned to the real repo's node_modules/@types: tsc
87
+ // resolves a bare "types": ["node"] by walking up from the config
88
+ // file's own directory, and our scoped tsconfig lives outside the repo
89
+ // tree (in the throwaway tmp dir), so without this it cannot find
90
+ // @types/node at all.
91
+ compilerOptions: { typeRoots: [path.join(REPO_ROOT, 'node_modules', '@types')] },
92
+ files: [path.join(REPO_ROOT, 'src', 'cli-exit.cts')],
93
+ include: [],
94
+ };
95
+ fs.writeFileSync(scopedTsconfigPath, JSON.stringify(scopedTsconfig, null, 2), 'utf8');
96
+
72
97
  execFileSync(
73
98
  process.execPath,
74
99
  [
75
100
  path.join(REPO_ROOT, 'node_modules', 'typescript', 'bin', 'tsc'),
76
- '-p', path.join(REPO_ROOT, 'tsconfig.build.json'),
101
+ '-p', scopedTsconfigPath,
77
102
  '--outDir', tmp,
78
103
  // A throwaway outDir must not reuse the in-tree incremental state, or
79
104
  // tsc skips emit for files it believes are already current.
@@ -87,6 +112,8 @@ function compileToTemp() {
87
112
  fs.rmSync(tmp, { recursive: true, force: true });
88
113
  const detail = [err.stdout, err.stderr].filter(Boolean).join('\n').trim();
89
114
  return { ok: false, detail };
115
+ } finally {
116
+ fs.rmSync(scopedTsconfigPath, { force: true });
90
117
  }
91
118
  }
92
119
 
@@ -182,4 +209,4 @@ function main() {
182
209
 
183
210
  if (require.main === module) process.exitCode = main();
184
211
 
185
- module.exports = { REASON, buildExpectedContent, OUTPUT_PATH, BANNER };
212
+ module.exports = { REASON, buildExpectedContent, compileToTemp, OUTPUT_PATH, BANNER };
@@ -19,6 +19,9 @@
19
19
  // node scripts/gen-test-timings.cjs <events.jsonl> [<events.jsonl> ...]
20
20
  // node scripts/gen-test-timings.cjs ~/.local/state/gsd-test/runs/*/test-events-*.jsonl
21
21
  // node scripts/gen-test-timings.cjs events.jsonl --out tests/test-timings.json
22
+ // node scripts/gen-test-timings.cjs --platform win32 test-timings-windows-shard*.jsonl
23
+ // (#5071: the per-shard exports CI uploads from its Windows conformance
24
+ // jobs -> tests/test-timings.win32.json, preferred by run-tests.cjs on win32)
22
25
  //
23
26
  // When several streams are supplied (multiple lanes, e.g. node22 + node24), a
24
27
  // file's recorded time is the MAX across them, not the mean: the packer exists
@@ -28,9 +31,9 @@
28
31
  // The table is ADVISORY and deliberately un-gated — there is no `--check` mode
29
32
  // and no CI lint that fails on staleness, because timing data legitimately
30
33
  // varies run to run. A file missing from the table falls back to the table's
31
- // median weight, so a stale table degrades chunk BALANCE gracefully instead of
32
- // failing the build. Regenerate it when the suite's cost profile has visibly
33
- // drifted, not on a schedule.
34
+ // mean weight (see makeFileWeigher in run-tests.cjs), so a stale table
35
+ // degrades chunk BALANCE gracefully instead of failing the build. Regenerate
36
+ // it when the suite's cost profile has visibly drifted, not on a schedule.
34
37
  'use strict';
35
38
 
36
39
  const fs = require('fs');
@@ -40,12 +43,32 @@ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
40
43
  const DEFAULT_OUT = join(__dirname, '..', 'tests', 'test-timings.json');
41
44
  const SCHEMA_VERSION = 1;
42
45
 
46
+ // #5071: `--platform <p>` writes the table measured ON that platform, which
47
+ // scripts/run-tests.cjs prefers there (see its makeFileWeigher). The default
48
+ // path must match run-tests.cjs's platformTimingsPath() —
49
+ // tests/run-tests-harness.test.cjs pins the two together. A closed set, in
50
+ // exactly Node's own `process.platform` spelling, because the value becomes
51
+ // part of a filename the runner looks up by that spelling.
52
+ const PLATFORMS = ['win32', 'darwin', 'linux'];
53
+ function platformOut(platform) {
54
+ return join(__dirname, '..', 'tests', `test-timings.${platform}.json`);
55
+ }
56
+
43
57
  function parseArgs(argv) {
44
58
  const inputs = [];
45
- let out = DEFAULT_OUT;
59
+ let out = null;
60
+ let platform = null;
46
61
  for (let i = 0; i < argv.length; i++) {
47
62
  const arg = argv[i];
48
- if (arg === '--out') {
63
+ if (arg === '--platform' || arg.startsWith('--platform=')) {
64
+ if (platform !== null) return { error: 'duplicate --platform flag' };
65
+ const value = arg === '--platform' ? argv[++i] : arg.slice('--platform='.length);
66
+ if (!value || value.startsWith('-')) return { error: `--platform requires one of: ${PLATFORMS.join(', ')}` };
67
+ if (!PLATFORMS.includes(value)) {
68
+ return { error: `unknown --platform "${value}" (expected one of: ${PLATFORMS.join(', ')})` };
69
+ }
70
+ platform = value;
71
+ } else if (arg === '--out') {
49
72
  const value = argv[++i];
50
73
  if (!value) return { error: '--out requires a path' };
51
74
  out = value;
@@ -60,9 +83,10 @@ function parseArgs(argv) {
60
83
  }
61
84
  }
62
85
  if (inputs.length === 0) {
63
- return { error: 'usage: gen-test-timings.cjs <reporter-events.jsonl> [...] [--out <path>]' };
86
+ return { error: 'usage: gen-test-timings.cjs <reporter-events.jsonl> [...] [--platform <win32|darwin|linux>] [--out <path>]' };
64
87
  }
65
- return { inputs, out };
88
+ if (out === null) out = platform ? platformOut(platform) : DEFAULT_OUT;
89
+ return { inputs, out, platform };
66
90
  }
67
91
 
68
92
  // Fold one reporter event stream into `acc`, keeping the MAX duration seen for
@@ -180,6 +204,7 @@ function main() {
180
204
  const payload = {
181
205
  schema_version: SCHEMA_VERSION,
182
206
  generated_by: 'scripts/gen-test-timings.cjs',
207
+ ...(parsed.platform ? { platform: parsed.platform } : {}),
183
208
  unit: 'ms',
184
209
  sources: sources.sort(),
185
210
  file_count: acc.size,
@@ -183,6 +183,17 @@ function setPendingOutcome(v) {
183
183
  function getPendingOutcome() {
184
184
  return globalThis[PENDING_OUTCOME_KEY];
185
185
  }
186
+ /**
187
+ * Declare the outcome a void-returning `main()` ends with (#5170, ADR-5057 §4): writes the
188
+ * pending-outcome cell that `runMain` projects. Validates `name` is an outcome
189
+ * `projectOutcome` accepts (PASS, FAIL or a registered name) and THROWS otherwise, so a typo'd
190
+ * name fails at the declaration rather than at process exit. Call it AFTER `output()`, which
191
+ * rewrites the cell on every call. `output()` and this are the only writers of the cell.
192
+ */
193
+ function declareOutcome(name) {
194
+ projectOutcome(name, 'v1');
195
+ setPendingOutcome(name);
196
+ }
186
197
  const EXIT_CONTRACT_FLAG_PREFIX = '--exit-contract=';
187
198
  /** Scan argv for the FIRST `--exit-contract=<value>` token; undefined if absent. */
188
199
  function findExitContractFlag(argv) {
@@ -555,4 +566,5 @@ module.exports = {
555
566
  terminateNow,
556
567
  setPendingOutcome,
557
568
  getPendingOutcome,
569
+ declareOutcome,
558
570
  };
@@ -6,6 +6,7 @@
6
6
 
7
7
  module.exports = {
8
8
  MACOS_CONFORMANCE_TIER_FILES: [
9
+ "tests/active-workstream-store.unit.test.cjs",
9
10
  "tests/adr-612-bracket-phase-counting.test.cjs",
10
11
  "tests/adr-index-gate.test.cjs",
11
12
  "tests/adr-parser.property.test.cjs",
@@ -32,6 +33,7 @@ module.exports = {
32
33
  "tests/changeset-parse.test.cjs",
33
34
  "tests/check-contract-drift.test.cjs",
34
35
  "tests/check-predicate.test.cjs",
36
+ "tests/check-router-cutover-equivalence.test.cjs",
35
37
  "tests/check-ui-plan-gate.test.cjs",
36
38
  "tests/check-ui-safety-gate.test.cjs",
37
39
  "tests/check-update-config-dir.test.cjs",
@@ -44,7 +46,7 @@ module.exports = {
44
46
  "tests/codex-config-hooks.test.cjs",
45
47
  "tests/codex-config-install.test.cjs",
46
48
  "tests/codex-config.test.cjs",
47
- "tests/commands.test.cjs",
49
+ "tests/commands.platform.test.cjs",
48
50
  "tests/commit-docs-bypass.test.cjs",
49
51
  "tests/commit-files-deletion.test.cjs",
50
52
  "tests/commit-files-pathspec.test.cjs",
@@ -61,6 +63,7 @@ module.exports = {
61
63
  "tests/default-flip-documentation-lint.test.cjs",
62
64
  "tests/discuss-phase-power.test.cjs",
63
65
  "tests/docs-parity-live-registry.test.cjs",
66
+ "tests/drift-whole-change-set.test.cjs",
64
67
  "tests/effort-surface-axis.test.cjs",
65
68
  "tests/effort-sync-installed-runtime.test.cjs",
66
69
  "tests/emitted-attribution.test.cjs",
@@ -75,12 +78,18 @@ module.exports = {
75
78
  "tests/features-index-gate.test.cjs",
76
79
  "tests/frontmatter.unit.test.cjs",
77
80
  "tests/gap-checker.property.test.cjs",
81
+ "tests/gate-api-coverage-verify-pre-escape.test.cjs",
82
+ "tests/gate-codebase-drift.unit.test.cjs",
83
+ "tests/gate-tdd-red-evidence-containment.test.cjs",
84
+ "tests/gate-ui-plan.unit.test.cjs",
85
+ "tests/gate-verify-command-paths.unit.test.cjs",
78
86
  "tests/gemini-runtime-removed.test.cjs",
79
87
  "tests/gen-context-index.test.cjs",
80
88
  "tests/gen-section-manifest.test.cjs",
81
89
  "tests/git-base-branch.test.cjs",
82
90
  "tests/graphify-query.test.cjs",
83
91
  "tests/graphify-visualization.test.cjs",
92
+ "tests/gsd-agent-isolation-guard.test.cjs",
84
93
  "tests/gsd-secret-read-guard.test.cjs",
85
94
  "tests/gsd-settings-advanced.test.cjs",
86
95
  "tests/gsd-statusline.test.cjs",
@@ -96,7 +105,6 @@ module.exports = {
96
105
  "tests/hooks-opt-in.test.cjs",
97
106
  "tests/host-integration.test.cjs",
98
107
  "tests/init-manager.test.cjs",
99
- "tests/init.test.cjs",
100
108
  "tests/install-minimal-hooks.test.cjs",
101
109
  "tests/install-path-detection.test.cjs",
102
110
  "tests/install-regressions.test.cjs",
@@ -115,9 +123,11 @@ module.exports = {
115
123
  "tests/issue-version-gate.test.cjs",
116
124
  "tests/kimi-upgrades.test.cjs",
117
125
  "tests/lint-docs-command-form.test.cjs",
126
+ "tests/lint-frontmatter-scalar-broad-grep.test.cjs",
118
127
  "tests/lint-retired-runtime-name.test.cjs",
119
128
  "tests/lint-workflow-shellcheck-fetch.test.cjs",
120
129
  "tests/list-seeds.test.cjs",
130
+ "tests/markdown-sectionizer-xml-tags.property.test.cjs",
121
131
  "tests/markdown-sectionizer.test.cjs",
122
132
  "tests/mcp-catalog.test.cjs",
123
133
  "tests/milestone-archive.test.cjs",
@@ -142,6 +152,8 @@ module.exports = {
142
152
  "tests/phase-id-drift-guard.test.cjs",
143
153
  "tests/phase-id.test.cjs",
144
154
  "tests/phase-locator.test.cjs",
155
+ "tests/phase-status.test.cjs",
156
+ "tests/phase.platform.test.cjs",
145
157
  "tests/phase.test.cjs",
146
158
  "tests/plan-count-single-owner.test.cjs",
147
159
  "tests/plan-document.test.cjs",
@@ -162,6 +174,7 @@ module.exports = {
162
174
  "tests/profile-output.test.cjs",
163
175
  "tests/profile-pipeline.test.cjs",
164
176
  "tests/project-root.test.cjs",
177
+ "tests/quick-batch-command-router.stdin.test.cjs",
165
178
  "tests/quick-batch.test.cjs",
166
179
  "tests/quick-branching.test.cjs",
167
180
  "tests/quick-research.test.cjs",
@@ -183,6 +196,7 @@ module.exports = {
183
196
  "tests/roadmap-phase-fallback.test.cjs",
184
197
  "tests/roadmap-upgrade-bracket.test.cjs",
185
198
  "tests/roadmap.test.cjs",
199
+ "tests/run-tests-accounting.test.cjs",
186
200
  "tests/run-tests-harness.test.cjs",
187
201
  "tests/runtime-artifact-layout.test.cjs",
188
202
  "tests/runtime-identity.test.cjs",
@@ -196,11 +210,14 @@ module.exports = {
196
210
  "tests/spawn-liveness-banner.test.cjs",
197
211
  "tests/state-document.test.cjs",
198
212
  "tests/state-transition.test.cjs",
213
+ "tests/state.platform.test.cjs",
199
214
  "tests/state.test.cjs",
200
215
  "tests/todos-workstream-scope.test.cjs",
201
216
  "tests/tracer-bullet.test.cjs",
217
+ "tests/uat-complete-session.test.cjs",
202
218
  "tests/uat-predicate.test.cjs",
203
219
  "tests/uat.test.cjs",
220
+ "tests/ui-auditor-screenshot-block.test.cjs",
204
221
  "tests/ui-interaction-capture.test.cjs",
205
222
  "tests/ui-safety-gate.test.cjs",
206
223
  "tests/ui-spec-inventory-provenance.test.cjs",
@@ -209,6 +226,7 @@ module.exports = {
209
226
  "tests/unusable-input.test.cjs",
210
227
  "tests/update-custom-backup.test.cjs",
211
228
  "tests/user-artifact-staging.test.cjs",
229
+ "tests/verification-append-audit.test.cjs",
212
230
  "tests/verification-overrides.test.cjs",
213
231
  "tests/verification-status.test.cjs",
214
232
  "tests/verify-archive-dirs-live-path.test.cjs",
@@ -50,8 +50,9 @@
50
50
  // repo's `engines.node` requires >=24.0.0 (package.json), where both
51
51
  // contracts have been stable since Node 20.
52
52
  //
53
- // Kept intentionally tiny: only the five event types run-tests.cjs needs are
54
- // handled — `test:enqueue`/`test:dequeue` (emitted by the RUNNER as it queues
53
+ // Kept intentionally tiny: only the event types run-tests.cjs needs are
54
+ // handled — per-file `test:summary` (#5071, see the loop) plus these five:
55
+ // `test:enqueue`/`test:dequeue` (emitted by the RUNNER as it queues
55
56
  // and begins each spawned test-file child, independent of whether anything
56
57
  // inside that file ever completes) plus `test:start`/`test:pass`/`test:fail`
57
58
  // (emitted per-subtest, once the child reports it). `test:dequeue` is the
@@ -94,13 +95,19 @@ module.exports = async function ndjsonEventReporter(source) {
94
95
  event.type === 'test:pass' ||
95
96
  event.type === 'test:fail'
96
97
  ) {
97
- const { file, name, nesting, testNumber } = event.data || {};
98
+ const { file, name, nesting, testNumber, details } = event.data || {};
99
+ // #4031: `kind` is node:test's `details.type` ('suite' for a suite,
100
+ // otherwise a test). run-tests.cjs's per-chunk accounting counts the
101
+ // pass/fail events that are NOT suites and compares them with the
102
+ // registration ledger (scripts/lib/registration-ledger-preload.cjs).
103
+ const kind = details && typeof details.type === 'string' ? details.type : undefined;
98
104
  const line = `${JSON.stringify({
99
105
  type: event.type,
100
106
  file,
101
107
  name,
102
108
  nesting,
103
109
  testNumber,
110
+ kind,
104
111
  ts: Date.now(),
105
112
  })}\n`;
106
113
  try {
@@ -109,6 +116,24 @@ module.exports = async function ndjsonEventReporter(source) {
109
116
  // Best-effort: a write failure here (e.g. the events dir vanished)
110
117
  // must never crash the test run this reporter is only observing.
111
118
  }
119
+ } else if (event.type === 'test:summary' && typeof (event.data || {}).file === 'string') {
120
+ // #5071: node:test emits one `test:summary` per test FILE (its
121
+ // `duration_ms` is that file's wall-clock) plus a run-level one with no
122
+ // `file`. Only the per-file ones are recorded: run-tests.cjs exports
123
+ // them, when asked, as the raw input for a per-platform timing table
124
+ // (scripts/gen-test-timings.cjs --platform). The run-level summary is
125
+ // not a file measurement and is skipped here.
126
+ const line = `${JSON.stringify({
127
+ type: event.type,
128
+ file: event.data.file,
129
+ duration_ms: event.data.duration_ms,
130
+ ts: Date.now(),
131
+ })}\n`;
132
+ try {
133
+ require('fs').appendFileSync(eventsPath, line);
134
+ } catch {
135
+ // Best-effort, as above.
136
+ }
112
137
  }
113
138
  }
114
139
  // Falls through to an implicit `return undefined` (nully): this reporter is
@@ -14,7 +14,9 @@ module.exports = {
14
14
  "tests/assumption-delta-checkpoint-e2e.test.cjs",
15
15
  "tests/assumption-delta.test.cjs",
16
16
  "tests/audit-command-cutover.test.cjs",
17
+ "tests/audit-workstream-layouts.test.cjs",
17
18
  "tests/augment-upgrades.test.cjs",
19
+ "tests/blocking-guard-budget-parity.test.cjs",
18
20
  "tests/broken-windows.test.cjs",
19
21
  "tests/capability-cli.test.cjs",
20
22
  "tests/capability-command-dispatch.test.cjs",
@@ -32,6 +34,8 @@ module.exports = {
32
34
  "tests/check-gap-analysis-plan-post-e2e.test.cjs",
33
35
  "tests/check-glossary-refs.test.cjs",
34
36
  "tests/check-predicate.test.cjs",
37
+ "tests/check-router-cutover-equivalence.test.cjs",
38
+ "tests/check-router-gate-boundaries.test.cjs",
35
39
  "tests/check-tdd-review-checkpoint-e2e.test.cjs",
36
40
  "tests/check-ui-safety-gate.test.cjs",
37
41
  "tests/check-update-config-dir.test.cjs",
@@ -53,7 +57,7 @@ module.exports = {
53
57
  "tests/codex-config.test.cjs",
54
58
  "tests/codex-inherit-smoke.test.cjs",
55
59
  "tests/command-routing-hub.test.cjs",
56
- "tests/commands.test.cjs",
60
+ "tests/commands.platform.test.cjs",
57
61
  "tests/commit-files-deletion.test.cjs",
58
62
  "tests/commit-files-pathspec.test.cjs",
59
63
  "tests/commonjs-marker.test.cjs",
@@ -63,17 +67,21 @@ module.exports = {
63
67
  "tests/config-get-default.test.cjs",
64
68
  "tests/config-loader.test.cjs",
65
69
  "tests/config-schema.property.test.cjs",
66
- "tests/config.test.cjs",
70
+ "tests/config.platform.test.cjs",
67
71
  "tests/configured-entrypoint-validation.test.cjs",
72
+ "tests/context-drift.test.cjs",
68
73
  "tests/copilot-install.test.cjs",
69
74
  "tests/copilot-upgrades.test.cjs",
70
75
  "tests/core-utils.test.cjs",
71
76
  "tests/cursor-hook-workspace-roots.test.cjs",
72
77
  "tests/cursor-hooks.test.cjs",
73
78
  "tests/cursor-subagent-isolation.test.cjs",
79
+ "tests/debug-session-management.test.cjs",
74
80
  "tests/dispatch-identity.test.cjs",
75
81
  "tests/dispatcher.test.cjs",
76
82
  "tests/drift-detection.test.cjs",
83
+ "tests/drift-whole-change-set.test.cjs",
84
+ "tests/effort-local-install.test.cjs",
77
85
  "tests/effort-surface-axis.test.cjs",
78
86
  "tests/effort-sync-installed-runtime.test.cjs",
79
87
  "tests/emitted-ack-trailer.test.cjs",
@@ -95,6 +103,16 @@ module.exports = {
95
103
  "tests/features-index-gate.test.cjs",
96
104
  "tests/frontmatter.test.cjs",
97
105
  "tests/gap-checker.property.test.cjs",
106
+ "tests/gate-api-coverage-verify-pre-escape.test.cjs",
107
+ "tests/gate-consumer-exit-awareness.test.cjs",
108
+ "tests/gate-decision-coverage-verify-stderr.test.cjs",
109
+ "tests/gate-exit.test.cjs",
110
+ "tests/gate-tdd-red-evidence-containment.test.cjs",
111
+ "tests/gate-tdd-review-checkpoint-hardening.test.cjs",
112
+ "tests/gate-tdd-review-checkpoint.unit.test.cjs",
113
+ "tests/gate-ui-plan.unit.test.cjs",
114
+ "tests/gate-ui-safety.unit.test.cjs",
115
+ "tests/gate-verify-command-paths.unit.test.cjs",
98
116
  "tests/gemini-runtime-removed.test.cjs",
99
117
  "tests/gen-context-index.test.cjs",
100
118
  "tests/gen-health-docs.test.cjs",
@@ -118,12 +136,12 @@ module.exports = {
118
136
  "tests/helpers-cleanup.test.cjs",
119
137
  "tests/helpers-process-isolation.test.cjs",
120
138
  "tests/hermes-skills-migration.test.cjs",
139
+ "tests/hook-activation-probe.test.cjs",
121
140
  "tests/hooks-commonjs-marker.test.cjs",
122
141
  "tests/hooks-crash-policy.test.cjs",
123
142
  "tests/hooks-opt-in.test.cjs",
124
143
  "tests/host-integration.test.cjs",
125
144
  "tests/init-manager.test.cjs",
126
- "tests/init.test.cjs",
127
145
  "tests/install-minimal-hooks.test.cjs",
128
146
  "tests/install-nested-layout.test.cjs",
129
147
  "tests/install-path-detection.test.cjs",
@@ -145,6 +163,7 @@ module.exports = {
145
163
  "tests/kimi-agent-converter.test.cjs",
146
164
  "tests/kimi-upgrades.test.cjs",
147
165
  "tests/kimi-variant-disambiguation.test.cjs",
166
+ "tests/launcher-homes-derivation.test.cjs",
148
167
  "tests/lint-phase-arg-assignment.test.cjs",
149
168
  "tests/lint-workflow-shellcheck-fetch.test.cjs",
150
169
  "tests/live-config-guard.test.cjs",
@@ -170,6 +189,7 @@ module.exports = {
170
189
  "tests/no-unbounded-dirname-walk.rule.test.cjs",
171
190
  "tests/no-unbounded-spawn.test.cjs",
172
191
  "tests/no-unguarded-nonportable-exec.rule.test.cjs",
192
+ "tests/node-compile-cache.test.cjs",
173
193
  "tests/npm-audit-baseline.test.cjs",
174
194
  "tests/npm-integrity-gate.test.cjs",
175
195
  "tests/nsegment-phase-grammar.test.cjs",
@@ -185,7 +205,7 @@ module.exports = {
185
205
  "tests/phase-completion-single-owner.test.cjs",
186
206
  "tests/phase-estimation.test.cjs",
187
207
  "tests/phase-locator.test.cjs",
188
- "tests/phase.test.cjs",
208
+ "tests/phase.platform.test.cjs",
189
209
  "tests/phase6-capstone-conformance.test.cjs",
190
210
  "tests/pi-config-dir-env-override.test.cjs",
191
211
  "tests/plan-count-single-owner.test.cjs",
@@ -212,6 +232,7 @@ module.exports = {
212
232
  "tests/profile-pipeline.test.cjs",
213
233
  "tests/prohibition-enforcement.test.cjs",
214
234
  "tests/project-root.test.cjs",
235
+ "tests/quick-batch-command-router.stdin.test.cjs",
215
236
  "tests/quick-batch.test.cjs",
216
237
  "tests/quick-branching.test.cjs",
217
238
  "tests/quick-research.test.cjs",
@@ -238,15 +259,18 @@ module.exports = {
238
259
  "tests/roadmap-parser.test.cjs",
239
260
  "tests/roadmap-upgrade-bracket.test.cjs",
240
261
  "tests/roadmap.test.cjs",
262
+ "tests/run-tests-accounting.test.cjs",
241
263
  "tests/run-tests-harness.test.cjs",
242
264
  "tests/run-tests-temp-root.test.cjs",
243
265
  "tests/run-with-timeout.test.cjs",
244
266
  "tests/runtime-artifact-layout-surface.test.cjs",
245
267
  "tests/runtime-artifact-layout.test.cjs",
246
268
  "tests/runtime-converters.test.cjs",
269
+ "tests/runtime-descriptor-owner.test.cjs",
247
270
  "tests/runtime-homes-descriptor-drive.test.cjs",
248
271
  "tests/runtime-identity.test.cjs",
249
272
  "tests/runtime-launcher-parity.test.cjs",
273
+ "tests/schema-drift.test.cjs",
250
274
  "tests/security.test.cjs",
251
275
  "tests/settings-jsonc.test.cjs",
252
276
  "tests/sh-hook-paths.test.cjs",
@@ -258,10 +282,12 @@ module.exports = {
258
282
  "tests/skill-manifest.test.cjs",
259
283
  "tests/slug-derivation-drift-guard.test.cjs",
260
284
  "tests/state-todos-render.test.cjs",
261
- "tests/state.test.cjs",
285
+ "tests/state.platform.test.cjs",
262
286
  "tests/teams-status.test.cjs",
263
287
  "tests/test-gate-watch-mode.test.cjs",
264
288
  "tests/todos-workstream-scope.test.cjs",
289
+ "tests/uat-complete-session.test.cjs",
290
+ "tests/ui-auditor-screenshot-block.test.cjs",
265
291
  "tests/ui-interaction-capture.test.cjs",
266
292
  "tests/undo-commit-selection-4465.test.cjs",
267
293
  "tests/undo-commit-selection.test.cjs",
@@ -270,9 +296,12 @@ module.exports = {
270
296
  "tests/unusable-input.test.cjs",
271
297
  "tests/update-custom-backup.test.cjs",
272
298
  "tests/user-artifact-staging.test.cjs",
299
+ "tests/verification-append-audit.test.cjs",
273
300
  "tests/verification-status.test.cjs",
274
301
  "tests/verify-archive-dirs-live-path.test.cjs",
275
302
  "tests/verify-command-grounding.test.cjs",
303
+ "tests/verify-lifecycle-writes-e2e.test.cjs",
304
+ "tests/verify-work-auto-transition.test.cjs",
276
305
  "tests/verify.test.cjs",
277
306
  "tests/windsurf-hooks-bridge.test.cjs",
278
307
  "tests/workflow-guard.test.cjs",
@@ -0,0 +1,155 @@
1
+ 'use strict';
2
+
3
+ // Registration ledger preload for scripts/run-tests.cjs (#4031).
4
+ //
5
+ // Why this exists. The runner passes `--test-force-exit` to every chunk (the
6
+ // Windows post-test hang backstop, #1051/#869). Under process isolation each
7
+ // test file's child streams its results to the `node --test` parent over a
8
+ // pipe, and a force-exit can end the parent while bytes of that pipe are still
9
+ // unread (nodejs/node#64833). The reporters never see the lost tail, so the
10
+ // run printed a smaller pass count and exited 0: a test that executed and
11
+ // passed (or failed) was indistinguishable from one that never existed.
12
+ //
13
+ // The parent cannot know what it did not receive, so the count of results the
14
+ // child produced has to come from the child, over a channel that does not
15
+ // share the pipe: this module is loaded into each test-file child with
16
+ // `--require` (`--test` forwards it to the file children) and counts the leaf
17
+ // `test:pass` / `test:fail` events the child's own reporter hands to the V8
18
+ // serializer that frames them onto that pipe, keyed by the `file` each event
19
+ // carries. When the child exits it appends one line per file to the file named
20
+ // by GSD_RUN_TESTS_LEDGER_FILE. The runner compares that per-file count with
21
+ // the leaf results its ndjson reporter actually received
22
+ // (analyzeChunkAccounting in run-tests.cjs) and fails the chunk when
23
+ // registered > reported.
24
+ //
25
+ // Why it taps the serializer and does NOT wrap `test()` / `it()`. node:test
26
+ // stamps every test with the location of the code that called it
27
+ // (`getCallerLocation()` in lib/internal/test_runner/harness.js) and reports
28
+ // that as the event's `file`. A wrapper around `test` is a JS frame between the
29
+ // test file and node:test, so every event would report THIS file as its
30
+ // location: spec-reporter failure locations would point here and no result
31
+ // could be matched back to its test file. Counting at the serializer adds no
32
+ // frame to the call and counts exactly what is put on the pipe, so the count
33
+ // and the parent's report are compared like for like: a skipped or todo test,
34
+ // a skipped suite and a test name/only filter need no special case
35
+ // (an excluded test emits no event on either side).
36
+ //
37
+ // Blind spots, stated plainly: a child that emits nothing counts 0 (no loss is
38
+ // visible); a SIGKILLed child never runs the `exit` handler below, so it leaves no
39
+ // ledger line; a file the parent reported but the ledger never saw is not flagged
40
+ // per file; and the whole count depends on node:test's child reporter framing its
41
+ // events through v8.DefaultSerializer.prototype.writeValue (true on Node 24). If a
42
+ // Node change moves that, every count becomes 0: the runner then fails a chunk whose
43
+ // ledger counted 0 while its reporter received results (analyzeChunkAccounting,
44
+ // `ledgerCountedNothing`), and tests/run-tests-accounting.test.cjs pins the hook.
45
+ //
46
+ // Inert unless it is inside a test-file child (NODE_TEST_CONTEXT is set by
47
+ // `node --test` for those, not for the runner parent), so requiring it anywhere
48
+ // else is a no-op. There it does two things: it makes the child's stdout pipe
49
+ // blocking (blockChildStdout: this is what stops `--test-force-exit` from
50
+ // discarding queued results, the loss this accounting exists to detect), and,
51
+ // when a ledger path was supplied, counts results. Never throws into the code it
52
+ // observes.
53
+
54
+ const fs = require('fs');
55
+ const path = require('path');
56
+ const { DefaultSerializer } = require('v8');
57
+
58
+ const RESULT_TYPES = new Set(['test:pass', 'test:fail']);
59
+
60
+ /**
61
+ * The file a reporter event counts toward, or null when the event is not a leaf test result the
62
+ * runner's ndjson reporter would record (anything but a pass/fail, a suite, an event with no file).
63
+ * analyzeChunkAccounting applies the same three conditions to the events it reads back.
64
+ */
65
+ function resultFileOf(item) {
66
+ if (item === null || typeof item !== 'object' || !RESULT_TYPES.has(item.type)) return null;
67
+ const data = item.data;
68
+ if (data === null || typeof data !== 'object' || typeof data.file !== 'string') return null;
69
+ if (data.details && data.details.type === 'suite') return null;
70
+ return data.file;
71
+ }
72
+
73
+ /**
74
+ * One spelling for every ledger line: the real path. node reports a result's `file` already resolved
75
+ * through symlinks (macOS /var -> /private/var), while a zero-result child's only name is process.argv[1],
76
+ * as given, so without this the two kinds of line disagree on the same file. Best-effort: a path that cannot
77
+ * be resolved keeps its absolute spelling (analyzeChunkAccounting normalizes both sides again regardless).
78
+ */
79
+ function canonicalPath(file) {
80
+ const absolute = path.resolve(file);
81
+ try {
82
+ return fs.realpathSync.native(absolute);
83
+ } catch {
84
+ return absolute;
85
+ }
86
+ }
87
+
88
+ function install(ledgerPath,serializerPrototype = DefaultSerializer.prototype) {
89
+ const counts = new Map(); // file -> leaf results handed to the serializer
90
+
91
+ const original = serializerPrototype.writeValue;
92
+ serializerPrototype.writeValue = function writeValueCountingResults(value) {
93
+ try {
94
+ const file = resultFileOf(value);
95
+ if (file !== null) counts.set(file, (counts.get(file) || 0) + 1);
96
+ } catch {
97
+ // Counting must never change what is serialized.
98
+ }
99
+ return Reflect.apply(original, this, arguments);
100
+ };
101
+
102
+ process.on('exit', () => {
103
+ try {
104
+ // A child that produced no result still records itself (count 0), so the runner can tell
105
+ // "the preload ran and saw nothing" from "the preload never ran".
106
+ if (counts.size === 0 && process.argv[1]) counts.set(process.argv[1], 0);
107
+ const lines = [];
108
+ for (const [file, count] of counts) {
109
+ lines.push(JSON.stringify({ type: 'registered', file: canonicalPath(file), count }));
110
+ }
111
+ fs.appendFileSync(ledgerPath, `${lines.join('\n')}\n`);
112
+ } catch {
113
+ // Best-effort: the ledger is a diagnostic channel and must never change
114
+ // the exit status of the test file it observes.
115
+ }
116
+ });
117
+ }
118
+
119
+ /**
120
+ * Make the test-file child's stdout (the pipe its results travel to the `node --test` parent on)
121
+ * blocking, so every frame it wrote has reached the OS when the child exits.
122
+ *
123
+ * Why: the runner passes `--test-force-exit`, and node forwards it to each file child. A forced
124
+ * child calls process.exit() as soon as its root test ends; its stdout is a non-blocking pipe on
125
+ * POSIX, so frames still queued in the Socket are discarded and the parent never receives those
126
+ * results (nodejs/node#64833; the fix proposed there, nodejs/node#64875, does exactly this with
127
+ * `_handle.setBlocking(true)` at force-exit). Measured on Node 24.18 / Linux with 20 files x 300
128
+ * tests, `--test-force-exit --test-concurrency=8`: 5039-5139 of 6000 results reported without
129
+ * this, 6000 of 6000 with it (and 6000 without force-exit). Doing it at load time rather than at
130
+ * exit means nothing is ever queued. The Windows hang guard that force-exit exists for (#1051)
131
+ * is untouched. Best-effort: a stdout with no pipe handle (a file, a TTY) is left alone.
132
+ */
133
+ function blockChildStdout(stdout) {
134
+ try {
135
+ const target = stdout === undefined ? process.stdout : stdout;
136
+ const handle = target && target._handle;
137
+ if (handle && typeof handle.setBlocking === 'function') {
138
+ handle.setBlocking(true);
139
+ return true;
140
+ }
141
+ } catch {
142
+ // Never throw into the test file this observes.
143
+ }
144
+ return false;
145
+ }
146
+
147
+ // Inside a test-file child only (NODE_TEST_CONTEXT is set by `node --test` for those, not for the
148
+ // runner parent): the blocking stdout needs no ledger path; the ledger count needs one.
149
+ if (process.env.NODE_TEST_CONTEXT) {
150
+ blockChildStdout();
151
+ const ledgerPath = process.env.GSD_RUN_TESTS_LEDGER_FILE;
152
+ if (ledgerPath) install(ledgerPath);
153
+ }
154
+
155
+ module.exports = { install, resultFileOf, blockChildStdout };