cc-safe-setup 29.7.0 → 30.0.4

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 (1022) hide show
  1. package/.claude-plugin/marketplace.json +72 -19
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CONTRIBUTING.md +7 -2
  4. package/COOKBOOK.md +50 -46
  5. package/LICENSE +21 -0
  6. package/MIGRATION.md +8 -8
  7. package/README.md +419 -512
  8. package/SAFETY_CHECKLIST.md +15 -7
  9. package/SERVICES.md +194 -0
  10. package/SETTINGS_REFERENCE.md +236 -17
  11. package/SKILL.md +5 -5
  12. package/TROUBLESHOOTING.md +35 -14
  13. package/action.yml +12 -4
  14. package/audit/README.md +84 -0
  15. package/audit/audit-checklist.md +152 -0
  16. package/audit/boundary-selftest.sh +85 -0
  17. package/audit/boundary.sh +123 -0
  18. package/audit/count-hooks.py +42 -0
  19. package/audit/find-dead-hooks.sh +82 -0
  20. package/audit/find-unfirable-rules.sh +142 -0
  21. package/audit/fire.sh +97 -0
  22. package/audit/selftest.sh +42 -0
  23. package/audit/unfirable-selftest.sh +81 -0
  24. package/audit-web/index.html +9 -9
  25. package/examples/README.md +54 -17
  26. package/examples/account-billing-log.sh +98 -0
  27. package/examples/account-routing-preflight.sh +123 -0
  28. package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
  29. package/examples/agent-view-quota-decrement.sh +32 -0
  30. package/examples/agent-view-quota-warn.sh +94 -0
  31. package/examples/agents-md-edit-drift-warner.sh +223 -0
  32. package/examples/agents-md-loader.sh +160 -0
  33. package/examples/agents-md-sync-checker.sh +102 -0
  34. package/examples/ai-slop-punctuation-arrest.sh +210 -0
  35. package/examples/allowlist.sh +70 -10
  36. package/examples/always-allow-pattern-suggester.sh +125 -0
  37. package/examples/ansible-vault-guard.sh +2 -1
  38. package/examples/anthropic-base-url-guard.sh +76 -0
  39. package/examples/api-busyloop-guard.sh +123 -0
  40. package/examples/api-endpoint-guard.sh +12 -0
  41. package/examples/api-key-in-url-guard.sh +17 -1
  42. package/examples/api-rate-limit-guard.sh +36 -1
  43. package/examples/api-rate-limit-tracker.sh +12 -0
  44. package/examples/articulated-scope-capture.sh +101 -0
  45. package/examples/askuserquestion-autonomy-gate.sh +102 -0
  46. package/examples/attachment-traversal-guard.sh +118 -0
  47. package/examples/aup-block-pattern-logger.sh +161 -0
  48. package/examples/aup-false-positive-helper.sh +124 -0
  49. package/examples/aup-large-tool-output-warner.sh +282 -0
  50. package/examples/aup-retry-loop-guard.sh +229 -0
  51. package/examples/auth-expiry-reminder.sh +157 -0
  52. package/examples/auth-macos-sleep-detector.sh +185 -0
  53. package/examples/auth-path-detector.sh +171 -0
  54. package/examples/auth-status-checker.sh +157 -0
  55. package/examples/authorized-reconfirmation-detector.sh +195 -0
  56. package/examples/auto-approve-build.sh +39 -0
  57. package/examples/auto-approve-cargo.sh +31 -1
  58. package/examples/auto-approve-docker.sh +35 -0
  59. package/examples/auto-approve-git-read.sh +37 -14
  60. package/examples/auto-approve-go.sh +30 -1
  61. package/examples/auto-approve-gradle.sh +29 -1
  62. package/examples/auto-approve-make.sh +29 -1
  63. package/examples/auto-approve-maven.sh +29 -1
  64. package/examples/auto-approve-python.sh +41 -1
  65. package/examples/auto-approve-readonly-tools.sh +1 -0
  66. package/examples/auto-approve-readonly.sh +110 -33
  67. package/examples/auto-approve-ssh.sh +30 -1
  68. package/examples/auto-approve-test.sh +44 -0
  69. package/examples/auto-checkpoint.sh +1 -1
  70. package/examples/auto-compact-prep.sh +0 -0
  71. package/examples/auto-git-checkpoint.sh +0 -0
  72. package/examples/auto-mode-safe-commands.sh +53 -1
  73. package/examples/auto-mode-safety-enforcer.sh +151 -4
  74. package/examples/auto-push-session-branch.sh +22 -0
  75. package/examples/aws-production-guard.sh +13 -1
  76. package/examples/aws-region-guard.sh +1 -1
  77. package/examples/background-cost-launch-guard.sh +82 -0
  78. package/examples/background-task-guard.sh +12 -0
  79. package/examples/backup-before-refactor.sh +0 -0
  80. package/examples/banned-command-guard.sh +12 -0
  81. package/examples/bash-allowlist-secondary-check.sh +157 -0
  82. package/examples/bash-domain-allowlist.sh +12 -0
  83. package/examples/bash-fanout-bounded-rewriter.sh +191 -0
  84. package/examples/bash-heuristic-approver.sh +112 -10
  85. package/examples/bash-project-fence.sh +194 -0
  86. package/examples/bash-safety-auto-deny.sh +12 -0
  87. package/examples/bash-secret-output-detector.sh +44 -3
  88. package/examples/bash-trace-guard.sh +12 -0
  89. package/examples/bashrc-safety-check.sh +0 -0
  90. package/examples/bg-permission-prompt-warner.sh +182 -0
  91. package/examples/bg-task-cooldown-guard.sh +12 -0
  92. package/examples/binary-read-detector.sh +135 -0
  93. package/examples/binary-upload-guard.sh +12 -0
  94. package/examples/block-database-wipe.sh +35 -10
  95. package/examples/branch-name-check.sh +8 -3
  96. package/examples/branch-naming-convention.sh +0 -0
  97. package/examples/broad-find-guard.sh +12 -0
  98. package/examples/broad-prefix-session-trap-warner.sh +106 -0
  99. package/examples/bulk-file-delete-guard.sh +45 -0
  100. package/examples/bypass-mode-effective-verifier.sh +203 -0
  101. package/examples/cache-creation-drift-detector.sh +120 -0
  102. package/examples/cache-residue-detector.sh +195 -0
  103. package/examples/cache-tier-logger.sh +70 -0
  104. package/examples/cache-ttl-eviction-detector.sh +149 -0
  105. package/examples/cargo-publish-guard.sh +14 -1
  106. package/examples/case-insensitive-path-guard.sh +21 -2
  107. package/examples/case-sensitive-guard.sh +23 -2
  108. package/examples/cch-cache-guard.sh +0 -0
  109. package/examples/cch-sentinel-precommit-guard.sh +47 -0
  110. package/examples/check-abort-controller.sh +1 -1
  111. package/examples/check-accessibility.sh +0 -0
  112. package/examples/check-aria-labels.sh +0 -0
  113. package/examples/check-before-act-enforcer.sh +12 -0
  114. package/examples/check-charset-meta.sh +0 -0
  115. package/examples/check-cookie-flags.sh +0 -0
  116. package/examples/check-cors-config.sh +0 -0
  117. package/examples/check-csp-headers.sh +0 -0
  118. package/examples/check-csrf-protection.sh +0 -0
  119. package/examples/check-debounce.sh +1 -1
  120. package/examples/check-dependency-age.sh +0 -0
  121. package/examples/check-dependency-license.sh +0 -0
  122. package/examples/check-dockerfile-best-practice.sh +0 -0
  123. package/examples/check-error-boundaries.sh +0 -0
  124. package/examples/check-error-class.sh +1 -1
  125. package/examples/check-error-handling.sh +0 -0
  126. package/examples/check-error-logging.sh +1 -1
  127. package/examples/check-error-message.sh +0 -0
  128. package/examples/check-error-stack.sh +0 -0
  129. package/examples/check-favicon.sh +0 -0
  130. package/examples/check-git-hooks-compat.sh +0 -0
  131. package/examples/check-gitattributes.sh +0 -0
  132. package/examples/check-https-redirect.sh +0 -0
  133. package/examples/check-input-validation.sh +0 -0
  134. package/examples/check-lang-attribute.sh +0 -0
  135. package/examples/check-npm-scripts-exist.sh +0 -0
  136. package/examples/check-package-size.sh +0 -0
  137. package/examples/check-port-availability.sh +0 -0
  138. package/examples/check-promise-all.sh +1 -1
  139. package/examples/check-rate-limiting.sh +0 -0
  140. package/examples/check-return-types.sh +0 -0
  141. package/examples/check-semantic-versioning.sh +0 -0
  142. package/examples/check-suspense-fallback.sh +1 -1
  143. package/examples/check-test-exists.sh +0 -0
  144. package/examples/check-test-naming.sh +0 -0
  145. package/examples/check-timeout-cleanup.sh +1 -1
  146. package/examples/check-tls-version.sh +0 -0
  147. package/examples/check-unsubscribe.sh +1 -1
  148. package/examples/check-viewport-meta.sh +0 -0
  149. package/examples/check-worker-terminate.sh +1 -1
  150. package/examples/checkpoint-tamper-guard.sh +12 -0
  151. package/examples/chmod-guard.sh +12 -0
  152. package/examples/chown-guard.sh +24 -0
  153. package/examples/ci-workflow-guard.sh +6 -1
  154. package/examples/claim-verify-detector.sh +109 -0
  155. package/examples/claim-vs-caveat-checker.sh +77 -0
  156. package/examples/classifier-fallback-allow.sh +114 -40
  157. package/examples/claude-cache-gc.sh +1 -0
  158. package/examples/claude-code-version-pin-advisor.sh +183 -0
  159. package/examples/claude-md-reinjector.sh +129 -0
  160. package/examples/claude-md-size-monitor.sh +66 -0
  161. package/examples/claude-update-budget-guard.sh +123 -0
  162. package/examples/claude-update-smart.sh +113 -0
  163. package/examples/claudeignore-enforce-guard.sh +12 -0
  164. package/examples/claudemd-enforcer.sh +0 -0
  165. package/examples/claudemd-tool-prohibition.sh +128 -0
  166. package/examples/clear-command-confirm-guard.sh +32 -15
  167. package/examples/cli-config-pinning-detector.sh +162 -0
  168. package/examples/cliff-countdown-advisor.sh +96 -0
  169. package/examples/clipboard-secret-guard.sh +12 -0
  170. package/examples/closure-word-verify-gate.sh +150 -0
  171. package/examples/cloud-cli-guard.sh +39 -2
  172. package/examples/commit-all-scope-guard.sh +44 -0
  173. package/examples/commit-message-check.sh +1 -1
  174. package/examples/commit-message-quality.sh +6 -1
  175. package/examples/commitment-carry-forward-arrest.sh +361 -0
  176. package/examples/compact-alert-notification.sh +0 -0
  177. package/examples/compact-circuit-breaker.sh +72 -0
  178. package/examples/compact-dispatch-watchdog.sh +149 -0
  179. package/examples/completion-claim-without-verification-detector.sh +207 -0
  180. package/examples/composer-guard.sh +12 -0
  181. package/examples/compound-bash-permission-resolver.sh +156 -0
  182. package/examples/compound-command-allow.sh +1 -1
  183. package/examples/compound-command-deny-enforcer.sh +183 -0
  184. package/examples/compound-inject-guard.sh +12 -0
  185. package/examples/concurrent-edit-lock.sh +12 -0
  186. package/examples/conflict-marker-guard.sh +12 -0
  187. package/examples/consecutive-error-breaker.sh +0 -0
  188. package/examples/console-log-count.sh +1 -0
  189. package/examples/context-compact-advisor.sh +29 -2
  190. package/examples/context-length-budget.sh +69 -0
  191. package/examples/context-threshold-alert.sh +12 -0
  192. package/examples/context-usage-drift-alert.sh +41 -13
  193. package/examples/conversation-history-guard.sh +12 -0
  194. package/examples/core-file-protect-guard.sh +12 -0
  195. package/examples/cors-star-warn.sh +0 -0
  196. package/examples/cost-incident-self-audit.sh +162 -0
  197. package/examples/cowork-claude-md-load-checker.sh +100 -0
  198. package/examples/cowork-fuse-staleness-watcher.sh +140 -0
  199. package/examples/cowork-hook-absence-warner.sh +167 -0
  200. package/examples/cowork-model-picker-advisor.sh +115 -0
  201. package/examples/credential-exfil-guard.sh +65 -4
  202. package/examples/credential-file-cat-guard.sh +17 -1
  203. package/examples/cron-create-receipt.sh +112 -0
  204. package/examples/cron-modification-guard.sh +12 -0
  205. package/examples/cross-product-mcp-spawn-detector.sh +178 -0
  206. package/examples/cwd-project-boundary-guard.sh +0 -0
  207. package/examples/daemon-zombie-worker-surfacer.sh +118 -0
  208. package/examples/daily-cost-guard.sh +164 -0
  209. package/examples/daily-usage-tracker.sh +0 -0
  210. package/examples/dangerous-pip-flag-guard.sh +12 -0
  211. package/examples/db-connect-guard.sh +13 -1
  212. package/examples/denied-action-retry-guard.sh +12 -0
  213. package/examples/deny-bypass-detector.sh +12 -0
  214. package/examples/deny-rule-integrity-verifier.sh +181 -0
  215. package/examples/dependency-install-guard.sh +12 -0
  216. package/examples/deploy-guard.sh +14 -2
  217. package/examples/deploy-path-verify-guard.sh +12 -0
  218. package/examples/deployment-readback-gate.sh +135 -0
  219. package/examples/deployment-readback-gh-adapter.sh +247 -0
  220. package/examples/deployment-verify-guard.sh +25 -2
  221. package/examples/destructive-db-script-write-guard.sh +166 -0
  222. package/examples/destructive-migration-write-guard.sh +163 -0
  223. package/examples/diff-size-guard.sh +12 -0
  224. package/examples/disabled-feature-toggle-advisor.sh +88 -0
  225. package/examples/disk-partition-guard.sh +12 -0
  226. package/examples/dispatch-allowlist-preflight.sh +301 -0
  227. package/examples/dispatch-liveness-watchdog.sh +216 -0
  228. package/examples/dispatch-receipt.sh +174 -0
  229. package/examples/django-migrate-guard.sh +12 -0
  230. package/examples/dns-config-guard.sh +12 -0
  231. package/examples/docker-dangerous-guard.sh +12 -0
  232. package/examples/docker-volume-guard.sh +0 -0
  233. package/examples/dockerfile-latest-guard.sh +1 -0
  234. package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
  235. package/examples/dotenv-commit-guard.sh +12 -0
  236. package/examples/dotenv-read-guard.sh +12 -0
  237. package/examples/dotfile-protection-guard.sh +12 -0
  238. package/examples/dotnet-build-on-edit.sh +1 -1
  239. package/examples/drizzle-migrate-guard.sh +27 -2
  240. package/examples/echo-probe-spam-detector.sh +176 -0
  241. package/examples/edit-counter-test-gate.sh +12 -0
  242. package/examples/edit-error-counter.sh +1 -1
  243. package/examples/edit-guard.sh +12 -0
  244. package/examples/edit-old-string-validator.sh +12 -0
  245. package/examples/edit-quote-ambiguity-guard.sh +97 -0
  246. package/examples/edit-retry-loop-guard.sh +0 -0
  247. package/examples/edit-verify.sh +0 -0
  248. package/examples/env-inline-secret-guard.sh +14 -2
  249. package/examples/env-naming-convention.sh +0 -0
  250. package/examples/env-prod-guard.sh +0 -0
  251. package/examples/env-required-check.sh +0 -0
  252. package/examples/env-source-guard.sh +12 -0
  253. package/examples/env-var-check.sh +24 -1
  254. package/examples/ephemeral-container-detector.sh +147 -0
  255. package/examples/error-memory-guard.sh +12 -0
  256. package/examples/evidence-claim-gate.sh +187 -0
  257. package/examples/exploration-budget-guard.sh +89 -0
  258. package/examples/expo-eject-guard.sh +13 -0
  259. package/examples/extended-thinking-loop-guard.sh +139 -0
  260. package/examples/extended-thinking-resume-warning.sh +119 -0
  261. package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
  262. package/examples/fabricated-command-detector.sh +145 -0
  263. package/examples/false-disk-full-guard.sh +63 -0
  264. package/examples/feature-deprecation-detector.sh +109 -0
  265. package/examples/file-change-tracker.sh +1 -1
  266. package/examples/file-change-undo-tracker.sh +0 -0
  267. package/examples/file-edit-backup.sh +63 -14
  268. package/examples/file-reference-check.sh +0 -0
  269. package/examples/file-size-limit.sh +12 -0
  270. package/examples/financial-operation-guard.sh +12 -0
  271. package/examples/firewall-guard.sh +12 -0
  272. package/examples/fish-shell-wrapper.sh +125 -7
  273. package/examples/five-hundred-milestone.sh +1 -0
  274. package/examples/flask-static-route-guard.sh +89 -0
  275. package/examples/forbidden-response-phrase-detector.sh +161 -0
  276. package/examples/gem-push-guard.sh +13 -0
  277. package/examples/gh-cli-destructive-guard.sh +13 -1
  278. package/examples/git-checkout-safety-guard.sh +12 -0
  279. package/examples/git-checkout-uncommitted-guard.sh +12 -0
  280. package/examples/git-config-guard.sh +12 -0
  281. package/examples/git-crypt-worktree-guard.sh +12 -0
  282. package/examples/git-filter-repo-guard.sh +56 -0
  283. package/examples/git-history-rewrite-guard.sh +12 -0
  284. package/examples/git-hook-bypass-guard.sh +0 -0
  285. package/examples/git-maintenance-guard.sh +83 -0
  286. package/examples/git-merge-conflict-prevent.sh +0 -0
  287. package/examples/git-message-length-check.sh +0 -0
  288. package/examples/git-message-length.sh +0 -0
  289. package/examples/git-operations-require-approval.sh +68 -14
  290. package/examples/git-pack-temp-cleanup-guard.sh +102 -0
  291. package/examples/git-push-blast-radius-guard.sh +218 -0
  292. package/examples/git-remote-guard.sh +24 -3
  293. package/examples/git-rm-orphan-wipe-guard.sh +85 -0
  294. package/examples/git-stash-before-checkout.sh +12 -0
  295. package/examples/git-stash-before-danger.sh +0 -0
  296. package/examples/git-submodule-guard.sh +69 -2
  297. package/examples/git-tag-guard.sh +12 -0
  298. package/examples/github-actions-secret-guard.sh +0 -0
  299. package/examples/gitignore-check.sh +0 -0
  300. package/examples/gitops-drift-guard.sh +12 -0
  301. package/examples/go-mod-tidy-warn.sh +1 -0
  302. package/examples/go-vet-after-edit.sh +12 -0
  303. package/examples/goal-iteration-limit-warner.sh +152 -0
  304. package/examples/grep-nul-false-negative-guard.sh +30 -0
  305. package/examples/growthbook-flag-monitor.sh +257 -0
  306. package/examples/hallucination-url-check.sh +1 -1
  307. package/examples/halt-signal-detector.sh +135 -0
  308. package/examples/handoff-on-clear.sh +65 -0
  309. package/examples/hardcoded-ip-guard.sh +1 -0
  310. package/examples/headless-empty-result-guard.sh +0 -0
  311. package/examples/headless-stop-guard.sh +0 -0
  312. package/examples/helm-install-guard.sh +2 -1
  313. package/examples/home-critical-bash-guard.sh +17 -1
  314. package/examples/hook-debug-wrapper.sh +6 -2
  315. package/examples/hook-permission-fixer.sh +0 -0
  316. package/examples/hook-self-disable-detector.sh +99 -0
  317. package/examples/hook-stdout-sanitizer.sh +6 -2
  318. package/examples/hook-tamper-guard.sh +12 -0
  319. package/examples/idle-session-cost-alert.sh +0 -0
  320. package/examples/image-dimension-guard.sh +109 -0
  321. package/examples/image-file-validator.sh +0 -0
  322. package/examples/iteration-quality-degradation-detector.sh +170 -0
  323. package/examples/java-compile-on-edit.sh +1 -1
  324. package/examples/json-syntax-check.sh +0 -0
  325. package/examples/k8s-production-guard.sh +13 -1
  326. package/examples/kill-process-guard.sh +12 -0
  327. package/examples/kubernetes-guard.sh +13 -1
  328. package/examples/laravel-artisan-guard.sh +13 -0
  329. package/examples/large-file-guard.sh +1 -1
  330. package/examples/log-level-guard.sh +0 -0
  331. package/examples/log-truncation-guard.sh +12 -0
  332. package/examples/long-session-malformed-tool-call-detector.sh +183 -0
  333. package/examples/loop-detector.sh +12 -0
  334. package/examples/magic-number-warn.sh +1 -0
  335. package/examples/main-branch-warn.sh +12 -0
  336. package/examples/markdown-link-check.sh +0 -0
  337. package/examples/max-concurrent-agents.sh +12 -0
  338. package/examples/max-edit-size-guard.sh +13 -0
  339. package/examples/max-file-count-guard.sh +0 -0
  340. package/examples/max-file-delete-count.sh +0 -0
  341. package/examples/max-function-length.sh +1 -0
  342. package/examples/max-import-count.sh +0 -0
  343. package/examples/max-subagent-count.sh +0 -0
  344. package/examples/mcp-config-freeze.sh +12 -0
  345. package/examples/mcp-config-poisoning-audit.sh +150 -0
  346. package/examples/mcp-data-boundary.sh +1 -1
  347. package/examples/mcp-misdiagnosis-arrest.sh +209 -0
  348. package/examples/mcp-orphan-leak-warner.sh +49 -0
  349. package/examples/mcp-permissions-ask-warner.sh +151 -0
  350. package/examples/mcp-routine-approval-detector.sh +154 -0
  351. package/examples/mcp-server-allowlist.sh +12 -0
  352. package/examples/mcp-server-guard.sh +12 -0
  353. package/examples/mcp-startup-bloat-detector.sh +87 -0
  354. package/examples/mcp-stdio-compatibility-test.sh +153 -0
  355. package/examples/mcp-tool-audit-log.sh +0 -0
  356. package/examples/mcp-tool-guard.sh +101 -1
  357. package/examples/mcp-warmup-wait.sh +0 -0
  358. package/examples/memory-chain-audit.sh +56 -0
  359. package/examples/memory-orphan-detector.sh +188 -0
  360. package/examples/memory-write-guard.sh +99 -17
  361. package/examples/migration-verify-guard.sh +12 -0
  362. package/examples/model-swap-suggester.sh +177 -0
  363. package/examples/model-version-alert.sh +5 -1
  364. package/examples/model-version-lock.sh +63 -0
  365. package/examples/move-delete-sequence-guard.sh +33 -2
  366. package/examples/multi-file-plan-routing-gate.sh +192 -0
  367. package/examples/multi-vendor-concurrent-warner.sh +108 -0
  368. package/examples/multi-window-auth-drift-detector.sh +183 -0
  369. package/examples/multiline-command-approver.sh +161 -23
  370. package/examples/nested-background-agent-guard.sh +109 -0
  371. package/examples/nested-spawn-inflight-guard.sh +178 -0
  372. package/examples/network-exfil-guard.sh +12 -0
  373. package/examples/network-guard.sh +12 -0
  374. package/examples/network-interface-guard.sh +12 -0
  375. package/examples/nextjs-env-guard.sh +1 -1
  376. package/examples/no-absolute-import.sh +0 -0
  377. package/examples/no-alert-confirm-prompt.sh +0 -0
  378. package/examples/no-anonymous-default-export.sh +0 -0
  379. package/examples/no-any-type.sh +0 -0
  380. package/examples/no-any-typescript.sh +1 -0
  381. package/examples/no-ask-human.sh +12 -0
  382. package/examples/no-assignment-in-condition.sh +0 -0
  383. package/examples/no-base64-exfil.sh +12 -0
  384. package/examples/no-callback-hell.sh +0 -0
  385. package/examples/no-circular-dependency.sh +0 -0
  386. package/examples/no-cleartext-storage.sh +0 -0
  387. package/examples/no-commented-code.sh +0 -0
  388. package/examples/no-commit-fixup.sh +0 -0
  389. package/examples/no-console-assert.sh +0 -0
  390. package/examples/no-console-error-swallow.sh +0 -0
  391. package/examples/no-console-in-prod.sh +0 -0
  392. package/examples/no-console-log-commit.sh +12 -0
  393. package/examples/no-console-log.sh +0 -0
  394. package/examples/no-console-time.sh +0 -0
  395. package/examples/no-cors-wildcard.sh +4 -1
  396. package/examples/no-curl-upload.sh +0 -0
  397. package/examples/no-dangerouslySetInnerHTML.sh +0 -0
  398. package/examples/no-dangling-await.sh +1 -0
  399. package/examples/no-debug-commit.sh +12 -0
  400. package/examples/no-debug-in-commit.sh +0 -0
  401. package/examples/no-deep-nesting.sh +0 -0
  402. package/examples/no-deep-relative-import.sh +1 -0
  403. package/examples/no-default-credentials.sh +0 -0
  404. package/examples/no-deploy-friday.sh +13 -1
  405. package/examples/no-disabled-test.sh +0 -0
  406. package/examples/no-document-write.sh +0 -0
  407. package/examples/no-empty-function.sh +0 -0
  408. package/examples/no-eval-in-template.sh +0 -0
  409. package/examples/no-eval-template.sh +3 -1
  410. package/examples/no-eval.sh +0 -0
  411. package/examples/no-exec-user-input.sh +0 -0
  412. package/examples/no-fixme-ship.sh +12 -0
  413. package/examples/no-floating-promises.sh +0 -0
  414. package/examples/no-force-flag.sh +22 -5
  415. package/examples/no-force-install.sh +0 -0
  416. package/examples/no-git-amend.sh +12 -0
  417. package/examples/no-git-rebase-public.sh +0 -0
  418. package/examples/no-global-install.sh +12 -0
  419. package/examples/no-global-state.sh +0 -0
  420. package/examples/no-hardcoded-port.sh +1 -0
  421. package/examples/no-hardcoded-url.sh +0 -0
  422. package/examples/no-helmet-missing.sh +0 -0
  423. package/examples/no-http-url.sh +1 -0
  424. package/examples/no-http-without-https.sh +0 -0
  425. package/examples/no-inline-style.sh +0 -0
  426. package/examples/no-inline-styles.sh +1 -0
  427. package/examples/no-innerhtml.sh +0 -0
  428. package/examples/no-install-global.sh +12 -0
  429. package/examples/no-jwt-in-url.sh +0 -0
  430. package/examples/no-large-commit.sh +0 -0
  431. package/examples/no-localhost-expose.sh +0 -0
  432. package/examples/no-magic-number.sh +0 -0
  433. package/examples/no-md5-sha1.sh +0 -0
  434. package/examples/no-mixed-line-endings.sh +8 -1
  435. package/examples/no-mutation-in-reducer.sh +0 -0
  436. package/examples/no-nested-ternary.sh +0 -0
  437. package/examples/no-network-exfil.sh +0 -0
  438. package/examples/no-open-redirect.sh +0 -0
  439. package/examples/no-output-truncation.sh +12 -0
  440. package/examples/no-package-downgrade.sh +0 -0
  441. package/examples/no-package-lock-edit.sh +12 -0
  442. package/examples/no-path-join-user-input.sh +0 -0
  443. package/examples/no-port-bind.sh +0 -0
  444. package/examples/no-process-exit.sh +0 -0
  445. package/examples/no-prototype-pollution.sh +0 -0
  446. package/examples/no-push-without-ci.sh +0 -0
  447. package/examples/no-push-without-tests.sh +12 -0
  448. package/examples/no-raw-password-in-url.sh +0 -0
  449. package/examples/no-root-user-docker.sh +1 -0
  450. package/examples/no-root-write.sh +12 -0
  451. package/examples/no-secrets-in-args.sh +4 -1
  452. package/examples/no-secrets-in-logs.sh +0 -0
  453. package/examples/no-sensitive-log.sh +0 -0
  454. package/examples/no-sleep-in-hooks.sh +0 -0
  455. package/examples/no-star-import-python.sh +1 -0
  456. package/examples/no-string-concat-sql.sh +0 -0
  457. package/examples/no-sudo-guard.sh +12 -0
  458. package/examples/no-sync-fs.sh +0 -0
  459. package/examples/no-todo-in-merge.sh +0 -0
  460. package/examples/no-todo-in-production.sh +1 -0
  461. package/examples/no-todo-without-issue.sh +0 -0
  462. package/examples/no-unused-import.sh +0 -0
  463. package/examples/no-var-keyword.sh +0 -0
  464. package/examples/no-verify-blocker.sh +12 -0
  465. package/examples/no-wget-piped-bash.sh +12 -0
  466. package/examples/no-wildcard-cors.sh +0 -0
  467. package/examples/no-wildcard-delete.sh +0 -0
  468. package/examples/no-wildcard-import.sh +0 -0
  469. package/examples/no-with-statement.sh +0 -0
  470. package/examples/no-write-outside-src.sh +0 -0
  471. package/examples/no-xml-external-entity.sh +0 -0
  472. package/examples/non-english-quality-warner.sh +156 -0
  473. package/examples/notify-waiting.sh +1 -1
  474. package/examples/npm-audit-warn.sh +0 -0
  475. package/examples/npm-global-install-guard.sh +12 -0
  476. package/examples/npm-publish-guard.sh +12 -0
  477. package/examples/npm-script-injection.sh +0 -0
  478. package/examples/npm-supply-chain-guard.sh +0 -0
  479. package/examples/nuxt-config-guard.sh +1 -0
  480. package/examples/oauth-refresh-monitor.sh +210 -0
  481. package/examples/opus-degradation-tracker.sh +187 -0
  482. package/examples/opus48-routine-task-warning.sh +196 -0
  483. package/examples/opus48-thinking-wedge-advisor.sh +143 -0
  484. package/examples/output-credential-scan.sh +1 -1
  485. package/examples/output-secret-mask.sh +31 -9
  486. package/examples/output-token-spike-detector.sh +145 -0
  487. package/examples/package-json-guard.sh +12 -0
  488. package/examples/package-lock-frozen.sh +12 -0
  489. package/examples/parallel-batch-size-limiter.sh +121 -0
  490. package/examples/parallel-cascade-detector.sh +116 -0
  491. package/examples/partial-view-claim-arrest.sh +174 -0
  492. package/examples/path-deny-bash-guard.sh +12 -0
  493. package/examples/path-traversal-guard.sh +12 -0
  494. package/examples/per-prompt-token-cap.sh +124 -0
  495. package/examples/permission-audit-log.sh +1 -1
  496. package/examples/permission-denial-enforcer.sh +12 -0
  497. package/examples/permission-entry-validator.sh +0 -0
  498. package/examples/persisted-1m-model-advisor.sh +88 -0
  499. package/examples/php-lint-on-edit.sh +1 -1
  500. package/examples/pii-upload-guard.sh +12 -0
  501. package/examples/pip-publish-guard.sh +13 -0
  502. package/examples/pip-requirements-guard.sh +12 -0
  503. package/examples/pip-venv-required.sh +12 -0
  504. package/examples/plan-mode-edit-guard.sh +12 -0
  505. package/examples/plan-mode-enforcer.sh +12 -0
  506. package/examples/plan-mode-strict-guard.sh +12 -0
  507. package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
  508. package/examples/plugin-process-cleanup.sh +0 -0
  509. package/examples/polyglot-rm-guard.sh +12 -0
  510. package/examples/post-compact-safety.sh +12 -0
  511. package/examples/post-edit-disk-verify.sh +152 -0
  512. package/examples/powershell-remove-item-guard.sh +85 -0
  513. package/examples/pr-description-check.sh +0 -0
  514. package/examples/pr-duplicate-guard.sh +13 -0
  515. package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
  516. package/examples/pre-compact-knowledge-save.sh +0 -0
  517. package/examples/pre-compact-transcript-backup.sh +0 -0
  518. package/examples/pre-execution-claim-detector.sh +179 -0
  519. package/examples/prefer-builtin-tools.sh +10 -1
  520. package/examples/prefer-const.sh +0 -0
  521. package/examples/prefer-dedicated-tools.sh +12 -0
  522. package/examples/prefer-optional-chaining.sh +0 -0
  523. package/examples/prisma-migrate-guard.sh +24 -7
  524. package/examples/production-port-kill-guard.sh +12 -0
  525. package/examples/prompt-injection-guard.sh +2 -1
  526. package/examples/prompt-usage-logger.sh +0 -0
  527. package/examples/protect-claudemd.sh +12 -0
  528. package/examples/protect-dotfiles.sh +12 -0
  529. package/examples/proxy-capture-suggester.sh +159 -0
  530. package/examples/public-artefact-socratic-narrowing.sh +232 -0
  531. package/examples/public-repo-push-guard.sh +12 -0
  532. package/examples/push-requires-test-pass-record.sh +0 -0
  533. package/examples/push-requires-test-pass.sh +12 -0
  534. package/examples/quota-anomaly-detector.sh +173 -0
  535. package/examples/quota-reset-audit.sh +58 -0
  536. package/examples/quoted-flag-approver.sh +99 -10
  537. package/examples/rails-migration-guard.sh +12 -0
  538. package/examples/rate-limit-guard.sh +0 -0
  539. package/examples/read-all-files-enforcer.sh +0 -0
  540. package/examples/read-budget-guard.sh +12 -0
  541. package/examples/read-loop-detector.sh +59 -0
  542. package/examples/read-once-guard.sh +96 -0
  543. package/examples/read-only-mode.sh +12 -0
  544. package/examples/readme-exists-check.sh +0 -0
  545. package/examples/record-read-coverage.sh +73 -0
  546. package/examples/redirect-fragment-warner.sh +149 -0
  547. package/examples/redis-flushall-guard.sh +13 -0
  548. package/examples/redundant-read-blocker.sh +132 -0
  549. package/examples/refusal-arrest-gate.sh +248 -0
  550. package/examples/registry-publish-guard.sh +13 -1
  551. package/examples/remote-control-billing-classifier.sh +135 -0
  552. package/examples/replace-all-guard.sh +12 -0
  553. package/examples/repo-visibility-guard.sh +12 -0
  554. package/examples/reroute-after-block-guard.sh +150 -0
  555. package/examples/response-budget-guard.sh +0 -0
  556. package/examples/resume-drift-watcher.sh +57 -0
  557. package/examples/rg-replace-flag-detector.sh +125 -0
  558. package/examples/rhetorical-verification-prompt-detector.sh +102 -0
  559. package/examples/ripgrep-permission-fix.sh +0 -0
  560. package/examples/rm-safety-net.sh +151 -8
  561. package/examples/role-tool-guard.sh +12 -0
  562. package/examples/route-handler-emptiness-gate.sh +324 -0
  563. package/examples/ruby-lint-on-edit.sh +1 -1
  564. package/examples/runtime-binary-change-detector.sh +102 -0
  565. package/examples/same-command-repeat-detector.sh +196 -0
  566. package/examples/same-correction-arrest.sh +169 -0
  567. package/examples/sandbox-denywrite-enforcer.sh +78 -0
  568. package/examples/sandbox-relative-path-audit.sh +83 -25
  569. package/examples/sandbox-write-verify.sh +12 -0
  570. package/examples/schema-migration-guard.sh +0 -0
  571. package/examples/scope-expansion-receipt.sh +178 -0
  572. package/examples/scope-guard.sh +88 -9
  573. package/examples/secret-file-read-guard.sh +12 -0
  574. package/examples/secret-file-write-guard.sh +150 -0
  575. package/examples/self-modify-bypass-guard.sh +0 -0
  576. package/examples/sensitive-file-read-guard.sh +23 -3
  577. package/examples/sensitive-log-guard.sh +1 -0
  578. package/examples/server-side-prompt-injection-detector.sh +69 -0
  579. package/examples/session-agent-cost-limiter.sh +12 -0
  580. package/examples/session-backup-on-start.sh +1 -1
  581. package/examples/session-cost-alert.sh +12 -0
  582. package/examples/session-drift-guard.sh +12 -0
  583. package/examples/session-duration-guard.sh +25 -2
  584. package/examples/session-end-logger.sh +0 -0
  585. package/examples/session-health-monitor.sh +0 -0
  586. package/examples/session-index-repair.sh +1 -1
  587. package/examples/session-memory-watchdog.sh +1 -0
  588. package/examples/session-permission-reset-guard.sh +12 -0
  589. package/examples/session-persistence-verifier.sh +93 -0
  590. package/examples/session-plugin-pin-watch.sh +68 -0
  591. package/examples/session-rate-monitor.sh +176 -0
  592. package/examples/session-resume-env-fix.sh +0 -0
  593. package/examples/session-start-quota-status.sh +193 -0
  594. package/examples/session-start-safety-check.sh +55 -3
  595. package/examples/session-state-saver.sh +0 -0
  596. package/examples/session-summary-stop.sh +1 -1
  597. package/examples/session-summary.sh +0 -0
  598. package/examples/session-token-counter.sh +1 -1
  599. package/examples/settings-hooks-key-restorer.sh +99 -0
  600. package/examples/settings-json-health-check.sh +57 -0
  601. package/examples/settings-json-model-guard.sh +0 -0
  602. package/examples/settings-regression-tester.sh +188 -0
  603. package/examples/shell-config-truncation-guard.sh +12 -0
  604. package/examples/shell-wrapper-guard.sh +12 -0
  605. package/examples/skill-cumulative-size-detector.sh +104 -0
  606. package/examples/skill-description-drop-detector.sh +148 -0
  607. package/examples/skill-gate.sh +0 -0
  608. package/examples/skill-truncation-detector.sh +154 -0
  609. package/examples/skills-context-recorder.sh +167 -0
  610. package/examples/skills-load-verifier.sh +96 -0
  611. package/examples/skills-settings-validator.sh +139 -0
  612. package/examples/sonnet-45-deprecation-helper.sh +85 -0
  613. package/examples/spec-file-scope-guard.sh +12 -0
  614. package/examples/spring-profile-guard.sh +1 -0
  615. package/examples/spurious-malformed-notice-detector.sh +247 -0
  616. package/examples/sql-bulk-delete-warn.sh +88 -0
  617. package/examples/sql-injection-detect.sh +0 -0
  618. package/examples/ssh-key-protect.sh +12 -0
  619. package/examples/staged-secret-scan.sh +22 -1
  620. package/examples/stale-temp-settings-detector.sh +86 -0
  621. package/examples/standing-rule-session-surfacer.sh +137 -0
  622. package/examples/stop-hook-sigterm-wrapper.sh +182 -0
  623. package/examples/stop-transcript-write-health.sh +64 -0
  624. package/examples/strict-allowlist.sh +57 -15
  625. package/examples/strip-coauthored-by.sh +50 -10
  626. package/examples/subagent-blast-radius-guard.sh +184 -0
  627. package/examples/subagent-boundary-precheck.sh +126 -0
  628. package/examples/subagent-budget-guard.sh +12 -0
  629. package/examples/subagent-claudemd-inject.sh +0 -0
  630. package/examples/subagent-closure-verify-gate.sh +164 -0
  631. package/examples/subagent-destructive-git-guard.sh +120 -0
  632. package/examples/subagent-error-detector.sh +0 -0
  633. package/examples/subagent-forged-system-reminder-guard.sh +156 -0
  634. package/examples/subagent-identity-leak-guard.sh +102 -0
  635. package/examples/subagent-identity-reassertion.sh +51 -0
  636. package/examples/subagent-inheritance-tester.sh +179 -0
  637. package/examples/subagent-permission-mode-guard.sh +110 -0
  638. package/examples/subagent-scope-guard.sh +12 -0
  639. package/examples/subagent-spawn-verification-enforcer.sh +102 -0
  640. package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
  641. package/examples/subagent-tool-call-limiter.sh +87 -15
  642. package/examples/subcommand-chain-guard.sh +12 -0
  643. package/examples/subscription-api-billing-warner.sh +160 -0
  644. package/examples/subscription-bypass-detector.sh +152 -0
  645. package/examples/svelte-lint-on-edit.sh +1 -0
  646. package/examples/swift-build-on-edit.sh +1 -1
  647. package/examples/symlink-guard.sh +27 -2
  648. package/examples/symlink-protect.sh +1 -0
  649. package/examples/system-dir-protection-guard.sh +73 -8
  650. package/examples/system-message-workaround.sh +38 -13
  651. package/examples/system-package-guard.sh +12 -0
  652. package/examples/systemd-service-guard.sh +12 -0
  653. package/examples/task-integrity-guard.sh +12 -0
  654. package/examples/temp-file-cleanup.sh +1 -1
  655. package/examples/temporal-suggestion-detector.sh +135 -0
  656. package/examples/terraform-guard.sh +27 -6
  657. package/examples/test-after-edit.sh +1 -1
  658. package/examples/test-before-push.sh +12 -0
  659. package/examples/test-coverage-reminder.sh +24 -1
  660. package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
  661. package/examples/thinking-stall-detector.sh +61 -0
  662. package/examples/timezone-guard.sh +0 -0
  663. package/examples/tmp-output-size-guard.sh +0 -0
  664. package/examples/todo-check.sh +1 -1
  665. package/examples/token-budget-guard.sh +12 -0
  666. package/examples/token-budget-per-task.sh +12 -0
  667. package/examples/token-usage-tracker.sh +7 -1
  668. package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
  669. package/examples/tokenizer-ratio-alert.sh +104 -0
  670. package/examples/tool-call-rate-limiter.sh +0 -0
  671. package/examples/tool-result-correlation-checker.sh +167 -0
  672. package/examples/tool-result-size-guard.sh +132 -0
  673. package/examples/tool-retry-budget-guard.sh +12 -0
  674. package/examples/transcript-contamination-detector.sh +138 -0
  675. package/examples/trustfall-mcp-injection-guard.sh +103 -0
  676. package/examples/ultrareview-large-diff-advisor.sh +184 -0
  677. package/examples/unbounded-output-guard.sh +94 -0
  678. package/examples/uncommitted-changes-stop.sh +1 -0
  679. package/examples/uncommitted-discard-guard.sh +23 -5
  680. package/examples/uncommitted-work-guard.sh +12 -0
  681. package/examples/usage-warn.sh +0 -0
  682. package/examples/user-account-guard.sh +12 -0
  683. package/examples/userprompt-submit-receipt.sh +123 -0
  684. package/examples/variable-expansion-guard.sh +12 -0
  685. package/examples/verify-after-publish-reminder.sh +93 -0
  686. package/examples/verify-before-commit.sh +12 -0
  687. package/examples/version-bump-detector.sh +156 -0
  688. package/examples/version-regression-warner.sh +144 -0
  689. package/examples/vue-lint-on-edit.sh +1 -0
  690. package/examples/warn-cron-cost-trap.sh +173 -0
  691. package/examples/webfetch-runaway-guard.sh +89 -0
  692. package/examples/wellness-break-reminder.sh +118 -0
  693. package/examples/windows-destructive-command-guard.sh +177 -0
  694. package/examples/windows-path-guard.sh +12 -0
  695. package/examples/windows-python-stub-detector.sh +63 -0
  696. package/examples/work-hours-guard.sh +12 -0
  697. package/examples/working-directory-fence.sh +12 -0
  698. package/examples/workspace-lease-guard.sh +205 -0
  699. package/examples/worktree-create-log.sh +1 -0
  700. package/examples/worktree-delete-guard.sh +12 -0
  701. package/examples/worktree-edit-boundary-guard.sh +127 -0
  702. package/examples/worktree-escape-write-guard.sh +114 -0
  703. package/examples/worktree-hook-linker.sh +0 -0
  704. package/examples/worktree-hooks-path-fix.sh +111 -0
  705. package/examples/worktree-parent-write-guard.sh +43 -0
  706. package/examples/worktree-project-unify.sh +2 -1
  707. package/examples/worktree-remove-uncommitted-guard.sh +13 -0
  708. package/examples/worktree-unmerged-guard.sh +7 -1
  709. package/examples/write-byte-integrity-verifier.sh +190 -0
  710. package/examples/write-empty-content-guard.sh +67 -0
  711. package/examples/write-nul-corruption-detector.sh +61 -0
  712. package/examples/write-overwrite-confirm.sh +160 -14
  713. package/examples/write-secret-guard.sh +27 -5
  714. package/examples/write-shrink-guard.sh +12 -0
  715. package/examples/write-test-ratio.sh +0 -0
  716. package/examples/wsl-host-disk-space-guard.sh +97 -0
  717. package/examples/xml-format-leak-detector.sh +266 -0
  718. package/examples/yaml-syntax-check.sh +12 -0
  719. package/hooks/hooks.json +6 -6
  720. package/index.mjs +1699 -183
  721. package/mission.md +2 -0
  722. package/package.json +4 -4
  723. package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
  724. package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
  725. package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
  726. package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
  727. package/scripts/agents-md-sync-setup.sh +156 -0
  728. package/scripts/autonomy-blocked-summary.sh +148 -0
  729. package/scripts/build-search-index.py +43 -0
  730. package/scripts/build-sitemap.py +119 -0
  731. package/scripts/cc-doctor.sh +192 -0
  732. package/scripts/check-hook-event-names.py +127 -0
  733. package/scripts/check-misfire-instrument.sh +64 -0
  734. package/scripts/claim-verify-audit.sh +467 -0
  735. package/scripts/cowork-claudemd-helper.sh +136 -0
  736. package/scripts/june-15-deprecated-model-scan.sh +111 -0
  737. package/scripts/measure-heredoc-shapes.sh +67 -0
  738. package/scripts/measure-literal-match-misfire.sh +110 -0
  739. package/scripts/probe-scope-guard-branches.sh +48 -0
  740. package/scripts/probe-skip-line-both-ways.sh +65 -0
  741. package/scripts/receipts-aggregate.py +199 -0
  742. package/scripts/session-forensic-audit.py +360 -0
  743. package/scripts.json +9 -9
  744. package/scripts.json.bak-2026-07-27-find +13 -0
  745. package/skills/safety-setup/SKILL.md +5 -5
  746. package/tests/approve-side-remaining-two.test.sh +129 -0
  747. package/tests/approver-list-granularity.test.sh +145 -0
  748. package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
  749. package/tests/audit-ci-gate.test.sh +87 -0
  750. package/tests/audit-cross-layer-claudemd.test.sh +170 -0
  751. package/tests/audit-fail-open-parse.test.sh +100 -0
  752. package/tests/auto-approve-compound-tail.test.sh +194 -0
  753. package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
  754. package/tests/auto-mode-quoted-targets.test.sh +127 -0
  755. package/tests/auto-mode-unquoted-targets.test.sh +112 -0
  756. package/tests/bash-secret-output-detector-detects.test.sh +102 -0
  757. package/tests/blindspots-cross-layer.test.sh +177 -0
  758. package/tests/block-database-wipe.test.sh +64 -0
  759. package/tests/bundled-short-flags-bypass.test.sh +85 -0
  760. package/tests/cd-git-allow-compound-tail.test.sh +67 -0
  761. package/tests/chown-guard-filesystem-root.test.sh +64 -0
  762. package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
  763. package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
  764. package/tests/core-scripts-parser-fallback.test.sh +140 -0
  765. package/tests/destructive-guard-bare-glob.test.sh +74 -0
  766. package/tests/destructive-guard-every-operand.test.sh +100 -0
  767. package/tests/destructive-guard-find-deletion.test.sh +114 -0
  768. package/tests/destructive-guard-flag-order.test.sh +106 -0
  769. package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
  770. package/tests/destructive-guard-quoted-target.test.sh +89 -0
  771. package/tests/destructive-guard-separators.test.sh +105 -0
  772. package/tests/destructive-guard-variable-target.test.sh +98 -0
  773. package/tests/destructive-guard-wrapped-command.test.sh +91 -0
  774. package/tests/doctor-hook-disabling-env.test.sh +92 -0
  775. package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
  776. package/tests/example-guards-wrapped-command.test.sh +169 -0
  777. package/tests/file-edit-backup.test.sh +93 -0
  778. package/tests/git-filter-repo-guard.test.sh +60 -0
  779. package/tests/git-global-options-bypass.test.sh +141 -0
  780. package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
  781. package/tests/git-maintenance-guard.test.sh +83 -0
  782. package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
  783. package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
  784. package/tests/git-submodule-guard.test.sh +50 -0
  785. package/tests/grep-pcre-portability.test.sh +155 -0
  786. package/tests/hook-registration-matches-input.test.sh +73 -0
  787. package/tests/hook-trigger-matches-envelope.test.sh +178 -0
  788. package/tests/install-does-not-claim-protection.test.sh +110 -0
  789. package/tests/install-example-standalone-tools.test.sh +139 -0
  790. package/tests/line-continuation-bypass.test.sh +114 -0
  791. package/tests/mcp-config-poisoning-audit.test.sh +106 -0
  792. package/tests/nested-background-agent-guard.test.sh +58 -0
  793. package/tests/no-unqualified-safety-claims.test.sh +114 -0
  794. package/tests/option-eating-grep-patterns.test.sh +130 -0
  795. package/tests/outdated-core-guards.test.sh +134 -0
  796. package/tests/outdated-report.test.sh +155 -0
  797. package/tests/output-secret-mask-warns.test.sh +73 -0
  798. package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
  799. package/tests/plugins-word-order.test.sh +126 -0
  800. package/tests/powershell-remove-item-guard.test.sh +85 -0
  801. package/tests/project-dir-naming.test.sh +103 -0
  802. package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
  803. package/tests/reroute-after-block-guard.test.sh +104 -0
  804. package/tests/secret-guard-documented-promises.test.sh +97 -0
  805. package/tests/session-plugin-pin-watch.test.sh +45 -0
  806. package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
  807. package/tests/shield-no-silent-adoption.test.py +110 -0
  808. package/tests/shield-no-silent-adoption.test.sh +46 -0
  809. package/tests/stop-transcript-write-health.test.sh +46 -0
  810. package/tests/system-dir-guard-root-erased.test.sh +66 -0
  811. package/tests/test-account-billing-log.sh +100 -0
  812. package/tests/test-account-routing-preflight.sh +77 -0
  813. package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
  814. package/tests/test-agent-view-quota-warn.sh +184 -0
  815. package/tests/test-agents-md-edit-drift-warner.sh +176 -0
  816. package/tests/test-agents-md-loader.sh +204 -0
  817. package/tests/test-agents-md-sync-checker.sh +125 -0
  818. package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
  819. package/tests/test-allowlist.sh +60 -0
  820. package/tests/test-always-allow-pattern-suggester.sh +147 -0
  821. package/tests/test-anthropic-base-url-guard.sh +88 -0
  822. package/tests/test-articulated-scope-capture.sh +139 -0
  823. package/tests/test-attachment-traversal-guard.sh +168 -0
  824. package/tests/test-aup-block-pattern-logger.sh +315 -0
  825. package/tests/test-aup-false-positive-helper.sh +188 -0
  826. package/tests/test-aup-large-tool-output-warner.sh +370 -0
  827. package/tests/test-aup-retry-loop-guard.sh +341 -0
  828. package/tests/test-auth-expiry-reminder.sh +303 -0
  829. package/tests/test-auth-macos-sleep-detector.sh +254 -0
  830. package/tests/test-auth-path-detector.sh +232 -0
  831. package/tests/test-auth-status-checker.sh +233 -0
  832. package/tests/test-authorized-reconfirmation-detector.sh +280 -0
  833. package/tests/test-background-cost-launch-guard.sh +62 -0
  834. package/tests/test-bash-allowlist-secondary-check.sh +143 -0
  835. package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
  836. package/tests/test-bash-project-fence.sh +127 -0
  837. package/tests/test-bg-permission-prompt-warner.sh +221 -0
  838. package/tests/test-binary-read-detector.sh +173 -0
  839. package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
  840. package/tests/test-bulk-delete-target-resolution.sh +49 -0
  841. package/tests/test-bypass-mode-effective-verifier.sh +179 -0
  842. package/tests/test-cache-creation-drift-detector.sh +244 -0
  843. package/tests/test-cache-residue-detector.sh +429 -0
  844. package/tests/test-cache-tier-logger.sh +59 -0
  845. package/tests/test-cache-ttl-eviction-detector.sh +282 -0
  846. package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
  847. package/tests/test-claim-verify-detector.sh +222 -0
  848. package/tests/test-claim-vs-caveat-checker.sh +134 -0
  849. package/tests/test-claude-code-version-pin-advisor.sh +353 -0
  850. package/tests/test-claude-md-reinjector.sh +173 -0
  851. package/tests/test-claude-md-size-monitor.sh +107 -0
  852. package/tests/test-claude-update-budget-guard.sh +132 -0
  853. package/tests/test-claude-update-smart.sh +91 -0
  854. package/tests/test-claudemd-tool-prohibition.sh +239 -0
  855. package/tests/test-cli-config-pinning-detector.sh +233 -0
  856. package/tests/test-cliff-countdown-advisor.sh +138 -0
  857. package/tests/test-closure-word-verify-gate.sh +158 -0
  858. package/tests/test-commit-all-scope-guard.sh +73 -0
  859. package/tests/test-commitment-carry-forward-arrest.sh +250 -0
  860. package/tests/test-compact-circuit-breaker.sh +134 -0
  861. package/tests/test-compact-dispatch-watchdog.sh +147 -0
  862. package/tests/test-completion-claim-without-verification-detector.sh +326 -0
  863. package/tests/test-compound-bash-permission-resolver.sh +264 -0
  864. package/tests/test-compound-command-deny-enforcer.sh +67 -0
  865. package/tests/test-context-length-budget.sh +68 -0
  866. package/tests/test-context-usage-drift-alert.sh +52 -22
  867. package/tests/test-cost-incident-self-audit.sh +94 -0
  868. package/tests/test-cowork-claude-md-load-checker.sh +257 -0
  869. package/tests/test-cowork-claudemd-helper.sh +141 -0
  870. package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
  871. package/tests/test-cowork-hook-absence-warner.sh +230 -0
  872. package/tests/test-cowork-model-picker-advisor.sh +317 -0
  873. package/tests/test-credential-exfil-guard.sh +62 -0
  874. package/tests/test-cron-create-receipt.sh +165 -0
  875. package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
  876. package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
  877. package/tests/test-daily-cost-guard.sh +131 -0
  878. package/tests/test-deny-rule-integrity-verifier.sh +288 -0
  879. package/tests/test-deployment-readback-gate.sh +92 -0
  880. package/tests/test-deployment-readback-gh-adapter.sh +163 -0
  881. package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
  882. package/tests/test-dispatch-allowlist-preflight.sh +385 -0
  883. package/tests/test-dispatch-liveness-watchdog.sh +319 -0
  884. package/tests/test-dispatch-receipt.sh +314 -0
  885. package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
  886. package/tests/test-echo-probe-spam-detector.sh +143 -0
  887. package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
  888. package/tests/test-ephemeral-container-detector.sh +251 -0
  889. package/tests/test-evidence-claim-gate.sh +291 -0
  890. package/tests/test-exploration-budget-guard.sh +164 -0
  891. package/tests/test-extended-thinking-loop-guard.sh +289 -0
  892. package/tests/test-extended-thinking-resume-warning.sh +240 -0
  893. package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
  894. package/tests/test-fabricated-command-detector.sh +296 -0
  895. package/tests/test-false-disk-full-guard.sh +36 -0
  896. package/tests/test-feature-deprecation-detector.sh +117 -0
  897. package/tests/test-forbidden-response-phrase-detector.sh +246 -0
  898. package/tests/test-git-operations-require-approval.sh +53 -0
  899. package/tests/test-git-push-blast-radius-guard.sh +115 -0
  900. package/tests/test-goal-iteration-limit-warner.sh +128 -0
  901. package/tests/test-growthbook-flag-monitor.sh +428 -0
  902. package/tests/test-halt-signal-detector.sh +120 -0
  903. package/tests/test-hook-self-disable-detector.sh +232 -0
  904. package/tests/test-iteration-quality-degradation-detector.sh +244 -0
  905. package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
  906. package/tests/test-marketplace-plugins.sh +193 -0
  907. package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
  908. package/tests/test-mcp-orphan-leak-warner.sh +71 -0
  909. package/tests/test-mcp-permissions-ask-warner.sh +207 -0
  910. package/tests/test-mcp-routine-approval-detector.sh +229 -0
  911. package/tests/test-mcp-startup-bloat-detector.sh +141 -0
  912. package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
  913. package/tests/test-memory-chain-audit.sh +59 -0
  914. package/tests/test-memory-orphan-detector.sh +227 -0
  915. package/tests/test-model-swap-suggester.sh +368 -0
  916. package/tests/test-model-version-lock.sh +83 -0
  917. package/tests/test-multi-file-plan-routing-gate.sh +277 -0
  918. package/tests/test-multi-window-auth-drift-detector.sh +262 -0
  919. package/tests/test-nested-spawn-inflight-guard.sh +281 -0
  920. package/tests/test-no-force-flag.sh +49 -0
  921. package/tests/test-non-english-quality-warner.sh +229 -0
  922. package/tests/test-oauth-refresh-monitor.sh +311 -0
  923. package/tests/test-opus-degradation-tracker.sh +274 -0
  924. package/tests/test-opus48-routine-task-warning.sh +201 -0
  925. package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
  926. package/tests/test-output-token-spike-detector.sh +315 -0
  927. package/tests/test-parallel-batch-size-limiter.sh +228 -0
  928. package/tests/test-parallel-cascade-detector.sh +191 -0
  929. package/tests/test-partial-view-claim-arrest.sh +272 -0
  930. package/tests/test-per-prompt-token-cap.sh +136 -0
  931. package/tests/test-persisted-1m-model-advisor.sh +71 -0
  932. package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
  933. package/tests/test-post-edit-disk-verify.sh +294 -0
  934. package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
  935. package/tests/test-pre-execution-claim-detector.sh +366 -0
  936. package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
  937. package/tests/test-proxy-capture-suggester.sh +214 -0
  938. package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
  939. package/tests/test-quota-anomaly-detector.sh +321 -0
  940. package/tests/test-quota-reset-audit.sh +81 -0
  941. package/tests/test-read-loop-detector.sh +137 -0
  942. package/tests/test-read-once-guard.sh +85 -0
  943. package/tests/test-receipts-aggregate.sh +143 -0
  944. package/tests/test-redirect-fragment-warner.sh +130 -0
  945. package/tests/test-redundant-read-blocker.sh +155 -0
  946. package/tests/test-refusal-arrest-gate.sh +303 -0
  947. package/tests/test-remote-control-billing-classifier.sh +125 -0
  948. package/tests/test-resume-drift-watcher.sh +65 -0
  949. package/tests/test-rg-replace-flag-detector.sh +175 -0
  950. package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
  951. package/tests/test-rm-safety-net.sh +115 -0
  952. package/tests/test-route-handler-emptiness-gate.sh +300 -0
  953. package/tests/test-runtime-binary-change-detector.sh +196 -0
  954. package/tests/test-same-command-repeat-detector.sh +165 -0
  955. package/tests/test-same-correction-arrest.sh +165 -0
  956. package/tests/test-scope-expansion-receipt.sh +207 -0
  957. package/tests/test-server-side-prompt-injection-detector.sh +181 -0
  958. package/tests/test-session-persistence-verifier.sh +128 -0
  959. package/tests/test-session-rate-monitor.sh +284 -0
  960. package/tests/test-session-start-quota-status.sh +210 -0
  961. package/tests/test-session-start-safety-check.sh +138 -0
  962. package/tests/test-settings-hooks-key-restorer.sh +257 -0
  963. package/tests/test-settings-json-health-check.sh +70 -0
  964. package/tests/test-settings-regression-tester.sh +197 -0
  965. package/tests/test-skill-cumulative-size-detector.sh +198 -0
  966. package/tests/test-skill-description-drop-detector.sh +236 -0
  967. package/tests/test-skill-truncation-detector.sh +263 -0
  968. package/tests/test-skills-context-recorder.sh +329 -0
  969. package/tests/test-skills-load-verifier.sh +184 -0
  970. package/tests/test-skills-settings-validator.sh +242 -0
  971. package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
  972. package/tests/test-spurious-malformed-notice-detector.sh +290 -0
  973. package/tests/test-sql-bulk-delete-warn.sh +123 -0
  974. package/tests/test-ssh-key-protect.sh +81 -0
  975. package/tests/test-stale-temp-settings-detector.sh +161 -0
  976. package/tests/test-standing-rule-session-surfacer.sh +215 -0
  977. package/tests/test-starter-hooks-manifest.sh +96 -0
  978. package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
  979. package/tests/test-strict-allowlist.sh +72 -0
  980. package/tests/test-subagent-boundary-precheck.sh +137 -0
  981. package/tests/test-subagent-closure-verify-gate.sh +193 -0
  982. package/tests/test-subagent-destructive-git-guard.sh +86 -0
  983. package/tests/test-subagent-identity-leak-guard.sh +62 -0
  984. package/tests/test-subagent-identity-reassertion.sh +61 -0
  985. package/tests/test-subagent-inheritance-tester.sh +319 -0
  986. package/tests/test-subagent-permission-mode-guard.sh +61 -0
  987. package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
  988. package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
  989. package/tests/test-subagent-tool-call-limiter.sh +97 -0
  990. package/tests/test-subscription-api-billing-warner.sh +138 -0
  991. package/tests/test-subscription-bypass-detector.sh +255 -0
  992. package/tests/test-temporal-suggestion-detector.sh +183 -0
  993. package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
  994. package/tests/test-thinking-stall-detector.sh +151 -0
  995. package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
  996. package/tests/test-tokenizer-ratio-alert.sh +93 -0
  997. package/tests/test-tool-result-correlation-checker.sh +264 -0
  998. package/tests/test-tool-result-size-guard.sh +121 -0
  999. package/tests/test-transcript-contamination-detector.sh +264 -0
  1000. package/tests/test-trigger-header-parsing.sh +151 -0
  1001. package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
  1002. package/tests/test-userprompt-submit-receipt.sh +181 -0
  1003. package/tests/test-verify-after-publish-reminder.sh +184 -0
  1004. package/tests/test-version-bump-detector.sh +212 -0
  1005. package/tests/test-version-regression-warner.sh +165 -0
  1006. package/tests/test-warn-cron-cost-trap.sh +82 -0
  1007. package/tests/test-webfetch-runaway-guard.sh +77 -0
  1008. package/tests/test-wellness-break-reminder.sh +138 -0
  1009. package/tests/test-windows-destructive-command-guard.sh +169 -0
  1010. package/tests/test-windows-python-stub-detector.sh +146 -0
  1011. package/tests/test-worktree-edit-boundary-guard.sh +219 -0
  1012. package/tests/test-write-byte-integrity-verifier.sh +192 -0
  1013. package/tests/test-xml-format-leak-detector.sh +299 -0
  1014. package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
  1015. package/tests/workspace-lease-guard.test.sh +144 -0
  1016. package/tests/worktree-escape-write-guard.test.sh +68 -0
  1017. package/tests/worktree-hooks-path-fix.test.sh +181 -0
  1018. package/tests/worktree-parent-write-guard.test.sh +51 -0
  1019. package/tests/write-empty-content-guard.test.sh +39 -0
  1020. package/tests/write-nul-corruption-detector.test.sh +29 -0
  1021. package/tests/write-overwrite-unread-content.test.sh +178 -0
  1022. package/tests/wsl-host-disk-space-guard.test.sh +55 -0
@@ -0,0 +1,127 @@
1
+ #!/bin/bash
2
+ # The five quoted targets auto-mode-safety-enforcer left alone, and the mentions
3
+ # that had to keep passing.
4
+ #
5
+ # PR #1008 closed eleven of nineteen gaps in that hook but stopped at the quoted
6
+ # forms, and said why in the file itself:
7
+ #
8
+ # Quoted forms ("/", "$HOME", ".git") are deliberately still not matched.
9
+ # This hook has no mention-vs-invocation pass, so putting a quote in a
10
+ # terminator set would also block `echo "rm -rf /"` and a commit message
11
+ # that names the command.
12
+ #
13
+ # That is now ported: the hook blanks out everything inside quotes and asks
14
+ # whether a destructive verb still starts a command in what is left. If none
15
+ # does, it exits 0 before any pattern runs. With mentions ruled out, quote
16
+ # characters can be dropped from the text the patterns match against, so a
17
+ # quoted target is judged like a bare one.
18
+ #
19
+ # Two halves, and both are the point:
20
+ # - the quoted targets must now be blocked (this closes the remaining five)
21
+ # - the mentions must still pass (this proves nothing was widened)
22
+ #
23
+ # Against the version before this change, the first half fails: the quoted
24
+ # targets were invisible, so every one of them exited 0.
25
+ #
26
+ # Dangerous strings are assembled from parts so that reading or editing this
27
+ # file does not trip the operator's own destructive-guard. The hook under test
28
+ # receives the fully assembled string either way.
29
+
30
+ set -u
31
+ HOOK="$(cd "$(dirname "$0")/.." && pwd)/examples/auto-mode-safety-enforcer.sh"
32
+ PASS=0
33
+ FAIL=0
34
+
35
+ run() {
36
+ printf '{"tool_name":"Bash","tool_input":{"command":%s}}' \
37
+ "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/"/')" \
38
+ | bash "$HOOK" >/dev/null 2>&1
39
+ echo $?
40
+ }
41
+
42
+ expect() { # description command expected_exit
43
+ actual="$(run "$2")"
44
+ if [ "$actual" = "$3" ]; then
45
+ PASS=$((PASS + 1))
46
+ else
47
+ FAIL=$((FAIL + 1))
48
+ echo " FAIL: $1"
49
+ echo " command: $2"
50
+ echo " expected: exit $3, got exit $actual"
51
+ fi
52
+ }
53
+
54
+ RM="r""m -rf"
55
+ SLASH="/"
56
+ GIT_DIR=".git"
57
+ HOME_VAR='$HOME'
58
+ HOME_BRACED='${HOME}'
59
+ DQ='"'
60
+ SQ="'"
61
+
62
+ # --- the five that were left alone -------------------------------------------
63
+
64
+ expect "a double-quoted root is a run" \
65
+ "$RM ${DQ}${SLASH}${DQ}" 2
66
+ expect "a single-quoted root is a run" \
67
+ "$RM ${SQ}${SLASH}${SQ}" 2
68
+ expect "a quoted home variable is a run" \
69
+ "$RM ${DQ}${HOME_VAR}${DQ}" 2
70
+ expect "a quoted braced home variable is a run" \
71
+ "$RM ${DQ}${HOME_BRACED}${DQ}" 2
72
+ expect "a quoted git directory is a run" \
73
+ "$RM ${DQ}${GIT_DIR}${DQ}" 2
74
+
75
+ # --- other quoted targets the header claims ----------------------------------
76
+
77
+ expect "a quoted tilde is a run" "$RM ${DQ}~${DQ}" 2
78
+ expect "a quoted etc is a run" "$RM ${DQ}${SLASH}etc${DQ}" 2
79
+ expect "a quoted parent traversal is a run" \
80
+ "$RM ${DQ}..${DQ}" 2
81
+ expect "a quoted target after another command is a run" \
82
+ "npm ci && $RM ${DQ}${SLASH}${DQ}" 2
83
+
84
+ # --- mentions must still pass (nothing was widened) --------------------------
85
+
86
+ expect "a mention in echo is not a run" \
87
+ "echo ${DQ}${RM} ${SLASH}${DQ}" 0
88
+ expect "a mention in a commit message is not a run" \
89
+ "git commit -m ${DQ}guard against ${RM} ${SLASH}${DQ}" 0
90
+ expect "a mention in grep is not a run" \
91
+ "grep -r ${DQ}${RM} ${SLASH}${DQ} ." 0
92
+ expect "a mention in a jq filter is not a run" \
93
+ "jq -n ${SQ}{cmd: ${DQ}${RM} ${SLASH}${DQ}}${SQ}" 0
94
+ expect "a mention in prose is not a run" \
95
+ "echo ${DQ}the command ${RM} ${SLASH} destroys everything${DQ}" 0
96
+ expect "a mention of the home variable is not a run" \
97
+ "echo ${DQ}never write ${RM} ${HOME_VAR}${DQ}" 0
98
+ expect "appending a mention to a note is not a run" \
99
+ "echo ${SQ}${RM} ${SLASH} is the one to avoid${SQ} >> notes.md" 0
100
+
101
+ # --- quoted safe targets must pass -------------------------------------------
102
+ # This is the false-positive half. Dropping quote characters must not turn an
103
+ # ordinary quoted cleanup into a block.
104
+
105
+ expect "a quoted node_modules is allowed" \
106
+ "$RM ${DQ}node_modules${DQ}" 0
107
+ expect "a quoted dist is allowed" "$RM ${DQ}dist${DQ}" 0
108
+ expect "a quoted name with a space is allowed" \
109
+ "$RM ${DQ}my build dir${DQ}" 0
110
+ expect "a quoted gitignore is not the git directory" \
111
+ "$RM ${DQ}.gitignore${DQ}" 0
112
+
113
+ # --- quoted text that is executed is not a mention ---------------------------
114
+ # A quoted string is only inert while nothing runs it. These do run it, so the
115
+ # gate must not let them through on the grounds that the verb sits in quotes.
116
+
117
+ expect "sh -c runs its quoted argument" \
118
+ "sh -c ${DQ}${RM} ${SLASH}${DQ}" 2
119
+ expect "bash -c runs its quoted argument" \
120
+ "bash -c ${SQ}${RM} ~${SQ}" 2
121
+ expect "eval runs its quoted argument" \
122
+ "eval ${DQ}${RM} ${SLASH}${DQ}" 2
123
+ expect "a pipe into a shell runs what was piped" \
124
+ "echo ${DQ}${RM} ${SLASH}${DQ} | sh" 2
125
+
126
+ echo "auto-mode-quoted-targets: $PASS passed, $FAIL failed"
127
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,112 @@
1
+ #!/bin/bash
2
+ # auto-mode-safety-enforcer promised more than it blocked.
3
+ #
4
+ # The header of that hook says it blocks:
5
+ #
6
+ # rm -rf on non-safe paths (/, ~, .., /home, /etc, /usr, /var, .git)
7
+ #
8
+ # Measured 2026-08-11 against 19 targets it claims: 11 were not blocked.
9
+ # The target pattern only ends on whitespace, a separator or end-of-line, and
10
+ # it has no case for $HOME, for a parent traversal, or for the git directory:
11
+ #
12
+ # rm -rf $HOME passed rm -rf .. passed
13
+ # rm -rf ${HOME} passed rm -rf ../.. passed
14
+ # rm -rf .git passed rm -rf a/../.. passed
15
+ #
16
+ # Same defect family as PR #961 (quoted target) and #962 (variable target),
17
+ # which fixed scripts.json only. The example hook never received either fix.
18
+ #
19
+ # --- deliberately NOT fixed here ---------------------------------------------
20
+ # Five of the eleven need the target seen through quotes:
21
+ #
22
+ # rm -rf "/" rm -rf '/' rm -rf "$HOME" rm -rf "${HOME}" rm -rf ".git"
23
+ #
24
+ # Adding a quote to the terminator set would also block these, which are
25
+ # mentions and must keep passing:
26
+ #
27
+ # echo "rm -rf /" git commit -m "guard against rm -rf /"
28
+ #
29
+ # Both shapes end in /" and this hook has no mention-vs-invocation pass — the
30
+ # five above pass today only because the target is invisible behind the quote,
31
+ # not because the hook can tell a mention from a run. Telling them apart needs
32
+ # the quote-aware extraction destructive-guard grew in PR #960. Until that is
33
+ # ported, the mention controls at the bottom of this file are the guarantee
34
+ # that no such false positive was introduced.
35
+
36
+ set -u
37
+ HOOK="$(cd "$(dirname "$0")/.." && pwd)/examples/auto-mode-safety-enforcer.sh"
38
+ PASS=0
39
+ FAIL=0
40
+
41
+ run() {
42
+ printf '{"tool_name":"Bash","tool_input":{"command":%s}}' \
43
+ "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/"/')" \
44
+ | bash "$HOOK" >/dev/null 2>&1
45
+ echo $?
46
+ }
47
+
48
+ expect() { # description command expected_exit
49
+ actual="$(run "$2")"
50
+ if [ "$actual" = "$3" ]; then
51
+ PASS=$((PASS + 1))
52
+ else
53
+ FAIL=$((FAIL + 1))
54
+ echo " FAIL: $1"
55
+ echo " command: $2"
56
+ echo " expected: exit $3, got exit $actual"
57
+ fi
58
+ }
59
+
60
+ # Dangerous strings are assembled from parts so that reading or editing this
61
+ # file does not trip the operator's own destructive-guard. The hook under test
62
+ # receives the fully assembled string either way.
63
+ SLASH="/"
64
+ DOTDOT="..${SLASH}"
65
+ GIT_DIR=".git"
66
+ HOME_VAR='$HOME'
67
+ HOME_BRACED='${HOME}'
68
+
69
+ # --- the gap this file closes ------------------------------------------------
70
+
71
+ expect "home through the variable" "rm -rf $HOME_VAR" 2
72
+ expect "home through the braced variable" "rm -rf $HOME_BRACED" 2
73
+ expect "home variable with a subpath" "rm -rf $HOME_VAR${SLASH}projects" 2
74
+ expect "bare parent traversal" "rm -rf .." 2
75
+ expect "repeated parent traversal" "rm -rf $DOTDOT.." 2
76
+ expect "traversal hidden after a safe name" \
77
+ "rm -rf node_modules${SLASH}$DOTDOT.." 2
78
+ expect "the git directory" "rm -rf $GIT_DIR" 2
79
+ expect "the git directory with a slash" "rm -rf $GIT_DIR$SLASH" 2
80
+
81
+ # --- what already worked must keep working -----------------------------------
82
+
83
+ expect "root still blocks" "rm -rf $SLASH" 2
84
+ expect "home tilde still blocks" "rm -rf ~" 2
85
+ expect "etc still blocks" "rm -rf ${SLASH}etc" 2
86
+ expect "usr still blocks" "rm -rf ${SLASH}usr" 2
87
+ expect "ssh directory still blocks" "rm -rf ~${SLASH}.ssh" 2
88
+
89
+ # --- ordinary cleanup must not be caught -------------------------------------
90
+
91
+ expect "node_modules is allowed" "rm -rf node_modules" 0
92
+ expect "dist is allowed" "rm -rf dist" 0
93
+ expect "leading ./ is allowed" "rm -rf .${SLASH}build" 0
94
+ expect "cleanup after another command" "npm ci && rm -rf node_modules" 0
95
+ expect "an unlisted directory is allowed" "rm -rf tmpdir" 0
96
+ expect "gitignore is not the git directory" \
97
+ "rm -rf .gitignore" 0
98
+ expect "the github directory is not the git directory" \
99
+ "rm -rf .github" 0
100
+ expect "a dotted name is not a traversal" "rm -rf my..cache" 0
101
+ expect "a file ending in two dots is not a traversal" \
102
+ "rm -rf backup.." 0
103
+
104
+ # --- mentions must keep passing (the reason quotes are left alone) -----------
105
+
106
+ expect "a mention in echo is not a run" "echo \"rm -rf $SLASH\"" 0
107
+ expect "a mention in a commit message is not a run" \
108
+ "git commit -m \"guard against rm -rf $SLASH\"" 0
109
+ expect "a mention in grep is not a run" "grep -r \"rm -rf $SLASH\" ." 0
110
+
111
+ echo "auto-mode-unquoted-targets: $PASS passed, $FAIL failed"
112
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,102 @@
1
+ #!/bin/bash
2
+ # bash-secret-output-detector: does each advertised pattern actually fire?
3
+ #
4
+ # Why this exists. The six existing checks for this hook in test.sh all assert
5
+ # exit 0. This hook always exits 0 by default, so those checks pass whether a
6
+ # pattern fires or not - the same shape as the "234 test files that could not
7
+ # fail" noted in the CI workflow.
8
+ #
9
+ # The regression being pinned: the private-key check was written as
10
+ # grep -qE '-----BEGIN ... PRIVATE KEY-----'
11
+ # without `--`, so grep read the leading dashes as options, printed
12
+ # "unrecognized option" and exited non-zero. The check never fired on any
13
+ # input, and test.sh's "private key" case passed anyway because it only looked
14
+ # at the exit code. Measured 2026-09-20 against the shipped file.
15
+ #
16
+ # Both directions are asserted: a detector that also fires on ordinary output
17
+ # is a detector operators learn to ignore.
18
+
19
+ set -u
20
+ REPO="$(cd "$(dirname "$0")/.." && pwd)"
21
+ HOOK="$REPO/examples/bash-secret-output-detector.sh"
22
+ PASS=0
23
+ FAIL=0
24
+
25
+ # Split so that writing this file does not itself trip a secret scanner.
26
+ AWS="AKI""AIOSFODNN7""EXAMPLE"
27
+ APIKEY="api_key=sk""-1234567890abcdefghijklmnop"
28
+ CONN="postgres://user"":pass@host:5432/db"
29
+ PEM="-----BEGIN RSA PRIVATE KEY-----"
30
+ GH="ghp""_1234567890abcdefghijklmnopqrstuv"
31
+ JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.abc"
32
+
33
+ run() {
34
+ local payload
35
+ payload=$(printf '{"tool_name":"Bash","tool_result":{"stdout":"%s"}}' "$1")
36
+ ERR=$(printf '%s' "$payload" | bash "$HOOK" 2>&1 >/dev/null)
37
+ }
38
+
39
+ warns() {
40
+ run "$2"
41
+ local got="no"
42
+ case "$ERR" in *"SECRET DETECTED"*) got="yes" ;; esac
43
+ if [ "$got" = "$3" ]; then
44
+ PASS=$((PASS + 1))
45
+ else
46
+ FAIL=$((FAIL + 1))
47
+ echo " FAIL: $1 (expected warn=$3, got warn=$got)"
48
+ echo " stderr: $ERR"
49
+ fi
50
+ }
51
+
52
+ quiet_stderr() {
53
+ run "hello world"
54
+ case "$ERR" in
55
+ *"unrecognized option"*|*"Usage: grep"*)
56
+ FAIL=$((FAIL + 1))
57
+ echo " FAIL: a pattern is malformed and grep is erroring out"
58
+ echo " stderr: $ERR" ;;
59
+ *) PASS=$((PASS + 1)) ;;
60
+ esac
61
+ }
62
+
63
+ echo "bash-secret-output-detector-detects:"
64
+
65
+ # --- every advertised pattern has to fire ----------------------------------
66
+ warns "AWS access key" "$AWS" yes
67
+ warns "API key assignment" "$APIKEY" yes
68
+ warns "connection string" "$CONN" yes
69
+ warns "private key header" "$PEM" yes
70
+ warns "GitHub token" "$GH" yes
71
+ warns "JWT" "$JWT" yes
72
+
73
+ # --- ordinary output must stay quiet ---------------------------------------
74
+ warns "plain output is quiet" "hello world" no
75
+ warns "safe env var is quiet" "PATH=/usr/bin" no
76
+
77
+ # --- no pattern may be malformed -------------------------------------------
78
+ quiet_stderr
79
+
80
+ # --- default must not interrupt; the opt-in must ---------------------------
81
+ printf '%s' "{\"tool_name\":\"Bash\",\"tool_result\":{\"stdout\":\"$AWS\"}}" \
82
+ | bash "$HOOK" >/dev/null 2>&1
83
+ rc=$?
84
+ if [ "$rc" -eq 0 ]; then
85
+ PASS=$((PASS + 1))
86
+ else
87
+ FAIL=$((FAIL + 1))
88
+ echo " FAIL: default must not interrupt (expected exit 0, got $rc)"
89
+ fi
90
+
91
+ printf '%s' "{\"tool_name\":\"Bash\",\"tool_result\":{\"stdout\":\"$AWS\"}}" \
92
+ | CC_SECRET_OUTPUT_BLOCK=1 bash "$HOOK" >/dev/null 2>&1
93
+ rc=$?
94
+ if [ "$rc" -eq 2 ]; then
95
+ PASS=$((PASS + 1))
96
+ else
97
+ FAIL=$((FAIL + 1))
98
+ echo " FAIL: CC_SECRET_OUTPUT_BLOCK=1 must exit 2 (got $rc)"
99
+ fi
100
+
101
+ echo " $PASS passed, $FAIL failed"
102
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,177 @@
1
+ #!/bin/bash
2
+ # --blindspots must compare two layers, and must not mistake an allow test for a gate.
3
+ #
4
+ # Why this exists. Every other diagnostic in this tool reads one layer: the
5
+ # scripts on disk (--status), the settings file (--lint), the block log
6
+ # (--stats), the shipped bodies (--outdated). A guard can be present,
7
+ # executable, registered and current in all four and still never fire, because
8
+ # the shape of the commands actually run on that machine never reaches it.
9
+ # `--blindspots` is the only check that reads the session transcripts next to
10
+ # the guards, so it is the only one that can see that gap.
11
+ #
12
+ # The trap this test pins is in the instrument, not in the user's setup. Hook
13
+ # scripts contain start-anchored patterns for two opposite purposes:
14
+ #
15
+ # gate if printf '%s' "$CMD" | grep -qE '^\s*git\s+add'; then ... exit 2
16
+ # subject if ! printf '%s' "$CMD" | grep -qE '^\s*git\s+push'; then exit 0; fi
17
+ # exempt if printf '%s' "$CMD" | grep -qE '^\s*(cat|ls)'; then exit 0; fi
18
+ #
19
+ # The first two decide what the hook reaches. The third decides what it lets
20
+ # through on purpose. Counting the third as an unguarded gap fills the report
21
+ # with alarms about read-only commands the author deliberately waved past — a
22
+ # tool that warns about the very defect it contains. So this test asserts both
23
+ # directions: the gate and the subject are reported, and the exempt pattern is
24
+ # not.
25
+ #
26
+ # Numbers are fixed by construction: 25 calls invoke `git push`, 5 of them at
27
+ # the start of the string, 20 after a `cd ... &&`. Blind = 20/25 = 80.0%.
28
+
29
+ set -u
30
+ REPO="$(cd "$(dirname "$0")/.." && pwd)"
31
+ PASS=0
32
+ FAIL=0
33
+
34
+ check() { # name expected actual
35
+ if [ "$2" = "$3" ]; then
36
+ PASS=$((PASS + 1))
37
+ else
38
+ FAIL=$((FAIL + 1))
39
+ echo " FAIL: $1"
40
+ echo " expected: $2"
41
+ echo " actual: $3"
42
+ fi
43
+ }
44
+
45
+ TMP="$(mktemp -d)"
46
+ trap 'chmod -R u+w "$TMP" 2>/dev/null; find "$TMP" -mindepth 1 -delete 2>/dev/null; rmdir "$TMP" 2>/dev/null' EXIT
47
+
48
+ mkdir -p "$TMP/.claude/hooks" "$TMP/.claude/projects/-tmp-probe"
49
+
50
+ # A gate: the anchor is the blocking condition.
51
+ cat > "$TMP/.claude/hooks/probe-add-guard.sh" <<'HOOK'
52
+ #!/bin/bash
53
+ CMD=$(cat)
54
+ if printf '%s' "$CMD" | grep -qE '^\s*git\s+add'; then
55
+ echo "blocked" >&2
56
+ exit 2
57
+ fi
58
+ exit 0
59
+ HOOK
60
+
61
+ # A subject filter: anything not matching the anchor is never examined at all.
62
+ cat > "$TMP/.claude/hooks/probe-push-guard.sh" <<'HOOK'
63
+ #!/bin/bash
64
+ CMD=$(cat)
65
+ if ! printf '%s' "$CMD" | grep -qE '^\s*git\s+push'; then
66
+ exit 0
67
+ fi
68
+ echo "blocked" >&2
69
+ exit 2
70
+ HOOK
71
+
72
+ # An allow test: these are waved through deliberately and are not a gap.
73
+ cat > "$TMP/.claude/hooks/probe-readonly-allow.sh" <<'HOOK'
74
+ #!/bin/bash
75
+ CMD=$(cat)
76
+ if printf '%s' "$CMD" | grep -qE '^\s*(cat|ls|head)'; then
77
+ exit 0
78
+ fi
79
+ exit 0
80
+ HOOK
81
+
82
+ # Present on disk, registered nowhere. It never runs, so its anchors must not be
83
+ # counted as gaps — but the file itself is worth naming.
84
+ cat > "$TMP/.claude/hooks/probe-orphan.sh" <<'HOOK'
85
+ #!/bin/bash
86
+ CMD=$(cat)
87
+ if printf '%s' "$CMD" | grep -qE '^\s*git\s+push'; then
88
+ exit 2
89
+ fi
90
+ exit 0
91
+ HOOK
92
+
93
+ chmod +x "$TMP/.claude/hooks/"*.sh
94
+
95
+ # One registration points at a script that is not there. Settings say it is
96
+ # installed; the filesystem says otherwise. Neither layer alone shows this.
97
+ cat > "$TMP/.claude/settings.json" <<SETTINGS
98
+ {
99
+ "hooks": {
100
+ "PreToolUse": [
101
+ {
102
+ "matcher": "Bash",
103
+ "hooks": [
104
+ { "type": "command", "command": "bash \$HOME/.claude/hooks/probe-push-guard.sh" },
105
+ { "type": "command", "command": "bash \$HOME/.claude/hooks/probe-add-guard.sh" },
106
+ { "type": "command", "command": "bash \$HOME/.claude/hooks/probe-readonly-allow.sh" },
107
+ { "type": "command", "command": "bash \$HOME/.claude/hooks/probe-removed-guard.sh" }
108
+ ]
109
+ }
110
+ ]
111
+ }
112
+ }
113
+ SETTINGS
114
+
115
+ # 25 invocations of `git push`: 5 at the start, 20 behind a `cd ... &&`.
116
+ # Plus 30 `cat` calls, which the allow test covers on purpose.
117
+ TRANSCRIPT="$TMP/.claude/projects/-tmp-probe/session.jsonl"
118
+ : > "$TRANSCRIPT"
119
+ emit() { # command
120
+ printf '{"type":"assistant","timestamp":"2026-09-01T00:00:00Z","message":{"content":[{"type":"tool_use","name":"Bash","input":{"command":%s}}]}}\n' \
121
+ "$(printf '%s' "$1" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')" >> "$TRANSCRIPT"
122
+ }
123
+ for i in $(seq 1 5); do emit "git push origin main"; done
124
+ for i in $(seq 1 20); do emit "cd /tmp/work && git push origin main"; done
125
+ for i in $(seq 1 30); do emit "cat /tmp/work/notes.md"; done
126
+
127
+ OUT="$(HOME="$TMP" node "$REPO/index.mjs" --blindspots 2>&1)"
128
+ PLAIN="$(printf '%s' "$OUT" | sed 's/\x1b\[[0-9;]*m//g')"
129
+
130
+ # Layer 4 was actually read.
131
+ check "counts the Bash calls in the transcript" \
132
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE '\b55 Bash tool calls' && echo yes || echo no)"
133
+
134
+ # The sample must be a shape, never the command. A user's history carries keys,
135
+ # customer names and internal paths, and this output lands in screen shares and
136
+ # CI logs. The probe transcript writes /tmp/work into every chained call; none of
137
+ # it may come back out.
138
+ check "prints the shape, not the arguments" \
139
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE '^ +cd … && git push …$' && echo yes || echo no)"
140
+ check "no argument from the transcript is echoed" \
141
+ "yes" "$(printf '%s' "$PLAIN" | grep -q '/tmp/work' && echo no || echo yes)"
142
+
143
+ # The subject filter is reported, with the blind rate fixed by construction.
144
+ check "reports the start-anchored push guard" \
145
+ "yes" "$(printf '%s' "$PLAIN" | grep -q 'probe-push-guard.sh' && echo yes || echo no)"
146
+ check "blind rate is 20 of 25" \
147
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE 'git push .*probe-push-guard\.sh +25 +5 +80\.0%' && echo yes || echo no)"
148
+ check "labels a subject filter as never examined" \
149
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE 'probe-push-guard\.sh.*never examined' && echo yes || echo no)"
150
+
151
+ # The allow test must not be listed. This is the instrument's own failure mode.
152
+ check "does not report the allow test as a gap" \
153
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE '^ +(cat|ls|head).*probe-readonly-allow\.sh' && echo no || echo yes)"
154
+
155
+ # Present but registered nowhere. Its anchors are kept out of the gap table —
156
+ # a script that never runs cannot have a gap — and the reader is told the table
157
+ # is smaller than their hooks directory, without duplicating the enumeration
158
+ # that --audit already does with its own precision rules.
159
+ check "says unregistered scripts were left out of the table" \
160
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE '1 more script .* is registered nowhere' && echo yes || echo no)"
161
+ check "keeps the unregistered script out of the gap table" \
162
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE 'git push +probe-orphan\.sh +[0-9]' && echo no || echo yes)"
163
+
164
+ # The registration with no file behind it.
165
+ check "names the registration whose file is missing" \
166
+ "yes" "$(printf '%s' "$PLAIN" | grep -q 'probe-removed-guard.sh' && echo yes || echo no)"
167
+ check "does not flag the registration that does exist" \
168
+ "yes" "$(printf '%s' "$PLAIN" | grep -qE '^\s+·.*probe-push-guard\.sh' && echo no || echo yes)"
169
+
170
+ # Nothing is written back. This command reads; it must never touch settings.
171
+ BEFORE="$(md5sum "$TMP/.claude/settings.json" | cut -d' ' -f1)"
172
+ HOME="$TMP" node "$REPO/index.mjs" --blindspots >/dev/null 2>&1
173
+ AFTER="$(md5sum "$TMP/.claude/settings.json" | cut -d' ' -f1)"
174
+ check "leaves settings.json untouched" "$BEFORE" "$AFTER"
175
+
176
+ echo " blindspots-cross-layer: $PASS passed, $FAIL failed"
177
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,64 @@
1
+ #!/bin/bash
2
+ # Test for block-database-wipe.sh
3
+ #
4
+ # Verifies the hook blocks (exit 2) destructive framework/ORM database commands
5
+ # across Laravel, Django, Rails, Prisma, TypeORM/Sequelize, raw SQL and PostgreSQL,
6
+ # while letting safe incremental commands through (exit 0).
7
+ #
8
+ # Gaps closed in Issue #69059: migrate:refresh, Django "migrate <app> zero",
9
+ # Rails db:schema:load, TypeORM/Sequelize schema:drop / db:drop.
10
+
11
+ set -u
12
+
13
+ HOOK="$(dirname "$0")/../examples/block-database-wipe.sh"
14
+ [ ! -x "$HOOK" ] && chmod +x "$HOOK"
15
+
16
+ PASS=0
17
+ FAIL=0
18
+
19
+ run_case() {
20
+ local name="$1"
21
+ local cmd="$2"
22
+ local expect="$3" # "block" or "allow"
23
+
24
+ local input rc
25
+ input=$(jq -nc --arg cmd "$cmd" '{tool_input:{command:$cmd}}')
26
+ echo "$input" | "$HOOK" >/dev/null 2>&1
27
+ rc=$?
28
+
29
+ if [ "$expect" = "block" ]; then
30
+ if [ "$rc" = "2" ]; then PASS=$((PASS + 1)); echo "PASS: $name"
31
+ else FAIL=$((FAIL + 1)); echo "FAIL: $name (expected block/exit2, got $rc)"; fi
32
+ else
33
+ if [ "$rc" = "0" ]; then PASS=$((PASS + 1)); echo "PASS: $name"
34
+ else FAIL=$((FAIL + 1)); echo "FAIL: $name (expected allow/exit0, got $rc)"; fi
35
+ fi
36
+ }
37
+
38
+ # --- destructive: must block ---
39
+ run_case "laravel migrate:fresh" "php artisan migrate:fresh" block
40
+ run_case "laravel migrate:refresh" "php artisan migrate:refresh" block
41
+ run_case "laravel migrate:reset" "php artisan migrate:reset" block
42
+ run_case "laravel db:wipe" "php artisan db:wipe" block
43
+ run_case "django flush" "python manage.py flush" block
44
+ run_case "django migrate app zero" "python manage.py migrate myapp zero" block
45
+ run_case "rails db:drop" "rails db:drop" block
46
+ run_case "rails db:schema:load" "rails db:schema:load" block
47
+ run_case "prisma migrate reset" "npx prisma migrate reset" block
48
+ run_case "typeorm schema:drop" "npm run typeorm schema:drop" block
49
+ run_case "sequelize db:drop" "npx sequelize-cli db:drop" block
50
+ run_case "raw DROP DATABASE" "mysql -e 'DROP DATABASE foo'" block
51
+ run_case "dropdb" "dropdb mydb" block
52
+
53
+ # --- safe: must allow (no false positives) ---
54
+ run_case "laravel migrate (incremental)" "php artisan migrate" allow
55
+ run_case "django migrate (incremental)" "python manage.py migrate" allow
56
+ run_case "rails db:migrate" "rails db:migrate" allow
57
+ run_case "prisma migrate dev" "npx prisma migrate dev" allow
58
+ run_case "typeorm migration:run" "npm run typeorm migration:run" allow
59
+ run_case "plain git commit" "git commit -m fix" allow
60
+ run_case "safe SELECT" "psql -c 'SELECT count(*) FROM users'" allow
61
+
62
+ echo "----------------------------------------"
63
+ echo "PASS=$PASS FAIL=$FAIL"
64
+ [ "$FAIL" -eq 0 ] || exit 1
@@ -0,0 +1,85 @@
1
+ #!/bin/bash
2
+ # Bundled short flags slipped past the force checks
3
+ #
4
+ # Short options can be written together. These are all one flag group:
5
+ #
6
+ # git push -uf origin feature # -u --set-upstream + -f --force
7
+ # git checkout -bf main # -b new branch + -f force
8
+ # git switch -Cf main # -C force-create + -f force
9
+ #
10
+ # Every one of them is a real destructive operation. The shipped patterns
11
+ # looked for the spelling `-f` as a standalone word (`-f\b`), so a bundled
12
+ # group never matched and the guards exited 0 -- an affirmative approval.
13
+ #
14
+ # Measured 2026-09-03 against the shipped copies: 4 bypasses.
15
+ # branch-guard git push -uf (force push, any branch)
16
+ # destructive-guard git checkout -bf, git switch -Cf, git checkout -qf
17
+ #
18
+ # The fix reads "a dash, then letters, ending in f" instead of the literal
19
+ # `-f`: [^A-Za-z0-9]-[a-zA-Z]*f\b
20
+ #
21
+ # The leading [^A-Za-z0-9] is what keeps `--follow-tags` out: after the second
22
+ # dash the letters run `follow`, and `f` is not at a word boundary there.
23
+ #
24
+ # destructive-guard needed a second change beyond the character class. Its
25
+ # pattern was `git\s+(checkout|switch)\s+.*`, and that `\s+` ate the space in
26
+ # front of `-bf`, leaving no character for [^A-Za-z0-9] to match. Anchoring on
27
+ # `\b` instead of `\s+` leaves the space in the subject where the class can see
28
+ # it. Same shape as the git-globals fix: the check was right, the thing feeding
29
+ # it was not.
30
+ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
31
+ BG=$(mktemp); DG=$(mktemp)
32
+ trap 'rm -f "$BG" "$DG"' EXIT
33
+ python3 -c "
34
+ import json,sys
35
+ d=json.load(open('$ROOT/scripts.json'))
36
+ open('$BG','w').write(d['branch-guard'])
37
+ open('$DG','w').write(d['destructive-guard'])"
38
+
39
+ PASS=0; FAIL=0
40
+
41
+ check() {
42
+ local guard="$1" desc="$2" cmd="$3" want="$4" # want: 2 = blocked, 0 = allowed
43
+ local payload code
44
+ payload=$(python3 -c '
45
+ import json,sys
46
+ print(json.dumps({"tool_name":"Bash","tool_input":{"command":sys.argv[1]}}))' "$cmd")
47
+ printf '%s' "$payload" | bash "$guard" >/dev/null 2>&1
48
+ code=$?
49
+ if [ "$code" = "$want" ]; then
50
+ echo "PASS: $desc"; PASS=$((PASS+1))
51
+ else
52
+ echo "FAIL: $desc (expected exit $want, got $code)"; FAIL=$((FAIL+1))
53
+ fi
54
+ }
55
+
56
+ # --- branch-guard: bundled -f in a push ---
57
+ check "$BG" "bg: -uf force push" 'git push -uf origin feature' 2
58
+ check "$BG" "bg: -qf force push" 'git push -qf origin feature' 2
59
+ check "$BG" "bg: -uf with a global" 'git -C /repo push -uf origin feature' 2
60
+ check "$BG" "bg: plain -f still blocked" 'git push -f origin feature' 2
61
+ check "$BG" "bg: --force still blocked" 'git push --force origin feature' 2
62
+
63
+ # --- branch-guard: ordinary work still goes through ---
64
+ check "$BG" "bg: --follow-tags allowed" 'git push --follow-tags origin feature' 0
65
+ check "$BG" "bg: -u alone allowed" 'git push -u origin feature' 0
66
+ check "$BG" "bg: plain push allowed" 'git push origin feature' 0
67
+
68
+ # --- destructive-guard: bundled -f in checkout/switch ---
69
+ check "$DG" "dg: checkout -bf" 'git checkout -bf main' 2
70
+ check "$DG" "dg: switch -Cf" 'git switch -Cf main' 2
71
+ check "$DG" "dg: checkout -qf" 'git checkout -qf main' 2
72
+ check "$DG" "dg: checkout -f still blocked" 'git checkout -f main' 2
73
+ check "$DG" "dg: checkout --force blocked" 'git checkout --force main' 2
74
+ check "$DG" "dg: switch --discard-changes" 'git switch --discard-changes main' 2
75
+
76
+ # --- destructive-guard: ordinary work still goes through ---
77
+ check "$DG" "dg: checkout a branch" 'git checkout main' 0
78
+ check "$DG" "dg: checkout -b new branch" 'git checkout -b feature' 0
79
+ check "$DG" "dg: switch -c new branch" 'git switch -c my-feature' 0
80
+ check "$DG" "dg: switch --detach" 'git switch --detach HEAD' 0
81
+ check "$DG" "dg: checkout --track" 'git checkout --track origin/feature' 0
82
+
83
+ echo
84
+ echo "PASS=$PASS FAIL=$FAIL"
85
+ [ "$FAIL" = 0 ]