@opengsd/gsd-core 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (498) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +12 -0
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-debug-session-manager.md +1 -1
  6. package/agents/gsd-debugger.md +1 -1
  7. package/agents/gsd-dom-verifier.md +169 -0
  8. package/agents/gsd-eval-auditor.md +1 -1
  9. package/agents/gsd-executor.md +78 -42
  10. package/agents/gsd-framework-selector.md +1 -3
  11. package/agents/gsd-intel-updater.md +1 -1
  12. package/agents/gsd-mempalace-curator.md +0 -1
  13. package/agents/gsd-pattern-mapper.md +11 -0
  14. package/agents/gsd-phase-researcher.md +3 -1
  15. package/agents/gsd-plan-checker.md +91 -112
  16. package/agents/gsd-planner.md +20 -4
  17. package/agents/gsd-project-researcher.md +1 -1
  18. package/agents/gsd-research-synthesizer.md +2 -2
  19. package/agents/gsd-roadmapper.md +15 -11
  20. package/agents/gsd-ui-checker.md +82 -7
  21. package/agents/gsd-ui-researcher.md +70 -3
  22. package/agents/gsd-verifier.md +24 -2
  23. package/bin/install.js +847 -200
  24. package/commands/gsd/discuss-phase.md +1 -1
  25. package/commands/gsd/execute-phase.md +1 -1
  26. package/commands/gsd/import.md +1 -1
  27. package/commands/gsd/ns-workflow.md +2 -1
  28. package/commands/gsd/phase.md +1 -1
  29. package/commands/gsd/quick-batch.md +105 -0
  30. package/commands/gsd/quick.md +8 -4
  31. package/commands/gsd/surface.md +18 -8
  32. package/gsd-core/bin/gsd-tools.cjs +761 -100
  33. package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
  34. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  35. package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
  36. package/gsd-core/bin/lib/api-coverage.cjs +30 -9
  37. package/gsd-core/bin/lib/artifacts.cjs +2 -0
  38. package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
  39. package/gsd-core/bin/lib/audit.cjs +163 -41
  40. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  41. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  42. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  43. package/gsd-core/bin/lib/capability-registry.cjs +785 -144
  44. package/gsd-core/bin/lib/capability-state.cjs +25 -4
  45. package/gsd-core/bin/lib/capability-validator.cjs +321 -18
  46. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  47. package/gsd-core/bin/lib/check-command-router.cjs +229 -6
  48. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  49. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  50. package/gsd-core/bin/lib/clusters.cjs +1 -0
  51. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  52. package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
  53. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  54. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  55. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  56. package/gsd-core/bin/lib/commands.cjs +877 -54
  57. package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
  58. package/gsd-core/bin/lib/config-loader.cjs +121 -29
  59. package/gsd-core/bin/lib/config.cjs +92 -2
  60. package/gsd-core/bin/lib/configuration.cjs +129 -37
  61. package/gsd-core/bin/lib/core-utils.cjs +118 -14
  62. package/gsd-core/bin/lib/decisions.cjs +213 -1
  63. package/gsd-core/bin/lib/edge-probe.cjs +23 -2
  64. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  65. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  66. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  67. package/gsd-core/bin/lib/frontmatter.cjs +975 -326
  68. package/gsd-core/bin/lib/gap-checker.cjs +41 -8
  69. package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
  71. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  72. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
  73. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
  74. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
  75. package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
  76. package/gsd-core/bin/lib/host-integration.cjs +96 -11
  77. package/gsd-core/bin/lib/init-command-router.cjs +132 -21
  78. package/gsd-core/bin/lib/init.cjs +252 -56
  79. package/gsd-core/bin/lib/install-engine.cjs +252 -15
  80. package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
  81. package/gsd-core/bin/lib/install-profiles.cjs +100 -18
  82. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  83. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  84. package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
  85. package/gsd-core/bin/lib/intel.cjs +101 -26
  86. package/gsd-core/bin/lib/io.cjs +195 -15
  87. package/gsd-core/bin/lib/learnings.cjs +85 -14
  88. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  89. package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
  90. package/gsd-core/bin/lib/markdown-table.cjs +175 -4
  91. package/gsd-core/bin/lib/milestone.cjs +112 -7
  92. package/gsd-core/bin/lib/model-catalog.cjs +177 -19
  93. package/gsd-core/bin/lib/model-resolver.cjs +10 -28
  94. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  95. package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
  96. package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
  97. package/gsd-core/bin/lib/phase-id.cjs +321 -13
  98. package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
  99. package/gsd-core/bin/lib/phase-locator.cjs +138 -17
  100. package/gsd-core/bin/lib/phase.cjs +1175 -115
  101. package/gsd-core/bin/lib/plan-document.cjs +273 -0
  102. package/gsd-core/bin/lib/plan-scan.cjs +13 -2
  103. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  104. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  105. package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
  106. package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
  107. package/gsd-core/bin/lib/probe-core.cjs +4 -1
  108. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  109. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  110. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  111. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  112. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  113. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  114. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
  115. package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
  116. package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
  117. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  118. package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
  119. package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
  120. package/gsd-core/bin/lib/roadmap.cjs +248 -64
  121. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
  122. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
  123. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
  124. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
  125. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  126. package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
  127. package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
  128. package/gsd-core/bin/lib/smart-entry.cjs +19 -31
  129. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  130. package/gsd-core/bin/lib/state-command-router.cjs +47 -18
  131. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  132. package/gsd-core/bin/lib/state-document.cjs +216 -5
  133. package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
  134. package/gsd-core/bin/lib/state-transition.cjs +850 -145
  135. package/gsd-core/bin/lib/state.cjs +1629 -287
  136. package/gsd-core/bin/lib/surface.cjs +33 -10
  137. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  138. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  139. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  140. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  141. package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
  142. package/gsd-core/bin/lib/uat.cjs +2542 -387
  143. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  144. package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
  145. package/gsd-core/bin/lib/unusable-input.cjs +13 -0
  146. package/gsd-core/bin/lib/update-context.cjs +6 -2
  147. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  148. package/gsd-core/bin/lib/validate.cjs +230 -12
  149. package/gsd-core/bin/lib/vendor/README.md +43 -5
  150. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  151. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  152. package/gsd-core/bin/lib/verification.cjs +287 -13
  153. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  154. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  155. package/gsd-core/bin/lib/verify.cjs +441 -56
  156. package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
  157. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  158. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  159. package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
  160. package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
  161. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  162. package/gsd-core/bin/shared/exit-codes.json +8 -0
  163. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  164. package/gsd-core/bin/shared/model-catalog.json +8 -1
  165. package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
  166. package/gsd-core/references/agent-contracts.md +6 -5
  167. package/gsd-core/references/api-coverage.md +24 -2
  168. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  169. package/gsd-core/references/checkpoints.md +37 -19
  170. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  171. package/gsd-core/references/edge-probe.md +17 -5
  172. package/gsd-core/references/execute-mvp-tdd.md +18 -18
  173. package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
  174. package/gsd-core/references/execute-phase-response-language.md +6 -0
  175. package/gsd-core/references/execute-phase-wave-guard.md +11 -9
  176. package/gsd-core/references/executor-examples.md +42 -0
  177. package/gsd-core/references/failing-direction.md +78 -0
  178. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  179. package/gsd-core/references/gate-prompts.md +1 -1
  180. package/gsd-core/references/git-integration.md +5 -5
  181. package/gsd-core/references/git-planning-commit.md +3 -3
  182. package/gsd-core/references/gsd-run-resolver.md +1 -1
  183. package/gsd-core/references/loop-hook-dispatch.md +22 -0
  184. package/gsd-core/references/model-profiles.md +1 -1
  185. package/gsd-core/references/mvp-concepts.md +2 -2
  186. package/gsd-core/references/nyquist-compliance.md +74 -0
  187. package/gsd-core/references/offer-next.md +3 -5
  188. package/gsd-core/references/phase-argument-parsing.md +3 -3
  189. package/gsd-core/references/plan-checker-examples.md +41 -0
  190. package/gsd-core/references/planner-antipatterns.md +25 -0
  191. package/gsd-core/references/planner-chunked.md +5 -1
  192. package/gsd-core/references/planner-coupling.md +42 -0
  193. package/gsd-core/references/planner-failing-direction.md +53 -0
  194. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  195. package/gsd-core/references/planner-quick-batch.md +71 -0
  196. package/gsd-core/references/planner-reviews.md +47 -0
  197. package/gsd-core/references/planner-revision.md +76 -3
  198. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  199. package/gsd-core/references/planning-config.md +39 -9
  200. package/gsd-core/references/response-language-directive.md +9 -0
  201. package/gsd-core/references/reviewer-instances.md +31 -0
  202. package/gsd-core/references/revision-loop.md +118 -11
  203. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  204. package/gsd-core/references/tdd.md +15 -12
  205. package/gsd-core/references/ui-brand.md +65 -21
  206. package/gsd-core/references/ui-consideration-probe.md +1 -1
  207. package/gsd-core/references/universal-anti-patterns.md +2 -2
  208. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  209. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  210. package/gsd-core/references/verify-mvp-mode.md +1 -1
  211. package/gsd-core/references/workstream-flag.md +11 -11
  212. package/gsd-core/templates/README.md +1 -1
  213. package/gsd-core/templates/SECURITY.md +3 -3
  214. package/gsd-core/templates/UI-SPEC.md +25 -3
  215. package/gsd-core/templates/VALIDATION.md +3 -3
  216. package/gsd-core/templates/phase-prompt.md +7 -0
  217. package/gsd-core/templates/state.md +7 -0
  218. package/gsd-core/templates/verification-report.md +5 -0
  219. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  220. package/gsd-core/workflows/add-backlog.md +3 -1
  221. package/gsd-core/workflows/add-phase.md +5 -3
  222. package/gsd-core/workflows/add-tests.md +4 -9
  223. package/gsd-core/workflows/add-todo.md +2 -2
  224. package/gsd-core/workflows/ai-integration-phase.md +5 -10
  225. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  226. package/gsd-core/workflows/audit-fix.md +14 -3
  227. package/gsd-core/workflows/audit-milestone.md +11 -9
  228. package/gsd-core/workflows/audit-uat.md +19 -2
  229. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  230. package/gsd-core/workflows/autonomous.md +12 -26
  231. package/gsd-core/workflows/check-todos.md +2 -2
  232. package/gsd-core/workflows/cleanup.md +3 -3
  233. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
  234. package/gsd-core/workflows/code-review-fix.md +3 -1
  235. package/gsd-core/workflows/code-review.md +192 -69
  236. package/gsd-core/workflows/complete-milestone.md +28 -14
  237. package/gsd-core/workflows/debug.md +6 -4
  238. package/gsd-core/workflows/diagnose-issues.md +17 -7
  239. package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
  240. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  241. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  242. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  243. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  244. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
  245. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  246. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  247. package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
  248. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  249. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  250. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
  252. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  253. package/gsd-core/workflows/discuss-phase.md +2 -2
  254. package/gsd-core/workflows/do.md +46 -19
  255. package/gsd-core/workflows/docs-update.md +6 -5
  256. package/gsd-core/workflows/edit-phase.md +3 -1
  257. package/gsd-core/workflows/eval-review.md +5 -10
  258. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
  259. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
  260. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  261. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  263. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
  264. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  265. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  266. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
  267. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  268. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  269. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  270. package/gsd-core/workflows/execute-phase.md +68 -66
  271. package/gsd-core/workflows/execute-plan.md +25 -20
  272. package/gsd-core/workflows/explore.md +3 -1
  273. package/gsd-core/workflows/extract-learnings.md +3 -1
  274. package/gsd-core/workflows/fast.md +8 -2
  275. package/gsd-core/workflows/forensics.md +3 -1
  276. package/gsd-core/workflows/graduation.md +6 -6
  277. package/gsd-core/workflows/health.md +4 -7
  278. package/gsd-core/workflows/help/modes/brief.md +2 -0
  279. package/gsd-core/workflows/help/modes/default.md +2 -0
  280. package/gsd-core/workflows/help/modes/full.md +12 -0
  281. package/gsd-core/workflows/help/modes/topic.md +2 -0
  282. package/gsd-core/workflows/help.md +2 -0
  283. package/gsd-core/workflows/import.md +17 -14
  284. package/gsd-core/workflows/inbox.md +5 -6
  285. package/gsd-core/workflows/ingest-docs.md +45 -12
  286. package/gsd-core/workflows/insert-phase.md +7 -5
  287. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  288. package/gsd-core/workflows/list-seeds.md +7 -3
  289. package/gsd-core/workflows/list-workspaces.md +3 -1
  290. package/gsd-core/workflows/manager.md +15 -26
  291. package/gsd-core/workflows/map-codebase.md +3 -1
  292. package/gsd-core/workflows/milestone-summary.md +3 -1
  293. package/gsd-core/workflows/mvp-phase.md +3 -3
  294. package/gsd-core/workflows/new-milestone.md +10 -22
  295. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  296. package/gsd-core/workflows/new-project.md +17 -29
  297. package/gsd-core/workflows/new-workspace.md +2 -2
  298. package/gsd-core/workflows/next.md +4 -2
  299. package/gsd-core/workflows/node-repair.md +2 -0
  300. package/gsd-core/workflows/note.md +2 -0
  301. package/gsd-core/workflows/onboard.md +1 -1
  302. package/gsd-core/workflows/pause-work.md +20 -5
  303. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  304. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  305. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
  306. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
  307. package/gsd-core/workflows/plan-phase.md +251 -54
  308. package/gsd-core/workflows/plan-review-convergence.md +148 -19
  309. package/gsd-core/workflows/plant-seed.md +3 -3
  310. package/gsd-core/workflows/pr-branch.md +195 -51
  311. package/gsd-core/workflows/profile-user.md +17 -15
  312. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  313. package/gsd-core/workflows/progress.md +52 -15
  314. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  315. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
  316. package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
  317. package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
  318. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  319. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  320. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  321. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  322. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  323. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  324. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  325. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  326. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  327. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  328. package/gsd-core/workflows/quick-batch.md +203 -0
  329. package/gsd-core/workflows/quick.md +33 -32
  330. package/gsd-core/workflows/reapply-patches.md +2 -0
  331. package/gsd-core/workflows/remove-phase.md +6 -4
  332. package/gsd-core/workflows/remove-workspace.md +3 -3
  333. package/gsd-core/workflows/resume-project.md +14 -14
  334. package/gsd-core/workflows/review.md +404 -21
  335. package/gsd-core/workflows/scan.md +3 -1
  336. package/gsd-core/workflows/section-manifest.json +12 -0
  337. package/gsd-core/workflows/secure-phase.md +3 -3
  338. package/gsd-core/workflows/session-report.md +2 -0
  339. package/gsd-core/workflows/settings-advanced.md +9 -9
  340. package/gsd-core/workflows/settings-integrations.md +66 -32
  341. package/gsd-core/workflows/settings.md +4 -6
  342. package/gsd-core/workflows/ship.md +22 -16
  343. package/gsd-core/workflows/sketch-wrap-up.md +13 -17
  344. package/gsd-core/workflows/sketch.md +13 -19
  345. package/gsd-core/workflows/smart-entry.md +4 -6
  346. package/gsd-core/workflows/spec-phase.md +31 -4
  347. package/gsd-core/workflows/spike-wrap-up.md +9 -11
  348. package/gsd-core/workflows/spike.md +21 -32
  349. package/gsd-core/workflows/stats.md +4 -2
  350. package/gsd-core/workflows/sync-skills.md +13 -5
  351. package/gsd-core/workflows/thread.md +13 -7
  352. package/gsd-core/workflows/transition.md +7 -5
  353. package/gsd-core/workflows/ui-phase.md +36 -21
  354. package/gsd-core/workflows/ui-review.md +7 -11
  355. package/gsd-core/workflows/ultraplan-phase.md +7 -13
  356. package/gsd-core/workflows/undo.md +9 -17
  357. package/gsd-core/workflows/update.md +47 -48
  358. package/gsd-core/workflows/validate-phase.md +3 -3
  359. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  360. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  361. package/gsd-core/workflows/verify-work.md +106 -21
  362. package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
  363. package/hooks/dist/gsd-check-update-worker.js +19 -2
  364. package/hooks/dist/gsd-config-reload.js +18 -12
  365. package/hooks/dist/gsd-context-monitor.js +302 -22
  366. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  367. package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
  368. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  369. package/hooks/dist/gsd-cursor-stop.js +2 -1
  370. package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
  371. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
  372. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  373. package/hooks/dist/gsd-graphify-update.sh +22 -18
  374. package/hooks/dist/gsd-node-runner.sh +77 -0
  375. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  376. package/hooks/dist/gsd-prompt-guard.js +46 -12
  377. package/hooks/dist/gsd-read-guard.js +18 -7
  378. package/hooks/dist/gsd-read-injection-scanner.js +22 -13
  379. package/hooks/dist/gsd-secret-read-guard.js +1079 -0
  380. package/hooks/dist/gsd-session-state.sh +1 -0
  381. package/hooks/dist/gsd-statusline.js +222 -29
  382. package/hooks/dist/gsd-validate-commit.sh +523 -12
  383. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  384. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  385. package/hooks/dist/gsd-workflow-guard.js +36 -17
  386. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  387. package/hooks/dist/gsd-write-guard.js +35 -25
  388. package/hooks/dist/lib/cli-exit.js +560 -0
  389. package/hooks/dist/lib/exit-code-registry.js +98 -0
  390. package/hooks/dist/lib/git-cmd.js +210 -1
  391. package/hooks/dist/lib/git-probe.js +84 -0
  392. package/hooks/dist/lib/hook-exit.js +81 -0
  393. package/hooks/dist/lib/injection-patterns.js +36 -6
  394. package/hooks/dist/managed-hooks-registry.cjs +4 -0
  395. package/hooks/gsd-agent-isolation-guard.js +77 -38
  396. package/hooks/gsd-check-update-worker.js +19 -2
  397. package/hooks/gsd-config-reload.js +18 -12
  398. package/hooks/gsd-context-monitor.js +302 -22
  399. package/hooks/gsd-cursor-post-tool.js +3 -1
  400. package/hooks/gsd-cursor-pre-tool.js +3 -1
  401. package/hooks/gsd-cursor-session-start.js +2 -1
  402. package/hooks/gsd-cursor-stop.js +2 -1
  403. package/hooks/gsd-cursor-subagent-start.js +28 -23
  404. package/hooks/gsd-cursor-subagent-stop.js +3 -1
  405. package/hooks/gsd-ensure-canonical-path.js +2 -1
  406. package/hooks/gsd-graphify-update.sh +22 -18
  407. package/hooks/gsd-node-runner.sh +77 -0
  408. package/hooks/gsd-phase-boundary.sh +1 -0
  409. package/hooks/gsd-prompt-guard.js +46 -12
  410. package/hooks/gsd-read-guard.js +18 -7
  411. package/hooks/gsd-read-injection-scanner.js +22 -13
  412. package/hooks/gsd-secret-read-guard.js +1079 -0
  413. package/hooks/gsd-session-state.sh +1 -0
  414. package/hooks/gsd-statusline.js +222 -29
  415. package/hooks/gsd-validate-commit.sh +523 -12
  416. package/hooks/gsd-windsurf-pre-command.js +16 -11
  417. package/hooks/gsd-windsurf-pre-write.js +22 -13
  418. package/hooks/gsd-workflow-guard.js +36 -17
  419. package/hooks/gsd-worktree-path-guard.js +36 -21
  420. package/hooks/gsd-write-guard.js +35 -25
  421. package/hooks/hooks.json +6 -0
  422. package/hooks/lib/cli-exit.js +560 -0
  423. package/hooks/lib/exit-code-registry.js +98 -0
  424. package/hooks/lib/git-cmd.js +210 -1
  425. package/hooks/lib/git-probe.js +84 -0
  426. package/hooks/lib/hook-exit.js +81 -0
  427. package/hooks/lib/injection-patterns.js +36 -6
  428. package/hooks/managed-hooks-registry.cjs +4 -0
  429. package/package.json +14 -9
  430. package/scripts/base64-scan.sh +74 -12
  431. package/scripts/build-hooks.js +12 -0
  432. package/scripts/check-glossary-refs.cjs +77 -15
  433. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  434. package/scripts/ci-check-job-near-cap.cjs +49 -0
  435. package/scripts/ci-pr-mergeability.cjs +262 -0
  436. package/scripts/ci-test-scope.cjs +52 -12
  437. package/scripts/ci-timeout-report.cjs +230 -0
  438. package/scripts/docs-guard-registry.cjs +406 -0
  439. package/scripts/gen-capability-registry.cjs +8 -6
  440. package/scripts/gen-exit-code-docs.cjs +318 -0
  441. package/scripts/gen-exit-code-registry.cjs +891 -0
  442. package/scripts/gen-features.cjs +836 -0
  443. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  444. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  445. package/scripts/gen-loop-host-contract.cjs +189 -4
  446. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  447. package/scripts/gen-state-md-docs.cjs +727 -0
  448. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  449. package/scripts/lib/ci-job-timing.cjs +72 -0
  450. package/scripts/lib/cli-exit.cjs +546 -44
  451. package/scripts/lib/drift-scan.cjs +32 -2
  452. package/scripts/lib/exit-code-registry.cjs +98 -0
  453. package/scripts/lib/ndjson-reporter.cjs +119 -0
  454. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  455. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  456. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  457. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  458. package/scripts/lint-docs-guard-registration.cjs +495 -0
  459. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
  460. package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
  461. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  462. package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
  463. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  464. package/scripts/lint-phase-enumeration-drift.cjs +45 -14
  465. package/scripts/lint-phase-id-drift.cjs +133 -8
  466. package/scripts/lint-planning-prompt-drift.cjs +38 -1
  467. package/scripts/lint-portable-grep.cjs +176 -0
  468. package/scripts/lint-removed-but-needed.cjs +184 -16
  469. package/scripts/lint-response-language-coverage.cjs +524 -0
  470. package/scripts/lint-seam-enforcement.cjs +182 -0
  471. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  472. package/scripts/lint-source-test-name-collision.cjs +241 -0
  473. package/scripts/lint-state-write-path-drift.cjs +337 -432
  474. package/scripts/lint-test-file-count.allowlist.json +124 -4
  475. package/scripts/lint-test-file-count.cjs +25 -3
  476. package/scripts/lint-unreachable-guard-drift.cjs +51 -64
  477. package/scripts/lint-vendored-deps.cjs +208 -35
  478. package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
  479. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  480. package/scripts/mutation-matrix.cjs +599 -50
  481. package/scripts/npm-audit-baseline.cjs +376 -0
  482. package/scripts/prompt-injection-scan.sh +83 -14
  483. package/scripts/require-issue-link-policy.cjs +16 -1
  484. package/scripts/secret-scan.sh +75 -13
  485. package/scripts/select-docs-guards.cjs +56 -0
  486. package/scripts/sync-runtime-launcher.cjs +22 -3
  487. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  488. package/skills/gsd-execute-phase/SKILL.md +1 -1
  489. package/skills/gsd-import/SKILL.md +1 -1
  490. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  491. package/skills/gsd-phase/SKILL.md +1 -1
  492. package/skills/gsd-quick/SKILL.md +8 -4
  493. package/skills/gsd-quick-batch/SKILL.md +105 -0
  494. package/skills/gsd-surface/SKILL.md +18 -8
  495. package/vscode/package.json +1 -1
  496. package/bin/lib/ui-safety-gate.cjs +0 -109
  497. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  498. package/scripts/state-write-path-drift-baseline.json +0 -19
@@ -10,11 +10,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.RUNTIMES_WITH_FAST_MODE = exports.EFFORT_ARGV = exports.EFFORT_RENDERING = exports.CLAUDE_AGENT_ALIASES = exports.KNOWN_PROVIDERS = exports.PROVIDER_PRESETS = exports.RUNTIMES_WITH_REASONING_EFFORT = exports.KNOWN_RUNTIMES = exports.RUNTIME_PROFILE_MAP = exports.MODEL_ALIAS_MAP = exports.AGENT_DEFAULT_TIERS = exports.AGENT_TO_PHASE_TYPE = exports.MODEL_PROFILES = exports.ADAPTIVE_TIER_VALUES = exports.VALID_TIERS = exports.VALID_AGENT_TIERS = exports.VALID_PHASE_TYPES = exports.VALID_PROFILES = exports.catalog = void 0;
13
+ exports.RUNTIMES_WITH_FAST_MODE = exports.EFFORT_ARGV = exports.EFFORT_RENDERING = exports.CLAUDE_AGENT_ALIASES = exports.KNOWN_PROVIDERS = exports.CODEX_MODEL_EFFORT = exports.PROVIDER_PRESETS = exports.RUNTIMES_WITH_REASONING_EFFORT = exports.KNOWN_RUNTIMES = exports.RUNTIME_PROFILE_MAP = exports.MODEL_ALIAS_MAP = exports.AGENT_DEFAULT_TIERS = exports.AGENT_TO_PHASE_TYPE = exports.MODEL_PROFILES = exports.ADAPTIVE_TIER_VALUES = exports.VALID_TIERS = exports.VALID_AGENT_TIERS = exports.VALID_PHASE_TYPES = exports.VALID_PROFILES = exports.catalog = void 0;
14
14
  exports.isAnthropicFlavoredModel = isAnthropicFlavoredModel;
15
15
  exports.nextTier = nextTier;
16
16
  exports.formatAgentToModelMapAsTable = formatAgentToModelMapAsTable;
17
17
  exports.getAgentToModelMapForProfile = getAgentToModelMapForProfile;
18
+ exports.clampEffortForHost = clampEffortForHost;
18
19
  exports.renderEffortArgv = renderEffortArgv;
19
20
  exports.renderEffortForRuntime = renderEffortForRuntime;
20
21
  exports.mergeEffortTierDefaults = mergeEffortTierDefaults;
@@ -99,6 +100,38 @@ exports.RUNTIMES_WITH_REASONING_EFFORT = new Set(Object.entries(_catalog.runtime
99
100
  .filter(([, tiers]) => Object.values(tiers).some((entry) => entry && entry.reasoning_effort))
100
101
  .map(([runtime]) => runtime));
101
102
  exports.PROVIDER_PRESETS = _catalog.providerPresets ?? {};
103
+ // ─── #3007 — Codex per-model effort capability ───────────────────────────────
104
+ //
105
+ // Codex's own `models.json` publishes `supported_reasoning_levels` per model and
106
+ // rejects an unsupported level at request time, so GSD must be conservative
107
+ // about what it sends: read the ceiling as DATA from the catalog (never
108
+ // branch on model id in code) and fall back to the family baseline for any
109
+ // model the catalog doesn't know about.
110
+ // (b) A malformed catalog entry (e.g. a non-array value like `"gpt-x": 5`) must
111
+ // degrade to "ignore that entry", never throw — model-catalog.cjs is required
112
+ // across the whole CLI, so one bad JSON value must not kill every command.
113
+ // `new Set(5)` would throw at module load; filter to array values first.
114
+ exports.CODEX_MODEL_EFFORT = Object.fromEntries(Object.entries(_catalog.codexModelEffort ?? {})
115
+ .filter(([, levels]) => Array.isArray(levels))
116
+ .map(([model, levels]) => [model, new Set(levels)]));
117
+ // (a) `??` only catches null/undefined. A malformed `"_baseline": null` still
118
+ // produces `new Set(null)` above — an empty Set, which is truthy — so a bare
119
+ // `??` fallback would never fire and every level would silently lose its
120
+ // advertised set (every effort would render as `value: null`). Guard on
121
+ // `.size > 0` so an empty/missing/malformed baseline always falls back to the
122
+ // hardcoded floor instead of failing open.
123
+ const CODEX_EFFORT_BASELINE = exports.CODEX_MODEL_EFFORT['_baseline'] && exports.CODEX_MODEL_EFFORT['_baseline'].size > 0
124
+ ? exports.CODEX_MODEL_EFFORT['_baseline']
125
+ : new Set(['low', 'medium', 'high', 'xhigh', 'max']);
126
+ function advertisedCodexEffort(model) {
127
+ if (typeof model !== 'string' || model.length === 0)
128
+ return CODEX_EFFORT_BASELINE;
129
+ return Object.prototype.hasOwnProperty.call(exports.CODEX_MODEL_EFFORT, model) ? exports.CODEX_MODEL_EFFORT[model] : CODEX_EFFORT_BASELINE;
130
+ }
131
+ // The full universal effort ladder, low-to-high. Used only to find "the
132
+ // nearest advertised level below" when a requested level isn't supported —
133
+ // never to invent behaviour for a level that isn't on it at all.
134
+ const EFFORT_LADDER = ['minimal', 'low', 'medium', 'high', 'xhigh', 'max', 'ultra'];
102
135
  // KNOWN_PROVIDERS excludes 'generic' — it is a sentinel (all null entries) that
103
136
  // forces users to supply model IDs via model_profile_overrides. It is not a
104
137
  // real catalog-backed provider (#49).
@@ -124,7 +157,10 @@ exports.KNOWN_PROVIDERS = new Set(Object.entries(exports.PROVIDER_PRESETS)
124
157
  // rejects all of these.
125
158
  exports.CLAUDE_AGENT_ALIASES = new Set(['opus', 'sonnet', 'haiku', 'fable']);
126
159
  function isAnthropicFlavoredModel(model) {
127
- return typeof model === 'string' && (exports.CLAUDE_AGENT_ALIASES.has(model) || model.toLowerCase().includes('claude'));
160
+ if (typeof model !== 'string')
161
+ return false;
162
+ const lower = model.toLowerCase();
163
+ return exports.CLAUDE_AGENT_ALIASES.has(lower) || lower.includes('claude');
128
164
  }
129
165
  function nextTier(currentTier) {
130
166
  const order = ['light', 'standard', 'heavy'];
@@ -165,12 +201,21 @@ exports.EFFORT_RENDERING = {
165
201
  },
166
202
  },
167
203
  codex: {
204
+ // #3007: 'max' and 'minimal' are stale here — Codex's per-model table
205
+ // (CODEX_MODEL_EFFORT above) is now the source of truth for what a given
206
+ // model actually advertises, and every model in the family baseline DOES
207
+ // advertise 'max' (no model advertises 'minimal'). This runtime-level
208
+ // spec is kept in sync with the family baseline so the two tables can
209
+ // never disagree; renderEffortForRuntime layers the per-model ceiling
210
+ // (and the 'ultra' policy rejection) on top of it.
211
+ // KEEP IN SYNC with EFFORT_ARGV.codex below — same family baseline, two
212
+ // channels (install-time vs invocation-time); they must never diverge.
168
213
  param: 'model_reasoning_effort',
169
214
  channel: 'api',
170
- supported: new Set(['minimal', 'low', 'medium', 'high', 'xhigh']),
215
+ supported: new Set(['low', 'medium', 'high', 'xhigh', 'max']),
171
216
  clamp(level) {
172
- if (level === 'max')
173
- return 'xhigh';
217
+ if (level === 'minimal')
218
+ return 'low';
174
219
  return level;
175
220
  },
176
221
  },
@@ -191,12 +236,45 @@ exports.EFFORT_ARGV = {
191
236
  },
192
237
  // First-party Codex docs: `model_reasoning_effort` is a config-only key with no
193
238
  // dedicated flag, so the generic `-c key=value` override is the only argv route.
239
+ // #3007: KEEP IN SYNC with EFFORT_RENDERING.codex above — this table must match
240
+ // the family baseline exactly (no 'minimal', 'max' passes through unclamped),
241
+ // otherwise the argv channel and the install-time channel disagree about the
242
+ // same runtime's capability.
194
243
  codex: {
195
244
  render: (level) => ['-c', `model_reasoning_effort=${level}`],
196
- supported: new Set(['minimal', 'low', 'medium', 'high', 'xhigh']),
197
- clamp: (level) => (level === 'max' ? 'xhigh' : level),
245
+ supported: new Set(['low', 'medium', 'high', 'xhigh', 'max']),
246
+ clamp: (level) => (level === 'minimal' ? 'low' : level),
198
247
  },
199
248
  };
249
+ /**
250
+ * Clamp a universal effort level to what a host actually accepts, or null.
251
+ *
252
+ * #3706 — extracted from `renderEffortArgv` so the two effort CHANNELS can share
253
+ * one capability table without one pretending to be the other. `EFFORT_ARGV[host]`
254
+ * describes what levels the host understands (`supported` + `clamp`); whether that
255
+ * reaches the host as a CLI flag or as a baked frontmatter key is the caller's
256
+ * business. The install-time OpenCode `variant:` writer needs the former without
257
+ * the latter, and hardcoding `'argv'` at that call site to borrow this logic read
258
+ * as if the frontmatter key were gated on the invocation-time axis. It is not —
259
+ * claude declares `effortSurface: "argv"` and independently bakes an `effort:` key.
260
+ *
261
+ * Returns null for a level the host does not accept, which every caller treats as
262
+ * "emit nothing". `inherit` lands here too: per #3533 (10d) it is not a wire level
263
+ * on any runtime, so it is in no `supported` set and must never be written out.
264
+ */
265
+ function clampEffortForHost(host, universalEffort) {
266
+ // Own-property lookup only: a plain `EFFORT_ARGV[host]` resolves `__proto__`
267
+ // and friends to inherited members that carry no clamp/render.
268
+ if (typeof host !== 'string' || !Object.prototype.hasOwnProperty.call(exports.EFFORT_ARGV, host))
269
+ return null;
270
+ const spec = exports.EFFORT_ARGV[host];
271
+ if (!spec || typeof spec.clamp !== 'function')
272
+ return null;
273
+ if (typeof universalEffort !== 'string' || universalEffort.length === 0)
274
+ return null;
275
+ const clamped = spec.clamp(universalEffort);
276
+ return spec.supported.has(clamped) ? clamped : null;
277
+ }
200
278
  /**
201
279
  * Render the invocation-time effort argument for a host.
202
280
  *
@@ -212,37 +290,117 @@ function renderEffortArgv(host, universalEffort, effortSurface) {
212
290
  // (and `constructor`/`toString`) to inherited members, which are truthy but
213
291
  // carry no `clamp`/`render` — a hostile host id would throw instead of
214
292
  // degrading. The host id reaches here from a descriptor, i.e. untrusted JSON.
215
- if (typeof host !== 'string' || !Object.prototype.hasOwnProperty.call(exports.EFFORT_ARGV, host))
293
+ // #3706: the clamp/supported half lives in clampEffortForHost so the
294
+ // install-time channel can reuse it; this function keeps the axis gate and
295
+ // the argv rendering. One table, one clamp, two channels.
296
+ const clamped = clampEffortForHost(host, universalEffort);
297
+ if (clamped === null)
216
298
  return empty;
217
299
  const spec = exports.EFFORT_ARGV[host];
218
- if (!spec || typeof spec.clamp !== 'function' || typeof spec.render !== 'function')
219
- return empty;
220
- if (typeof universalEffort !== 'string' || universalEffort.length === 0)
221
- return empty;
222
- const clamped = spec.clamp(universalEffort);
223
- if (!spec.supported.has(clamped))
300
+ if (typeof spec.render !== 'function')
224
301
  return empty;
225
302
  return { argv: spec.render(clamped), value: clamped, host };
226
303
  }
227
304
  /**
228
305
  * Render a universal effort string for a specific runtime.
306
+ *
307
+ * `model` (#3007) is consulted ONLY for codex: Codex's per-model
308
+ * `supported_reasoning_levels` means the same universal level can be a clean
309
+ * pass-through on one model and a clamp (or, for 'ultra', an outright
310
+ * rejection) on another. Every other runtime ignores the third argument
311
+ * entirely — passing a model id to claude changes nothing.
229
312
  */
230
- function renderEffortForRuntime(runtime, universalEffort) {
313
+ function renderEffortForRuntime(runtime, universalEffort, model) {
231
314
  // #3533 (10d): 'inherit' is not a wire level on ANY runtime — it means
232
315
  // "omit the key / pass no argument and follow the session/host default".
233
316
  // Renderers must never emit it as a literal; null param/channel tells
234
- // resolve-execution consumers there is no propagation.
317
+ // resolve-execution consumers there is no propagation. Never measured
318
+ // against any supported set.
235
319
  if (universalEffort === 'inherit') {
236
- return { value: 'inherit', param: null, channel: null };
320
+ return { value: 'inherit', param: null, channel: null, requested: 'inherit', clamped: false, reason: null };
237
321
  }
238
322
  const spec = exports.EFFORT_RENDERING[runtime];
239
323
  if (!spec) {
240
- return { value: universalEffort, param: null, channel: null };
324
+ return { value: universalEffort, param: null, channel: null, requested: universalEffort, clamped: false, reason: null };
325
+ }
326
+ if (runtime === 'codex') {
327
+ // #2167 — 'ultra' turns on Codex's automatic task delegation, which would
328
+ // let Codex spawn agents underneath GSD's own orchestration. GSD rejects
329
+ // it unconditionally as a POLICY call, never as a capability clamp — this
330
+ // holds even for a model (e.g. gpt-5.6-sol) that DOES advertise 'ultra',
331
+ // so it is never softened down to 'max'.
332
+ if (universalEffort === 'ultra') {
333
+ return {
334
+ value: null,
335
+ param: null,
336
+ channel: null,
337
+ requested: 'ultra',
338
+ clamped: false,
339
+ reason: "'ultra' turns on Codex's automatic task delegation, which would let Codex spawn agents underneath GSD's own orchestration (#2167); GSD rejects it regardless of what the model advertises.",
340
+ };
341
+ }
342
+ const allowed = advertisedCodexEffort(model);
343
+ if (allowed.has(universalEffort)) {
344
+ return { value: universalEffort, param: spec.param, channel: spec.channel, requested: universalEffort, clamped: false, reason: null };
345
+ }
346
+ const idx = EFFORT_LADDER.indexOf(universalEffort);
347
+ if (idx === -1) {
348
+ // Not on the ladder at all (e.g. 'MAX') — preserve prior behaviour:
349
+ // fall through to the runtime-level clamp rather than inventing new
350
+ // handling for input the ladder doesn't recognize.
351
+ return { value: spec.clamp(universalEffort), param: spec.param, channel: spec.channel, requested: universalEffort, clamped: false, reason: null };
352
+ }
353
+ // Every model's advertised set is a contiguous run up to 'max' (or 'ultra'
354
+ // for sol, already handled above), so the only unsupported level in
355
+ // practice is 'minimal' — below every model's floor. Walk UP the ladder
356
+ // to the nearest level the model actually advertises (its floor): there
357
+ // is nothing below 'minimal' to fall back to.
358
+ // Walking UP is safe today only because every advertised set floors at
359
+ // 'low' — a future model whose floor is, say, 'high' would silently turn
360
+ // a requested 'low' into 'high': MORE reasoning and MORE cost than asked
361
+ // for, with no error. `clamped`/`reason` below is what makes that
362
+ // escalation visible to a caller instead of a silent cost surprise, which
363
+ // is why those fields are not optional decoration.
364
+ for (let i = idx + 1; i < EFFORT_LADDER.length; i++) {
365
+ const candidate = EFFORT_LADDER[i];
366
+ // 'ultra' is never a valid clamp target: it would re-enter, by the back
367
+ // door, the delegation mode the #2167 rejection above exists to keep
368
+ // out. A clamp may never produce a value that a direct request for
369
+ // that same value would have refused.
370
+ if (candidate === 'ultra') {
371
+ continue;
372
+ }
373
+ if (allowed.has(candidate)) {
374
+ return {
375
+ value: candidate,
376
+ param: spec.param,
377
+ channel: spec.channel,
378
+ requested: universalEffort,
379
+ clamped: true,
380
+ reason: `requested '${universalEffort}' is not in ${model ? `${model}'s` : "the codex family baseline's"} advertised reasoning levels; clamped up to its floor, '${candidate}'.`,
381
+ };
382
+ }
383
+ }
384
+ // No advertised level at or above the request either (shouldn't happen
385
+ // given today's catalog data, but never throw): reject rather than emit
386
+ // an unsupported level.
387
+ return {
388
+ value: null,
389
+ param: null,
390
+ channel: null,
391
+ requested: universalEffort,
392
+ clamped: false,
393
+ reason: `requested '${universalEffort}' is not in ${model ? `${model}'s` : "the codex family baseline's"} advertised reasoning levels, and no advertised level is available either.`,
394
+ };
241
395
  }
396
+ const value = spec.clamp(universalEffort);
242
397
  return {
243
- value: spec.clamp(universalEffort),
398
+ value,
244
399
  param: spec.param,
245
400
  channel: spec.channel,
401
+ requested: universalEffort,
402
+ clamped: value !== universalEffort,
403
+ reason: value !== universalEffort ? `requested '${universalEffort}' clamped to '${value}' for ${runtime}.` : null,
246
404
  };
247
405
  }
248
406
  /**
@@ -35,6 +35,7 @@ const model_catalog_cjs_1 = require("./model-catalog.cjs");
35
35
  const node_fs_1 = __importDefault(require("node:fs"));
36
36
  const node_path_1 = __importDefault(require("node:path"));
37
37
  const runtime_name_policy_cjs_1 = require("./runtime-name-policy.cjs");
38
+ const runtime_slash_cjs_1 = require("./runtime-slash.cjs");
38
39
  // eslint-disable-next-line @typescript-eslint/no-require-imports
39
40
  const planningWorkspaceMod = require("./planning-workspace.cjs");
40
41
  const { planningDir } = planningWorkspaceMod;
@@ -58,38 +59,19 @@ const { planningDir } = planningWorkspaceMod;
58
59
  // registry-parity test guards this set so a future alias-capable runtime fails
59
60
  // loudly here instead of silently omitting.
60
61
  const RUNTIMES_WITH_NATIVE_ALIASES = new Set(['claude']);
61
- let _installMarkerCache;
62
- function readInstallRuntimeMarker() {
63
- if (_installMarkerCache !== undefined)
64
- return _installMarkerCache;
65
- try {
66
- const markerPath = node_path_1.default.join(__dirname, '..', '..', '.gsd-runtime');
67
- const raw = node_fs_1.default.readFileSync(markerPath, 'utf8').trim();
68
- _installMarkerCache = raw || null;
69
- }
70
- catch {
71
- // No marker: dev/source tree, or an install predating #2297. Fall through to
72
- // the 'claude' default (keeps tier aliases — never worse than the bug).
73
- _installMarkerCache = null;
74
- }
75
- return _installMarkerCache;
76
- }
77
- // Test seams for the install-marker rung (the dev/source tree has no marker, so
78
- // the file read always bottoms out at 'claude' — these let tests exercise the
79
- // third precedence rung and reset the module-level cache between cases).
80
- function _setInstallRuntimeMarkerForTests(value) {
81
- _installMarkerCache = value;
82
- }
83
- function _resetInstallRuntimeMarkerCacheForTests() {
84
- _installMarkerCache = undefined;
85
- }
62
+ // #3897 rung 2: the marker reader + its cache and test seams were promoted to
63
+ // the canonical owner, `runtime-slash.cts` (imported above) — this module now
64
+ // consumes that single implementation instead of holding its own copy. N5:
65
+ // behaviour and the seam contract are unchanged by the move; the re-exports
66
+ // below (`export =` at the bottom of this file) preserve every existing
67
+ // caller's `require('./model-resolver.cjs')` surface byte-for-behaviour.
86
68
  // The runtime whose install is actually resolving, canonicalized so an alias or
87
69
  // case variant (e.g. "claude-code"/"Claude") cannot defeat the native-alias
88
70
  // check below (#2297 review). Precedence mirrors resolveRuntime()
89
71
  // (runtime-slash.cts): GSD_RUNTIME env → project config.runtime → per-install
90
72
  // .gsd-runtime marker → 'claude'.
91
73
  function resolveActiveRuntime(config) {
92
- return (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(process.env['GSD_RUNTIME'], config['runtime'], readInstallRuntimeMarker()) || 'claude';
74
+ return (0, runtime_name_policy_cjs_1.resolveRuntimeNameFromCandidates)(process.env['GSD_RUNTIME'], config['runtime'], (0, runtime_slash_cjs_1.readInstallRuntimeMarker)()) || 'claude';
93
75
  }
94
76
  // Did the PROJECT's own config (root `.planning/config.json` or the active
95
77
  // workstream/project override) explicitly set resolve_model_ids to "omit"?
@@ -841,8 +823,8 @@ module.exports = {
841
823
  resolveTierFromConfig,
842
824
  _resetModelPolicyWarningCacheForTests,
843
825
  _resetModelOverrideWarningCacheForTests,
844
- _setInstallRuntimeMarkerForTests,
845
- _resetInstallRuntimeMarkerCacheForTests,
826
+ _setInstallRuntimeMarkerForTests: runtime_slash_cjs_1._setInstallRuntimeMarkerForTests,
827
+ _resetInstallRuntimeMarkerCacheForTests: runtime_slash_cjs_1._resetInstallRuntimeMarkerCacheForTests,
846
828
  VALID_GRANULARITIES,
847
829
  resolveGranularityInternal,
848
830
  assertValidGranularityOverride,
@@ -117,7 +117,11 @@ function listPlanningDocCandidates(cwd) {
117
117
  return [...candidates].sort();
118
118
  }
119
119
  function listCodebaseMapFiles(cwd) {
120
- const codebaseDir = node_path_1.default.join(planningRoot(cwd), 'codebase');
120
+ // #3964: project-scoped, agreeing with init's map-codebase surface and
121
+ // verify.cts's codebase drift check — a flat-root read made
122
+ // has_codebase_map/needs_codebase_map answer for the wrong project under
123
+ // GSD_PROJECT.
124
+ const codebaseDir = node_path_1.default.join(planningDir(cwd), 'codebase');
121
125
  if (!node_fs_1.default.existsSync(codebaseDir))
122
126
  return [];
123
127
  return REQUIRED_CODEBASE_MAP_FILES.filter((file) => node_fs_1.default.existsSync(node_path_1.default.join(codebaseDir, file)));
@@ -6,7 +6,7 @@
6
6
  * Unsupported in this router:
7
7
  * - scaffold: routed through top-level scaffold command.
8
8
  *
9
- * CJS-only subcommands: mvp-mode (dispatched directly, before hub).
9
+ * CJS-only subcommands: mvp-mode, tdd-applicable (dispatched directly, before hub).
10
10
  *
11
11
  * #3788: dispatch is mediated by CommandRoutingHub. The public entry point
12
12
  * and observable CLI behaviour are unchanged.
@@ -57,6 +57,13 @@ function routePhaseCommand({ phase, args, cwd, raw, error }) {
57
57
  phase.cmdPhaseMvpMode(cwd, args.slice(2), raw);
58
58
  return;
59
59
  }
60
+ // `tdd-applicable` (#4273): same CJS-native dispatch shape as `mvp-mode`
61
+ // immediately above — a precedence cascade over plan/task/config sources
62
+ // with its own typed JSON result, not routed through the SDK query layer.
63
+ if (subcommand === 'tdd-applicable') {
64
+ phase.cmdPhaseTddApplicable(cwd, args.slice(2), raw);
65
+ return;
66
+ }
60
67
  // ── Build the CJS registry ──────────────────────────────────────────────────
61
68
  // Each handler receives a ctx object from the hub and must return a HubResult.
62
69
  const cjsRegistry = {
@@ -224,14 +231,14 @@ function routePhaseCommand({ phase, args, cwd, raw, error }) {
224
231
  // ── Build manifest (available subcommands for UnknownCommand detection) ─────
225
232
  // `availableSubcommands` is what the error message shows. It excludes
226
233
  // unsupported commands (already handled above) but does NOT include 'mvp-mode'
227
- // because it was absent from PHASE_SUBCOMMANDS in the original and was not
228
- // shown in the "Available:" list there either.
234
+ // or 'tdd-applicable' (#4273) because both are absent from PHASE_SUBCOMMANDS
235
+ // and were not shown in the "Available:" list there either.
229
236
  //
230
237
  // `manifestSubcommands` is the full routing set for the hub — it includes
231
- // 'mvp-mode' (which the original code routed via a handler even without a
232
- // manifest entry) so the hub's UnknownCommand check passes for it.
238
+ // 'mvp-mode' and 'tdd-applicable' (both routed via a handler even without a
239
+ // manifest entry) so the hub's UnknownCommand check passes for them.
233
240
  const availableSubcommands = command_aliases_cjs_1.PHASE_SUBCOMMANDS.filter(s => !UNSUPPORTED[s]);
234
- const manifestSubcommands = ['mvp-mode', ...availableSubcommands];
241
+ const manifestSubcommands = ['mvp-mode', 'tdd-applicable', ...availableSubcommands];
235
242
  const manifest = { phase: manifestSubcommands };
236
243
  // ── Construct hub ──────────────────────────────────────────────────────────
237
244
  // #175: Hub is CJS-only — no mode param, no sdkLoader.
@@ -218,14 +218,23 @@ function applyCalibration(rawTokens, factor) {
218
218
  * Extract a two-space-indented scalar block (`estimate:` / `actuals:`) out of a
219
219
  * document's leading YAML frontmatter.
220
220
  *
221
- * Hand-rolled because gsd-core ships no external dependencies (CONTRIBUTING.md
222
- * "No external dependencies in core") — js-yaml is a devDependency and is not
223
- * available at runtime. Scope is deliberately narrow: the leading `---` block
224
- * only, so a `estimate:` line inside a fenced code block in the body cannot be
225
- * mistaken for frontmatter (the DEFECT.FRONTMATTER-SCALAR-BROAD-GREP class).
226
- *
227
- * Numeric-looking values are returned as numbers so parseEstimate/parseActuals
228
- * see the types they validate; everything else stays a string.
221
+ * Hand-rolled for its TYPE CONTRACT, not for dependency availability — js-yaml
222
+ * is vendored and available at runtime as of ADR-3473 §8.1 (#3881), which
223
+ * migrated `src/frontmatter.cts`'s `extractFrontmatter` onto it. That parser
224
+ * runs under js-yaml's FAILSAFE_SCHEMA, which resolves every scalar as a
225
+ * string, whereas this function deliberately returns numbers for
226
+ * numeric-looking values (`out[m[1]] = asNumber : rawValue`) so
227
+ * `parseEstimate`/`parseActuals` see the types they validate. A naive swap
228
+ * onto `extractFrontmatter` would turn `tokens: 5000` into `"5000"` and make
229
+ * `isPositiveInt` reject every estimate. Scope is deliberately narrow: the
230
+ * leading `---` block only, so an `estimate:` line inside a fenced code
231
+ * block in the body cannot be mistaken for frontmatter (the
232
+ * DEFECT.FRONTMATTER-SCALAR-BROAD-GREP class). Migrating this function onto
233
+ * the shared parser (with a typed coercion layer over its string-only
234
+ * output) is tracked as follow-on work under ADR-3473 §8.1, not done here —
235
+ * this module is calibration-critical and has a history of subtle numeric
236
+ * defects shipping past a large green suite (#2631 factor², #2632
237
+ * self-defeating loop).
229
238
  */
230
239
  function extractFrontmatterBlock(text, key) {
231
240
  if (typeof text !== 'string')