@opengsd/gsd-core 1.2.0 → 1.3.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 (532) hide show
  1. package/README.ja-JP.md +46 -791
  2. package/README.ko-KR.md +44 -780
  3. package/README.md +42 -218
  4. package/README.pt-BR.md +47 -414
  5. package/README.zh-CN.md +46 -763
  6. package/agents/gsd-ai-researcher.md +2 -2
  7. package/agents/gsd-debug-session-manager.md +1 -1
  8. package/agents/gsd-debugger.md +8 -8
  9. package/agents/gsd-doc-writer.md +7 -6
  10. package/agents/gsd-domain-researcher.md +15 -2
  11. package/agents/gsd-eval-auditor.md +1 -1
  12. package/agents/gsd-eval-planner.md +2 -2
  13. package/agents/gsd-executor.md +21 -8
  14. package/agents/gsd-framework-selector.md +1 -1
  15. package/agents/gsd-intel-updater.md +4 -4
  16. package/agents/gsd-phase-researcher.md +19 -6
  17. package/agents/gsd-plan-checker.md +3 -3
  18. package/agents/gsd-planner.md +36 -23
  19. package/agents/gsd-project-researcher.md +13 -0
  20. package/agents/gsd-research-synthesizer.md +6 -2
  21. package/agents/gsd-roadmapper.md +6 -6
  22. package/agents/gsd-ui-researcher.md +16 -3
  23. package/agents/gsd-user-profiler.md +2 -2
  24. package/agents/gsd-verifier.md +8 -8
  25. package/assets/gsd-logo-2000-transparent.png +0 -0
  26. package/assets/gsd-logo-2000-transparent.svg +17 -0
  27. package/assets/gsd-logo-2000.png +0 -0
  28. package/assets/gsd-logo-2000.svg +21 -0
  29. package/assets/terminal.svg +68 -0
  30. package/bin/install.js +255 -103
  31. package/commands/gsd/add-tests.md +1 -1
  32. package/commands/gsd/ai-integration-phase.md +3 -3
  33. package/commands/gsd/audit-fix.md +1 -1
  34. package/commands/gsd/audit-milestone.md +1 -1
  35. package/commands/gsd/audit-uat.md +1 -1
  36. package/commands/gsd/autonomous.md +2 -2
  37. package/commands/gsd/capture.md +6 -6
  38. package/commands/gsd/cleanup.md +1 -1
  39. package/commands/gsd/code-review.md +1 -1
  40. package/commands/gsd/complete-milestone.md +2 -2
  41. package/commands/gsd/config.md +3 -3
  42. package/commands/gsd/debug.md +1 -1
  43. package/commands/gsd/discuss-phase.md +5 -4
  44. package/commands/gsd/docs-update.md +1 -1
  45. package/commands/gsd/eval-review.md +2 -2
  46. package/commands/gsd/execute-phase.md +2 -2
  47. package/commands/gsd/explore.md +1 -1
  48. package/commands/gsd/extract-learnings.md +2 -2
  49. package/commands/gsd/fast.md +1 -1
  50. package/commands/gsd/forensics.md +1 -1
  51. package/commands/gsd/graphify.md +9 -9
  52. package/commands/gsd/health.md +1 -1
  53. package/commands/gsd/help.md +2 -2
  54. package/commands/gsd/import.md +5 -5
  55. package/commands/gsd/inbox.md +1 -1
  56. package/commands/gsd/ingest-docs.md +4 -4
  57. package/commands/gsd/manager.md +3 -3
  58. package/commands/gsd/map-codebase.md +1 -1
  59. package/commands/gsd/milestone-summary.md +1 -1
  60. package/commands/gsd/mvp-phase.md +4 -4
  61. package/commands/gsd/new-milestone.md +5 -5
  62. package/commands/gsd/new-project.md +5 -5
  63. package/commands/gsd/pause-work.md +2 -2
  64. package/commands/gsd/phase.md +4 -4
  65. package/commands/gsd/plan-phase.md +2 -2
  66. package/commands/gsd/plan-review-convergence.md +4 -4
  67. package/commands/gsd/pr-branch.md +1 -1
  68. package/commands/gsd/profile-user.md +2 -2
  69. package/commands/gsd/progress.md +4 -4
  70. package/commands/gsd/quick.md +1 -1
  71. package/commands/gsd/resume-work.md +1 -1
  72. package/commands/gsd/review.md +3 -2
  73. package/commands/gsd/secure-phase.md +1 -1
  74. package/commands/gsd/settings.md +1 -1
  75. package/commands/gsd/ship.md +2 -2
  76. package/commands/gsd/sketch.md +7 -7
  77. package/commands/gsd/spec-phase.md +2 -2
  78. package/commands/gsd/spike.md +3 -3
  79. package/commands/gsd/stats.md +1 -1
  80. package/commands/gsd/surface.md +4 -4
  81. package/commands/gsd/thread.md +1 -1
  82. package/commands/gsd/ui-phase.md +2 -2
  83. package/commands/gsd/ui-review.md +2 -2
  84. package/commands/gsd/ultraplan-phase.md +2 -2
  85. package/commands/gsd/undo.md +3 -3
  86. package/commands/gsd/update.md +3 -3
  87. package/commands/gsd/validate-phase.md +1 -1
  88. package/commands/gsd/verify-work.md +2 -2
  89. package/commands/gsd/workspace.md +4 -4
  90. package/{get-shit-done → gsd-core}/bin/check-latest-version.cjs +1 -1
  91. package/{get-shit-done → gsd-core}/bin/gsd-tools.cjs +50 -4
  92. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  93. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  94. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  95. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  96. package/gsd-core/bin/lib/audit.cjs +743 -0
  97. package/gsd-core/bin/lib/check-command-router.cjs +342 -0
  98. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  99. package/gsd-core/bin/lib/clock.cjs +95 -0
  100. package/gsd-core/bin/lib/clusters.cjs +128 -0
  101. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  102. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  103. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  104. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  105. package/gsd-core/bin/lib/commands.cjs +1202 -0
  106. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  107. package/gsd-core/bin/lib/config-types.cjs +19 -0
  108. package/gsd-core/bin/lib/config.cjs +714 -0
  109. package/{get-shit-done → gsd-core}/bin/lib/configuration.cjs +76 -85
  110. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  111. package/gsd-core/bin/lib/core.cjs +2007 -0
  112. package/{get-shit-done → gsd-core}/bin/lib/decisions.cjs +9 -7
  113. package/gsd-core/bin/lib/docs.cjs +252 -0
  114. package/gsd-core/bin/lib/drift.cjs +364 -0
  115. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  116. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  117. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  118. package/gsd-core/bin/lib/graphify.cjs +496 -0
  119. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  120. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  121. package/gsd-core/bin/lib/init.cjs +1799 -0
  122. package/gsd-core/bin/lib/install-profiles.cjs +526 -0
  123. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  124. package/gsd-core/bin/lib/installer-migration-report.cjs +347 -0
  125. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  126. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  127. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  128. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  129. package/gsd-core/bin/lib/installer-migrations.cjs +784 -0
  130. package/gsd-core/bin/lib/intel.cjs +607 -0
  131. package/gsd-core/bin/lib/learnings.cjs +270 -0
  132. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  133. package/gsd-core/bin/lib/milestone.cjs +373 -0
  134. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  135. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  136. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  137. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  138. package/{get-shit-done → gsd-core}/bin/lib/observability/redaction.cjs +19 -21
  139. package/{get-shit-done → gsd-core}/bin/lib/package-identity.cjs +5 -1
  140. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  141. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  142. package/gsd-core/bin/lib/phase.cjs +1307 -0
  143. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  144. package/{get-shit-done → gsd-core}/bin/lib/plan-scan.cjs +18 -24
  145. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  146. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  147. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  148. package/gsd-core/bin/lib/project-root.cjs +119 -0
  149. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  150. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  151. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  152. package/gsd-core/bin/lib/roadmap-upgrade.cjs +491 -0
  153. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  154. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +254 -0
  155. package/gsd-core/bin/lib/runtime-homes.cjs +169 -0
  156. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  157. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  158. package/{get-shit-done → gsd-core}/bin/lib/schema-detect.cjs +20 -26
  159. package/gsd-core/bin/lib/secrets.cjs +34 -0
  160. package/gsd-core/bin/lib/security.cjs +407 -0
  161. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  162. package/gsd-core/bin/lib/shell-command-projection.cjs +524 -0
  163. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  164. package/{get-shit-done → gsd-core}/bin/lib/state-document.cjs +78 -82
  165. package/gsd-core/bin/lib/state.cjs +2010 -0
  166. package/gsd-core/bin/lib/surface.cjs +406 -0
  167. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  168. package/gsd-core/bin/lib/template.cjs +237 -0
  169. package/gsd-core/bin/lib/uat.cjs +297 -0
  170. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  171. package/gsd-core/bin/lib/update-context.cjs +218 -0
  172. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  173. package/gsd-core/bin/lib/validate.cjs +112 -0
  174. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  175. package/gsd-core/bin/lib/verify.cjs +1451 -0
  176. package/{get-shit-done → gsd-core}/bin/lib/workstream-inventory-builder.cjs +19 -12
  177. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  178. package/{get-shit-done → gsd-core}/bin/lib/workstream-name-policy.cjs +28 -31
  179. package/gsd-core/bin/lib/workstream.cjs +380 -0
  180. package/gsd-core/bin/lib/worktree-safety.cjs +912 -0
  181. package/{get-shit-done → gsd-core}/bin/shared/config-defaults.manifest.json +1 -0
  182. package/{get-shit-done → gsd-core}/bin/shared/config-schema.manifest.json +17 -1
  183. package/{get-shit-done → gsd-core}/bin/shared/model-catalog.json +27 -0
  184. package/{get-shit-done → gsd-core}/references/artifact-types.md +1 -1
  185. package/{get-shit-done → gsd-core}/references/checkpoints.md +1 -1
  186. package/{get-shit-done → gsd-core}/references/few-shot-examples/plan-checker.md +2 -2
  187. package/{get-shit-done → gsd-core}/references/few-shot-examples/verifier.md +12 -12
  188. package/{get-shit-done → gsd-core}/references/model-profile-resolution.md +1 -1
  189. package/{get-shit-done → gsd-core}/references/mvp-concepts.md +1 -1
  190. package/{get-shit-done → gsd-core}/references/planner-graphify-auto-update.md +2 -2
  191. package/{get-shit-done → gsd-core}/references/planner-human-verify-mode.md +1 -1
  192. package/{get-shit-done → gsd-core}/references/planner-mvp-mode.md +1 -1
  193. package/{get-shit-done → gsd-core}/references/ui-brand.md +4 -2
  194. package/{get-shit-done → gsd-core}/references/verification-patterns.md +1 -1
  195. package/gsd-core/references/worktree-branch-check.md +38 -0
  196. package/{get-shit-done → gsd-core}/references/worktree-path-safety.md +4 -26
  197. package/{get-shit-done → gsd-core}/templates/README.md +2 -2
  198. package/{get-shit-done → gsd-core}/templates/codebase/structure.md +10 -10
  199. package/{get-shit-done → gsd-core}/templates/copilot-instructions.md +1 -1
  200. package/{get-shit-done → gsd-core}/templates/phase-prompt.md +10 -10
  201. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  202. package/{get-shit-done → gsd-core}/workflows/add-backlog.md +1 -1
  203. package/{get-shit-done → gsd-core}/workflows/add-phase.md +1 -1
  204. package/{get-shit-done → gsd-core}/workflows/add-tests.md +1 -1
  205. package/{get-shit-done → gsd-core}/workflows/add-todo.md +1 -1
  206. package/{get-shit-done → gsd-core}/workflows/ai-integration-phase.md +4 -4
  207. package/{get-shit-done → gsd-core}/workflows/audit-fix.md +2 -2
  208. package/{get-shit-done → gsd-core}/workflows/audit-milestone.md +3 -1
  209. package/{get-shit-done → gsd-core}/workflows/audit-uat.md +1 -1
  210. package/{get-shit-done → gsd-core}/workflows/autonomous.md +10 -8
  211. package/{get-shit-done → gsd-core}/workflows/check-todos.md +1 -1
  212. package/{get-shit-done → gsd-core}/workflows/cleanup.md +44 -4
  213. package/{get-shit-done → gsd-core}/workflows/code-review-fix.md +4 -4
  214. package/{get-shit-done → gsd-core}/workflows/code-review.md +6 -4
  215. package/{get-shit-done → gsd-core}/workflows/complete-milestone.md +2 -2
  216. package/{get-shit-done → gsd-core}/workflows/debug.md +7 -2
  217. package/{get-shit-done → gsd-core}/workflows/diagnose-issues.md +6 -2
  218. package/{get-shit-done → gsd-core}/workflows/discovery-phase.md +5 -5
  219. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/advisor.md +5 -5
  220. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/auto.md +1 -1
  221. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/chain.md +1 -1
  222. package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/power.md +1 -1
  223. package/{get-shit-done → gsd-core}/workflows/discuss-phase-assumptions.md +4 -4
  224. package/{get-shit-done → gsd-core}/workflows/discuss-phase.md +6 -6
  225. package/{get-shit-done → gsd-core}/workflows/do.md +1 -1
  226. package/{get-shit-done → gsd-core}/workflows/docs-update.md +19 -5
  227. package/{get-shit-done → gsd-core}/workflows/edit-phase.md +1 -1
  228. package/{get-shit-done → gsd-core}/workflows/eval-review.md +3 -3
  229. package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/codebase-drift-gate.md +16 -3
  230. package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/post-merge-gate.md +1 -1
  231. package/{get-shit-done → gsd-core}/workflows/execute-phase.md +89 -57
  232. package/{get-shit-done → gsd-core}/workflows/execute-plan.md +8 -8
  233. package/{get-shit-done → gsd-core}/workflows/explore.md +5 -3
  234. package/{get-shit-done → gsd-core}/workflows/extract-learnings.md +1 -1
  235. package/{get-shit-done → gsd-core}/workflows/forensics.md +1 -1
  236. package/{get-shit-done → gsd-core}/workflows/graduation.md +1 -1
  237. package/{get-shit-done → gsd-core}/workflows/health.md +1 -1
  238. package/{get-shit-done → gsd-core}/workflows/help/modes/default.md +3 -3
  239. package/{get-shit-done → gsd-core}/workflows/help/modes/full.md +6 -6
  240. package/{get-shit-done → gsd-core}/workflows/import.md +3 -1
  241. package/{get-shit-done → gsd-core}/workflows/ingest-docs.md +5 -5
  242. package/{get-shit-done → gsd-core}/workflows/insert-phase.md +1 -1
  243. package/{get-shit-done → gsd-core}/workflows/list-workspaces.md +1 -1
  244. package/{get-shit-done → gsd-core}/workflows/manager.md +3 -3
  245. package/{get-shit-done → gsd-core}/workflows/map-codebase.md +3 -1
  246. package/{get-shit-done → gsd-core}/workflows/milestone-summary.md +1 -1
  247. package/{get-shit-done → gsd-core}/workflows/mvp-phase.md +7 -7
  248. package/{get-shit-done → gsd-core}/workflows/new-milestone.md +5 -5
  249. package/{get-shit-done → gsd-core}/workflows/new-project.md +8 -8
  250. package/{get-shit-done → gsd-core}/workflows/new-workspace.md +1 -1
  251. package/{get-shit-done → gsd-core}/workflows/next.md +1 -1
  252. package/{get-shit-done → gsd-core}/workflows/pause-work.md +1 -1
  253. package/{get-shit-done → gsd-core}/workflows/plan-milestone-gaps.md +1 -1
  254. package/{get-shit-done → gsd-core}/workflows/plan-phase.md +29 -28
  255. package/{get-shit-done → gsd-core}/workflows/plan-review-convergence.md +10 -10
  256. package/{get-shit-done → gsd-core}/workflows/plant-seed.md +1 -1
  257. package/{get-shit-done → gsd-core}/workflows/profile-user.md +11 -11
  258. package/{get-shit-done → gsd-core}/workflows/progress.md +1 -1
  259. package/{get-shit-done → gsd-core}/workflows/quick.md +7 -29
  260. package/{get-shit-done → gsd-core}/workflows/reapply-patches.md +2 -2
  261. package/{get-shit-done → gsd-core}/workflows/remove-phase.md +1 -1
  262. package/{get-shit-done → gsd-core}/workflows/remove-workspace.md +1 -1
  263. package/{get-shit-done → gsd-core}/workflows/resume-project.md +2 -2
  264. package/{get-shit-done → gsd-core}/workflows/review.md +110 -2
  265. package/{get-shit-done → gsd-core}/workflows/scan.md +3 -1
  266. package/{get-shit-done → gsd-core}/workflows/secure-phase.md +5 -3
  267. package/{get-shit-done → gsd-core}/workflows/settings-advanced.md +196 -6
  268. package/{get-shit-done → gsd-core}/workflows/settings-integrations.md +2 -2
  269. package/{get-shit-done → gsd-core}/workflows/settings.md +16 -2
  270. package/{get-shit-done → gsd-core}/workflows/ship.md +56 -4
  271. package/{get-shit-done → gsd-core}/workflows/sketch-wrap-up.md +1 -1
  272. package/{get-shit-done → gsd-core}/workflows/sketch.md +5 -5
  273. package/{get-shit-done → gsd-core}/workflows/spec-phase.md +2 -2
  274. package/{get-shit-done → gsd-core}/workflows/spike-wrap-up.md +1 -1
  275. package/{get-shit-done → gsd-core}/workflows/spike.md +1 -1
  276. package/{get-shit-done → gsd-core}/workflows/stats.md +1 -1
  277. package/{get-shit-done → gsd-core}/workflows/sync-skills.md +3 -3
  278. package/{get-shit-done → gsd-core}/workflows/thread.md +1 -1
  279. package/{get-shit-done → gsd-core}/workflows/transition.md +2 -2
  280. package/{get-shit-done → gsd-core}/workflows/ui-phase.md +5 -5
  281. package/{get-shit-done → gsd-core}/workflows/ui-review.md +3 -3
  282. package/{get-shit-done → gsd-core}/workflows/ultraplan-phase.md +1 -1
  283. package/{get-shit-done → gsd-core}/workflows/undo.md +2 -2
  284. package/{get-shit-done → gsd-core}/workflows/update.md +41 -16
  285. package/{get-shit-done → gsd-core}/workflows/validate-phase.md +5 -3
  286. package/{get-shit-done → gsd-core}/workflows/verify-phase.md +4 -4
  287. package/{get-shit-done → gsd-core}/workflows/verify-work.md +7 -7
  288. package/hooks/dist/gsd-check-update-worker.js +16 -3
  289. package/hooks/dist/gsd-check-update.js +7 -5
  290. package/hooks/dist/gsd-context-monitor.js +2 -2
  291. package/hooks/dist/gsd-statusline.js +39 -21
  292. package/hooks/dist/gsd-update-banner.js +6 -2
  293. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  294. package/hooks/dist/managed-hooks-registry.cjs +35 -0
  295. package/hooks/gsd-check-update-worker.js +16 -3
  296. package/hooks/gsd-check-update.js +7 -5
  297. package/hooks/gsd-context-monitor.js +2 -2
  298. package/hooks/gsd-statusline.js +39 -21
  299. package/hooks/gsd-update-banner.js +6 -2
  300. package/hooks/gsd-worktree-path-guard.js +169 -0
  301. package/hooks/managed-hooks-registry.cjs +1 -0
  302. package/package.json +17 -11
  303. package/scripts/affected-tests-lib.cjs +1 -1
  304. package/scripts/base64-scan.sh +12 -0
  305. package/scripts/build-hooks.js +5 -1
  306. package/scripts/changeset/cli.cjs +2 -2
  307. package/scripts/changeset/github-release-notes.cjs +1 -1
  308. package/scripts/changeset/lint.cjs +1 -1
  309. package/scripts/check-alias-drift.cjs +8 -8
  310. package/scripts/check-env.cjs +5 -1
  311. package/scripts/ci-test-scope.cjs +34 -9
  312. package/scripts/command-contract-helpers.cjs +1 -1
  313. package/scripts/fix-slash-commands.cjs +5 -5
  314. package/scripts/gen-inventory-manifest.cjs +3 -3
  315. package/scripts/generate-package-identity.cjs +28 -7
  316. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  317. package/scripts/lint-command-contract.cjs +1 -1
  318. package/scripts/lint-legacy-dir-name.cjs +156 -0
  319. package/scripts/lint-package-identity-drift.cjs +8 -8
  320. package/scripts/lint-pr-check-project-dir.cjs +0 -1
  321. package/scripts/lint-shell-command-projection-drift.cjs +1 -1
  322. package/scripts/lint-skill-deps.cjs +1 -1
  323. package/scripts/lint-test-file-count.allowlist.json +129 -32
  324. package/scripts/lint-test-file-count.cjs +85 -30
  325. package/scripts/mutation-matrix.cjs +219 -0
  326. package/scripts/prompt-injection-scan.sh +5 -1
  327. package/scripts/release-notes/format-github-release-notes.cjs +256 -0
  328. package/scripts/release-tarball-smoke.cjs +9 -9
  329. package/scripts/run-tests.cjs +34 -2
  330. package/scripts/strip-prose-atrefs.cjs +2 -2
  331. package/scripts/sync-runtime-launcher.cjs +2 -2
  332. package/scripts/verify-npm-publish.cjs +252 -0
  333. package/get-shit-done/bin/lib/active-workstream-store.cjs +0 -302
  334. package/get-shit-done/bin/lib/adr-parser.cjs +0 -394
  335. package/get-shit-done/bin/lib/agent-command-router.cjs +0 -65
  336. package/get-shit-done/bin/lib/artifacts.cjs +0 -53
  337. package/get-shit-done/bin/lib/audit.cjs +0 -755
  338. package/get-shit-done/bin/lib/check-command-router.cjs +0 -333
  339. package/get-shit-done/bin/lib/cjs-command-router-adapter.cjs +0 -118
  340. package/get-shit-done/bin/lib/clock.cjs +0 -96
  341. package/get-shit-done/bin/lib/clusters.cjs +0 -135
  342. package/get-shit-done/bin/lib/code-review-flags.cjs +0 -74
  343. package/get-shit-done/bin/lib/command-aliases.cjs +0 -815
  344. package/get-shit-done/bin/lib/command-arg-projection.cjs +0 -62
  345. package/get-shit-done/bin/lib/command-routing-hub.cjs +0 -388
  346. package/get-shit-done/bin/lib/commands.cjs +0 -1188
  347. package/get-shit-done/bin/lib/config-schema.cjs +0 -31
  348. package/get-shit-done/bin/lib/config.cjs +0 -728
  349. package/get-shit-done/bin/lib/context-utilization.cjs +0 -47
  350. package/get-shit-done/bin/lib/core.cjs +0 -2121
  351. package/get-shit-done/bin/lib/docs.cjs +0 -270
  352. package/get-shit-done/bin/lib/drift.cjs +0 -388
  353. package/get-shit-done/bin/lib/fallow-runner.cjs +0 -109
  354. package/get-shit-done/bin/lib/frontmatter.cjs +0 -389
  355. package/get-shit-done/bin/lib/gap-checker.cjs +0 -205
  356. package/get-shit-done/bin/lib/graphify.cjs +0 -592
  357. package/get-shit-done/bin/lib/gsd2-import.cjs +0 -514
  358. package/get-shit-done/bin/lib/init-command-router.cjs +0 -58
  359. package/get-shit-done/bin/lib/init.cjs +0 -2112
  360. package/get-shit-done/bin/lib/install-profiles.cjs +0 -603
  361. package/get-shit-done/bin/lib/installer-migration-authoring.cjs +0 -117
  362. package/get-shit-done/bin/lib/installer-migration-report.cjs +0 -354
  363. package/get-shit-done/bin/lib/installer-migrations/000-first-time-baseline.cjs +0 -220
  364. package/get-shit-done/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +0 -41
  365. package/get-shit-done/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +0 -80
  366. package/get-shit-done/bin/lib/installer-migrations.cjs +0 -778
  367. package/get-shit-done/bin/lib/intel.cjs +0 -708
  368. package/get-shit-done/bin/lib/learnings.cjs +0 -421
  369. package/get-shit-done/bin/lib/milestone.cjs +0 -314
  370. package/get-shit-done/bin/lib/model-catalog.cjs +0 -212
  371. package/get-shit-done/bin/lib/model-profiles.cjs +0 -31
  372. package/get-shit-done/bin/lib/observability/event.cjs +0 -82
  373. package/get-shit-done/bin/lib/observability/logger.cjs +0 -174
  374. package/get-shit-done/bin/lib/phase-command-router.cjs +0 -191
  375. package/get-shit-done/bin/lib/phase-lifecycle.cjs +0 -80
  376. package/get-shit-done/bin/lib/phase.cjs +0 -1607
  377. package/get-shit-done/bin/lib/phases-command-router.cjs +0 -39
  378. package/get-shit-done/bin/lib/planning-workspace.cjs +0 -238
  379. package/get-shit-done/bin/lib/profile-output.cjs +0 -1141
  380. package/get-shit-done/bin/lib/profile-pipeline.cjs +0 -539
  381. package/get-shit-done/bin/lib/project-root.cjs +0 -112
  382. package/get-shit-done/bin/lib/prompt-budget.cjs +0 -399
  383. package/get-shit-done/bin/lib/review-reviewer-selection.cjs +0 -125
  384. package/get-shit-done/bin/lib/roadmap-command-router.cjs +0 -28
  385. package/get-shit-done/bin/lib/roadmap.cjs +0 -650
  386. package/get-shit-done/bin/lib/runtime-artifact-layout.cjs +0 -301
  387. package/get-shit-done/bin/lib/runtime-homes.cjs +0 -222
  388. package/get-shit-done/bin/lib/runtime-name-policy.cjs +0 -83
  389. package/get-shit-done/bin/lib/runtime-slash.cjs +0 -112
  390. package/get-shit-done/bin/lib/secrets.cjs +0 -32
  391. package/get-shit-done/bin/lib/security.cjs +0 -600
  392. package/get-shit-done/bin/lib/semver-compare.cjs +0 -35
  393. package/get-shit-done/bin/lib/shell-command-projection.cjs +0 -500
  394. package/get-shit-done/bin/lib/state-command-router.cjs +0 -252
  395. package/get-shit-done/bin/lib/state.cjs +0 -2038
  396. package/get-shit-done/bin/lib/surface.cjs +0 -470
  397. package/get-shit-done/bin/lib/task-command-router.cjs +0 -81
  398. package/get-shit-done/bin/lib/template.cjs +0 -228
  399. package/get-shit-done/bin/lib/uat.cjs +0 -289
  400. package/get-shit-done/bin/lib/update-context.cjs +0 -209
  401. package/get-shit-done/bin/lib/validate-command-router.cjs +0 -83
  402. package/get-shit-done/bin/lib/validate.cjs +0 -92
  403. package/get-shit-done/bin/lib/verify-command-router.cjs +0 -40
  404. package/get-shit-done/bin/lib/verify.cjs +0 -1511
  405. package/get-shit-done/bin/lib/workstream-inventory.cjs +0 -146
  406. package/get-shit-done/bin/lib/workstream.cjs +0 -389
  407. package/get-shit-done/bin/lib/worktree-safety.cjs +0 -985
  408. package/get-shit-done/workflows/_runtime-launcher.snippet.sh +0 -1
  409. package/scripts/lint-no-source-grep-extras.cjs +0 -81
  410. package/scripts/lint-no-source-grep.cjs +0 -174
  411. package/scripts/lint-shared-module-handsync.cjs +0 -388
  412. package/scripts/shared-module-handsync-allowlist.json +0 -183
  413. /package/{get-shit-done → gsd-core}/bin/shared/runtime-aliases.manifest.json +0 -0
  414. /package/{get-shit-done → gsd-core}/bin/verify-reapply-patches.cjs +0 -0
  415. /package/{get-shit-done → gsd-core}/contexts/dev.md +0 -0
  416. /package/{get-shit-done → gsd-core}/contexts/research.md +0 -0
  417. /package/{get-shit-done → gsd-core}/contexts/review.md +0 -0
  418. /package/{get-shit-done → gsd-core}/references/agent-contracts.md +0 -0
  419. /package/{get-shit-done → gsd-core}/references/ai-evals.md +0 -0
  420. /package/{get-shit-done → gsd-core}/references/ai-frameworks.md +0 -0
  421. /package/{get-shit-done → gsd-core}/references/autonomous-smart-discuss.md +0 -0
  422. /package/{get-shit-done → gsd-core}/references/common-bug-patterns.md +0 -0
  423. /package/{get-shit-done → gsd-core}/references/context-budget.md +0 -0
  424. /package/{get-shit-done → gsd-core}/references/continuation-format.md +0 -0
  425. /package/{get-shit-done → gsd-core}/references/debugger-philosophy.md +0 -0
  426. /package/{get-shit-done → gsd-core}/references/decimal-phase-calculation.md +0 -0
  427. /package/{get-shit-done → gsd-core}/references/doc-conflict-engine.md +0 -0
  428. /package/{get-shit-done → gsd-core}/references/domain-probes.md +0 -0
  429. /package/{get-shit-done → gsd-core}/references/execute-mvp-tdd.md +0 -0
  430. /package/{get-shit-done → gsd-core}/references/executor-examples.md +0 -0
  431. /package/{get-shit-done → gsd-core}/references/gate-prompts.md +0 -0
  432. /package/{get-shit-done → gsd-core}/references/gates.md +0 -0
  433. /package/{get-shit-done → gsd-core}/references/git-integration.md +0 -0
  434. /package/{get-shit-done → gsd-core}/references/git-planning-commit.md +0 -0
  435. /package/{get-shit-done → gsd-core}/references/ios-scaffold.md +0 -0
  436. /package/{get-shit-done → gsd-core}/references/mandatory-initial-read.md +0 -0
  437. /package/{get-shit-done → gsd-core}/references/model-profiles.md +0 -0
  438. /package/{get-shit-done → gsd-core}/references/phase-argument-parsing.md +0 -0
  439. /package/{get-shit-done → gsd-core}/references/planner-antipatterns.md +0 -0
  440. /package/{get-shit-done → gsd-core}/references/planner-chunked.md +0 -0
  441. /package/{get-shit-done → gsd-core}/references/planner-gap-closure.md +0 -0
  442. /package/{get-shit-done → gsd-core}/references/planner-interface-context.md +0 -0
  443. /package/{get-shit-done → gsd-core}/references/planner-reviews.md +0 -0
  444. /package/{get-shit-done → gsd-core}/references/planner-revision.md +0 -0
  445. /package/{get-shit-done → gsd-core}/references/planner-source-audit.md +0 -0
  446. /package/{get-shit-done → gsd-core}/references/planning-config.md +0 -0
  447. /package/{get-shit-done → gsd-core}/references/project-skills-discovery.md +0 -0
  448. /package/{get-shit-done → gsd-core}/references/questioning.md +0 -0
  449. /package/{get-shit-done → gsd-core}/references/revision-loop.md +0 -0
  450. /package/{get-shit-done → gsd-core}/references/scout-codebase.md +0 -0
  451. /package/{get-shit-done → gsd-core}/references/skeleton-template.md +0 -0
  452. /package/{get-shit-done → gsd-core}/references/sketch-interactivity.md +0 -0
  453. /package/{get-shit-done → gsd-core}/references/sketch-theme-system.md +0 -0
  454. /package/{get-shit-done → gsd-core}/references/sketch-tooling.md +0 -0
  455. /package/{get-shit-done → gsd-core}/references/sketch-variant-patterns.md +0 -0
  456. /package/{get-shit-done → gsd-core}/references/spidr-splitting.md +0 -0
  457. /package/{get-shit-done → gsd-core}/references/tdd.md +0 -0
  458. /package/{get-shit-done → gsd-core}/references/thinking-models-debug.md +0 -0
  459. /package/{get-shit-done → gsd-core}/references/thinking-models-execution.md +0 -0
  460. /package/{get-shit-done → gsd-core}/references/thinking-models-planning.md +0 -0
  461. /package/{get-shit-done → gsd-core}/references/thinking-models-research.md +0 -0
  462. /package/{get-shit-done → gsd-core}/references/thinking-models-verification.md +0 -0
  463. /package/{get-shit-done → gsd-core}/references/thinking-partner.md +0 -0
  464. /package/{get-shit-done → gsd-core}/references/universal-anti-patterns.md +0 -0
  465. /package/{get-shit-done → gsd-core}/references/user-profiling.md +0 -0
  466. /package/{get-shit-done → gsd-core}/references/user-story-template.md +0 -0
  467. /package/{get-shit-done → gsd-core}/references/verification-overrides.md +0 -0
  468. /package/{get-shit-done → gsd-core}/references/verify-mvp-mode.md +0 -0
  469. /package/{get-shit-done → gsd-core}/references/workstream-flag.md +0 -0
  470. /package/{get-shit-done → gsd-core}/templates/AI-SPEC.md +0 -0
  471. /package/{get-shit-done → gsd-core}/templates/DEBUG.md +0 -0
  472. /package/{get-shit-done → gsd-core}/templates/SECURITY.md +0 -0
  473. /package/{get-shit-done → gsd-core}/templates/UAT.md +0 -0
  474. /package/{get-shit-done → gsd-core}/templates/UI-SPEC.md +0 -0
  475. /package/{get-shit-done → gsd-core}/templates/VALIDATION.md +0 -0
  476. /package/{get-shit-done → gsd-core}/templates/claude-md.md +0 -0
  477. /package/{get-shit-done → gsd-core}/templates/codebase/architecture.md +0 -0
  478. /package/{get-shit-done → gsd-core}/templates/codebase/concerns.md +0 -0
  479. /package/{get-shit-done → gsd-core}/templates/codebase/conventions.md +0 -0
  480. /package/{get-shit-done → gsd-core}/templates/codebase/integrations.md +0 -0
  481. /package/{get-shit-done → gsd-core}/templates/codebase/stack.md +0 -0
  482. /package/{get-shit-done → gsd-core}/templates/codebase/testing.md +0 -0
  483. /package/{get-shit-done → gsd-core}/templates/config.json +0 -0
  484. /package/{get-shit-done → gsd-core}/templates/context.md +0 -0
  485. /package/{get-shit-done → gsd-core}/templates/continue-here.md +0 -0
  486. /package/{get-shit-done → gsd-core}/templates/debug-subagent-prompt.md +0 -0
  487. /package/{get-shit-done → gsd-core}/templates/dev-preferences.md +0 -0
  488. /package/{get-shit-done → gsd-core}/templates/discovery.md +0 -0
  489. /package/{get-shit-done → gsd-core}/templates/discussion-log.md +0 -0
  490. /package/{get-shit-done → gsd-core}/templates/milestone-archive.md +0 -0
  491. /package/{get-shit-done → gsd-core}/templates/milestone.md +0 -0
  492. /package/{get-shit-done → gsd-core}/templates/planner-subagent-prompt.md +0 -0
  493. /package/{get-shit-done → gsd-core}/templates/project.md +0 -0
  494. /package/{get-shit-done → gsd-core}/templates/requirements.md +0 -0
  495. /package/{get-shit-done → gsd-core}/templates/research-project/ARCHITECTURE.md +0 -0
  496. /package/{get-shit-done → gsd-core}/templates/research-project/FEATURES.md +0 -0
  497. /package/{get-shit-done → gsd-core}/templates/research-project/PITFALLS.md +0 -0
  498. /package/{get-shit-done → gsd-core}/templates/research-project/STACK.md +0 -0
  499. /package/{get-shit-done → gsd-core}/templates/research-project/SUMMARY.md +0 -0
  500. /package/{get-shit-done → gsd-core}/templates/research.md +0 -0
  501. /package/{get-shit-done → gsd-core}/templates/retrospective.md +0 -0
  502. /package/{get-shit-done → gsd-core}/templates/roadmap.md +0 -0
  503. /package/{get-shit-done → gsd-core}/templates/spec.md +0 -0
  504. /package/{get-shit-done → gsd-core}/templates/state.md +0 -0
  505. /package/{get-shit-done → gsd-core}/templates/summary-complex.md +0 -0
  506. /package/{get-shit-done → gsd-core}/templates/summary-minimal.md +0 -0
  507. /package/{get-shit-done → gsd-core}/templates/summary-standard.md +0 -0
  508. /package/{get-shit-done → gsd-core}/templates/summary.md +0 -0
  509. /package/{get-shit-done → gsd-core}/templates/user-profile.md +0 -0
  510. /package/{get-shit-done → gsd-core}/templates/user-setup.md +0 -0
  511. /package/{get-shit-done → gsd-core}/templates/verification-report.md +0 -0
  512. /package/{get-shit-done → gsd-core}/workflows/analyze-dependencies.md +0 -0
  513. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/all.md +0 -0
  514. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/analyze.md +0 -0
  515. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/batch.md +0 -0
  516. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/default.md +0 -0
  517. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/modes/text.md +0 -0
  518. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/checkpoint.json +0 -0
  519. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/context.md +0 -0
  520. /package/{get-shit-done → gsd-core}/workflows/discuss-phase/templates/discussion-log.md +0 -0
  521. /package/{get-shit-done → gsd-core}/workflows/discuss-phase-power.md +0 -0
  522. /package/{get-shit-done → gsd-core}/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -0
  523. /package/{get-shit-done → gsd-core}/workflows/fast.md +0 -0
  524. /package/{get-shit-done → gsd-core}/workflows/help/modes/brief.md +0 -0
  525. /package/{get-shit-done → gsd-core}/workflows/help/modes/topic.md +0 -0
  526. /package/{get-shit-done → gsd-core}/workflows/help.md +0 -0
  527. /package/{get-shit-done → gsd-core}/workflows/inbox.md +0 -0
  528. /package/{get-shit-done → gsd-core}/workflows/list-phase-assumptions.md +0 -0
  529. /package/{get-shit-done → gsd-core}/workflows/node-repair.md +0 -0
  530. /package/{get-shit-done → gsd-core}/workflows/note.md +0 -0
  531. /package/{get-shit-done → gsd-core}/workflows/pr-branch.md +0 -0
  532. /package/{get-shit-done → gsd-core}/workflows/session-report.md +0 -0
@@ -14,7 +14,7 @@ A plan that survives review from 2-3 independent AI systems is more robust.
14
14
  Check which AI CLIs are available on the system:
15
15
 
16
16
  ```bash
17
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
17
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
18
18
  # Check each CLI
19
19
  command -v gemini >/dev/null 2>&1 && echo "gemini:available" || echo "gemini:missing"
20
20
  command -v claude >/dev/null 2>&1 && echo "claude:available" || echo "claude:missing"
@@ -23,6 +23,7 @@ command -v coderabbit >/dev/null 2>&1 && echo "coderabbit:available" || echo "co
23
23
  command -v opencode >/dev/null 2>&1 && echo "opencode:available" || echo "opencode:missing"
24
24
  command -v qwen >/dev/null 2>&1 && echo "qwen:available" || echo "qwen:missing"
25
25
  command -v cursor >/dev/null 2>&1 && echo "cursor:available" || echo "cursor:missing"
26
+ command -v agy >/dev/null 2>&1 && echo "antigravity:available" || echo "antigravity:missing"
26
27
 
27
28
  # Check local model servers (OpenAI-compatible HTTP API — no CLI binary required)
28
29
  OLLAMA_HOST=$(gsd_run query config-get review.ollama_host 2>/dev/null | jq -r '.' 2>/dev/null || echo "")
@@ -46,6 +47,7 @@ Parse flags from `$ARGUMENTS`:
46
47
  - `--opencode` → include OpenCode
47
48
  - `--qwen` → include Qwen Code
48
49
  - `--cursor` → include Cursor
50
+ - `--agy` or `--antigravity` → include Antigravity CLI
49
51
  - `--ollama` → include Ollama (local server, OpenAI-compatible)
50
52
  - `--lm-studio` → include LM Studio (local server, OpenAI-compatible)
51
53
  - `--llama-cpp` → include llama.cpp (local server, OpenAI-compatible)
@@ -73,6 +75,7 @@ No external AI CLIs found. Install at least one:
73
75
  - opencode: https://opencode.ai (leverages GitHub Copilot subscription models)
74
76
  - qwen: https://github.com/nicepkg/qwen-code (Alibaba Qwen models)
75
77
  - cursor: https://cursor.com (Cursor IDE agent mode)
78
+ - agy: curl -fsSL https://antigravity.google/cli/install.sh | bash (Antigravity CLI — free with Google credentials)
76
79
 
77
80
  Then run /gsd:review again.
78
81
  ```
@@ -218,6 +221,8 @@ GEMINI_MODEL=$(gsd_run query config-get review.models.gemini 2>/dev/null | jq -r
218
221
  CLAUDE_MODEL=$(gsd_run query config-get review.models.claude 2>/dev/null | jq -r '.' 2>/dev/null || true)
219
222
  CODEX_MODEL=$(gsd_run query config-get review.models.codex 2>/dev/null | jq -r '.' 2>/dev/null || true)
220
223
  OPENCODE_MODEL=$(gsd_run query config-get review.models.opencode 2>/dev/null | jq -r '.' 2>/dev/null || true)
224
+ # review.models.agy is reserved for future model-pinning support; agy selects its model internally
225
+ AGY_MODEL=$(gsd_run query config-get review.models.agy 2>/dev/null | jq -r '.' 2>/dev/null || true)
221
226
  ```
222
227
 
223
228
  For each selected CLI, invoke in sequence (not parallel — avoid rate limits):
@@ -285,6 +290,103 @@ if [ ! -s /tmp/gsd-review-cursor-{phase}.md ]; then
285
290
  fi
286
291
  ```
287
292
 
293
+ **Antigravity CLI:**
294
+
295
+ **Maintainer note — why this block has three layers (last updated against agy 1.0.2):**
296
+
297
+ `agy -p` (the `--print` non-interactive flag) works correctly on macOS and Linux: it sends the
298
+ prompt, receives the model response, and writes it to stdout. On **native Windows** it silently
299
+ produces no stdout output despite the API call succeeding — a bug in `text_drip.go`'s non-TTY
300
+ flush path, tracked at https://github.com/google-antigravity/antigravity-cli/issues/27466 and
301
+ still open as of agy 1.0.2.
302
+
303
+ Regardless of platform, `agy` always persists the full exchange to a transcript file on disk.
304
+ The transcript fallback (Step 2 below) reads that file directly, giving Windows users full review
305
+ coverage without any extra tooling. This pattern was first documented by the community MCP bridge
306
+ at https://github.com/SinanTufekci/Claude-Code-Antigravity-CLI-MCP-Server — we inline the same
307
+ logic here in pure bash/jq so no additional dependency is required.
308
+
309
+ **Stale-response guard (why the pre-flight watermark matters):**
310
+ Without a watermark, the fallback would read the last `PLANNER_RESPONSE` entry in the transcript
311
+ regardless of when it was written — including entries from a previous invocation in the same
312
+ workspace. To prevent that, we record the transcript's line count *before* calling `agy -p`. In
313
+ the fallback, we only read lines appended after that count. If no new lines were written (agy
314
+ failed before producing a response), `_AGY_RESULT` is empty and Step 3 fires — never stale. If
315
+ the conv-id changed (agy started a fresh session), all lines in the new file are new and we use
316
+ skip=0.
317
+
318
+ **If the upstream stdout bug is fixed** (check the issue above): Step 2 silently becomes
319
+ unreachable; stdout is non-empty and Step 1 handles it. No code change needed.
320
+
321
+ **If the transcript paths change** in a future `agy` release: Step 2 silently becomes a no-op
322
+ and Step 3 fires with a clear error message in REVIEWS.md. No silent corruption. To debug:
323
+ - `~/.gemini/antigravity-cli/cache/last_conversations.json` — workspace → conv-id map
324
+ - `~/.gemini/antigravity-cli/brain/<id>/.system_generated/logs/transcript.jsonl`
325
+ Filter: `source=="MODEL"`, `status=="DONE"`, `type=="PLANNER_RESPONSE"`, take the last match's `content` field.
326
+
327
+ Invocation specifics (verified agy 1.0.0, macOS arm64 and Linux amd64):
328
+ - `-p` takes the prompt as a **flag value** — `echo X | agy -p` errors with "flag needs an argument: -p"
329
+ - `--print-timeout` defaults to 5m, aligning with this workflow's global timeout
330
+ - No `-m` / `--model` flag — agy selects the model internally
331
+
332
+ ```bash
333
+ # Pre-flight: snapshot the transcript watermark before invoking agy.
334
+ # Must run BEFORE agy -p — this is what prevents the fallback from reading a stale prior response.
335
+ _AGY_WS=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
336
+ _AGY_CACHE="$HOME/.gemini/antigravity-cli/cache/last_conversations.json"
337
+ _AGY_MARK_CONV=""
338
+ _AGY_MARK_LINES=0
339
+ if [ -f "$_AGY_CACHE" ]; then
340
+ _AGY_MARK_CONV=$(jq -r --arg ws "$_AGY_WS" '
341
+ .[$ws] //
342
+ (to_entries
343
+ | map(select(.key | ascii_downcase == ($ws | ascii_downcase)))
344
+ | first | .value) //
345
+ empty
346
+ ' "$_AGY_CACHE" 2>/dev/null)
347
+ if [ -n "$_AGY_MARK_CONV" ] && [ "$_AGY_MARK_CONV" != "null" ]; then
348
+ _AGY_MARK_TX="$HOME/.gemini/antigravity-cli/brain/${_AGY_MARK_CONV}/.system_generated/logs/transcript.jsonl"
349
+ [ -f "$_AGY_MARK_TX" ] && _AGY_MARK_LINES=$(wc -l < "$_AGY_MARK_TX" | tr -d ' ')
350
+ fi
351
+ fi
352
+
353
+ # Step 1 — primary invocation: stdout works on macOS, Linux, and WSL
354
+ agy -p "$(cat /tmp/gsd-review-prompt-{phase}.md)" 2>/dev/null > /tmp/gsd-review-antigravity-{phase}.md
355
+
356
+ # Step 2 — transcript fallback: catches Windows agy -p stdout bug (and any future stdout-silent edge cases).
357
+ # Reads only lines appended AFTER the pre-flight watermark. If agy failed before writing a new response,
358
+ # _AGY_RESULT is empty and Step 3 fires — no stale content can leak through.
359
+ # Undocumented paths, verified agy 1.0.0–1.0.2. See maintainer note above if these break.
360
+ if [ ! -s /tmp/gsd-review-antigravity-{phase}.md ]; then
361
+ if [ -f "$_AGY_CACHE" ]; then
362
+ _AGY_CONV=$(jq -r --arg ws "$_AGY_WS" '
363
+ .[$ws] //
364
+ (to_entries
365
+ | map(select(.key | ascii_downcase == ($ws | ascii_downcase)))
366
+ | first | .value) //
367
+ empty
368
+ ' "$_AGY_CACHE" 2>/dev/null)
369
+ if [ -n "$_AGY_CONV" ] && [ "$_AGY_CONV" != "null" ]; then
370
+ _AGY_TX="$HOME/.gemini/antigravity-cli/brain/${_AGY_CONV}/.system_generated/logs/transcript.jsonl"
371
+ if [ -f "$_AGY_TX" ]; then
372
+ # If conv-id changed, agy started a new session — all lines are new, skip 0.
373
+ # If same conv-id, only read lines beyond the watermark.
374
+ [ "$_AGY_CONV" = "$_AGY_MARK_CONV" ] && _AGY_SKIP=$_AGY_MARK_LINES || _AGY_SKIP=0
375
+ _AGY_RESULT=$(tail -n +"$((_AGY_SKIP + 1))" "$_AGY_TX" 2>/dev/null | \
376
+ jq -r 'select(.source=="MODEL" and .status=="DONE" and .type=="PLANNER_RESPONSE") | .content' \
377
+ 2>/dev/null | tail -1)
378
+ [ -n "$_AGY_RESULT" ] && echo "$_AGY_RESULT" > /tmp/gsd-review-antigravity-{phase}.md
379
+ fi
380
+ fi
381
+ fi
382
+ fi
383
+
384
+ # Step 3 — final guard: both approaches yielded nothing (auth error, first-run setup, path schema changed, etc.)
385
+ if [ ! -s /tmp/gsd-review-antigravity-{phase}.md ]; then
386
+ echo "Antigravity review failed or returned empty output." > /tmp/gsd-review-antigravity-{phase}.md
387
+ fi
388
+ ```
389
+
288
390
  **Ollama (local, OpenAI-compatible):**
289
391
 
290
392
  Read host and model from config. All three local backends share the same `/v1/chat/completions` endpoint — only host and model differ. Use `jq --rawfile` to safely encode the multi-line prompt as JSON without shell-escaping issues.
@@ -493,7 +595,7 @@ After all reviewers complete, collect trim metadata files written during the run
493
595
  ```markdown
494
596
  ---
495
597
  phase: {N}
496
- reviewers: [gemini, claude, codex, coderabbit, opencode, qwen, cursor, ollama, lm_studio, llama_cpp] # populate at runtime with only the reviewers actually invoked
598
+ reviewers: [gemini, claude, codex, coderabbit, opencode, qwen, cursor, antigravity, ollama, lm_studio, llama_cpp] # populate at runtime with only the reviewers actually invoked
497
599
  reviewed_at: {ISO timestamp}
498
600
  plans_reviewed: [{list of PLAN.md files}]
499
601
  trimmed_reviewers: # only present if at least one reviewer was trimmed
@@ -552,6 +654,12 @@ trimmed_reviewers: # only present if at least one reviewer was trimmed
552
654
 
553
655
  ---
554
656
 
657
+ ## Antigravity Review
658
+
659
+ {antigravity review content}
660
+
661
+ ---
662
+
555
663
  ## Ollama Review
556
664
 
557
665
  {ollama review content}
@@ -39,7 +39,7 @@ Exit.
39
39
  ## Step 2: Check for existing documents
40
40
 
41
41
  ```bash
42
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
42
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
43
43
  INIT=$(gsd_run query init.map-codebase 2>/dev/null || echo "{}")
44
44
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
45
45
  ```
@@ -72,6 +72,8 @@ mkdir -p .planning/codebase
72
72
 
73
73
  Spawn a single `gsd-codebase-mapper` agent with the selected focus area:
74
74
 
75
+ Print: `◆ Spawning scanner... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
76
+
75
77
  ```
76
78
  Agent(
77
79
  prompt="Scan this codebase with focus: {focus}. Write results to .planning/codebase/. Produce only: {document_list}",
@@ -3,7 +3,7 @@ Verify threat mitigations for a completed phase. Confirm PLAN.md threat register
3
3
  </purpose>
4
4
 
5
5
  <required_reading>
6
- @~/.claude/get-shit-done/references/ui-brand.md
6
+ @~/.claude/gsd-core/references/ui-brand.md
7
7
  </required_reading>
8
8
 
9
9
  <available_agent_types>
@@ -16,7 +16,7 @@ Valid GSD subagent types (use exact names — do not fall back to 'general-purpo
16
16
  ## 0. Initialize
17
17
 
18
18
  ```bash
19
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
19
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
20
20
  INIT=$(gsd_run query init.phase-op "${PHASE_ARG}")
21
21
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
22
22
  AGENT_SKILLS_AUDITOR=$(gsd_run query agent-skills gsd-security-auditor)
@@ -93,6 +93,8 @@ Call AskUserQuestion with threat table and options:
93
93
  - `register_authored_at_plan_time: true` — **Verify mitigations exist** — do not scan for new threats. The register is complete; verify each threat's mitigation is present in the implementation.
94
94
  - `register_authored_at_plan_time: false` (retroactive-STRIDE mode) — **Retroactive-STRIDE: build a STRIDE register from implementation files first, then verify mitigations.** The phase was authored before formal threat modelling; the auditor must construct the register from scratch before verifying.
95
95
 
96
+ Print: `◆ Spawning security auditor... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
97
+
96
98
  ```
97
99
  Agent(
98
100
  prompt="Read ~/.claude/agents/gsd-security-auditor.md for instructions.\n\n" +
@@ -117,7 +119,7 @@ Handle return:
117
119
  ## 6. Write/Update SECURITY.md
118
120
 
119
121
  **State B (create):**
120
- 1. Read template from `~/.claude/get-shit-done/templates/SECURITY.md`
122
+ 1. Read template from `~/.claude/gsd-core/templates/SECURITY.md`
121
123
  2. Fill: frontmatter, threat register, accepted risks, audit trail
122
124
  3. Write to `${PHASE_DIR}/${PADDED_PHASE}-SECURITY.md`
123
125
 
@@ -1,12 +1,14 @@
1
1
  <purpose>
2
2
  Interactive configuration of GSD power-user knobs — plan bounce, node repair, subagent timeouts,
3
3
  inline plan threshold, cross-AI execution, base branch, branch templates, response language,
4
- context window, gitignored search, graphify build timeout, and runtime model tier overrides.
4
+ context window, gitignored search, graphify build timeout, runtime model tier overrides, and
5
+ model policy configuration (provider + budget → canonical tier mapping, or manual model ID
6
+ assignment per cost tier).
5
7
 
6
8
  This is a companion to `/gsd:settings` — the common-case prompt there covers model profile,
7
9
  research/plan_check/verifier toggles, branching strategy, UI/AI phase gates, and worktree
8
10
  isolation. This advanced command covers everything else that is user-settable, grouped into
9
- seven sections so each prompt batch stays cognitively scoped. Every answer pre-selects the
11
+ eight sections so each prompt batch stays cognitively scoped. Every answer pre-selects the
10
12
  current value; numeric-input answers that are non-numeric are rejected and re-prompted.
11
13
  </purpose>
12
14
 
@@ -20,7 +22,7 @@ Read all files referenced by the invoking prompt's execution_context before star
20
22
  Ensure config exists and resolve the workstream-aware config path (mirrors `settings.md`):
21
23
 
22
24
  ```bash
23
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
25
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
24
26
  gsd_run query config-ensure-section
25
27
  if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
26
28
  if [[ -f .planning/active-workstream ]]; then
@@ -81,6 +83,13 @@ Runtime Model Tiers:
81
83
  - `model_profile_overrides.<runtime>.sonnet` (default: built-in for the runtime, or absent)
82
84
  - `model_profile_overrides.<runtime>.haiku` (default: built-in for the runtime, or absent)
83
85
 
86
+ Model Policy:
87
+ - `model_policy.provider` (default: `null` — known values: anthropic, openai, google, qwen)
88
+ - `model_policy.budget` (default: `null` — known values: high, medium, low)
89
+ - `model_policy.high` (default: `null` — model ID for the high-cost tier; used by generic provider path)
90
+ - `model_policy.medium` (default: `null` — model ID for the medium-cost tier; used by generic provider path)
91
+ - `model_policy.low` (default: `null` — model ID for the low-cost tier; used by generic provider path)
92
+
84
93
  Each field's **current value is pre-selected** in the prompt rendering below. When the
85
94
  current value is absent from the config, render the documented default as the pre-selected
86
95
  option so the user sees what the effective value is.
@@ -500,7 +509,7 @@ gsd_run query config-set model_profile_overrides.gemini.haiku null
500
509
 
501
510
  Conceptual shape after merge (unchanged top-level keys like `model_profile`,
502
511
  `granularity`, `mode`, `brave_search`, `agent_skills.*`, `hooks.context_warnings`, and
503
- anything not listed in Sections 1–7 MUST survive the update):
512
+ anything not listed in Sections 1–8 MUST survive the update):
504
513
 
505
514
  ```json
506
515
  {
@@ -542,6 +551,14 @@ anything not listed in Sections 1–7 MUST survive the update):
542
551
  "sonnet": <new|existing|null>,
543
552
  "haiku": <new|existing|null>
544
553
  }
554
+ },
555
+ "model_policy": {
556
+ ...existing_model_policy,
557
+ "provider": <new|existing|null>,
558
+ "budget": <new|existing|null>,
559
+ "high": <new|existing|null>,
560
+ "medium": <new|existing|null>,
561
+ "low": <new|existing|null>
545
562
  }
546
563
  }
547
564
  ```
@@ -551,6 +568,170 @@ route each write through `gsd-tools.cjs query config-set` so sibling preservatio
551
568
  the central setter.
552
569
  </step>
553
570
 
571
+ ### Section 8 — Model Policy
572
+
573
+ This section configures the `model_policy` key in `.planning/config.json`. Model policy
574
+ defines which AI models GSD uses at each cost tier (low / medium / high), independently
575
+ of the `runtime` and `model_profile` selections above. Two paths are offered:
576
+
577
+ - **Known provider:** choose a provider and a budget level; GSD materializes the canonical
578
+ tier mapping for that provider.
579
+ - **Generic provider:** enter low / medium / high model IDs manually.
580
+
581
+ **Step A — Read and display the current model policy:**
582
+
583
+ ```bash
584
+ cat "$GSD_CONFIG_PATH" | python3 -c "import sys,json; c=json.load(sys.stdin); mp=c.get('model_policy',{}); print(json.dumps(mp,indent=2))" 2>/dev/null || echo "{}"
585
+ ```
586
+
587
+ Display the current values (or "(unset)" for any absent field) before asking:
588
+
589
+ ```text
590
+ Current model_policy:
591
+ provider : <value or "(unset)">
592
+ budget : <value or "(unset)">
593
+ low : <value or "(unset)">
594
+ medium : <value or "(unset)">
595
+ high : <value or "(unset)">
596
+ ```
597
+
598
+ **Step B — Choose configuration path:**
599
+
600
+ ```text
601
+ AskUserQuestion([
602
+ {
603
+ question: "How do you want to configure the model policy?",
604
+ header: "Model Policy",
605
+ multiSelect: false,
606
+ options: [
607
+ { label: "Known provider", description: "Choose a provider (Claude / OpenAI / Gemini / Qwen) and a budget level — GSD writes the canonical tier mapping automatically." },
608
+ { label: "Generic provider", description: "Enter low / medium / high model IDs manually for any provider or custom deployment." },
609
+ { label: "Keep current", description: "Leave model_policy unchanged." }
610
+ ]
611
+ }
612
+ ])
613
+ ```
614
+
615
+ **If "Keep current" is selected:** skip Steps C–E and move on to the confirm step.
616
+
617
+ **Step C — Known-provider path:**
618
+
619
+ ```text
620
+ AskUserQuestion([
621
+ {
622
+ question: "Which provider?",
623
+ header: "Provider",
624
+ multiSelect: false,
625
+ options: [
626
+ { label: "anthropic", description: "claude-opus-4-8 / claude-sonnet-4-6 / claude-haiku-4-5 (Anthropic / Claude)" },
627
+ { label: "openai", description: "gpt-5.5 / gpt-5.3-codex / gpt-5.4-mini (OpenAI / Codex)" },
628
+ { label: "google", description: "gemini-3-pro / gemini-3-flash / gemini-2.5-flash-lite (Google Gemini)" },
629
+ { label: "qwen", description: "qwen3-max-2026-01-23 / qwen3-coder-plus / qwen3-coder-next (Qwen)" }
630
+ ]
631
+ }
632
+ ])
633
+ ```
634
+
635
+ After the user picks a provider, ask:
636
+
637
+ ```text
638
+ AskUserQuestion([
639
+ {
640
+ question: "Which budget level?",
641
+ header: "Budget",
642
+ multiSelect: false,
643
+ options: [
644
+ { label: "high", description: "All tiers use the highest-quality model for the chosen provider. Highest cost." },
645
+ { label: "medium", description: "High tier → top model; medium → mid model; low → cheapest model. Best cost/quality ratio." },
646
+ { label: "low", description: "All tiers use the cheapest model for the chosen provider. Lowest cost." }
647
+ ]
648
+ }
649
+ ])
650
+ ```
651
+
652
+ Canonical tier mappings by provider and budget:
653
+
654
+ | Provider | Budget | high | medium | low |
655
+ |-----------|--------|----------------------------|----------------------------|----------------------------|
656
+ | anthropic | high | claude-opus-4-8 | claude-opus-4-8 | claude-opus-4-8 |
657
+ | anthropic | medium | claude-opus-4-8 | claude-sonnet-4-6 | claude-haiku-4-5 |
658
+ | anthropic | low | claude-haiku-4-5 | claude-haiku-4-5 | claude-haiku-4-5 |
659
+ | openai | high | gpt-5.5 | gpt-5.5 | gpt-5.5 |
660
+ | openai | medium | gpt-5.5 | gpt-5.3-codex | gpt-5.4-mini |
661
+ | openai | low | gpt-5.4-mini | gpt-5.4-mini | gpt-5.4-mini |
662
+ | google | high | gemini-3-pro | gemini-3-pro | gemini-3-pro |
663
+ | google | medium | gemini-3-pro | gemini-3-flash | gemini-2.5-flash-lite |
664
+ | google | low | gemini-2.5-flash-lite | gemini-2.5-flash-lite | gemini-2.5-flash-lite |
665
+ | qwen | high | qwen3-max-2026-01-23 | qwen3-max-2026-01-23 | qwen3-max-2026-01-23 |
666
+ | qwen | medium | qwen3-max-2026-01-23 | qwen3-coder-plus | qwen3-coder-next |
667
+ | qwen | low | qwen3-coder-next | qwen3-coder-next | qwen3-coder-next |
668
+
669
+ Look up the selected (provider, budget) row and proceed to Step E to write those values.
670
+
671
+ **Step D — Generic-provider path:**
672
+
673
+ Prompt the user to enter each model ID as a free-text input. An empty input means "keep
674
+ the current value for that tier." Validate that non-empty inputs are non-blank strings
675
+ (no whitespace-only values); if validation fails, re-prompt that single field.
676
+
677
+ ```text
678
+ AskUserQuestion([
679
+ {
680
+ question: "Model ID for the HIGH-cost tier? (most capable model — used for heavy reasoning tasks)",
681
+ header: "High-tier model",
682
+ multiSelect: false,
683
+ options: [
684
+ { label: "Keep current", description: "Leave unchanged (current: <model_policy.high or '(unset)'>)." },
685
+ { label: "Enter model ID", description: "Type the exact model identifier. Non-blank string required." }
686
+ ]
687
+ },
688
+ {
689
+ question: "Model ID for the MEDIUM-cost tier? (balanced model — used for most agents)",
690
+ header: "Medium-tier model",
691
+ multiSelect: false,
692
+ options: [
693
+ { label: "Keep current", description: "Leave unchanged (current: <model_policy.medium or '(unset)'>)." },
694
+ { label: "Enter model ID", description: "Type the exact model identifier." }
695
+ ]
696
+ },
697
+ {
698
+ question: "Model ID for the LOW-cost tier? (cheapest model — used for lightweight/fast tasks)",
699
+ header: "Low-tier model",
700
+ multiSelect: false,
701
+ options: [
702
+ { label: "Keep current", description: "Leave unchanged (current: <model_policy.low or '(unset)'>)." },
703
+ { label: "Enter model ID", description: "Type the exact model identifier." }
704
+ ]
705
+ }
706
+ ])
707
+ ```
708
+
709
+ Set `provider = "custom"` and `budget = null` when writing the generic-provider result.
710
+ Proceed to Step E.
711
+
712
+ **Step E — Write model_policy to config:**
713
+
714
+ ```bash
715
+ # Known-provider path — write all four keys atomically:
716
+ gsd_run query config-set model_policy.provider "<provider>" # e.g., anthropic / openai / google / qwen
717
+ gsd_run query config-set model_policy.budget "<budget>" # high / medium / low
718
+ gsd_run query config-set model_policy.high "<high-id>"
719
+ gsd_run query config-set model_policy.medium "<medium-id>"
720
+ gsd_run query config-set model_policy.low "<low-id>"
721
+
722
+ # Generic-provider path — write only tiers the user changed ("Keep current" skipped):
723
+ gsd_run query config-set model_policy.provider "custom"
724
+ gsd_run query config-set model_policy.budget null
725
+ # Per-tier writes for each non-"Keep current" answer:
726
+ gsd_run query config-set model_policy.high "<high-id>" # omit if user chose "Keep current"
727
+ gsd_run query config-set model_policy.medium "<medium-id>" # omit if user chose "Keep current"
728
+ gsd_run query config-set model_policy.low "<low-id>" # omit if user chose "Keep current"
729
+ ```
730
+
731
+ Never write a tier the user explicitly chose to keep; the existing value must survive.
732
+
733
+ </step>
734
+
554
735
  <step name="confirm">
555
736
  Display:
556
737
 
@@ -594,6 +775,11 @@ Display:
594
775
  | fast_mode.routing_tier_defaults.standard | {true/false} |
595
776
  | fast_mode.routing_tier_defaults.heavy | {true/false} |
596
777
  | fast_mode.agent_overrides.<agent-id> | {true/false} |
778
+ | model_policy.provider | {anthropic/openai/google/qwen/custom/null} |
779
+ | model_policy.budget | {high/medium/low/null} |
780
+ | model_policy.high | {model-id/null} |
781
+ | model_policy.medium | {model-id/null} |
782
+ | model_policy.low | {model-id/null} |
597
783
 
598
784
  These settings apply to future /gsd:plan-phase, /gsd:execute-phase, /gsd:discuss-phase,
599
785
  and /gsd:ship runs.
@@ -607,7 +793,7 @@ UI/AI phase gates), use /gsd:settings.
607
793
 
608
794
  <success_criteria>
609
795
  - [ ] Current config read from resolved `$GSD_CONFIG_PATH`
610
- - [ ] Seven sections rendered (Planning, Execution, Discussion, Cross-AI, Git, Runtime/Output, Runtime Model Tiers)
796
+ - [ ] Eight sections rendered (Planning, Execution, Discussion, Cross-AI, Git, Runtime/Output, Runtime Model Tiers, Model Policy)
611
797
  - [ ] Every field pre-selected to its current value (or documented default if absent)
612
798
  - [ ] Numeric inputs validated — non-numeric rejected and re-prompted
613
799
  - [ ] Branch-template inputs validated — non-default must contain a placeholder
@@ -616,5 +802,9 @@ UI/AI phase gates), use /gsd:settings.
616
802
  - [ ] Section 7 shows current runtime and built-in tier table
617
803
  - [ ] Group B runtimes display "(no built-in default — your runtime handles model selection)"
618
804
  - [ ] Override set/clear/keep paths all work correctly for each tier
619
- - [ ] Confirmation table rendered listing all 23 fields (19 + runtime + 3 tier overrides)
805
+ - [ ] Section 8 (Model Policy) offers three top-level choices: Known provider, Generic provider, Keep current
806
+ - [ ] Known-provider path: provider + budget → canonical tier mapping written to model_policy.{provider,budget,high,medium,low}
807
+ - [ ] Generic-provider path: per-tier manual model IDs; "Keep current" tiers are never written; provider=custom budget=null
808
+ - [ ] model_policy written under the model_policy key in config.json, never as a top-level flat key
809
+ - [ ] Confirmation table rendered listing all fields including model_policy.{provider,budget,high,medium,low}
620
810
  </success_criteria>
@@ -25,7 +25,7 @@ log the plaintext value. The workflow follows these rules:
25
25
  other than `config.json` itself.
26
26
  - **`config-set` output is masked** for keys in the secret set
27
27
  (`brave_search`, `firecrawl`, `exa_search`) — see
28
- `get-shit-done/bin/lib/secrets.cjs`.
28
+ `gsd-core/bin/lib/secrets.cjs`.
29
29
  - **Agent-type and CLI slug validation.** `agent_skills.<agent-type>` and
30
30
  `review.models.<cli>` keys are matched against `^[a-zA-Z0-9_-]+$`. Inputs
31
31
  containing path separators (`/`, `\`, `..`), whitespace, or shell
@@ -42,7 +42,7 @@ Read all files referenced by the invoking prompt's execution_context before star
42
42
  Ensure config exists and resolve the active config path (flat vs workstream, #2282):
43
43
 
44
44
  ```bash
45
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
45
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
46
46
  gsd_run query config-ensure-section
47
47
  if [[ -z "${GSD_CONFIG_PATH:-}" ]]; then
48
48
  if [[ -f .planning/active-workstream ]]; then
@@ -12,7 +12,7 @@ Read all files referenced by the invoking prompt's execution_context before star
12
12
  Ensure config exists and load current state:
13
13
 
14
14
  ```bash
15
- _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
15
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
16
16
  gsd_run query config-ensure-section
17
17
  INIT=$(gsd_run query state.load)
18
18
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
@@ -57,6 +57,11 @@ Parse current values (default to `true` if not present):
57
57
  - `model_profile` — which model each agent uses (default: `balanced`)
58
58
  - `git.branching_strategy` — branching approach (default: `"none"`)
59
59
  - `workflow.use_worktrees` — whether parallel executor agents run in worktree isolation (default: `true`)
60
+ - `model_policy.provider` — provider slug for model policy (default: `null`; known values: anthropic, openai, google, qwen; set via /gsd:config --advanced)
61
+ - `model_policy.budget` — budget level for model policy (default: `null`; known values: high, medium, low; set via /gsd:config --advanced)
62
+ - `model_policy.high` — model ID for high-cost tier (default: `null`; set via /gsd:config --advanced)
63
+ - `model_policy.medium` — model ID for medium-cost tier (default: `null`; set via /gsd:config --advanced)
64
+ - `model_policy.low` — model ID for low-cost tier (default: `null`; set via /gsd:config --advanced)
60
65
  </step>
61
66
 
62
67
  <step name="present_settings">
@@ -423,6 +428,15 @@ Merge new settings into existing config.json:
423
428
  "hooks": {
424
429
  "context_warnings": true/false,
425
430
  "workflow_guard": true/false
431
+ },
432
+ "model_policy": {
433
+ // Read-only in this flow — written only by /gsd:config --advanced (Section 8).
434
+ // Listed here so safe-merge never clobbers an existing model_policy object.
435
+ "provider": <existing|null>,
436
+ "budget": <existing|null>,
437
+ "high": <existing|null>,
438
+ "medium": <existing|null>,
439
+ "low": <existing|null>
426
440
  }
427
441
  }
428
442
  ```
@@ -537,7 +551,7 @@ Quick commands:
537
551
  - /gsd:plan-phase --research — force research
538
552
  - /gsd:plan-phase --skip-research — skip research
539
553
  - /gsd:plan-phase --skip-verify — skip plan check
540
- - /gsd:config --advanced — power-user tuning (plan bounce, timeouts, branch templates, cross-AI, context window)
554
+ - /gsd:config --advanced — power-user tuning (plan bounce, timeouts, branch templates, cross-AI, context window, model policy)
541
555
  ```
542
556
  </step>
543
557