@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,231 @@
1
+ #!/usr/bin/env bash
2
+ # secret-scan-lint.sh — Lint governance policy for .secretscanignore exclusions
3
+ #
4
+ # Usage:
5
+ # scripts/secret-scan-lint.sh --file <path-to-.secretscanignore>
6
+ # scripts/secret-scan-lint.sh --file <path-to-.secretscanignore> --strict
7
+ #
8
+ # Exit codes:
9
+ # 0 = every exclusion has full annotation OR is grandfathered (with deprecation warning)
10
+ # 1 = annotation violation: missing required key, expired date, or unguarded wildcard
11
+ # without rule-id; OR (under --strict) any grandfathered entry is present
12
+ # 2 = usage/config error (file not found, invalid arguments)
13
+ #
14
+ # Annotation syntax (sidecar comment, must immediately precede the path line):
15
+ # # allow: <pattern> reason="..." owner="..." expires="YYYY-MM-DD" [rule-id="..."]
16
+ # <pattern>
17
+ #
18
+ # Required annotation keys: reason, owner, expires
19
+ # Optional annotation key: rule-id (REQUIRED when pattern contains '*' wildcards)
20
+ #
21
+ # Grandfathered entries: paths with any preceding plain comment (not a structured
22
+ # annotation) are treated as grandfathered in default mode — exit 0 with a
23
+ # deprecation warning to stderr. Under --strict, grandfathered entries cause exit 1.
24
+ #
25
+ # Design references:
26
+ # - GitGuardian exclusion annotation convention:
27
+ # https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
28
+ # - CNCF Security TAG threat-model exception lifecycle:
29
+ # https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md
30
+ #
31
+ # Exit-code alignment with secret-scan.sh:
32
+ # Both scripts use 0=clean, 1=policy-violation/findings, 2=usage/config-error.
33
+ # The symmetry is intentional — CI can treat either non-zero as a gate failure.
34
+
35
+ set -euo pipefail
36
+
37
+ # ─── Argument Parsing ─────────────────────────────────────────────────────────
38
+
39
+ STRICT=false
40
+ IGNOREFILE=""
41
+
42
+ usage() {
43
+ echo "Usage: $0 --file <path-to-.secretscanignore> [--strict]" >&2
44
+ exit 2
45
+ }
46
+
47
+ while [[ $# -gt 0 ]]; do
48
+ case "$1" in
49
+ --file)
50
+ shift
51
+ [[ $# -eq 0 ]] && usage
52
+ IGNOREFILE="$1"
53
+ shift
54
+ ;;
55
+ --strict)
56
+ STRICT=true
57
+ shift
58
+ ;;
59
+ -h|--help)
60
+ usage
61
+ ;;
62
+ *)
63
+ echo "Error: unknown argument: $1" >&2
64
+ usage
65
+ ;;
66
+ esac
67
+ done
68
+
69
+ if [[ -z "$IGNOREFILE" ]]; then
70
+ usage
71
+ fi
72
+
73
+ if [[ ! -f "$IGNOREFILE" ]]; then
74
+ echo "Error: file not found: $IGNOREFILE" >&2
75
+ exit 2
76
+ fi
77
+
78
+ # ─── Date Helpers ─────────────────────────────────────────────────────────────
79
+
80
+ # Returns today's date as YYYY-MM-DD (portable across macOS and Linux)
81
+ today_date() {
82
+ date +%Y-%m-%d
83
+ }
84
+
85
+ # Returns true (0) if date1 < date2 (both YYYY-MM-DD strings)
86
+ date_is_past() {
87
+ local check_date="$1"
88
+ local today
89
+ today=$(today_date)
90
+ # Lexicographic comparison works for ISO-8601 dates
91
+ [[ "$check_date" < "$today" ]]
92
+ }
93
+
94
+ # ─── Annotation Parser ────────────────────────────────────────────────────────
95
+
96
+ # Returns value of a key="value" or key='value' pair from a string.
97
+ # Usage: extract_key <string> <key>
98
+ extract_key() {
99
+ local str="$1"
100
+ local key="$2"
101
+ # Match key="value" or key='value'
102
+ local val
103
+ val=$(echo "$str" | grep -oE "${key}=['\"][^'\"]+['\"]" | head -1 | sed "s/${key}=['\"]//;s/['\"]$//") || true
104
+ echo "$val"
105
+ }
106
+
107
+ # Returns true (0) if the string contains a wildcard glob character (* or **)
108
+ contains_wildcard() {
109
+ local pattern="$1"
110
+ [[ "$pattern" == *"*"* ]]
111
+ }
112
+
113
+ # Returns true (0) if a comment line is a structured annotation
114
+ # (must start with "# allow:" prefix)
115
+ is_structured_annotation() {
116
+ local comment="$1"
117
+ [[ "$comment" =~ ^#[[:space:]]+allow:[[:space:]] ]]
118
+ }
119
+
120
+ # ─── Main Lint Logic ──────────────────────────────────────────────────────────
121
+
122
+ VIOLATIONS=0
123
+ WARNINGS=0
124
+
125
+ # We process the file line-by-line, tracking the comment immediately preceding
126
+ # each path entry. If the preceding line was a comment, we inspect it.
127
+
128
+ prev_comment=""
129
+ lineno=0
130
+
131
+ while IFS= read -r line || [[ -n "$line" ]]; do
132
+ lineno=$((lineno + 1))
133
+
134
+ # Skip empty lines (reset prev_comment to avoid false association)
135
+ if [[ -z "${line// }" ]]; then
136
+ prev_comment=""
137
+ continue
138
+ fi
139
+
140
+ # Accumulate comment lines
141
+ if [[ "$line" =~ ^[[:space:]]*# ]]; then
142
+ prev_comment="$line"
143
+ continue
144
+ fi
145
+
146
+ # This is a path/pattern entry.
147
+ local_path="$line"
148
+
149
+ # ── Case 1: No preceding comment at all ────────────────────────────────────
150
+ if [[ -z "$prev_comment" ]]; then
151
+ echo "VIOLATION (line $lineno): '$local_path' has no annotation comment." >&2
152
+ echo " Required: # allow: <pattern> reason=\"...\" owner=\"...\" expires=\"YYYY-MM-DD\"" >&2
153
+ VIOLATIONS=$((VIOLATIONS + 1))
154
+ prev_comment=""
155
+ continue
156
+ fi
157
+
158
+ # ── Case 2: Preceding comment exists — check if it's a structured annotation ─
159
+ if is_structured_annotation "$prev_comment"; then
160
+ # Extract required keys
161
+ reason=$(extract_key "$prev_comment" "reason")
162
+ owner=$(extract_key "$prev_comment" "owner")
163
+ expires=$(extract_key "$prev_comment" "expires")
164
+ rule_id=$(extract_key "$prev_comment" "rule-id")
165
+
166
+ local_ok=true
167
+
168
+ if [[ -z "$reason" ]]; then
169
+ echo "VIOLATION (line $lineno): '$local_path' annotation missing required key: reason" >&2
170
+ local_ok=false
171
+ fi
172
+
173
+ if [[ -z "$owner" ]]; then
174
+ echo "VIOLATION (line $lineno): '$local_path' annotation missing required key: owner" >&2
175
+ local_ok=false
176
+ fi
177
+
178
+ if [[ -z "$expires" ]]; then
179
+ echo "VIOLATION (line $lineno): '$local_path' annotation missing required key: expires" >&2
180
+ local_ok=false
181
+ elif date_is_past "$expires"; then
182
+ echo "VIOLATION (line $lineno): '$local_path' annotation 'expires' date is in the past: $expires" >&2
183
+ echo " Review this exclusion and update or remove it." >&2
184
+ local_ok=false
185
+ fi
186
+
187
+ if contains_wildcard "$local_path" && [[ -z "$rule_id" ]]; then
188
+ echo "VIOLATION (line $lineno): '$local_path' uses a wildcard but is missing required key: rule-id" >&2
189
+ echo " Wildcard exclusions (** *.ext) require an explicit rule-id for auditability." >&2
190
+ local_ok=false
191
+ fi
192
+
193
+ if [[ "$local_ok" == false ]]; then
194
+ VIOLATIONS=$((VIOLATIONS + 1))
195
+ fi
196
+
197
+ else
198
+ # ── Case 3: Preceding comment is plain (not structured) — grandfathered ──
199
+ if [[ "$STRICT" == true ]]; then
200
+ echo "VIOLATION (line $lineno): '$local_path' is grandfathered (no structured annotation) — rejected under --strict mode." >&2
201
+ echo " Add: # allow: $local_path reason=\"...\" owner=\"...\" expires=\"YYYY-MM-DD\"" >&2
202
+ VIOLATIONS=$((VIOLATIONS + 1))
203
+ else
204
+ echo "WARNING (line $lineno): '$local_path' is grandfathered (missing structured annotation)." >&2
205
+ echo " DEPRECATION: migrate to structured annotation before removing grandfather status." >&2
206
+ echo " Required: # allow: $local_path reason=\"...\" owner=\"...\" expires=\"YYYY-MM-DD\"" >&2
207
+ echo " See: https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets" >&2
208
+ WARNINGS=$((WARNINGS + 1))
209
+ fi
210
+ fi
211
+
212
+ prev_comment=""
213
+
214
+ done < "$IGNOREFILE"
215
+
216
+ # ─── Summary ──────────────────────────────────────────────────────────────────
217
+
218
+ if [[ $VIOLATIONS -gt 0 ]]; then
219
+ echo "secret-scan-lint: $VIOLATIONS violation(s) found" >&2
220
+ if [[ $STRICT == true ]]; then
221
+ echo "secret-scan-lint: --strict mode active — grandfathered entries are not permitted" >&2
222
+ fi
223
+ exit 1
224
+ fi
225
+
226
+ if [[ $WARNINGS -gt 0 ]]; then
227
+ echo "secret-scan-lint: $WARNINGS grandfathered entry/entries (deprecation warning)" >&2
228
+ fi
229
+
230
+ echo "secret-scan-lint: OK"
231
+ exit 0
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env bash
2
+ # secret-scan.sh — Check files for accidentally committed secrets/credentials
3
+ #
4
+ # Usage:
5
+ # scripts/secret-scan.sh --diff origin/main # CI mode: scan changed files
6
+ # scripts/secret-scan.sh --file path/to/file # Scan a single file
7
+ # scripts/secret-scan.sh --dir agents/ # Scan all files in a directory
8
+ # scripts/secret-scan.sh --diff origin/main --strict # Strict/release mode
9
+ #
10
+ # Flags:
11
+ # --strict Reduced-exclusion mode for release and security-audit CI lanes.
12
+ # Under --strict:
13
+ # - Grandfathered (un-annotated) .secretscanignore entries are
14
+ # treated as FAILURES rather than silently honoured.
15
+ # - Exclusions whose 'expires' date is in the past are ignored
16
+ # (the file IS scanned, not skipped).
17
+ # This flag does not change secret-detection logic — only which
18
+ # exclusions are applied.
19
+ #
20
+ # Exit codes:
21
+ # 0 = clean
22
+ # 1 = findings detected
23
+ # 2 = usage error
24
+ #
25
+ # Annotation format for .secretscanignore (required for --strict compliance):
26
+ # # allow: <pattern> reason="..." owner="..." expires="YYYY-MM-DD" [rule-id="..."]
27
+ # <pattern>
28
+ #
29
+ # Design references:
30
+ # - GitGuardian exclusion annotation convention:
31
+ # https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
32
+ # - CNCF Security TAG threat-model exception lifecycle:
33
+ # https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md
34
+ #
35
+ # Periodic reduced-exclusion scan procedure:
36
+ # Run this script with --strict on every release branch and during scheduled
37
+ # security reviews. This mode intentionally skips grandfathered entries and
38
+ # expired exclusions so that accumulated technical debt in the ignore-list
39
+ # cannot permanently hide secrets. See SECURITY.md for the audit runbook.
40
+ set -euo pipefail
41
+
42
+ # ─── Global mode flag ─────────────────────────────────────────────────────────
43
+ STRICT_MODE=false
44
+
45
+ # ─── Secret Patterns ─────────────────────────────────────────────────────────
46
+ # Format: "LABEL:::REGEX"
47
+ # Each entry is a human label paired with a POSIX extended regex.
48
+
49
+ SECRET_PATTERNS=(
50
+ # AWS
51
+ "AWS Access Key:::AKIA[0-9A-Z]{16}"
52
+ "AWS Secret Key:::aws_secret_access_key[[:space:]]*=[[:space:]]*[A-Za-z0-9/+=]{40}"
53
+
54
+ # OpenAI / Anthropic / AI providers
55
+ "OpenAI API Key:::sk-[A-Za-z0-9]{20,}"
56
+ "Anthropic API Key:::sk-ant-[A-Za-z0-9_-]{20,}"
57
+
58
+ # GitHub
59
+ "GitHub PAT:::ghp_[A-Za-z0-9]{36}"
60
+ "GitHub OAuth:::gho_[A-Za-z0-9]{36}"
61
+ "GitHub App Token:::ghs_[A-Za-z0-9]{36}"
62
+ "GitHub Fine-grained PAT:::github_pat_[A-Za-z0-9_]{20,}"
63
+
64
+ # Stripe
65
+ "Stripe Secret Key:::sk_live_[A-Za-z0-9]{24,}"
66
+ "Stripe Publishable Key:::pk_live_[A-Za-z0-9]{24,}"
67
+
68
+ # Generic patterns
69
+ "Private Key Header:::-----BEGIN[[:space:]]+(RSA|EC|DSA|OPENSSH)?[[:space:]]*PRIVATE[[:space:]]+KEY-----"
70
+ "Generic API Key Assignment:::api[_-]?key[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
71
+ "Generic Secret Assignment:::secret[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
72
+ "Generic Token Assignment:::token[[:space:]]*[:=][[:space:]]*['\"][A-Za-z0-9_-]{20,}['\"]"
73
+ "Generic Password Assignment:::password[[:space:]]*[:=][[:space:]]*['\"][^'\"]{8,}['\"]"
74
+
75
+ # Slack
76
+ "Slack Bot Token:::xoxb-[0-9]{10,}-[A-Za-z0-9]{20,}"
77
+ "Slack Webhook:::hooks\.slack\.com/services/T[A-Z0-9]{8,}/B[A-Z0-9]{8,}/[A-Za-z0-9]{24}"
78
+
79
+ # Google
80
+ "Google API Key:::AIza[A-Za-z0-9_-]{35}"
81
+
82
+ # NPM
83
+ "NPM Token:::npm_[A-Za-z0-9]{36}"
84
+
85
+ # .env file content (key=value with sensitive-looking keys)
86
+ "Env Variable Leak:::(DATABASE_URL|DB_PASSWORD|REDIS_URL|MONGO_URI|JWT_SECRET|SESSION_SECRET|ENCRYPTION_KEY)[[:space:]]*=[[:space:]]*[^[:space:]]{8,}"
87
+ )
88
+
89
+ # ─── Ignorelist ──────────────────────────────────────────────────────────────
90
+ #
91
+ # Entries in IGNORED_FILES are loaded from .secretscanignore.
92
+ # In --strict mode, only fully-annotated entries with a future 'expires' date
93
+ # are loaded. Grandfathered entries and expired entries are skipped (the
94
+ # corresponding files ARE scanned, not excluded).
95
+ #
96
+ # Annotation format (structured comment must immediately precede the path):
97
+ # # allow: <pattern> reason="..." owner="..." expires="YYYY-MM-DD" [rule-id="..."]
98
+ # <pattern>
99
+ #
100
+ # Entries without a structured annotation are grandfathered:
101
+ # - Default mode: accepted (file excluded), deprecation warning emitted
102
+ # - Strict mode: rejected (file scanned, no exclusion applied)
103
+
104
+ IGNOREFILE=".secretscanignore"
105
+ IGNORED_FILES=()
106
+
107
+ # Returns value of key="value" annotation pair from a string
108
+ _extract_annotation_key() {
109
+ local str="$1"
110
+ local key="$2"
111
+ echo "$str" | grep -oE "${key}=['\"][^'\"]+['\"]" | head -1 | sed "s/${key}=['\"]//;s/['\"]$//" || true
112
+ }
113
+
114
+ # Returns today as YYYY-MM-DD
115
+ _today() {
116
+ date +%Y-%m-%d
117
+ }
118
+
119
+ # Returns 0 (true) if a date string YYYY-MM-DD is strictly in the past
120
+ _date_is_past() {
121
+ local d="$1"
122
+ [[ "$d" < "$(_today)" ]]
123
+ }
124
+
125
+ load_ignorelist() {
126
+ if [[ ! -f "$IGNOREFILE" ]]; then
127
+ return
128
+ fi
129
+
130
+ local prev_comment=""
131
+
132
+ while IFS= read -r line || [[ -n "$line" ]]; do
133
+ # Empty line resets context
134
+ if [[ -z "${line// }" ]]; then
135
+ prev_comment=""
136
+ continue
137
+ fi
138
+
139
+ # Accumulate comment
140
+ if [[ "$line" =~ ^[[:space:]]*# ]]; then
141
+ prev_comment="$line"
142
+ continue
143
+ fi
144
+
145
+ # This is a path entry
146
+ local pattern="$line"
147
+
148
+ # Determine if preceding comment is a structured annotation
149
+ local is_structured=false
150
+ if [[ "$prev_comment" =~ ^#[[:space:]]+allow:[[:space:]] ]]; then
151
+ is_structured=true
152
+ fi
153
+
154
+ if [[ "$is_structured" == true ]]; then
155
+ # Parse structured annotation
156
+ local expires
157
+ expires=$(_extract_annotation_key "$prev_comment" "expires")
158
+
159
+ if [[ -n "$expires" ]] && _date_is_past "$expires"; then
160
+ # Expired exclusion — never apply, regardless of mode
161
+ echo "secret-scan: WARNING: exclusion '$pattern' has expired (expires=$expires) — entry ignored" >&2
162
+ prev_comment=""
163
+ continue
164
+ fi
165
+
166
+ # Valid structured annotation — always apply
167
+ IGNORED_FILES+=("$pattern")
168
+
169
+ else
170
+ # Grandfathered (plain comment or no comment)
171
+ if [[ "$STRICT_MODE" == true ]]; then
172
+ # Strict mode: do NOT apply grandfathered exclusion
173
+ echo "secret-scan: WARNING (--strict): grandfathered exclusion '$pattern' not applied" >&2
174
+ else
175
+ # Default mode: apply but warn
176
+ echo "secret-scan: DEPRECATION WARNING: '$pattern' has no structured annotation — grandfather applied" >&2
177
+ echo " Migrate to: # allow: $pattern reason=\"...\" owner=\"...\" expires=\"YYYY-MM-DD\"" >&2
178
+ IGNORED_FILES+=("$pattern")
179
+ fi
180
+ fi
181
+
182
+ prev_comment=""
183
+ done < "$IGNOREFILE"
184
+ }
185
+
186
+ is_ignored() {
187
+ local file="$1"
188
+ if [[ ${#IGNORED_FILES[@]} -eq 0 ]]; then
189
+ return 1
190
+ fi
191
+ for pattern in "${IGNORED_FILES[@]}"; do
192
+ # Support glob-style matching
193
+ # shellcheck disable=SC2254
194
+ case "$file" in
195
+ $pattern) return 0 ;;
196
+ esac
197
+ done
198
+ return 1
199
+ }
200
+
201
+ # ─── Skip Rules ──────────────────────────────────────────────────────────────
202
+
203
+ should_skip_file() {
204
+ local file="$1"
205
+ # Skip binary files
206
+ case "$file" in
207
+ *.png|*.jpg|*.jpeg|*.gif|*.ico|*.woff|*.woff2|*.ttf|*.eot|*.otf) return 0 ;;
208
+ *.zip|*.tar|*.gz|*.bz2|*.xz|*.7z) return 0 ;;
209
+ *.pdf|*.doc|*.docx|*.xls|*.xlsx) return 0 ;;
210
+ esac
211
+ # Skip lockfiles and node_modules
212
+ case "$file" in
213
+ */node_modules/*) return 0 ;;
214
+ */package-lock.json) return 0 ;;
215
+ */yarn.lock) return 0 ;;
216
+ */pnpm-lock.yaml) return 0 ;;
217
+ esac
218
+ # Skip the scan scripts themselves and test files
219
+ case "$file" in
220
+ */secret-scan.sh) return 0 ;;
221
+ */secret-scan-lint.test.cjs) return 0 ;;
222
+ */security-scan.test.cjs) return 0 ;;
223
+ */security-prompt-injection.test.cjs) return 0 ;;
224
+ tests/fixtures/adversarial/security/*|*/tests/fixtures/adversarial/security/*) return 0 ;;
225
+ esac
226
+ return 1
227
+ }
228
+
229
+ # ─── File Collection ─────────────────────────────────────────────────────────
230
+
231
+ collect_files() {
232
+ local mode="$1"
233
+ shift
234
+
235
+ case "$mode" in
236
+ --diff)
237
+ local base="${1:-origin/main}"
238
+ git diff --name-only --diff-filter=ACMR "$base"...HEAD 2>/dev/null \
239
+ | grep -vE '\.(png|jpg|jpeg|gif|ico|woff|woff2|ttf|eot|otf|zip|tar|gz|pdf)$' || true
240
+ ;;
241
+ --file)
242
+ if [[ -f "$1" ]]; then
243
+ echo "$1"
244
+ else
245
+ echo "Error: file not found: $1" >&2
246
+ exit 2
247
+ fi
248
+ ;;
249
+ --dir)
250
+ local dir="$1"
251
+ if [[ ! -d "$dir" ]]; then
252
+ echo "Error: directory not found: $dir" >&2
253
+ exit 2
254
+ fi
255
+ find "$dir" -type f ! -path '*/node_modules/*' ! -path '*/.git/*' ! -path '*/dist/*' \
256
+ ! -name '*.png' ! -name '*.jpg' ! -name '*.gif' ! -name '*.woff*' 2>/dev/null || true
257
+ ;;
258
+ --stdin)
259
+ cat
260
+ ;;
261
+ *)
262
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> | --stdin" >&2
263
+ exit 2
264
+ ;;
265
+ esac
266
+ }
267
+
268
+ # ─── Scanner ─────────────────────────────────────────────────────────────────
269
+
270
+ scan_file() {
271
+ local file="$1"
272
+ local found=0
273
+
274
+ if is_ignored "$file"; then
275
+ return 0
276
+ fi
277
+
278
+ for entry in "${SECRET_PATTERNS[@]}"; do
279
+ local label="${entry%%:::*}"
280
+ local pattern="${entry#*:::}"
281
+
282
+ local matches
283
+ matches=$(grep -nE -e "$pattern" "$file" 2>/dev/null || true)
284
+ if [[ -n "$matches" ]]; then
285
+ if [[ $found -eq 0 ]]; then
286
+ echo "FAIL: $file"
287
+ found=1
288
+ fi
289
+ echo "$matches" | while IFS= read -r line; do
290
+ echo " [$label] $line"
291
+ done
292
+ fi
293
+ done
294
+
295
+ return $found
296
+ }
297
+
298
+ # ─── Main ────────────────────────────────────────────────────────────────────
299
+
300
+ main() {
301
+ if [[ $# -eq 0 ]]; then
302
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> [--strict]" >&2
303
+ exit 2
304
+ fi
305
+
306
+ # Parse --strict flag first (may appear anywhere in argv)
307
+ local remaining_args=()
308
+ for arg in "$@"; do
309
+ if [[ "$arg" == "--strict" ]]; then
310
+ STRICT_MODE=true
311
+ else
312
+ remaining_args+=("$arg")
313
+ fi
314
+ done
315
+ set -- "${remaining_args[@]}"
316
+
317
+ if [[ $# -eq 0 ]]; then
318
+ echo "Usage: $0 --diff [base] | --file <path> | --dir <path> [--strict]" >&2
319
+ exit 2
320
+ fi
321
+
322
+ load_ignorelist
323
+
324
+ local mode="$1"
325
+ shift
326
+
327
+ local files
328
+ files=$(collect_files "$mode" "$@")
329
+
330
+ if [[ -z "$files" ]]; then
331
+ echo "secret-scan: no files to scan"
332
+ exit 0
333
+ fi
334
+
335
+ local total=0
336
+ local failed=0
337
+
338
+ while IFS= read -r file; do
339
+ [[ -z "$file" ]] && continue
340
+ if should_skip_file "$file"; then
341
+ continue
342
+ fi
343
+ total=$((total + 1))
344
+ if ! scan_file "$file"; then
345
+ failed=$((failed + 1))
346
+ fi
347
+ done <<< "$files"
348
+
349
+ echo ""
350
+ echo "secret-scan: scanned $total files, $failed with findings"
351
+
352
+ if [[ $failed -gt 0 ]]; then
353
+ exit 1
354
+ fi
355
+ exit 0
356
+ }
357
+
358
+ main "$@"