@opengsd/gsd-core 1.12.0 → 1.14.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 (455) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +12 -0
  4. package/agents/gsd-advisor-researcher.compact.md +85 -0
  5. package/agents/gsd-ai-researcher.compact.md +96 -0
  6. package/agents/gsd-assumptions-analyzer.compact.md +81 -0
  7. package/agents/gsd-code-fixer.compact.md +458 -0
  8. package/agents/gsd-code-fixer.md +5 -5
  9. package/agents/gsd-code-reviewer.compact.md +269 -0
  10. package/agents/gsd-code-reviewer.md +15 -3
  11. package/agents/gsd-codebase-mapper.compact.md +760 -0
  12. package/agents/gsd-debug-session-manager.compact.md +345 -0
  13. package/agents/gsd-doc-classifier.compact.md +192 -0
  14. package/agents/gsd-doc-synthesizer.compact.md +200 -0
  15. package/agents/gsd-doc-verifier.compact.md +143 -0
  16. package/agents/gsd-doc-writer.compact.md +440 -0
  17. package/agents/gsd-dom-verifier.compact.md +138 -0
  18. package/agents/gsd-domain-researcher.compact.md +141 -0
  19. package/agents/gsd-eval-auditor.compact.md +160 -0
  20. package/agents/gsd-eval-planner.compact.md +137 -0
  21. package/agents/gsd-executor.md +63 -35
  22. package/agents/gsd-framework-selector.compact.md +82 -0
  23. package/agents/gsd-integration-checker.compact.md +245 -0
  24. package/agents/gsd-intel-updater.compact.md +226 -0
  25. package/agents/gsd-mempalace-curator.compact.md +45 -0
  26. package/agents/gsd-nyquist-auditor.compact.md +179 -0
  27. package/agents/gsd-pattern-mapper.compact.md +275 -0
  28. package/agents/gsd-plan-checker.md +76 -57
  29. package/agents/gsd-planner.md +14 -0
  30. package/agents/gsd-project-researcher.compact.md +587 -0
  31. package/agents/gsd-research-synthesizer.compact.md +212 -0
  32. package/agents/gsd-roadmapper.compact.md +454 -0
  33. package/agents/gsd-roadmapper.md +13 -0
  34. package/agents/gsd-security-auditor.compact.md +162 -0
  35. package/agents/gsd-ui-auditor.compact.md +404 -0
  36. package/agents/gsd-ui-checker.compact.md +277 -0
  37. package/agents/gsd-ui-checker.md +19 -3
  38. package/agents/gsd-ui-researcher.compact.md +282 -0
  39. package/agents/gsd-ui-researcher.md +29 -0
  40. package/agents/gsd-user-profiler.compact.md +108 -0
  41. package/agents/gsd-verifier.md +23 -1
  42. package/bin/install.js +444 -134
  43. package/commands/gsd/cleanup.md +1 -0
  44. package/commands/gsd/code-review.md +2 -1
  45. package/commands/gsd/complete-milestone.md +1 -0
  46. package/commands/gsd/config.md +1 -0
  47. package/commands/gsd/debug.md +1 -0
  48. package/commands/gsd/execute-phase.md +1 -1
  49. package/commands/gsd/graphify.md +1 -0
  50. package/commands/gsd/health.md +1 -0
  51. package/commands/gsd/mempalace-capture.md +1 -0
  52. package/commands/gsd/mempalace-recall.md +1 -0
  53. package/commands/gsd/new-milestone.md +1 -0
  54. package/commands/gsd/new-project.md +1 -0
  55. package/commands/gsd/next.md +1 -0
  56. package/commands/gsd/ns-workflow.md +2 -1
  57. package/commands/gsd/pause-work.md +1 -0
  58. package/commands/gsd/phase.md +2 -1
  59. package/commands/gsd/pr-branch.md +1 -0
  60. package/commands/gsd/quick-batch.md +105 -0
  61. package/commands/gsd/resume-work.md +1 -0
  62. package/commands/gsd/review-backlog.md +1 -0
  63. package/commands/gsd/settings.md +2 -1
  64. package/commands/gsd/stats.md +1 -0
  65. package/commands/gsd/surface.md +18 -8
  66. package/commands/gsd/thread.md +1 -0
  67. package/commands/gsd/workspace.md +1 -0
  68. package/commands/gsd/workstreams.md +1 -0
  69. package/gsd-core/bin/check-latest-version.cjs +8 -3
  70. package/gsd-core/bin/gsd-tools.cjs +532 -174
  71. package/gsd-core/bin/lib/adr-parser.cjs +1 -1
  72. package/gsd-core/bin/lib/artifacts.cjs +2 -1
  73. package/gsd-core/bin/lib/audit.cjs +39 -22
  74. package/gsd-core/bin/lib/broken-windows.cjs +168 -49
  75. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  76. package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
  77. package/gsd-core/bin/lib/capability-loader.cjs +135 -1
  78. package/gsd-core/bin/lib/capability-registry.cjs +528 -116
  79. package/gsd-core/bin/lib/capability-source.cjs +19 -2
  80. package/gsd-core/bin/lib/capability-state.cjs +7 -1
  81. package/gsd-core/bin/lib/capability-validator.cjs +134 -5
  82. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  83. package/gsd-core/bin/lib/check-command-router.cjs +198 -38
  84. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  85. package/gsd-core/bin/lib/clusters.cjs +1 -0
  86. package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
  87. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  88. package/gsd-core/bin/lib/commands.cjs +981 -79
  89. package/gsd-core/bin/lib/config-loader.cjs +4 -0
  90. package/gsd-core/bin/lib/config.cjs +153 -38
  91. package/gsd-core/bin/lib/core-utils.cjs +34 -7
  92. package/gsd-core/bin/lib/coverage.cjs +1 -1
  93. package/gsd-core/bin/lib/decisions.cjs +343 -28
  94. package/gsd-core/bin/lib/edge-probe.cjs +14 -1
  95. package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
  96. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  97. package/gsd-core/bin/lib/frontmatter.cjs +137 -23
  98. package/gsd-core/bin/lib/gap-checker.cjs +22 -13
  99. package/gsd-core/bin/lib/git-base-branch.cjs +10 -2
  100. package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
  101. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  102. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +54 -11
  103. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +87 -23
  104. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
  105. package/gsd-core/bin/lib/host-integration.cjs +57 -5
  106. package/gsd-core/bin/lib/init-command-router.cjs +14 -0
  107. package/gsd-core/bin/lib/init.cjs +539 -60
  108. package/gsd-core/bin/lib/install-engine.cjs +199 -14
  109. package/gsd-core/bin/lib/install-model-override-resolver.cjs +45 -0
  110. package/gsd-core/bin/lib/install-profiles.cjs +36 -14
  111. package/gsd-core/bin/lib/installer-migration-report.cjs +1 -0
  112. package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
  113. package/gsd-core/bin/lib/io.cjs +35 -0
  114. package/gsd-core/bin/lib/loop-resolver.cjs +64 -39
  115. package/gsd-core/bin/lib/markdown-table.cjs +123 -0
  116. package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
  117. package/gsd-core/bin/lib/milestone.cjs +41 -10
  118. package/gsd-core/bin/lib/model-resolver.cjs +101 -10
  119. package/gsd-core/bin/lib/phase-command-router.cjs +20 -7
  120. package/gsd-core/bin/lib/phase-id.cjs +412 -31
  121. package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
  122. package/gsd-core/bin/lib/phase.cjs +941 -98
  123. package/gsd-core/bin/lib/plan-document.cjs +10 -0
  124. package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
  125. package/gsd-core/bin/lib/planning-snapshot.cjs +206 -30
  126. package/gsd-core/bin/lib/planning-workspace.cjs +153 -29
  127. package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
  128. package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
  129. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  130. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  131. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  132. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +61 -2
  133. package/gsd-core/bin/lib/research-store.cjs +11 -12
  134. package/gsd-core/bin/lib/review-lane-descriptor.cjs +53 -5
  135. package/gsd-core/bin/lib/review-lane-invocation.cjs +96 -1
  136. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  137. package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
  138. package/gsd-core/bin/lib/roadmap-parser.cjs +555 -41
  139. package/gsd-core/bin/lib/roadmap.cjs +292 -69
  140. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +260 -43
  141. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +28 -20
  142. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +294 -108
  143. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +408 -47
  144. package/gsd-core/bin/lib/security.cjs +126 -7
  145. package/gsd-core/bin/lib/shell-command-projection.cjs +4 -0
  146. package/gsd-core/bin/lib/smart-entry.cjs +7 -9
  147. package/gsd-core/bin/lib/state-document.cjs +159 -32
  148. package/gsd-core/bin/lib/state-md-schema.cjs +44 -27
  149. package/gsd-core/bin/lib/state-transition.cjs +465 -62
  150. package/gsd-core/bin/lib/state.cjs +906 -151
  151. package/gsd-core/bin/lib/surface.cjs +83 -10
  152. package/gsd-core/bin/lib/task-command-router.cjs +12 -6
  153. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  154. package/gsd-core/bin/lib/uat.cjs +1420 -516
  155. package/gsd-core/bin/lib/update-context.cjs +36 -26
  156. package/gsd-core/bin/lib/validate.cjs +230 -12
  157. package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
  158. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  159. package/gsd-core/bin/lib/verification.cjs +316 -23
  160. package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
  161. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  162. package/gsd-core/bin/lib/verify.cjs +531 -36
  163. package/gsd-core/bin/lib/workstream-inventory.cjs +21 -2
  164. package/gsd-core/bin/lib/worktree-safety.cjs +21 -7
  165. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  166. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  167. package/gsd-core/bin/verify-reapply-patches.cjs +507 -81
  168. package/gsd-core/references/agent-contracts.md +3 -3
  169. package/gsd-core/references/compact-content-gate.md +66 -0
  170. package/gsd-core/references/edge-probe.md +17 -13
  171. package/gsd-core/references/execute-mvp-tdd.md +18 -16
  172. package/gsd-core/references/execute-phase-response-language.md +6 -0
  173. package/gsd-core/references/executor-examples.md +42 -0
  174. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  175. package/gsd-core/references/loop-hook-dispatch.md +18 -0
  176. package/gsd-core/references/model-profiles.md +12 -3
  177. package/gsd-core/references/mvp-concepts.md +2 -2
  178. package/gsd-core/references/plan-checker-examples.md +41 -0
  179. package/gsd-core/references/planner-antipatterns.md +25 -0
  180. package/gsd-core/references/planner-chunked.md +5 -1
  181. package/gsd-core/references/planner-coupling.md +42 -0
  182. package/gsd-core/references/planner-quick-batch.md +71 -0
  183. package/gsd-core/references/planner-reviews.md +47 -0
  184. package/gsd-core/references/planner-revision.md +75 -2
  185. package/gsd-core/references/planning-config.md +5 -1
  186. package/gsd-core/references/response-language-directive.md +9 -0
  187. package/gsd-core/references/revision-loop.md +118 -11
  188. package/gsd-core/references/tdd.md +17 -9
  189. package/gsd-core/references/thinking-models-planning.md +18 -2
  190. package/gsd-core/references/verification-patterns.md +17 -4
  191. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  192. package/gsd-core/references/worktree-path-safety.md +112 -2
  193. package/gsd-core/templates/README.md +7 -1
  194. package/gsd-core/templates/phase-prompt.md +4 -0
  195. package/gsd-core/templates/state.md +6 -3
  196. package/gsd-core/templates/summary.compact.md +212 -0
  197. package/gsd-core/templates/user-setup.compact.md +199 -0
  198. package/gsd-core/templates/user-setup.md +0 -9
  199. package/gsd-core/templates/verification-report.md +5 -0
  200. package/gsd-core/workflows/add-backlog.md +2 -0
  201. package/gsd-core/workflows/add-phase.md +2 -0
  202. package/gsd-core/workflows/add-tests.md +1 -1
  203. package/gsd-core/workflows/add-todo.md +4 -3
  204. package/gsd-core/workflows/ai-integration-phase.md +1 -1
  205. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  206. package/gsd-core/workflows/audit-fix.md +2 -0
  207. package/gsd-core/workflows/audit-milestone.md +2 -0
  208. package/gsd-core/workflows/audit-uat.md +2 -0
  209. package/gsd-core/workflows/autonomous.md +15 -10
  210. package/gsd-core/workflows/check-todos.md +5 -3
  211. package/gsd-core/workflows/cleanup.md +4 -2
  212. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +22 -13
  213. package/gsd-core/workflows/code-review-fix.md +5 -3
  214. package/gsd-core/workflows/code-review.md +211 -43
  215. package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
  216. package/gsd-core/workflows/complete-milestone.md +40 -254
  217. package/gsd-core/workflows/debug.md +1 -1
  218. package/gsd-core/workflows/diagnose-issues.md +5 -1
  219. package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -0
  220. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  221. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  222. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  223. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  224. package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -0
  225. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  226. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  227. package/gsd-core/workflows/discuss-phase/modes/text.md +2 -0
  228. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  229. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  230. package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
  231. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  232. package/gsd-core/workflows/discuss-phase.md +1 -1
  233. package/gsd-core/workflows/do.md +43 -13
  234. package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
  235. package/gsd-core/workflows/docs-update.md +15 -156
  236. package/gsd-core/workflows/edit-phase.md +2 -0
  237. package/gsd-core/workflows/eval-review.md +1 -1
  238. package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
  239. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +20 -3
  240. package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
  241. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +24 -3
  242. package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
  243. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +8 -2
  244. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -0
  245. package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
  246. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  247. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  248. package/gsd-core/workflows/execute-phase.md +78 -159
  249. package/gsd-core/workflows/execute-plan.md +28 -15
  250. package/gsd-core/workflows/explore.md +2 -0
  251. package/gsd-core/workflows/extract-learnings.md +2 -0
  252. package/gsd-core/workflows/fast.md +6 -0
  253. package/gsd-core/workflows/forensics.md +2 -0
  254. package/gsd-core/workflows/graduation.md +1 -1
  255. package/gsd-core/workflows/health.md +1 -1
  256. package/gsd-core/workflows/help/modes/brief.md +2 -0
  257. package/gsd-core/workflows/help/modes/default.md +2 -0
  258. package/gsd-core/workflows/help/modes/full.compact.md +398 -0
  259. package/gsd-core/workflows/help/modes/full.md +12 -0
  260. package/gsd-core/workflows/help/modes/topic.md +2 -0
  261. package/gsd-core/workflows/help.md +3 -1
  262. package/gsd-core/workflows/import.md +3 -3
  263. package/gsd-core/workflows/inbox.md +1 -1
  264. package/gsd-core/workflows/ingest-docs.md +1 -1
  265. package/gsd-core/workflows/insert-phase.md +2 -0
  266. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  267. package/gsd-core/workflows/list-seeds.md +2 -0
  268. package/gsd-core/workflows/list-workspaces.md +2 -0
  269. package/gsd-core/workflows/manager.md +3 -3
  270. package/gsd-core/workflows/map-codebase.md +52 -3
  271. package/gsd-core/workflows/milestone-summary.md +2 -0
  272. package/gsd-core/workflows/mvp-phase.md +1 -1
  273. package/gsd-core/workflows/new-milestone.md +55 -13
  274. package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
  275. package/gsd-core/workflows/new-project.md +37 -205
  276. package/gsd-core/workflows/new-workspace.md +1 -1
  277. package/gsd-core/workflows/next.md +2 -0
  278. package/gsd-core/workflows/node-repair.md +2 -0
  279. package/gsd-core/workflows/note.md +2 -0
  280. package/gsd-core/workflows/onboard.md +1 -1
  281. package/gsd-core/workflows/pause-work.md +19 -4
  282. package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
  283. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  284. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +2 -0
  285. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +9 -0
  286. package/gsd-core/workflows/plan-phase.md +144 -185
  287. package/gsd-core/workflows/plan-review-convergence.md +102 -10
  288. package/gsd-core/workflows/plant-seed.md +1 -1
  289. package/gsd-core/workflows/pr-branch.md +30 -10
  290. package/gsd-core/workflows/profile-user.md +1 -1
  291. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  292. package/gsd-core/workflows/progress.md +25 -3
  293. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +37 -2
  294. package/gsd-core/workflows/quick/steps/research-phase.md +3 -3
  295. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  296. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  297. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  298. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  299. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  300. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  301. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  302. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  303. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  304. package/gsd-core/workflows/quick-batch.md +203 -0
  305. package/gsd-core/workflows/quick.md +21 -4
  306. package/gsd-core/workflows/reapply-patches.md +79 -3
  307. package/gsd-core/workflows/remove-phase.md +2 -0
  308. package/gsd-core/workflows/remove-workspace.md +1 -1
  309. package/gsd-core/workflows/resume-project.md +6 -2
  310. package/gsd-core/workflows/review.md +215 -10
  311. package/gsd-core/workflows/scan.md +2 -0
  312. package/gsd-core/workflows/section-manifest.json +12 -0
  313. package/gsd-core/workflows/secure-phase.md +1 -1
  314. package/gsd-core/workflows/session-report.md +2 -0
  315. package/gsd-core/workflows/settings-advanced.md +2 -0
  316. package/gsd-core/workflows/settings-integrations.md +9 -8
  317. package/gsd-core/workflows/settings.md +19 -6
  318. package/gsd-core/workflows/ship.md +10 -10
  319. package/gsd-core/workflows/sketch-wrap-up.md +2 -0
  320. package/gsd-core/workflows/sketch.md +1 -1
  321. package/gsd-core/workflows/smart-entry.md +1 -1
  322. package/gsd-core/workflows/spec-phase.md +24 -19
  323. package/gsd-core/workflows/spike-wrap-up.md +2 -0
  324. package/gsd-core/workflows/spike.md +1 -1
  325. package/gsd-core/workflows/stats.md +2 -0
  326. package/gsd-core/workflows/sync-skills.md +12 -4
  327. package/gsd-core/workflows/thread.md +2 -0
  328. package/gsd-core/workflows/transition.md +2 -0
  329. package/gsd-core/workflows/ui-phase.md +26 -5
  330. package/gsd-core/workflows/ui-review.md +1 -1
  331. package/gsd-core/workflows/ultraplan-phase.md +2 -0
  332. package/gsd-core/workflows/undo.md +1 -1
  333. package/gsd-core/workflows/update.md +48 -43
  334. package/gsd-core/workflows/validate-phase.md +1 -1
  335. package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
  336. package/gsd-core/workflows/verify-work.md +68 -182
  337. package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
  338. package/hooks/dist/gsd-check-update-worker.js +19 -2
  339. package/hooks/dist/gsd-context-monitor.js +371 -27
  340. package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
  341. package/hooks/dist/gsd-node-runner.sh +1 -0
  342. package/hooks/dist/gsd-prompt-guard.js +30 -5
  343. package/hooks/dist/gsd-read-guard.js +2 -0
  344. package/hooks/dist/gsd-read-injection-scanner.js +5 -5
  345. package/hooks/dist/gsd-secret-read-guard.js +1105 -0
  346. package/hooks/dist/gsd-statusline.js +18 -10
  347. package/hooks/dist/gsd-validate-commit.sh +474 -7
  348. package/hooks/dist/gsd-workflow-guard.js +2 -1
  349. package/hooks/dist/gsd-worktree-path-guard.js +25 -14
  350. package/hooks/dist/gsd-write-guard.js +46 -1
  351. package/hooks/dist/lib/dispatch-identity.js +187 -0
  352. package/hooks/dist/lib/filename-classification.js +64 -0
  353. package/hooks/dist/lib/git-cmd.js +210 -1
  354. package/hooks/dist/lib/injection-patterns.js +36 -6
  355. package/hooks/dist/lib/isolation-deny-reason.js +53 -1
  356. package/hooks/dist/lib/isolation-sentinel.js +58 -19
  357. package/hooks/dist/managed-hooks-registry.cjs +1 -0
  358. package/hooks/gsd-agent-isolation-guard.js +42 -16
  359. package/hooks/gsd-check-update-worker.js +19 -2
  360. package/hooks/gsd-context-monitor.js +371 -27
  361. package/hooks/gsd-cursor-subagent-start.js +34 -14
  362. package/hooks/gsd-node-runner.sh +1 -0
  363. package/hooks/gsd-prompt-guard.js +30 -5
  364. package/hooks/gsd-read-guard.js +2 -0
  365. package/hooks/gsd-read-injection-scanner.js +5 -5
  366. package/hooks/gsd-secret-read-guard.js +1105 -0
  367. package/hooks/gsd-statusline.js +18 -10
  368. package/hooks/gsd-validate-commit.sh +474 -7
  369. package/hooks/gsd-workflow-guard.js +2 -1
  370. package/hooks/gsd-worktree-path-guard.js +25 -14
  371. package/hooks/gsd-write-guard.js +46 -1
  372. package/hooks/hooks.json +6 -0
  373. package/hooks/lib/dispatch-identity.js +187 -0
  374. package/hooks/lib/filename-classification.js +64 -0
  375. package/hooks/lib/git-cmd.js +210 -1
  376. package/hooks/lib/injection-patterns.js +36 -6
  377. package/hooks/lib/isolation-deny-reason.js +53 -1
  378. package/hooks/lib/isolation-sentinel.js +58 -19
  379. package/hooks/managed-hooks-registry.cjs +1 -0
  380. package/package.json +13 -9
  381. package/scripts/benchmark-compact-content-variants.cjs +298 -0
  382. package/scripts/benchmark-compact-content.cjs +368 -0
  383. package/scripts/build-hooks.js +11 -4
  384. package/scripts/check-contract-drift.cjs +4 -1
  385. package/scripts/check-env.cjs +36 -8
  386. package/scripts/check-glossary-refs.cjs +25 -21
  387. package/scripts/ci-next-health.cjs +271 -0
  388. package/scripts/ci-prepare-test-scope.cjs +7 -7
  389. package/scripts/ci-test-scope.cjs +133 -20
  390. package/scripts/ci-timeout-report.cjs +1 -1
  391. package/scripts/diff-touches-shipped-paths.cjs +1 -1
  392. package/scripts/docs-guard-registry.cjs +17 -2
  393. package/scripts/gen-adr-index.cjs +8 -2
  394. package/scripts/gen-inventory-manifest.cjs +12 -0
  395. package/scripts/gen-loop-host-contract.cjs +67 -15
  396. package/scripts/gen-platform-conformance-tier.cjs +557 -0
  397. package/scripts/lib/drift-scan.cjs +1 -1
  398. package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
  399. package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
  400. package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
  401. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  402. package/scripts/lib/suite-detection.cjs +32 -0
  403. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  404. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  405. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  406. package/scripts/lint-allowed-tools-parity.cjs +221 -0
  407. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +24 -2
  408. package/scripts/lint-phase-enumeration-drift.cjs +24 -6
  409. package/scripts/lint-phase-id-drift.cjs +465 -15
  410. package/scripts/lint-portable-grep.cjs +176 -0
  411. package/scripts/lint-response-language-coverage.cjs +530 -0
  412. package/scripts/lint-source-test-name-collision.cjs +1 -1
  413. package/scripts/lint-test-file-count.allowlist.json +4 -1
  414. package/scripts/lint-vendored-deps.cjs +128 -17
  415. package/scripts/lint-workflow-shellcheck-baseline.json +1112 -0
  416. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  417. package/scripts/npm-audit-baseline.cjs +376 -0
  418. package/scripts/prompt-injection-scan.sh +22 -0
  419. package/scripts/require-issue-link-policy.cjs +16 -1
  420. package/scripts/workflow-size.cjs +139 -0
  421. package/skills/gsd-cleanup/SKILL.md +1 -0
  422. package/skills/gsd-code-review/SKILL.md +2 -1
  423. package/skills/gsd-complete-milestone/SKILL.md +1 -0
  424. package/skills/gsd-config/SKILL.md +1 -0
  425. package/skills/gsd-debug/SKILL.md +1 -0
  426. package/skills/gsd-execute-phase/SKILL.md +1 -1
  427. package/skills/gsd-graphify/SKILL.md +1 -0
  428. package/skills/gsd-health/SKILL.md +1 -0
  429. package/skills/gsd-mempalace-capture/SKILL.md +1 -0
  430. package/skills/gsd-mempalace-recall/SKILL.md +1 -0
  431. package/skills/gsd-new-milestone/SKILL.md +1 -0
  432. package/skills/gsd-new-project/SKILL.md +1 -0
  433. package/skills/gsd-next/SKILL.md +1 -0
  434. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  435. package/skills/gsd-pause-work/SKILL.md +1 -0
  436. package/skills/gsd-phase/SKILL.md +2 -1
  437. package/skills/gsd-pr-branch/SKILL.md +1 -0
  438. package/skills/gsd-quick-batch/SKILL.md +105 -0
  439. package/skills/gsd-resume-work/SKILL.md +1 -0
  440. package/skills/gsd-review-backlog/SKILL.md +1 -0
  441. package/skills/gsd-settings/SKILL.md +2 -1
  442. package/skills/gsd-stats/SKILL.md +1 -0
  443. package/skills/gsd-surface/SKILL.md +18 -8
  444. package/skills/gsd-thread/SKILL.md +1 -0
  445. package/skills/gsd-workspace/SKILL.md +1 -0
  446. package/skills/gsd-workstreams/SKILL.md +1 -0
  447. package/vscode/package.json +1 -1
  448. package/gsd-core/templates/claude-md.md +0 -145
  449. package/gsd-core/templates/codebase/concerns.md +0 -310
  450. package/gsd-core/templates/codebase/conventions.md +0 -307
  451. package/gsd-core/templates/codebase/integrations.md +0 -280
  452. package/gsd-core/templates/codebase/structure.md +0 -285
  453. package/gsd-core/templates/codebase/testing.md +0 -480
  454. package/gsd-core/templates/debug-subagent-prompt.md +0 -91
  455. package/gsd-core/templates/discovery.md +0 -146
@@ -165,7 +165,7 @@ function normalizeSkillManifest(runtimeConfigDir, manifest) {
165
165
  * - registry is threaded into resolveProfile so capability skills
166
166
  * participate in the base skill set and their requires: chains expand.
167
167
  */
168
- function resolveSurface(runtimeConfigDir, manifest, clusterMap, registry) {
168
+ function resolveSurface(runtimeConfigDir, manifest, clusterMap, registry, surfaceOverride) {
169
169
  // Merge capability clusters into the cluster map when registry is provided.
170
170
  // The ADR-857 phase 4a HARD gate guarantees that when a capId matches a CLUSTERS
171
171
  // key, the values are EQUAL — so the spread is idempotent for matching names.
@@ -205,7 +205,7 @@ function resolveSurface(runtimeConfigDir, manifest, clusterMap, registry) {
205
205
  cm = merged;
206
206
  }
207
207
  const skillManifest = normalizeSkillManifest(runtimeConfigDir, manifest);
208
- const surface = readSurface(runtimeConfigDir);
208
+ const surface = surfaceOverride === undefined ? readSurface(runtimeConfigDir) : surfaceOverride;
209
209
  // Determine base profile name: from surface state or from .gsd-profile marker
210
210
  const baseProfileName = (surface && surface.baseProfile)
211
211
  ? surface.baseProfile
@@ -316,10 +316,9 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap, registry,
316
316
  os: deps.os, env: deps.env,
317
317
  });
318
318
  const skillManifest = normalizeSkillManifest(layout.configDir, manifest);
319
- const resolved = resolveSurface(layout.configDir, skillManifest, clusterMap, registry);
320
- // Profile toggles must converge retired surfaces too. Once a kind disappears
321
- // from artifactLayout there is no normal sync pass left to prune it (#2644).
322
- retiredArtifactCleanup.pruneRetiredRuntimeArtifacts(layout.runtime, layout.configDir);
319
+ const hasCandidateState = opts !== undefined && Object.prototype.hasOwnProperty.call(opts, 'surfaceState');
320
+ const candidateState = hasCandidateState ? (opts.surfaceState ?? null) : undefined;
321
+ const resolved = resolveSurface(layout.configDir, skillManifest, clusterMap, registry, candidateState);
323
322
  // #1575: agents kind now mirrors createRuntimeArtifactInstallPlan — build
324
323
  // agentCtx (pathPrefix + attribution) and pass it to kind.stage() so
325
324
  // stageAgentsForRuntimeWithConverter applies the full inline-loop pipeline
@@ -353,7 +352,7 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap, registry,
353
352
  // not referenced by any skill's _calls_agents_ manifest entry would be silently
354
353
  // dropped from the surface path. For tiered profiles (core/standard) or when
355
354
  // surface mods exist, pass the resolved set so only the filtered subset stages.
356
- const _surfaceState = readSurface(layout.configDir);
355
+ const _surfaceState = candidateState === undefined ? readSurface(layout.configDir) : candidateState;
357
356
  const _baseProfileName = (_surfaceState && _surfaceState.baseProfile)
358
357
  ? _surfaceState.baseProfile
359
358
  : (readActiveProfile(layout.configDir) || 'full');
@@ -361,17 +360,29 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap, registry,
361
360
  _surfaceState.explicitAdds.length > 0 ||
362
361
  _surfaceState.explicitRemoves.length > 0);
363
362
  const _isUnmodifiedFull = _baseProfileName === 'full' && !_hasSurfaceMods;
363
+ const stagedKinds = [];
364
364
  try {
365
365
  for (const kind of layout.kinds) {
366
366
  let staged;
367
- if (kind.kind === 'agents') {
367
+ // #4211: kimi-agents is an AGENT kind — kimiAgentsKind.stage() forwards
368
+ // agentCtx into stageAgentsForRuntimeWithConverter exactly as agentsKind
369
+ // does, and createRuntimeArtifactInstallPlan hands every kind the
370
+ // context. Staging it bare here dropped the path-prefix rewrites and the
371
+ // attribution trailer from Kimi's generated subagents, and (under an
372
+ // unmodified `full` profile) staged only the skill-referenced subset the
373
+ // install path stages with `skills: '*'`.
374
+ if (kind.kind === 'agents' || kind.kind === 'kimi-agents') {
368
375
  const agentProfile = _isUnmodifiedFull ? { ...resolved, skills: '*' } : resolved;
369
376
  staged = kind.stage(agentProfile, agentCtx);
370
377
  }
371
378
  else {
372
379
  staged = kind.stage(resolved);
373
380
  }
374
- if (kind.kind === 'skills') {
381
+ // #4211: kimi-agents takes the skill-body rewrite too —
382
+ // createRuntimeArtifactInstallPlan routes `skills` and `kimi-agents`
383
+ // through rewriteStagedSkillBodies together, so omitting it here left
384
+ // Kimi's surface-materialized prompts with unrewritten paths.
385
+ if (kind.kind === 'skills' || kind.kind === 'kimi-agents') {
375
386
  runtimeArtifactConversion.rewriteStagedSkillBodies(staged, {
376
387
  runtime: layout.runtime,
377
388
  configDir: layout.configDir,
@@ -396,7 +407,22 @@ function applySurface(runtimeConfigDir, layout, manifest, clusterMap, registry,
396
407
  // the parity test in tests/runtime-artifact-layout-surface.test.cjs
397
408
  // enforces that the two writers never diverge again.
398
409
  const dest = assertDestWithinConfigHome(kind.home ?? layout.configDir, kind.destSubpath);
399
- _syncGsdDir(staged, dest, kind, skillManifest, layout.runtime);
410
+ stagedKinds.push({ kind, staged, dest });
411
+ }
412
+ // Do not mutate installed artifacts until every kind has staged
413
+ // successfully. A missing source provider therefore leaves both artifacts
414
+ // and the persisted surface state untouched.
415
+ retiredArtifactCleanup.pruneRetiredRuntimeArtifacts(layout.runtime, layout.configDir);
416
+ for (const item of stagedKinds) {
417
+ _syncGsdDir(item.staged, item.dest, item.kind, skillManifest, layout.runtime);
418
+ }
419
+ if (hasCandidateState) {
420
+ if (candidateState === null) {
421
+ node_fs_1.default.rmSync(node_path_1.default.join(runtimeConfigDir, SURFACE_FILE_NAME), { force: true });
422
+ }
423
+ else if (candidateState !== undefined) {
424
+ writeSurface(runtimeConfigDir, candidateState);
425
+ }
400
426
  }
401
427
  }
402
428
  finally {
@@ -557,6 +583,53 @@ function _syncGsdDir(stagedDir, destDir, kind, manifest, runtime) {
557
583
  // (no agentFileExtension declared) keep the staged filename verbatim.
558
584
  const _agentExt = runtime ? runtimeArtifactConversion.agentFileExtensionFor(runtime) : undefined;
559
585
  const isRenamedAgents = !!_agentExt && kindName === 'agents';
586
+ if (kindName === 'kimi-agents') {
587
+ // #4211: Kimi's managed tree is `gsd.yaml` + `gsd.md` + `subagents/gsd-*.{yaml,md}`
588
+ // (runtime-artifact-layout.cts kimiAgentsKind), and install copies it
589
+ // RECURSIVELY (_copyStaged in src/install-engine.cts). Surface apply fell
590
+ // through to the flat command/agent branch below, which reads only `*.md`
591
+ // at the top level: the YAML half and the whole subagents/ subtree were
592
+ // dropped, and `gsd.md` was written as `gsdgsd.md` (the flat branch
593
+ // re-applies kind.prefix to a name that already carries it). A surface
594
+ // change could therefore corrupt Kimi's installed artifacts while still
595
+ // reporting success.
596
+ node_fs_1.default.cpSync(stagedDir, destDir, { recursive: true });
597
+ // Prune GSD-owned files the new surface no longer stages, with exactly the
598
+ // ownership rule install's _removeGsdEntries applies to this kind: the two
599
+ // root files, and `gsd-`-prefixed .yaml/.md under subagents/. Everything
600
+ // else in the directory is user-owned and is preserved.
601
+ const _rootStaged = new Set(node_fs_1.default.readdirSync(stagedDir));
602
+ for (const fileName of ['gsd.yaml', 'gsd.md']) {
603
+ if (!_rootStaged.has(fileName)) {
604
+ try {
605
+ node_fs_1.default.rmSync(node_path_1.default.join(destDir, fileName), { force: true });
606
+ }
607
+ catch { /* ignore */ }
608
+ }
609
+ }
610
+ const _stagedSubagentsDir = node_path_1.default.join(stagedDir, 'subagents');
611
+ const _destSubagentsDir = node_path_1.default.join(destDir, 'subagents');
612
+ const _stagedSubagents = node_fs_1.default.existsSync(_stagedSubagentsDir)
613
+ ? new Set(node_fs_1.default.readdirSync(_stagedSubagentsDir))
614
+ : new Set();
615
+ if (node_fs_1.default.existsSync(_destSubagentsDir)) {
616
+ for (const entry of node_fs_1.default.readdirSync(_destSubagentsDir, { withFileTypes: true })) {
617
+ if (!entry.isFile())
618
+ continue;
619
+ if (!entry.name.startsWith('gsd-'))
620
+ continue;
621
+ if (!entry.name.endsWith('.yaml') && !entry.name.endsWith('.md'))
622
+ continue;
623
+ if (_stagedSubagents.has(entry.name))
624
+ continue;
625
+ try {
626
+ node_fs_1.default.rmSync(node_path_1.default.join(_destSubagentsDir, entry.name), { force: true });
627
+ }
628
+ catch { /* ignore */ }
629
+ }
630
+ }
631
+ return;
632
+ }
560
633
  if (kindName === 'skills') {
561
634
  // Skills kind: work with directories, not files.
562
635
  // Each staged entry is a directory named ${prefix}${stem}.
@@ -11,6 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11
11
  };
12
12
  const node_fs_1 = __importDefault(require("node:fs"));
13
13
  const node_path_1 = __importDefault(require("node:path"));
14
+ const security_cjs_1 = require("./security.cjs");
14
15
  // eslint-disable-next-line @typescript-eslint/no-require-imports
15
16
  const ioMod = require("./io.cjs");
16
17
  const { output, error, ERROR_REASON } = ioMod;
@@ -108,12 +109,14 @@ function routeResolveContent({ args, cwd, raw }, deps = {}) {
108
109
  return;
109
110
  }
110
111
  const projectRoot = node_path_1.default.resolve(cwd || process.cwd());
111
- const resolvedPlanPath = node_path_1.default.resolve(projectRoot, plan);
112
- const rel = node_path_1.default.relative(projectRoot, resolvedPlanPath);
113
- if (rel === '..' || rel.startsWith(`..${node_path_1.default.sep}`)) {
112
+ // Lexical containment (ADR-4650): this path is validated before existence is
113
+ // checked below, so realpath resolution is neither available nor required.
114
+ const contained = (0, security_cjs_1.tryWithinRootLexical)(plan, projectRoot);
115
+ if (contained === null) {
114
116
  error(`Plan file is outside project scope: ${plan}`, ERROR_REASON.USAGE);
115
117
  return;
116
118
  }
119
+ const resolvedPlanPath = contained;
117
120
  if (!node_fs_1.default.existsSync(resolvedPlanPath)) {
118
121
  error(`Plan file not found: ${plan}`, ERROR_REASON.USAGE);
119
122
  return;
@@ -173,11 +176,14 @@ function routeTaskCommand({ args, cwd, raw }) {
173
176
  else if (args[2]) {
174
177
  const projectRoot = node_path_1.default.resolve(cwd || process.cwd());
175
178
  const requestedPath = args[2];
176
- const resolvedTaskPath = node_path_1.default.resolve(projectRoot, requestedPath);
177
- const rel = node_path_1.default.relative(projectRoot, resolvedTaskPath);
178
- if (rel === '..' || rel.startsWith(`..${node_path_1.default.sep}`)) {
179
+ // Lexical containment (ADR-4650): validated before existence is checked below.
180
+ // `error()` here does not return/throw (preserved from before this migration),
181
+ // so resolvedTaskPath must still be computed identically on the rejected path.
182
+ const contained = (0, security_cjs_1.tryWithinRootLexical)(requestedPath, projectRoot);
183
+ if (contained === null) {
179
184
  error(`Task file is outside project scope: ${requestedPath}`, ERROR_REASON.USAGE);
180
185
  }
186
+ const resolvedTaskPath = contained ?? node_path_1.default.resolve(projectRoot, requestedPath);
181
187
  if (!node_fs_1.default.existsSync(resolvedTaskPath)) {
182
188
  error(`Task file not found: ${requestedPath}`, ERROR_REASON.USAGE);
183
189
  }
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /**
3
+ * TDD RED-evidence classification (#3770).
4
+ *
5
+ * The `type: tdd` executor gate previously accepted ANY nonzero test command as
6
+ * RED: syntax errors, zero-test discovery, fixture crashes, parser errors, and
7
+ * unrelated assertions all authorized production edits (GREEN). This module
8
+ * defines the compact RED evidence the gate now requires — the TARGET test's
9
+ * identity plus a matching assertion failure — and classifies a persisted test
10
+ * run into exactly one verdict:
11
+ *
12
+ * RED_EVIDENCE_OK — nonzero exit AND the target test failed as a REAL test
13
+ * (distinctly named, TAP-reported failure). The ONLY
14
+ * verdict that may advance to GREEN.
15
+ * INVALID_RED — everything else, with a machine-readable reason:
16
+ * unexpected_green | zero_tests_discovered |
17
+ * nonzero_exit_without_test_failure |
18
+ * fixture_or_load_failure | no_target_test_failure |
19
+ * invalid_record | unreadable_record (router arm).
20
+ *
21
+ * Everything here is PURE — no fs, no spawn, no clock — so the executor can
22
+ * persist the record (command, exit code, failing test, expected, actual) and
23
+ * validate it via `gsd_run check tdd-red-evidence <record.json>`.
24
+ *
25
+ * TAP parsing reuses the proven primitives from prohibition-enforcement
26
+ * (`parseNodeTestSummary`, `tapFailedTestNames`) — the same contract the
27
+ * prohibition probe's fail-first prover already relies on (#1259).
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.classifyRedEvidence = classifyRedEvidence;
31
+ exports.buildRedEvidenceRecord = buildRedEvidenceRecord;
32
+ const prohibition_enforcement_cjs_1 = require("./prohibition-enforcement.cjs");
33
+ /** Basename of a path-like string ('' for non-strings) — separators `/` and `\`. */
34
+ function baseOf(p) {
35
+ return typeof p === 'string' ? (p.split(/[\\/]/).pop() ?? p) : '';
36
+ }
37
+ /** Coerce and validate the raw record's scalar fields. Returns null exit_code only when absent/non-numeric. */
38
+ function readInput(input) {
39
+ const command = typeof input?.command === 'string' ? input.command : '';
40
+ const output = typeof input?.output === 'string' ? input.output : '';
41
+ const targetTest = typeof input?.targetTest === 'string' ? input.targetTest.trim() : '';
42
+ const exitCode = typeof input?.exitCode === 'number' && Number.isFinite(input.exitCode) ? input.exitCode : null;
43
+ if (!command || !targetTest || exitCode === null)
44
+ return null;
45
+ return { command, exitCode, output, targetTest };
46
+ }
47
+ /**
48
+ * Classify a persisted RED-phase test run. Fail-closed: malformed input, an
49
+ * unparseable/empty TAP summary, a file-named (load/crash) failure, or a
50
+ * failure that is not the target test's are all INVALID_RED — only a nonzero
51
+ * exit WITH the distinctly-named target test failing is RED_EVIDENCE_OK.
52
+ * Never throws.
53
+ */
54
+ function classifyRedEvidence(input) {
55
+ const parsed = readInput(input);
56
+ if (!parsed) {
57
+ return {
58
+ verdict: 'INVALID_RED',
59
+ reason: 'invalid_record',
60
+ evidence: {
61
+ command: typeof input?.command === 'string' ? input.command : '',
62
+ exit_code: null,
63
+ target_test: '',
64
+ tests: 0,
65
+ pass: 0,
66
+ fail: 0,
67
+ failing_tests: [],
68
+ },
69
+ };
70
+ }
71
+ const { command, exitCode, output, targetTest } = parsed;
72
+ const summary = (0, prohibition_enforcement_cjs_1.parseNodeTestSummary)(output);
73
+ const failing = (0, prohibition_enforcement_cjs_1.tapFailedTestNames)(output);
74
+ const evidence = {
75
+ command,
76
+ exit_code: exitCode,
77
+ target_test: targetTest,
78
+ tests: summary.tests,
79
+ pass: summary.pass,
80
+ fail: summary.fail,
81
+ failing_tests: failing,
82
+ };
83
+ // Existing fail-fast rule, now machine-checked: exit 0 during RED is an
84
+ // unexpected GREEN — the feature may already exist or the test is wrong.
85
+ if (exitCode === 0) {
86
+ return { verdict: 'INVALID_RED', reason: 'unexpected_green', evidence };
87
+ }
88
+ // Zero-test discovery: the discovery pattern / fixture matched no tests.
89
+ // A run that executed nothing cannot prove anything about the behavior.
90
+ if (summary.tests === 0) {
91
+ return { verdict: 'INVALID_RED', reason: 'zero_tests_discovered', evidence };
92
+ }
93
+ // Nonzero exit but TAP reports no failing test: harness/setup/parser crash
94
+ // whose failure never reached a test assertion (or unparseable output).
95
+ if (summary.fail === 0 || failing.length === 0) {
96
+ return { verdict: 'INVALID_RED', reason: 'nonzero_exit_without_test_failure', evidence };
97
+ }
98
+ // Fixture/load failure: every failing entry is named like the target FILE —
99
+ // node reports a load-time crash (throw-on-require, syntax error, ENOENT
100
+ // fixture) as a file-named `not ok 1 - <file>`, never the target test.
101
+ const targetBase = baseOf(input?.targetFile ?? '');
102
+ const distinctlyNamed = failing.filter((n) => (targetBase ? baseOf(n) !== targetBase : true));
103
+ if (distinctlyNamed.length === 0) {
104
+ return { verdict: 'INVALID_RED', reason: 'fixture_or_load_failure', evidence };
105
+ }
106
+ // Unrelated failure: real tests ran and failed, but none is the target test
107
+ // the plan named — an unrelated assertion must not authorize GREEN.
108
+ if (!distinctlyNamed.includes(targetTest)) {
109
+ return { verdict: 'INVALID_RED', reason: 'no_target_test_failure', evidence };
110
+ }
111
+ return { verdict: 'RED_EVIDENCE_OK', reason: 'target_test_failed', evidence };
112
+ }
113
+ /**
114
+ * Project a classification into the persisted record shape — command, exit
115
+ * code, failing test, expected, actual, verdict, reason — so the evidence
116
+ * survives past the terminal and the gate can re-verify it deterministically.
117
+ * Pure: JSON-serializable, no timestamps (the record's mtime/commit carries time).
118
+ */
119
+ function buildRedEvidenceRecord(input, result) {
120
+ const failingTest = result.evidence.failing_tests.find((n) => n === result.evidence.target_test) ??
121
+ result.evidence.failing_tests[0] ??
122
+ null;
123
+ return {
124
+ command: result.evidence.command,
125
+ exit_code: result.evidence.exit_code,
126
+ failing_test: failingTest,
127
+ target_test: result.evidence.target_test,
128
+ expected: typeof input?.expected === 'string' ? input.expected : null,
129
+ actual: typeof input?.actual === 'string' ? input.actual : null,
130
+ verdict: result.verdict,
131
+ reason: result.reason,
132
+ };
133
+ }