@therocketcode/gsd-core 1.4.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 (568) hide show
  1. package/.claude-plugin/plugin.json +23 -0
  2. package/GEMINI.md +53 -0
  3. package/LICENSE +21 -0
  4. package/README.ja-JP.md +125 -0
  5. package/README.ko-KR.md +125 -0
  6. package/README.md +144 -0
  7. package/README.pt-BR.md +125 -0
  8. package/README.zh-CN.md +125 -0
  9. package/agents/gsd-advisor-researcher.md +108 -0
  10. package/agents/gsd-ai-researcher.md +114 -0
  11. package/agents/gsd-assumptions-analyzer.md +105 -0
  12. package/agents/gsd-code-fixer.md +668 -0
  13. package/agents/gsd-code-reviewer.md +387 -0
  14. package/agents/gsd-codebase-mapper.md +853 -0
  15. package/agents/gsd-debug-session-manager.md +314 -0
  16. package/agents/gsd-debugger.md +1452 -0
  17. package/agents/gsd-doc-classifier.md +168 -0
  18. package/agents/gsd-doc-synthesizer.md +204 -0
  19. package/agents/gsd-doc-verifier.md +217 -0
  20. package/agents/gsd-doc-writer.md +616 -0
  21. package/agents/gsd-domain-researcher.md +147 -0
  22. package/agents/gsd-eval-auditor.md +191 -0
  23. package/agents/gsd-eval-planner.md +154 -0
  24. package/agents/gsd-executor.md +785 -0
  25. package/agents/gsd-framework-selector.md +160 -0
  26. package/agents/gsd-integration-checker.md +470 -0
  27. package/agents/gsd-intel-updater.md +342 -0
  28. package/agents/gsd-nyquist-auditor.md +203 -0
  29. package/agents/gsd-pattern-mapper.md +335 -0
  30. package/agents/gsd-phase-researcher.md +867 -0
  31. package/agents/gsd-plan-checker.md +978 -0
  32. package/agents/gsd-planner.md +1204 -0
  33. package/agents/gsd-project-researcher.md +611 -0
  34. package/agents/gsd-research-synthesizer.md +259 -0
  35. package/agents/gsd-roadmapper.md +688 -0
  36. package/agents/gsd-security-auditor.md +155 -0
  37. package/agents/gsd-ui-auditor.md +495 -0
  38. package/agents/gsd-ui-checker.md +309 -0
  39. package/agents/gsd-ui-researcher.md +374 -0
  40. package/agents/gsd-user-profiler.md +171 -0
  41. package/agents/gsd-verifier.md +923 -0
  42. package/assets/gsd-logo-2000-transparent.png +0 -0
  43. package/assets/gsd-logo-2000-transparent.svg +17 -0
  44. package/assets/gsd-logo-2000.png +0 -0
  45. package/assets/gsd-logo-2000.svg +21 -0
  46. package/assets/terminal.svg +68 -0
  47. package/bin/install.js +12726 -0
  48. package/bin/lib/ui-safety-gate.cjs +107 -0
  49. package/commands/gsd/add-tests.md +42 -0
  50. package/commands/gsd/ai-integration-phase.md +37 -0
  51. package/commands/gsd/audit-fix.md +34 -0
  52. package/commands/gsd/audit-milestone.md +37 -0
  53. package/commands/gsd/audit-uat.md +24 -0
  54. package/commands/gsd/autonomous.md +48 -0
  55. package/commands/gsd/capture.md +62 -0
  56. package/commands/gsd/cleanup.md +24 -0
  57. package/commands/gsd/code-review.md +59 -0
  58. package/commands/gsd/complete-milestone.md +143 -0
  59. package/commands/gsd/config.md +56 -0
  60. package/commands/gsd/debug.md +52 -0
  61. package/commands/gsd/discover-product.md +65 -0
  62. package/commands/gsd/discuss-phase.md +77 -0
  63. package/commands/gsd/docs-update.md +49 -0
  64. package/commands/gsd/eval-review.md +33 -0
  65. package/commands/gsd/execute-phase.md +66 -0
  66. package/commands/gsd/explore.md +27 -0
  67. package/commands/gsd/extract-learnings.md +23 -0
  68. package/commands/gsd/fast.md +31 -0
  69. package/commands/gsd/forensics.md +57 -0
  70. package/commands/gsd/graphify.md +204 -0
  71. package/commands/gsd/health.md +31 -0
  72. package/commands/gsd/help.md +28 -0
  73. package/commands/gsd/import.md +45 -0
  74. package/commands/gsd/inbox.md +39 -0
  75. package/commands/gsd/ingest-docs.md +42 -0
  76. package/commands/gsd/manager.md +45 -0
  77. package/commands/gsd/map-codebase.md +83 -0
  78. package/commands/gsd/milestone-summary.md +51 -0
  79. package/commands/gsd/model-domain.md +65 -0
  80. package/commands/gsd/mvp-phase.md +45 -0
  81. package/commands/gsd/new-milestone.md +45 -0
  82. package/commands/gsd/new-project.md +47 -0
  83. package/commands/gsd/ns-context.md +23 -0
  84. package/commands/gsd/ns-ideate.md +24 -0
  85. package/commands/gsd/ns-manage.md +29 -0
  86. package/commands/gsd/ns-project.md +22 -0
  87. package/commands/gsd/ns-review.md +26 -0
  88. package/commands/gsd/ns-workflow.md +28 -0
  89. package/commands/gsd/pause-work.md +43 -0
  90. package/commands/gsd/phase.md +56 -0
  91. package/commands/gsd/plan-phase.md +64 -0
  92. package/commands/gsd/plan-review-convergence.md +59 -0
  93. package/commands/gsd/pr-branch.md +26 -0
  94. package/commands/gsd/profile-user.md +46 -0
  95. package/commands/gsd/progress.md +48 -0
  96. package/commands/gsd/quick.md +174 -0
  97. package/commands/gsd/recommend-architecture.md +64 -0
  98. package/commands/gsd/resume-work.md +30 -0
  99. package/commands/gsd/review-backlog.md +63 -0
  100. package/commands/gsd/review.md +42 -0
  101. package/commands/gsd/secure-phase.md +36 -0
  102. package/commands/gsd/settings.md +29 -0
  103. package/commands/gsd/ship.md +24 -0
  104. package/commands/gsd/sketch.md +60 -0
  105. package/commands/gsd/spec-phase.md +63 -0
  106. package/commands/gsd/spike.md +57 -0
  107. package/commands/gsd/stats.md +20 -0
  108. package/commands/gsd/surface.md +155 -0
  109. package/commands/gsd/testing-strategy.md +65 -0
  110. package/commands/gsd/thread.md +24 -0
  111. package/commands/gsd/ui-phase.md +35 -0
  112. package/commands/gsd/ui-review.md +33 -0
  113. package/commands/gsd/ultraplan-phase.md +34 -0
  114. package/commands/gsd/undo.md +35 -0
  115. package/commands/gsd/update.md +49 -0
  116. package/commands/gsd/validate-phase.md +36 -0
  117. package/commands/gsd/verify-work.md +39 -0
  118. package/commands/gsd/workspace.md +52 -0
  119. package/commands/gsd/workstreams.md +70 -0
  120. package/gemini-extension.json +6 -0
  121. package/gsd-core/bin/check-latest-version.cjs +161 -0
  122. package/gsd-core/bin/gsd-tools.cjs +1928 -0
  123. package/gsd-core/bin/lib/active-workstream-store.cjs +291 -0
  124. package/gsd-core/bin/lib/adr-parser.cjs +399 -0
  125. package/gsd-core/bin/lib/agent-command-router.cjs +68 -0
  126. package/gsd-core/bin/lib/artifacts.cjs +51 -0
  127. package/gsd-core/bin/lib/audit.cjs +743 -0
  128. package/gsd-core/bin/lib/check-command-router.cjs +343 -0
  129. package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
  130. package/gsd-core/bin/lib/cli-exit.cjs +42 -0
  131. package/gsd-core/bin/lib/clock.cjs +95 -0
  132. package/gsd-core/bin/lib/clusters.cjs +132 -0
  133. package/gsd-core/bin/lib/code-review-flags.cjs +59 -0
  134. package/gsd-core/bin/lib/command-aliases.cjs +809 -0
  135. package/gsd-core/bin/lib/command-arg-projection.cjs +55 -0
  136. package/gsd-core/bin/lib/command-routing-hub.cjs +300 -0
  137. package/gsd-core/bin/lib/commands.cjs +1203 -0
  138. package/gsd-core/bin/lib/config-schema.cjs +29 -0
  139. package/gsd-core/bin/lib/config-types.cjs +19 -0
  140. package/gsd-core/bin/lib/config.cjs +738 -0
  141. package/gsd-core/bin/lib/configuration.cjs +239 -0
  142. package/gsd-core/bin/lib/context-utilization.cjs +48 -0
  143. package/gsd-core/bin/lib/core.cjs +2051 -0
  144. package/gsd-core/bin/lib/decisions.cjs +118 -0
  145. package/gsd-core/bin/lib/docs.cjs +252 -0
  146. package/gsd-core/bin/lib/drift.cjs +364 -0
  147. package/gsd-core/bin/lib/fallow-runner.cjs +115 -0
  148. package/gsd-core/bin/lib/frontmatter.cjs +442 -0
  149. package/gsd-core/bin/lib/gap-checker.cjs +257 -0
  150. package/gsd-core/bin/lib/graphify.cjs +496 -0
  151. package/gsd-core/bin/lib/gsd2-import.cjs +456 -0
  152. package/gsd-core/bin/lib/init-command-router.cjs +62 -0
  153. package/gsd-core/bin/lib/init.cjs +1815 -0
  154. package/gsd-core/bin/lib/install-profiles.cjs +584 -0
  155. package/gsd-core/bin/lib/installer-migration-authoring.cjs +122 -0
  156. package/gsd-core/bin/lib/installer-migration-report.cjs +350 -0
  157. package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +218 -0
  158. package/gsd-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
  159. package/gsd-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
  160. package/gsd-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
  161. package/gsd-core/bin/lib/installer-migrations.cjs +823 -0
  162. package/gsd-core/bin/lib/intel.cjs +590 -0
  163. package/gsd-core/bin/lib/learnings.cjs +270 -0
  164. package/gsd-core/bin/lib/legacy-cleanup.cjs +253 -0
  165. package/gsd-core/bin/lib/milestone.cjs +373 -0
  166. package/gsd-core/bin/lib/model-catalog.cjs +154 -0
  167. package/gsd-core/bin/lib/model-profiles.cjs +24 -0
  168. package/gsd-core/bin/lib/observability/event.cjs +51 -0
  169. package/gsd-core/bin/lib/observability/logger.cjs +146 -0
  170. package/gsd-core/bin/lib/observability/redaction.cjs +48 -0
  171. package/gsd-core/bin/lib/package-identity.cjs +35 -0
  172. package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
  173. package/gsd-core/bin/lib/phase-command-router.cjs +189 -0
  174. package/gsd-core/bin/lib/phase-lifecycle.cjs +74 -0
  175. package/gsd-core/bin/lib/phase.cjs +1307 -0
  176. package/gsd-core/bin/lib/phases-command-router.cjs +43 -0
  177. package/gsd-core/bin/lib/plan-scan.cjs +91 -0
  178. package/gsd-core/bin/lib/planning-workspace.cjs +245 -0
  179. package/gsd-core/bin/lib/profile-output.cjs +1120 -0
  180. package/gsd-core/bin/lib/profile-pipeline.cjs +517 -0
  181. package/gsd-core/bin/lib/project-root.cjs +119 -0
  182. package/gsd-core/bin/lib/prompt-budget.cjs +305 -0
  183. package/gsd-core/bin/lib/research-provider.cjs +137 -0
  184. package/gsd-core/bin/lib/research-store.cjs +167 -0
  185. package/gsd-core/bin/lib/review-reviewer-selection.cjs +121 -0
  186. package/gsd-core/bin/lib/roadmap-command-router.cjs +166 -0
  187. package/gsd-core/bin/lib/roadmap-upgrade.cjs +476 -0
  188. package/gsd-core/bin/lib/roadmap.cjs +600 -0
  189. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +312 -0
  190. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
  191. package/gsd-core/bin/lib/runtime-homes.cjs +190 -0
  192. package/gsd-core/bin/lib/runtime-name-policy.cjs +96 -0
  193. package/gsd-core/bin/lib/runtime-slash.cjs +119 -0
  194. package/gsd-core/bin/lib/schema-detect.cjs +159 -0
  195. package/gsd-core/bin/lib/secrets.cjs +34 -0
  196. package/gsd-core/bin/lib/security.cjs +480 -0
  197. package/gsd-core/bin/lib/semver-compare.cjs +42 -0
  198. package/gsd-core/bin/lib/shell-command-projection.cjs +533 -0
  199. package/gsd-core/bin/lib/state-command-router.cjs +160 -0
  200. package/gsd-core/bin/lib/state-document.cjs +259 -0
  201. package/gsd-core/bin/lib/state.cjs +2010 -0
  202. package/gsd-core/bin/lib/surface.cjs +449 -0
  203. package/gsd-core/bin/lib/task-command-router.cjs +85 -0
  204. package/gsd-core/bin/lib/template.cjs +237 -0
  205. package/gsd-core/bin/lib/uat.cjs +297 -0
  206. package/gsd-core/bin/lib/ui-safety-gate.cjs +98 -0
  207. package/gsd-core/bin/lib/update-context.cjs +218 -0
  208. package/gsd-core/bin/lib/validate-command-router.cjs +91 -0
  209. package/gsd-core/bin/lib/validate.cjs +112 -0
  210. package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
  211. package/gsd-core/bin/lib/verification.cjs +193 -0
  212. package/gsd-core/bin/lib/verify-command-router.cjs +44 -0
  213. package/gsd-core/bin/lib/verify.cjs +1451 -0
  214. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +81 -0
  215. package/gsd-core/bin/lib/workstream-inventory.cjs +147 -0
  216. package/gsd-core/bin/lib/workstream-name-policy.cjs +91 -0
  217. package/gsd-core/bin/lib/workstream.cjs +380 -0
  218. package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
  219. package/gsd-core/bin/lib/worktree-safety.cjs +943 -0
  220. package/gsd-core/bin/shared/config-defaults.manifest.json +98 -0
  221. package/gsd-core/bin/shared/config-schema.manifest.json +192 -0
  222. package/gsd-core/bin/shared/model-catalog.json +149 -0
  223. package/gsd-core/bin/shared/runtime-aliases.manifest.json +75 -0
  224. package/gsd-core/bin/verify-reapply-patches.cjs +349 -0
  225. package/gsd-core/contexts/dev.md +21 -0
  226. package/gsd-core/contexts/research.md +22 -0
  227. package/gsd-core/contexts/review.md +23 -0
  228. package/gsd-core/references/agent-contracts.md +79 -0
  229. package/gsd-core/references/ai-evals.md +156 -0
  230. package/gsd-core/references/ai-frameworks.md +186 -0
  231. package/gsd-core/references/architecture-decision.md +74 -0
  232. package/gsd-core/references/artifact-types.md +131 -0
  233. package/gsd-core/references/auth-in-tests.md +91 -0
  234. package/gsd-core/references/autonomous-smart-discuss.md +277 -0
  235. package/gsd-core/references/checkpoints.md +814 -0
  236. package/gsd-core/references/common-bug-patterns.md +114 -0
  237. package/gsd-core/references/context-budget.md +85 -0
  238. package/gsd-core/references/continuation-format.md +253 -0
  239. package/gsd-core/references/db-test-isolation.md +54 -0
  240. package/gsd-core/references/debugger-philosophy.md +76 -0
  241. package/gsd-core/references/decimal-phase-calculation.md +64 -0
  242. package/gsd-core/references/doc-conflict-engine.md +91 -0
  243. package/gsd-core/references/domain-modeling.md +80 -0
  244. package/gsd-core/references/domain-probes.md +125 -0
  245. package/gsd-core/references/e2e-tiering.md +35 -0
  246. package/gsd-core/references/execute-mvp-tdd.md +81 -0
  247. package/gsd-core/references/executor-examples.md +110 -0
  248. package/gsd-core/references/few-shot-examples/plan-checker.md +73 -0
  249. package/gsd-core/references/few-shot-examples/verifier.md +109 -0
  250. package/gsd-core/references/flaky-test-checklist.md +22 -0
  251. package/gsd-core/references/gate-prompts.md +100 -0
  252. package/gsd-core/references/gates.md +70 -0
  253. package/gsd-core/references/git-integration.md +298 -0
  254. package/gsd-core/references/git-planning-commit.md +40 -0
  255. package/gsd-core/references/ios-scaffold.md +123 -0
  256. package/gsd-core/references/mandatory-initial-read.md +2 -0
  257. package/gsd-core/references/model-profile-resolution.md +38 -0
  258. package/gsd-core/references/model-profiles.md +245 -0
  259. package/gsd-core/references/mvp-concepts.md +49 -0
  260. package/gsd-core/references/phase-argument-parsing.md +61 -0
  261. package/gsd-core/references/planner-antipatterns.md +89 -0
  262. package/gsd-core/references/planner-chunked.md +49 -0
  263. package/gsd-core/references/planner-gap-closure.md +62 -0
  264. package/gsd-core/references/planner-graphify-auto-update.md +67 -0
  265. package/gsd-core/references/planner-human-verify-mode.md +57 -0
  266. package/gsd-core/references/planner-interface-context.md +62 -0
  267. package/gsd-core/references/planner-load-graph-context.md +36 -0
  268. package/gsd-core/references/planner-mvp-mode.md +53 -0
  269. package/gsd-core/references/planner-reviews.md +39 -0
  270. package/gsd-core/references/planner-revision.md +87 -0
  271. package/gsd-core/references/planner-source-audit.md +73 -0
  272. package/gsd-core/references/planning-config.md +473 -0
  273. package/gsd-core/references/product-discovery.md +49 -0
  274. package/gsd-core/references/project-skills-discovery.md +19 -0
  275. package/gsd-core/references/questioning.md +162 -0
  276. package/gsd-core/references/realistic-test-data.md +44 -0
  277. package/gsd-core/references/research-documentation-lookup.md +29 -0
  278. package/gsd-core/references/research-philosophy.md +29 -0
  279. package/gsd-core/references/research-verification-protocol.md +27 -0
  280. package/gsd-core/references/revision-loop.md +97 -0
  281. package/gsd-core/references/scout-codebase.md +51 -0
  282. package/gsd-core/references/skeleton-template.md +48 -0
  283. package/gsd-core/references/sketch-interactivity.md +41 -0
  284. package/gsd-core/references/sketch-theme-system.md +94 -0
  285. package/gsd-core/references/sketch-tooling.md +45 -0
  286. package/gsd-core/references/sketch-variant-patterns.md +81 -0
  287. package/gsd-core/references/spidr-splitting.md +69 -0
  288. package/gsd-core/references/tdd.md +330 -0
  289. package/gsd-core/references/test-containers.md +55 -0
  290. package/gsd-core/references/test-strategy.md +75 -0
  291. package/gsd-core/references/thinking-models-debug.md +44 -0
  292. package/gsd-core/references/thinking-models-execution.md +50 -0
  293. package/gsd-core/references/thinking-models-planning.md +62 -0
  294. package/gsd-core/references/thinking-models-research.md +50 -0
  295. package/gsd-core/references/thinking-models-verification.md +55 -0
  296. package/gsd-core/references/thinking-partner.md +96 -0
  297. package/gsd-core/references/ui-brand.md +162 -0
  298. package/gsd-core/references/universal-anti-patterns.md +63 -0
  299. package/gsd-core/references/user-profiling.md +681 -0
  300. package/gsd-core/references/user-story-template.md +58 -0
  301. package/gsd-core/references/verification-overrides.md +227 -0
  302. package/gsd-core/references/verification-patterns.md +612 -0
  303. package/gsd-core/references/verify-mvp-mode.md +85 -0
  304. package/gsd-core/references/workstream-flag.md +111 -0
  305. package/gsd-core/references/worktree-branch-check.md +38 -0
  306. package/gsd-core/references/worktree-path-safety.md +67 -0
  307. package/gsd-core/templates/AI-SPEC.md +246 -0
  308. package/gsd-core/templates/DEBUG.md +169 -0
  309. package/gsd-core/templates/README.md +77 -0
  310. package/gsd-core/templates/SECURITY.md +61 -0
  311. package/gsd-core/templates/UAT.md +265 -0
  312. package/gsd-core/templates/UI-SPEC.md +100 -0
  313. package/gsd-core/templates/VALIDATION.md +76 -0
  314. package/gsd-core/templates/adr.md +58 -0
  315. package/gsd-core/templates/claude-md.md +145 -0
  316. package/gsd-core/templates/codebase/architecture.md +255 -0
  317. package/gsd-core/templates/codebase/concerns.md +310 -0
  318. package/gsd-core/templates/codebase/conventions.md +307 -0
  319. package/gsd-core/templates/codebase/integrations.md +280 -0
  320. package/gsd-core/templates/codebase/stack.md +186 -0
  321. package/gsd-core/templates/codebase/structure.md +285 -0
  322. package/gsd-core/templates/codebase/testing.md +480 -0
  323. package/gsd-core/templates/config.json +62 -0
  324. package/gsd-core/templates/context.md +352 -0
  325. package/gsd-core/templates/continue-here.md +78 -0
  326. package/gsd-core/templates/copilot-instructions.md +7 -0
  327. package/gsd-core/templates/debug-subagent-prompt.md +91 -0
  328. package/gsd-core/templates/dev-preferences.md +21 -0
  329. package/gsd-core/templates/discovery.md +146 -0
  330. package/gsd-core/templates/discussion-log.md +63 -0
  331. package/gsd-core/templates/domain-model.md +54 -0
  332. package/gsd-core/templates/milestone-archive.md +123 -0
  333. package/gsd-core/templates/milestone.md +115 -0
  334. package/gsd-core/templates/phase-prompt.md +610 -0
  335. package/gsd-core/templates/planner-subagent-prompt.md +117 -0
  336. package/gsd-core/templates/product-brief.md +55 -0
  337. package/gsd-core/templates/project.md +186 -0
  338. package/gsd-core/templates/requirements.md +231 -0
  339. package/gsd-core/templates/research-project/ARCHITECTURE.md +204 -0
  340. package/gsd-core/templates/research-project/FEATURES.md +147 -0
  341. package/gsd-core/templates/research-project/PITFALLS.md +200 -0
  342. package/gsd-core/templates/research-project/STACK.md +120 -0
  343. package/gsd-core/templates/research-project/SUMMARY.md +170 -0
  344. package/gsd-core/templates/research.md +592 -0
  345. package/gsd-core/templates/retrospective.md +54 -0
  346. package/gsd-core/templates/roadmap.md +202 -0
  347. package/gsd-core/templates/spec.md +307 -0
  348. package/gsd-core/templates/state.md +195 -0
  349. package/gsd-core/templates/summary-complex.md +59 -0
  350. package/gsd-core/templates/summary-minimal.md +41 -0
  351. package/gsd-core/templates/summary-standard.md +48 -0
  352. package/gsd-core/templates/summary.md +248 -0
  353. package/gsd-core/templates/test-strategy.md +50 -0
  354. package/gsd-core/templates/user-profile.md +146 -0
  355. package/gsd-core/templates/user-setup.md +311 -0
  356. package/gsd-core/templates/verification-report.md +322 -0
  357. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -0
  358. package/gsd-core/workflows/add-backlog.md +91 -0
  359. package/gsd-core/workflows/add-phase.md +113 -0
  360. package/gsd-core/workflows/add-tests.md +355 -0
  361. package/gsd-core/workflows/add-todo.md +161 -0
  362. package/gsd-core/workflows/ai-integration-phase.md +295 -0
  363. package/gsd-core/workflows/analyze-dependencies.md +96 -0
  364. package/gsd-core/workflows/audit-fix.md +178 -0
  365. package/gsd-core/workflows/audit-milestone.md +360 -0
  366. package/gsd-core/workflows/audit-uat.md +110 -0
  367. package/gsd-core/workflows/autonomous.md +797 -0
  368. package/gsd-core/workflows/check-todos.md +180 -0
  369. package/gsd-core/workflows/cleanup.md +195 -0
  370. package/gsd-core/workflows/code-review-fix.md +502 -0
  371. package/gsd-core/workflows/code-review.md +658 -0
  372. package/gsd-core/workflows/complete-milestone.md +855 -0
  373. package/gsd-core/workflows/debug.md +237 -0
  374. package/gsd-core/workflows/diagnose-issues.md +245 -0
  375. package/gsd-core/workflows/discover-product.md +112 -0
  376. package/gsd-core/workflows/discovery-phase.md +291 -0
  377. package/gsd-core/workflows/discuss-phase/modes/advisor.md +176 -0
  378. package/gsd-core/workflows/discuss-phase/modes/all.md +28 -0
  379. package/gsd-core/workflows/discuss-phase/modes/analyze.md +44 -0
  380. package/gsd-core/workflows/discuss-phase/modes/auto.md +57 -0
  381. package/gsd-core/workflows/discuss-phase/modes/batch.md +52 -0
  382. package/gsd-core/workflows/discuss-phase/modes/chain.md +98 -0
  383. package/gsd-core/workflows/discuss-phase/modes/default.md +141 -0
  384. package/gsd-core/workflows/discuss-phase/modes/power.md +44 -0
  385. package/gsd-core/workflows/discuss-phase/modes/text.md +55 -0
  386. package/gsd-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
  387. package/gsd-core/workflows/discuss-phase/templates/context.md +136 -0
  388. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
  389. package/gsd-core/workflows/discuss-phase-assumptions.md +675 -0
  390. package/gsd-core/workflows/discuss-phase-power.md +291 -0
  391. package/gsd-core/workflows/discuss-phase.md +499 -0
  392. package/gsd-core/workflows/do.md +111 -0
  393. package/gsd-core/workflows/docs-update.md +1176 -0
  394. package/gsd-core/workflows/edit-phase.md +295 -0
  395. package/gsd-core/workflows/eval-review.md +156 -0
  396. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
  397. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
  398. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
  399. package/gsd-core/workflows/execute-phase.md +1752 -0
  400. package/gsd-core/workflows/execute-plan.md +526 -0
  401. package/gsd-core/workflows/explore.md +146 -0
  402. package/gsd-core/workflows/extract-learnings.md +243 -0
  403. package/gsd-core/workflows/fast.md +124 -0
  404. package/gsd-core/workflows/forensics.md +279 -0
  405. package/gsd-core/workflows/graduation.md +196 -0
  406. package/gsd-core/workflows/health.md +224 -0
  407. package/gsd-core/workflows/help/modes/brief.md +22 -0
  408. package/gsd-core/workflows/help/modes/default.md +50 -0
  409. package/gsd-core/workflows/help/modes/full.md +789 -0
  410. package/gsd-core/workflows/help/modes/topic.md +74 -0
  411. package/gsd-core/workflows/help.md +24 -0
  412. package/gsd-core/workflows/import.md +256 -0
  413. package/gsd-core/workflows/inbox.md +387 -0
  414. package/gsd-core/workflows/ingest-docs.md +340 -0
  415. package/gsd-core/workflows/insert-phase.md +152 -0
  416. package/gsd-core/workflows/list-phase-assumptions.md +178 -0
  417. package/gsd-core/workflows/list-workspaces.md +57 -0
  418. package/gsd-core/workflows/manager.md +393 -0
  419. package/gsd-core/workflows/map-codebase.md +446 -0
  420. package/gsd-core/workflows/milestone-summary.md +224 -0
  421. package/gsd-core/workflows/model-domain.md +162 -0
  422. package/gsd-core/workflows/mvp-phase.md +222 -0
  423. package/gsd-core/workflows/new-milestone.md +635 -0
  424. package/gsd-core/workflows/new-project.md +1555 -0
  425. package/gsd-core/workflows/new-workspace.md +240 -0
  426. package/gsd-core/workflows/next.md +299 -0
  427. package/gsd-core/workflows/node-repair.md +92 -0
  428. package/gsd-core/workflows/note.md +158 -0
  429. package/gsd-core/workflows/pause-work.md +244 -0
  430. package/gsd-core/workflows/plan-milestone-gaps.md +281 -0
  431. package/gsd-core/workflows/plan-phase.md +1814 -0
  432. package/gsd-core/workflows/plan-review-convergence.md +346 -0
  433. package/gsd-core/workflows/plant-seed.md +230 -0
  434. package/gsd-core/workflows/pr-branch.md +157 -0
  435. package/gsd-core/workflows/profile-user.md +453 -0
  436. package/gsd-core/workflows/progress.md +699 -0
  437. package/gsd-core/workflows/quick.md +1017 -0
  438. package/gsd-core/workflows/reapply-patches.md +426 -0
  439. package/gsd-core/workflows/recommend-architecture.md +135 -0
  440. package/gsd-core/workflows/remove-phase.md +156 -0
  441. package/gsd-core/workflows/remove-workspace.md +108 -0
  442. package/gsd-core/workflows/resume-project.md +332 -0
  443. package/gsd-core/workflows/review.md +748 -0
  444. package/gsd-core/workflows/scan.md +107 -0
  445. package/gsd-core/workflows/secure-phase.md +182 -0
  446. package/gsd-core/workflows/session-report.md +146 -0
  447. package/gsd-core/workflows/settings-advanced.md +810 -0
  448. package/gsd-core/workflows/settings-integrations.md +312 -0
  449. package/gsd-core/workflows/settings.md +566 -0
  450. package/gsd-core/workflows/ship.md +405 -0
  451. package/gsd-core/workflows/sketch-wrap-up.md +286 -0
  452. package/gsd-core/workflows/sketch.md +361 -0
  453. package/gsd-core/workflows/spec-phase.md +263 -0
  454. package/gsd-core/workflows/spike-wrap-up.md +307 -0
  455. package/gsd-core/workflows/spike.md +453 -0
  456. package/gsd-core/workflows/stats.md +80 -0
  457. package/gsd-core/workflows/sync-skills.md +182 -0
  458. package/gsd-core/workflows/testing-strategy.md +122 -0
  459. package/gsd-core/workflows/thread.md +222 -0
  460. package/gsd-core/workflows/transition.md +694 -0
  461. package/gsd-core/workflows/ui-phase.md +328 -0
  462. package/gsd-core/workflows/ui-review.md +193 -0
  463. package/gsd-core/workflows/ultraplan-phase.md +199 -0
  464. package/gsd-core/workflows/undo.md +314 -0
  465. package/gsd-core/workflows/update.md +496 -0
  466. package/gsd-core/workflows/validate-phase.md +181 -0
  467. package/gsd-core/workflows/verify-phase.md +544 -0
  468. package/gsd-core/workflows/verify-work.md +781 -0
  469. package/hooks/dist/gsd-check-update-worker.js +108 -0
  470. package/hooks/dist/gsd-check-update.js +66 -0
  471. package/hooks/dist/gsd-config-reload.js +133 -0
  472. package/hooks/dist/gsd-context-monitor.js +195 -0
  473. package/hooks/dist/gsd-cursor-post-tool.js +75 -0
  474. package/hooks/dist/gsd-cursor-session-start.js +52 -0
  475. package/hooks/dist/gsd-graphify-update.sh +158 -0
  476. package/hooks/dist/gsd-phase-boundary.sh +47 -0
  477. package/hooks/dist/gsd-prompt-guard.js +97 -0
  478. package/hooks/dist/gsd-read-guard.js +101 -0
  479. package/hooks/dist/gsd-read-injection-scanner.js +203 -0
  480. package/hooks/dist/gsd-session-state.sh +59 -0
  481. package/hooks/dist/gsd-statusline.js +566 -0
  482. package/hooks/dist/gsd-update-banner.js +138 -0
  483. package/hooks/dist/gsd-validate-commit.sh +57 -0
  484. package/hooks/dist/gsd-workflow-guard.js +167 -0
  485. package/hooks/dist/gsd-worktree-path-guard.js +169 -0
  486. package/hooks/dist/lib/git-cmd.js +150 -0
  487. package/hooks/dist/lib/gsd-graphify-rebuild.sh +65 -0
  488. package/hooks/dist/managed-hooks-registry.cjs +38 -0
  489. package/hooks/gsd-check-update-worker.js +108 -0
  490. package/hooks/gsd-check-update.js +66 -0
  491. package/hooks/gsd-config-reload.js +133 -0
  492. package/hooks/gsd-context-monitor.js +195 -0
  493. package/hooks/gsd-cursor-post-tool.js +75 -0
  494. package/hooks/gsd-cursor-session-start.js +52 -0
  495. package/hooks/gsd-graphify-update.sh +158 -0
  496. package/hooks/gsd-phase-boundary.sh +47 -0
  497. package/hooks/gsd-prompt-guard.js +97 -0
  498. package/hooks/gsd-read-guard.js +101 -0
  499. package/hooks/gsd-read-injection-scanner.js +203 -0
  500. package/hooks/gsd-session-state.sh +59 -0
  501. package/hooks/gsd-statusline.js +566 -0
  502. package/hooks/gsd-update-banner.js +138 -0
  503. package/hooks/gsd-validate-commit.sh +57 -0
  504. package/hooks/gsd-workflow-guard.js +167 -0
  505. package/hooks/gsd-worktree-path-guard.js +169 -0
  506. package/hooks/hooks.json +69 -0
  507. package/hooks/lib/git-cmd.js +150 -0
  508. package/hooks/lib/gsd-graphify-rebuild.sh +65 -0
  509. package/hooks/managed-hooks-registry.cjs +38 -0
  510. package/package.json +115 -0
  511. package/scripts/affected-tests-lib.cjs +542 -0
  512. package/scripts/audit-workflow-script-paths.cjs +73 -0
  513. package/scripts/base64-scan.sh +351 -0
  514. package/scripts/build-hooks.js +247 -0
  515. package/scripts/changeset/README.md +129 -0
  516. package/scripts/changeset/cli.cjs +590 -0
  517. package/scripts/changeset/github-release-notes.cjs +199 -0
  518. package/scripts/changeset/lint.cjs +111 -0
  519. package/scripts/changeset/new.cjs +137 -0
  520. package/scripts/changeset/parse.cjs +114 -0
  521. package/scripts/changeset/render.cjs +34 -0
  522. package/scripts/changeset/serialize.cjs +130 -0
  523. package/scripts/check-alias-drift.cjs +114 -0
  524. package/scripts/check-env.cjs +312 -0
  525. package/scripts/check-npm-integrity.cjs +215 -0
  526. package/scripts/ci-guard-runner.cjs +22 -0
  527. package/scripts/ci-prepare-test-scope.cjs +51 -0
  528. package/scripts/ci-rebase-check.cjs +86 -0
  529. package/scripts/ci-test-scope.cjs +431 -0
  530. package/scripts/command-contract-helpers.cjs +64 -0
  531. package/scripts/diff-touches-shipped-paths.cjs +155 -0
  532. package/scripts/fix-slash-commands.cjs +147 -0
  533. package/scripts/gen-inventory-manifest.cjs +115 -0
  534. package/scripts/gen-research-agents.cjs +276 -0
  535. package/scripts/generate-package-identity.cjs +125 -0
  536. package/scripts/issue-dedupe.cjs +278 -0
  537. package/scripts/lib/allowlist-ratchet.cjs +136 -0
  538. package/scripts/lib/cli-exit.cjs +56 -0
  539. package/scripts/lint-command-contract.cjs +114 -0
  540. package/scripts/lint-descriptions.cjs +87 -0
  541. package/scripts/lint-docs-required.cjs +222 -0
  542. package/scripts/lint-legacy-dir-name.cjs +160 -0
  543. package/scripts/lint-package-identity-drift.cjs +141 -0
  544. package/scripts/lint-pr-check-project-dir.cjs +99 -0
  545. package/scripts/lint-shell-command-projection-drift.cjs +62 -0
  546. package/scripts/lint-skill-deps.cjs +185 -0
  547. package/scripts/lint-test-file-count.allowlist.json +135 -0
  548. package/scripts/lint-test-file-count.cjs +246 -0
  549. package/scripts/mutation-matrix.cjs +222 -0
  550. package/scripts/pr-template-policy.cjs +268 -0
  551. package/scripts/prompt-injection-scan.sh +207 -0
  552. package/scripts/release-notes/discord-release-summary.cjs +373 -0
  553. package/scripts/release-notes/format-github-release-notes.cjs +261 -0
  554. package/scripts/release-tarball-smoke.cjs +629 -0
  555. package/scripts/research-profiles.cjs +149 -0
  556. package/scripts/run-affected-tests.cjs +7 -0
  557. package/scripts/run-cross-platform-tests.cjs +67 -0
  558. package/scripts/run-tests.cjs +315 -0
  559. package/scripts/secret-scan-lint.sh +231 -0
  560. package/scripts/secret-scan.sh +358 -0
  561. package/scripts/setup-branch-protection.sh +236 -0
  562. package/scripts/strip-prose-atrefs.cjs +106 -0
  563. package/scripts/sync-manifest-versions.cjs +119 -0
  564. package/scripts/sync-rulesets.sh +34 -0
  565. package/scripts/sync-runtime-launcher.cjs +399 -0
  566. package/scripts/test-failure-reasons.cjs +34 -0
  567. package/scripts/verify-npm-publish.cjs +240 -0
  568. package/scripts/workflow-policy.cjs +450 -0
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * scripts/mutation-matrix.cjs
6
+ *
7
+ * Single source of truth for the ADR-457 Stryker mutation gate dynamic matrix.
8
+ *
9
+ * Computes which covered modules changed vs a base ref and emits a GitHub
10
+ * Actions matrix JSON so CI can run one Stryker shard per changed module in
11
+ * parallel rather than a single serial run over all modules.
12
+ *
13
+ * Usage:
14
+ * node scripts/mutation-matrix.cjs --base origin/next
15
+ * printf 'src/config-schema.cts\n' | node scripts/mutation-matrix.cjs
16
+ * node scripts/mutation-matrix.cjs --base origin/next --print
17
+ *
18
+ * Output (stdout, default): JSON object
19
+ * {
20
+ * "has_work": "true"|"false",
21
+ * "matrix": {
22
+ * "include": [
23
+ * { "name": "<module>", "mutate": "gsd-core/bin/lib/<module>.cjs", "tests": "<space-joined test files>" },
24
+ * ...
25
+ * ]
26
+ * }
27
+ * }
28
+ *
29
+ * Exit codes: 0 always (empty matrix is not an error, has_work "false").
30
+ */
31
+
32
+ const { execFileSync } = require('child_process');
33
+ const { readFileSync } = require('fs');
34
+
35
+ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
36
+
37
+ // ── Single source of truth: covered modules ───────────────────────────────────
38
+ // Each entry: { cjs: '<built artifact>', tests: ['tests/...', ...] }
39
+ // A module is "covered" iff its tests are wired into the Stryker command runner
40
+ // (stryker.config.mjs commandRunner.command). Mutating an uncovered module can
41
+ // only ever produce survived mutants — so we scope strictly to these 6.
42
+ const COVERED = {
43
+ 'context-utilization': {
44
+ cjs: 'gsd-core/bin/lib/context-utilization.cjs',
45
+ tests: [
46
+ 'tests/context-utilization.property.test.cjs',
47
+ ],
48
+ },
49
+ 'prompt-budget': {
50
+ cjs: 'gsd-core/bin/lib/prompt-budget.cjs',
51
+ tests: [
52
+ 'tests/prompt-budget.property.test.cjs',
53
+ 'tests/prompt-budget.unit.test.cjs',
54
+ ],
55
+ },
56
+ frontmatter: {
57
+ cjs: 'gsd-core/bin/lib/frontmatter.cjs',
58
+ tests: [
59
+ 'tests/frontmatter.property.test.cjs',
60
+ 'tests/frontmatter.unit.test.cjs',
61
+ ],
62
+ },
63
+ 'adr-parser': {
64
+ cjs: 'gsd-core/bin/lib/adr-parser.cjs',
65
+ tests: [
66
+ 'tests/adr-parser.property.test.cjs',
67
+ 'tests/adr-parser.test.cjs',
68
+ 'tests/adr-parser.unit.test.cjs',
69
+ ],
70
+ },
71
+ 'config-schema': {
72
+ cjs: 'gsd-core/bin/lib/config-schema.cjs',
73
+ tests: [
74
+ 'tests/config-schema.property.test.cjs',
75
+ ],
76
+ },
77
+ 'active-workstream-store': {
78
+ cjs: 'gsd-core/bin/lib/active-workstream-store.cjs',
79
+ tests: [
80
+ 'tests/active-workstream-store.test.cjs',
81
+ 'tests/active-workstream-store.unit.test.cjs',
82
+ ],
83
+ },
84
+ };
85
+
86
+ // ── Files that, when changed, invalidate ALL modules ─────────────────────────
87
+ // Changes to the Stryker config, this script itself, or any covered test file
88
+ // affect all mutation scores and must force a full re-run.
89
+ const GLOBAL_TRIGGERS = new Set([
90
+ 'stryker.config.mjs',
91
+ 'scripts/mutation-matrix.cjs',
92
+ ]);
93
+
94
+ // Also flag all test files that belong to any covered module as global triggers.
95
+ for (const mod of Object.values(COVERED)) {
96
+ for (const t of mod.tests) {
97
+ GLOBAL_TRIGGERS.add(t);
98
+ }
99
+ }
100
+
101
+ // ── Argument parsing ──────────────────────────────────────────────────────────
102
+ function parseArgs(argv) {
103
+ const out = { base: null, print: false };
104
+ for (let i = 0; i < argv.length; i++) {
105
+ const arg = argv[i];
106
+ if (arg === '--base') {
107
+ out.base = argv[++i];
108
+ if (!out.base || out.base.startsWith('--')) {
109
+ throw new Error('--base requires a value');
110
+ }
111
+ } else if (arg.startsWith('--base=')) {
112
+ out.base = arg.slice('--base='.length);
113
+ if (!out.base) throw new Error('--base requires a value');
114
+ } else if (arg === '--print') {
115
+ out.print = true;
116
+ } else if (arg === '--help' || arg === '-h') {
117
+ console.log([
118
+ 'Usage:',
119
+ ' node scripts/mutation-matrix.cjs --base <ref> [--print]',
120
+ ' printf "src/foo.cts\\n" | node scripts/mutation-matrix.cjs [--print]',
121
+ '',
122
+ 'Options:',
123
+ ' --base <ref> Git ref to diff against (default: origin/${GITHUB_BASE_REF:-next})',
124
+ ' --print Human-readable output instead of JSON',
125
+ ].join('\n'));
126
+ throw new ExitError(0);
127
+ } else {
128
+ throw new Error(`unknown argument: ${arg}`);
129
+ }
130
+ }
131
+ return out;
132
+ }
133
+
134
+ // ── Changed-file resolution ───────────────────────────────────────────────────
135
+ function resolveChangedFiles(args) {
136
+ // When --base is provided, always use git diff (regardless of stdin).
137
+ // When --base is absent AND stdin is not a TTY (isTTY is falsy / undefined),
138
+ // read a newline-delimited file list from stdin.
139
+ if (!args.base && process.stdin.isTTY !== true) {
140
+ const raw = readFileSync(process.stdin.fd, 'utf8');
141
+ return raw.split('\n').map(l => l.trim()).filter(Boolean);
142
+ }
143
+
144
+ // Otherwise (--base given, or stdin is a real TTY), diff against the base ref.
145
+ const defaultBase = `origin/${process.env.GITHUB_BASE_REF || 'next'}`;
146
+ const base = args.base || defaultBase;
147
+ const stdout = execFileSync('git', ['diff', '--name-only', `${base}...HEAD`], {
148
+ encoding: 'utf8',
149
+ });
150
+ return stdout.split('\n').map(l => l.trim()).filter(Boolean);
151
+ }
152
+
153
+ // ── Module classification ─────────────────────────────────────────────────────
154
+ function computeMatrix(changedFiles) {
155
+ // Check for global triggers first — if any hit, include every covered module.
156
+ const allModuleNames = Object.keys(COVERED);
157
+ for (const f of changedFiles) {
158
+ if (GLOBAL_TRIGGERS.has(f)) {
159
+ return allModuleNames;
160
+ }
161
+ }
162
+
163
+ // Otherwise find which modules have their src/*.cts changed.
164
+ const changed = new Set();
165
+ for (const f of changedFiles) {
166
+ // Match src/<module>.cts (top-level src/, not nested)
167
+ const m = f.match(/^src\/([^/]+)\.cts$/);
168
+ if (m && COVERED[m[1]]) {
169
+ changed.add(m[1]);
170
+ }
171
+ }
172
+ return [...changed];
173
+ }
174
+
175
+ // ── Output formatting ─────────────────────────────────────────────────────────
176
+ function buildResult(moduleNames) {
177
+ const include = moduleNames.map(name => ({
178
+ name,
179
+ mutate: COVERED[name].cjs,
180
+ tests: COVERED[name].tests.join(' '),
181
+ }));
182
+
183
+ return {
184
+ has_work: include.length > 0 ? 'true' : 'false',
185
+ matrix: { include },
186
+ };
187
+ }
188
+
189
+ function printHuman(result, changedFiles) {
190
+ console.log(`Changed files (${changedFiles.length}):`);
191
+ for (const f of changedFiles) console.log(` ${f}`);
192
+ console.log('');
193
+ console.log(`has_work: ${result.has_work}`);
194
+ console.log(`Shards (${result.matrix.include.length}):`);
195
+ for (const shard of result.matrix.include) {
196
+ console.log(` [${shard.name}]`);
197
+ console.log(` mutate: ${shard.mutate}`);
198
+ console.log(` tests: ${shard.tests}`);
199
+ }
200
+ }
201
+
202
+ // ── Main ──────────────────────────────────────────────────────────────────────
203
+ function main() {
204
+ try {
205
+ const args = parseArgs(process.argv.slice(2));
206
+ const changedFiles = resolveChangedFiles(args);
207
+ const moduleNames = computeMatrix(changedFiles);
208
+ const result = buildResult(moduleNames);
209
+
210
+ if (args.print) {
211
+ printHuman(result, changedFiles);
212
+ } else {
213
+ console.log(JSON.stringify(result, null, 2));
214
+ }
215
+ } catch (err) {
216
+ if (err instanceof ExitError) throw err;
217
+ console.error(`mutation-matrix: ${err.message}`);
218
+ throw new ExitError(2);
219
+ }
220
+ }
221
+
222
+ runMain(main);
@@ -0,0 +1,268 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { matchesGlob } = require('path');
4
+
5
+ const TRUSTED_AUTHOR_ASSOCIATIONS = new Set([
6
+ 'CONTRIBUTOR',
7
+ 'COLLABORATOR',
8
+ 'MEMBER',
9
+ 'OWNER',
10
+ ]);
11
+
12
+ const DEFAULT_TEMPLATE_MARKERS = [
13
+ 'Wrong template',
14
+ 'Every PR must use a typed template',
15
+ 'Select the template that matches your PR',
16
+ ];
17
+
18
+ /**
19
+ * Glob patterns for files that are considered CI/tooling/docs scope.
20
+ * If ALL changed files in a PR match at least one of these patterns,
21
+ * template enforcement is skipped automatically.
22
+ */
23
+ const TOOLING_PATH_ALLOWLIST = [
24
+ '.github/**',
25
+ 'scripts/**',
26
+ 'docs/**',
27
+ '*.md',
28
+ '.changeset/**',
29
+ 'package.json',
30
+ 'package-lock.json',
31
+ 'pnpm-lock.yaml',
32
+ 'yarn.lock',
33
+ 'Pipfile',
34
+ 'Pipfile.lock',
35
+ 'requirements.txt',
36
+ 'requirements*.txt',
37
+ 'poetry.lock',
38
+ 'Gemfile',
39
+ 'Gemfile.lock',
40
+ 'go.sum',
41
+ 'go.mod',
42
+ ];
43
+
44
+ /**
45
+ * Matches an explicit PR-template exemption marker of the form:
46
+ * <!-- pr-template-exempt: <non-empty reason> -->
47
+ *
48
+ * Capture group 1 is the reason (trimmed). Empty/whitespace-only reasons
49
+ * do NOT match because the pattern requires at least one non-whitespace
50
+ * character in the captured body.
51
+ */
52
+ const EXEMPT_MARKER_REGEX = /<!--\s*pr-template-exempt:\s*([\s\S]*?\S)\s*-->/;
53
+
54
+ const TEMPLATES = [
55
+ {
56
+ name: 'fix',
57
+ heading: 'Fix PR',
58
+ requiredHeadings: [
59
+ 'Fix PR',
60
+ 'Linked Issue',
61
+ 'What was broken',
62
+ 'What this fix does',
63
+ 'Testing',
64
+ 'Checklist',
65
+ ],
66
+ },
67
+ {
68
+ name: 'enhancement',
69
+ heading: 'Enhancement PR',
70
+ requiredHeadings: [
71
+ 'Enhancement PR',
72
+ 'Linked Issue',
73
+ 'What this enhancement improves',
74
+ 'Before / After',
75
+ 'How it was implemented',
76
+ 'Testing',
77
+ 'Scope confirmation',
78
+ 'Checklist',
79
+ ],
80
+ },
81
+ {
82
+ name: 'feature',
83
+ heading: 'Feature PR',
84
+ requiredHeadings: [
85
+ 'Feature PR',
86
+ 'Linked Issue',
87
+ 'Feature summary',
88
+ 'What changed',
89
+ 'Implementation notes',
90
+ 'Spec compliance',
91
+ 'Testing',
92
+ 'Scope confirmation',
93
+ 'Checklist',
94
+ ],
95
+ },
96
+ ];
97
+
98
+ function stripMarkdownDecoration(value) {
99
+ return value
100
+ .replace(/^\s*#+\s*/, '')
101
+ .replace(/\s*#+\s*$/, '')
102
+ .replace(/\*\*/g, '')
103
+ .trim()
104
+ .toLowerCase();
105
+ }
106
+
107
+ function extractHeadings(body) {
108
+ const headings = new Set();
109
+ for (const line of String(body || '').split(/\r?\n/)) {
110
+ if (/^\s*#{1,6}\s+\S/.test(line)) {
111
+ headings.add(stripMarkdownDecoration(line));
112
+ }
113
+ }
114
+ return headings;
115
+ }
116
+
117
+ function includesDefaultTemplate(body) {
118
+ const text = String(body || '').toLowerCase();
119
+ return DEFAULT_TEMPLATE_MARKERS.some((marker) => text.includes(marker.toLowerCase()));
120
+ }
121
+
122
+ function matchingTemplate(body) {
123
+ const headings = extractHeadings(body);
124
+ for (const template of TEMPLATES) {
125
+ if (!headings.has(stripMarkdownDecoration(template.heading))) continue;
126
+ const missingHeadings = template.requiredHeadings.filter((heading) => {
127
+ return !headings.has(stripMarkdownDecoration(heading));
128
+ });
129
+ return {
130
+ template: template.name,
131
+ missingHeadings,
132
+ };
133
+ }
134
+ return {
135
+ template: null,
136
+ missingHeadings: [],
137
+ };
138
+ }
139
+
140
+ /**
141
+ * Returns true iff every path in changedFiles matches at least one glob
142
+ * pattern in the allowlist. Returns false for an empty file list (no
143
+ * files means we cannot confirm it is a tooling-only PR).
144
+ */
145
+ function allPathsAreTooling(changedFiles, allowlist) {
146
+ if (!Array.isArray(changedFiles) || changedFiles.length === 0) return false;
147
+ return changedFiles.every((file) =>
148
+ allowlist.some((pattern) => matchesGlob(file, pattern)),
149
+ );
150
+ }
151
+
152
+ /**
153
+ * Returns true iff the body contains an explicit exemption marker with a
154
+ * non-empty (non-whitespace) reason.
155
+ */
156
+ function hasExemptMarker(body, regex) {
157
+ const match = regex.exec(String(body || ''));
158
+ if (!match) return false;
159
+ return match[1].trim().length > 0;
160
+ }
161
+
162
+ function evaluatePrTemplate(body, authorAssociation, changedFiles) {
163
+ const association = String(authorAssociation || '').toUpperCase();
164
+ const trusted = TRUSTED_AUTHOR_ASSOCIATIONS.has(association);
165
+ const normalizedBody = String(body || '').trim();
166
+
167
+ // --- Carve-out 1: all changed files are in the tooling allowlist ---
168
+ if (allPathsAreTooling(changedFiles, TOOLING_PATH_ALLOWLIST)) {
169
+ return {
170
+ valid: true,
171
+ action: 'pass',
172
+ trusted,
173
+ authorAssociation: association || 'UNKNOWN',
174
+ template: null,
175
+ reason: null,
176
+ missingHeadings: [],
177
+ skipped: 'tooling-paths',
178
+ };
179
+ }
180
+
181
+ // --- Carve-out 2: explicit exemption marker in the PR body ---
182
+ if (hasExemptMarker(normalizedBody, EXEMPT_MARKER_REGEX)) {
183
+ return {
184
+ valid: true,
185
+ action: 'pass',
186
+ trusted,
187
+ authorAssociation: association || 'UNKNOWN',
188
+ template: null,
189
+ reason: null,
190
+ missingHeadings: [],
191
+ skipped: 'exempt-marker',
192
+ };
193
+ }
194
+
195
+ let valid = true;
196
+ let reason = 'PR body uses a typed pull request template.';
197
+ let template = null;
198
+ let missingHeadings = [];
199
+
200
+ if (!normalizedBody) {
201
+ valid = false;
202
+ reason = 'PR body is empty; a typed pull request template is required.';
203
+ } else {
204
+ const match = matchingTemplate(normalizedBody);
205
+ template = match.template;
206
+ missingHeadings = match.missingHeadings;
207
+ if (template && missingHeadings.length === 0) {
208
+ valid = true;
209
+ } else if (template && missingHeadings.length > 0) {
210
+ valid = false;
211
+ reason = `PR body appears to use the ${template} template but is missing required headings.`;
212
+ } else if (includesDefaultTemplate(normalizedBody)) {
213
+ valid = false;
214
+ reason = 'PR body still contains the default wrong-template guidance.';
215
+ } else {
216
+ valid = false;
217
+ reason = 'PR body does not match the fix, enhancement, or feature template.';
218
+ }
219
+ }
220
+
221
+ let action = 'pass';
222
+ if (!valid) {
223
+ action = trusted ? 'warn' : 'close';
224
+ }
225
+
226
+ return {
227
+ valid,
228
+ action,
229
+ trusted,
230
+ authorAssociation: association || 'UNKNOWN',
231
+ template,
232
+ reason,
233
+ missingHeadings,
234
+ };
235
+ }
236
+
237
+ function main() {
238
+ const changedFiles = process.env.CHANGED_FILES
239
+ ? process.env.CHANGED_FILES.split('\n').map((f) => f.trim()).filter(Boolean)
240
+ : undefined;
241
+ const result = evaluatePrTemplate(
242
+ process.env.PR_BODY || '',
243
+ process.env.AUTHOR_ASSOCIATION || '',
244
+ changedFiles,
245
+ );
246
+ process.stdout.write(`${JSON.stringify(result)}\n`);
247
+ if (process.env.GITHUB_OUTPUT) {
248
+ const fs = require('fs');
249
+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `result=${JSON.stringify(result)}\n`);
250
+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `action=${result.action}\n`);
251
+ fs.appendFileSync(process.env.GITHUB_OUTPUT, `valid=${result.valid ? 'true' : 'false'}\n`);
252
+ }
253
+ }
254
+
255
+ if (require.main === module) {
256
+ main();
257
+ }
258
+
259
+ module.exports = {
260
+ evaluatePrTemplate,
261
+ extractHeadings,
262
+ includesDefaultTemplate,
263
+ matchingTemplate,
264
+ allPathsAreTooling,
265
+ hasExemptMarker,
266
+ TOOLING_PATH_ALLOWLIST,
267
+ EXEMPT_MARKER_REGEX,
268
+ };
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env bash
2
+ # prompt-injection-scan.sh — Scan files for prompt injection patterns
3
+ #
4
+ # Usage:
5
+ # scripts/prompt-injection-scan.sh --diff origin/main # CI mode: scan changed .md files
6
+ # scripts/prompt-injection-scan.sh --file path/to/file # Scan a single file
7
+ # scripts/prompt-injection-scan.sh --dir agents/ # Scan all files in a directory
8
+ #
9
+ # Exit codes:
10
+ # 0 = clean
11
+ # 1 = findings detected
12
+ # 2 = usage error
13
+ set -euo pipefail
14
+
15
+ # ─── Patterns ────────────────────────────────────────────────────────────────
16
+ # Each pattern is a POSIX extended regex. Keep alphabetized by category.
17
+
18
+ PATTERNS=(
19
+ # Instruction override
20
+ 'ignore[[:space:]]+(all[[:space:]]+)?(previous|prior|above|earlier|preceding)[[:space:]]+(instructions|prompts|rules|directives|context)'
21
+ 'disregard[[:space:]]+(all[[:space:]]+)?(previous|prior|above)[[:space:]]+(instructions|prompts|rules)'
22
+ 'forget[[:space:]]+(all[[:space:]]+)?(previous|prior|above)[[:space:]]+(instructions|prompts|rules|context)'
23
+ 'override[[:space:]]+(all[[:space:]]+)?(system|previous|safety)[[:space:]]+(instructions|prompts|rules|checks|filters|guards)'
24
+ 'override[[:space:]]+(system|safety|security)[[:space:]]'
25
+
26
+ # Role manipulation
27
+ 'you[[:space:]]+are[[:space:]]+now[[:space:]]+(a|an|my)[[:space:]]'
28
+ 'from[[:space:]]+now[[:space:]]+on[[:space:]]+(you|pretend|act|behave)'
29
+ 'pretend[[:space:]]+(you[[:space:]]+are|to[[:space:]]+be)[[:space:]]'
30
+ 'act[[:space:]]+as[[:space:]]+(a|an|if|my)[[:space:]]'
31
+ 'roleplay[[:space:]]+as[[:space:]]'
32
+ 'assume[[:space:]]+the[[:space:]]+role[[:space:]]+of[[:space:]]'
33
+
34
+ # System prompt extraction
35
+ 'output[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
36
+ 'reveal[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
37
+ 'show[[:space:]]+me[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
38
+ 'print[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
39
+ 'what[[:space:]]+(is|are)[[:space:]]+(your|the)[[:space:]]+(system[[:space:]]+)?(prompt|instructions)'
40
+ 'repeat[[:space:]]+(your|the|all)[[:space:]]+(system[[:space:]]+)?(prompt|instructions|rules)'
41
+
42
+ # Fake message boundaries
43
+ '</?system>'
44
+ '</?assistant>'
45
+ '</?human>'
46
+ '\[SYSTEM\]'
47
+ '\[/SYSTEM\]'
48
+ '\[INST\]'
49
+ '\[/INST\]'
50
+ '<<SYS>>'
51
+ '<</SYS>>'
52
+
53
+ # Tool call injection / code execution in markdown
54
+ 'eval[[:space:]]*\([[:space:]]*["\x27]'
55
+ 'exec[[:space:]]*\([[:space:]]*["\x27]'
56
+ 'Function[[:space:]]*\([[:space:]]*["\x27].*return'
57
+
58
+ # Jailbreak / DAN patterns
59
+ 'do[[:space:]]+anything[[:space:]]+now'
60
+ 'DAN[[:space:]]+mode'
61
+ 'developer[[:space:]]+mode[[:space:]]+(enabled|output|activated)'
62
+ 'jailbreak'
63
+ 'bypass[[:space:]]+(safety|content|security)[[:space:]]+(filter|check|rule|guard)'
64
+ )
65
+
66
+ # ─── Allowlist ───────────────────────────────────────────────────────────────
67
+ # Files that legitimately discuss injection patterns (security docs, tests, this script)
68
+ ALLOWLIST=(
69
+ 'scripts/prompt-injection-scan.sh'
70
+ 'scripts/base64-scan.sh'
71
+ 'scripts/secret-scan.sh'
72
+ 'tests/security-scan.test.cjs'
73
+ 'tests/security.test.cjs'
74
+ 'tests/prompt-injection-scan.test.cjs'
75
+ 'tests/verify.test.cjs'
76
+ 'gsd-core/bin/lib/security.cjs'
77
+ 'hooks/gsd-prompt-guard.js'
78
+ 'hooks/gsd-read-injection-scanner.js'
79
+ 'tests/read-injection-scanner.test.cjs'
80
+ 'tests/security-prompt-injection.test.cjs'
81
+ 'tests/fixtures/adversarial/security/'
82
+ 'SECURITY.md'
83
+ # These files contain intentional injection examples / security-model prose
84
+ # and are not attack vectors — they explain/demonstrate injection patterns.
85
+ 'TEST-EXAMPLES.md'
86
+ 'explanation/security-model.md'
87
+ )
88
+
89
+ is_allowlisted() {
90
+ local file="$1"
91
+ for allowed in "${ALLOWLIST[@]}"; do
92
+ if [[ "$file" == *"$allowed"* ]]; then
93
+ return 0
94
+ fi
95
+ done
96
+ return 1
97
+ }
98
+
99
+ # ─── File Collection ─────────────────────────────────────────────────────────
100
+
101
+ collect_files() {
102
+ local mode="$1"
103
+ shift
104
+
105
+ case "$mode" in
106
+ --diff)
107
+ local base="${1:-origin/main}"
108
+ # Get changed files in the diff, filter to scannable extensions
109
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
110
+ | grep -E '\.(md|cjs|js|json|yml|yaml|sh)$' || true
111
+ ;;
112
+ --file)
113
+ if [[ -f "$1" ]]; then
114
+ echo "$1"
115
+ else
116
+ echo "Error: file not found: $1" >&2
117
+ exit 2
118
+ fi
119
+ ;;
120
+ --dir)
121
+ local dir="$1"
122
+ if [[ ! -d "$dir" ]]; then
123
+ echo "Error: directory not found: $dir" >&2
124
+ exit 2
125
+ fi
126
+ find "$dir" -type f \( -name '*.md' -o -name '*.cjs' -o -name '*.js' -o -name '*.json' -o -name '*.yml' -o -name '*.yaml' -o -name '*.sh' \) \
127
+ ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' 2>/dev/null || true
128
+ ;;
129
+ --stdin)
130
+ cat
131
+ ;;
132
+ *)
133
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
134
+ exit 2
135
+ ;;
136
+ esac
137
+ }
138
+
139
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
140
+
141
+ scan_file() {
142
+ local file="$1"
143
+ local found=0
144
+
145
+ if is_allowlisted "$file"; then
146
+ return 0
147
+ fi
148
+
149
+ for pattern in "${PATTERNS[@]}"; do
150
+ # Use grep -iE for case-insensitive extended regex
151
+ # -n for line numbers, -c for count mode first to check
152
+ local matches
153
+ matches=$(grep -inE -e "$pattern" "$file" 2>/dev/null || true)
154
+ if [[ -n "$matches" ]]; then
155
+ if [[ $found -eq 0 ]]; then
156
+ echo "FAIL: $file"
157
+ found=1
158
+ fi
159
+ echo "$matches" | while IFS= read -r line; do
160
+ echo " $line"
161
+ done
162
+ fi
163
+ done
164
+
165
+ return $found
166
+ }
167
+
168
+ # ─── Main ────────────────────────────────────────────────────────────────────
169
+
170
+ main() {
171
+ if [[ $# -eq 0 ]]; then
172
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path>" >&2
173
+ exit 2
174
+ fi
175
+
176
+ local mode="$1"
177
+ shift
178
+
179
+ local files
180
+ files=$(collect_files "$mode" "$@")
181
+
182
+ if [[ -z "$files" ]]; then
183
+ echo "prompt-injection-scan: no files to scan"
184
+ exit 0
185
+ fi
186
+
187
+ local total=0
188
+ local failed=0
189
+
190
+ while IFS= read -r file; do
191
+ [[ -z "$file" ]] && continue
192
+ total=$((total + 1))
193
+ if ! scan_file "$file"; then
194
+ failed=$((failed + 1))
195
+ fi
196
+ done <<< "$files"
197
+
198
+ echo ""
199
+ echo "prompt-injection-scan: scanned $total files, $failed with findings"
200
+
201
+ if [[ $failed -gt 0 ]]; then
202
+ exit 1
203
+ fi
204
+ exit 0
205
+ }
206
+
207
+ main "$@"