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,173 @@
1
+ #!/bin/bash
2
+ # Tests for binary-read-detector.sh
3
+ # Covers: 25 binary extensions detection, advisory mode (exit 0),
4
+ # block mode (exit 2), disable env, custom extension list,
5
+ # multiple-path matching, fail-open on bad input.
6
+
7
+ HOOK="examples/binary-read-detector.sh"
8
+ PASS=0 FAIL=0
9
+
10
+ run_hook() {
11
+ local payload="$1"; shift
12
+ env -u CC_BINARY_READ_DISABLE -u CC_BINARY_READ_BLOCK \
13
+ -u CC_BINARY_READ_EXTENSIONS \
14
+ "$@" bash "$HOOK" <<< "$payload" 2>&1
15
+ }
16
+
17
+ run_and_capture() {
18
+ local payload="$1"; shift
19
+ env -u CC_BINARY_READ_DISABLE -u CC_BINARY_READ_BLOCK \
20
+ -u CC_BINARY_READ_EXTENSIONS \
21
+ "$@" bash "$HOOK" <<< "$payload" 2>&1
22
+ LAST_RC=$?
23
+ }
24
+
25
+ assert_contains() { if echo "$2" | grep -qF "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
26
+ assert_not_contains() { if ! echo "$2" | grep -qF "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
27
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
28
+
29
+ # Test 1: empty input — pass through
30
+ run_and_capture '{}'
31
+ assert_exit "empty input pass" "$LAST_RC" "0"
32
+
33
+ # Test 2: text-only prompt — silent
34
+ run_and_capture '{"prompt":"please run the tests and report"}'
35
+ assert_exit "text prompt pass" "$LAST_RC" "0"
36
+ OUT=$(run_hook '{"prompt":"please run the tests and report"}')
37
+ assert_not_contains "text prompt silent" "$OUT" "Binary path reference"
38
+
39
+ # Test 3: PNG reference — advisory (exit 0)
40
+ OUT=$(run_hook '{"prompt":"read screenshot.png and describe it"}')
41
+ LAST_RC=$?
42
+ run_and_capture '{"prompt":"read screenshot.png and describe it"}'
43
+ assert_exit "png advisory exit 0" "$LAST_RC" "0"
44
+ assert_contains "png named in advisory" "$OUT" "screenshot.png"
45
+ assert_contains "advisory references #62639" "$OUT" "#62639"
46
+
47
+ # Test 4: JPG reference
48
+ OUT=$(run_hook '{"prompt":"open foo.jpg and tell me what is shown"}')
49
+ assert_contains "jpg detected" "$OUT" "foo.jpg"
50
+
51
+ # Test 5: PDF reference
52
+ OUT=$(run_hook '{"prompt":"summarize document.pdf"}')
53
+ assert_contains "pdf detected" "$OUT" "document.pdf"
54
+
55
+ # Test 6: HEIC reference
56
+ OUT=$(run_hook '{"prompt":"read IMG_1234.heic"}')
57
+ assert_contains "heic detected" "$OUT" "IMG_1234.heic"
58
+
59
+ # Test 7: WEBP reference
60
+ OUT=$(run_hook '{"prompt":"check image.webp"}')
61
+ assert_contains "webp detected" "$OUT" "image.webp"
62
+
63
+ # Test 8: GIF reference
64
+ OUT=$(run_hook '{"prompt":"read animation.gif"}')
65
+ assert_contains "gif detected" "$OUT" "animation.gif"
66
+
67
+ # Test 9: MP4 reference
68
+ OUT=$(run_hook '{"prompt":"analyze video.mp4"}')
69
+ assert_contains "mp4 detected" "$OUT" "video.mp4"
70
+
71
+ # Test 10: zip reference
72
+ OUT=$(run_hook '{"prompt":"extract archive.zip"}')
73
+ assert_contains "zip detected" "$OUT" "archive.zip"
74
+
75
+ # Test 11: DOCX reference
76
+ OUT=$(run_hook '{"prompt":"read contract.docx"}')
77
+ assert_contains "docx detected" "$OUT" "contract.docx"
78
+
79
+ # Test 12: XLSX reference
80
+ OUT=$(run_hook '{"prompt":"open data.xlsx"}')
81
+ assert_contains "xlsx detected" "$OUT" "data.xlsx"
82
+
83
+ # Test 13: multiple binary paths in same prompt
84
+ OUT=$(run_hook '{"prompt":"compare foo.png with bar.pdf"}')
85
+ assert_contains "first path in multi" "$OUT" "foo.png"
86
+ assert_contains "second path in multi" "$OUT" "bar.pdf"
87
+
88
+ # Test 14: path with directory
89
+ OUT=$(run_hook '{"prompt":"read ~/Downloads/screenshot.png"}')
90
+ assert_contains "path with home dir" "$OUT" "Downloads/screenshot.png"
91
+
92
+ # Test 15: absolute path
93
+ OUT=$(run_hook '{"prompt":"read /Users/me/Desktop/foo.png"}')
94
+ assert_contains "absolute path" "$OUT" "Desktop/foo.png"
95
+
96
+ # Test 16: case-insensitive matching
97
+ OUT=$(run_hook '{"prompt":"open IMAGE.PNG"}')
98
+ assert_contains "uppercase ext detected" "$OUT" "IMAGE.PNG"
99
+
100
+ # Test 17: mixed case
101
+ OUT=$(run_hook '{"prompt":"read Photo.Jpeg"}')
102
+ assert_contains "mixed case detected" "$OUT" "Photo.Jpeg"
103
+
104
+ # Test 18: DISABLE env suppresses everything
105
+ run_and_capture '{"prompt":"read foo.png"}' CC_BINARY_READ_DISABLE=1
106
+ assert_exit "disable exit 0" "$LAST_RC" "0"
107
+ OUT=$(run_hook '{"prompt":"read foo.png"}' CC_BINARY_READ_DISABLE=1)
108
+ assert_not_contains "disable silent" "$OUT" "Binary path reference"
109
+
110
+ # Test 19: BLOCK env changes exit to 2
111
+ run_and_capture '{"prompt":"read foo.png"}' CC_BINARY_READ_BLOCK=1
112
+ assert_exit "block exit 2" "$LAST_RC" "2"
113
+ OUT=$(run_hook '{"prompt":"read foo.png"}' CC_BINARY_READ_BLOCK=1)
114
+ assert_contains "block still emits advisory" "$OUT" "Binary path reference"
115
+
116
+ # Test 20: custom EXTENSIONS env (only .secret)
117
+ run_and_capture '{"prompt":"read foo.png"}' CC_BINARY_READ_EXTENSIONS=secret
118
+ assert_exit "custom ext png excluded pass" "$LAST_RC" "0"
119
+ OUT=$(run_hook '{"prompt":"read foo.secret"}' CC_BINARY_READ_EXTENSIONS=secret)
120
+ assert_contains "custom ext secret detected" "$OUT" "foo.secret"
121
+
122
+ # Test 21: malformed JSON — fail-open
123
+ run_and_capture 'not-json'
124
+ assert_exit "malformed input exit 0" "$LAST_RC" "0"
125
+
126
+ # Test 22: missing prompt field — fail-open
127
+ run_and_capture '{"other":"field"}'
128
+ assert_exit "missing prompt exit 0" "$LAST_RC" "0"
129
+
130
+ # Test 23: empty prompt — fail-open silent
131
+ run_and_capture '{"prompt":""}'
132
+ assert_exit "empty prompt exit 0" "$LAST_RC" "0"
133
+ OUT=$(run_hook '{"prompt":""}')
134
+ assert_not_contains "empty prompt silent" "$OUT" "Binary path reference"
135
+
136
+ # Test 24: user_message field as alternative name
137
+ OUT=$(run_hook '{"user_message":"read photo.png"}')
138
+ assert_contains "user_message field works" "$OUT" "photo.png"
139
+
140
+ # Test 25: advisory mentions PreToolUse bypass
141
+ OUT=$(run_hook '{"prompt":"read foo.png"}')
142
+ assert_contains "advisory names PreToolUse bypass" "$OUT" "PreToolUse hooks will NOT fire"
143
+
144
+ # Test 26: advisory provides four operator-side options
145
+ OUT=$(run_hook '{"prompt":"read foo.png"}')
146
+ assert_contains "advisory option 1 verify trust" "$OUT" "Verify the file is trusted"
147
+ assert_contains "advisory option 2 pre-process" "$OUT" "Pre-process to text"
148
+ assert_contains "advisory option 3 PostToolUse" "$OUT" "PostToolUse"
149
+ assert_contains "advisory option 4 OS layer" "$OUT" "AppArmor"
150
+
151
+ # Test 27: advisory mentions disable env
152
+ OUT=$(run_hook '{"prompt":"read foo.png"}')
153
+ assert_contains "advisory mentions disable env" "$OUT" "CC_BINARY_READ_DISABLE=1"
154
+
155
+ # Test 28: text file (.txt) not detected
156
+ OUT=$(run_hook '{"prompt":"read notes.txt and summarize"}')
157
+ assert_not_contains "txt not detected" "$OUT" "Binary path reference"
158
+
159
+ # Test 29: source code file (.py, .js) not detected
160
+ OUT=$(run_hook '{"prompt":"read main.py"}')
161
+ assert_not_contains "py not detected" "$OUT" "Binary path reference"
162
+ OUT=$(run_hook '{"prompt":"read app.js"}')
163
+ assert_not_contains "js not detected" "$OUT" "Binary path reference"
164
+
165
+ # Test 30: bin / exe / dll detected (binaries)
166
+ OUT=$(run_hook '{"prompt":"run firmware.bin"}')
167
+ assert_contains "bin detected" "$OUT" "firmware.bin"
168
+ OUT=$(run_hook '{"prompt":"open setup.exe"}')
169
+ assert_contains "exe detected" "$OUT" "setup.exe"
170
+
171
+ echo ""
172
+ echo "Results: $PASS passed, $FAIL failed"
173
+ [ "$FAIL" = "0" ] && exit 0 || exit 1
@@ -0,0 +1,167 @@
1
+ #!/bin/bash
2
+ # Tests for broad-prefix-session-trap-warner.sh (Cluster 6 Axis 8)
3
+ # Covers: default prefix matching across nine prefix categories,
4
+ # silent on non-matching commands, custom pattern override,
5
+ # disable/silent environment toggles, JSON output shape, fail-open.
6
+
7
+ HOOK="examples/broad-prefix-session-trap-warner.sh"
8
+ PASS=0 FAIL=0
9
+
10
+ run_hook() {
11
+ local payload="$1"; shift
12
+ env -u CC_BROAD_PREFIX_PATTERNS -u CC_BROAD_PREFIX_DISABLE \
13
+ -u CC_BROAD_PREFIX_SILENT \
14
+ "$@" bash "$HOOK" <<< "$payload" 2>&1
15
+ }
16
+
17
+ assert_contains() { if echo "$2" | grep -qF "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
18
+ assert_not_contains() { if ! echo "$2" | grep -qF "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
19
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
20
+
21
+ # Test 1: empty input — silent, exit 0
22
+ OUT=$(run_hook '{}')
23
+ RC=$?
24
+ assert_exit "empty input exit 0" "$RC" "0"
25
+ assert_not_contains "empty input silent" "$OUT" "broad-prefix"
26
+
27
+ # Test 2: docker matches the default broad-prefix list
28
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps -a"}}')
29
+ RC=$?
30
+ assert_exit "docker exit 0" "$RC" "0"
31
+ assert_contains "docker warns" "$OUT" "broad-prefix command detected"
32
+ assert_contains "docker references #62437" "$OUT" "#62437"
33
+ assert_contains "docker recommends Approve once" "$OUT" "Approve once"
34
+ assert_contains "docker emits PreToolUse hookSpecificOutput" "$OUT" "PreToolUse"
35
+
36
+ # Test 3: kubectl matches the default broad-prefix list
37
+ OUT=$(run_hook '{"tool_input":{"command":"kubectl get pods -n kube-system"}}')
38
+ assert_contains "kubectl warns" "$OUT" "broad-prefix command detected"
39
+ assert_contains "kubectl names matched pattern" "$OUT" "kubectl"
40
+
41
+ # Test 4: gcloud matches the default broad-prefix list
42
+ OUT=$(run_hook '{"tool_input":{"command":"gcloud compute instances list"}}')
43
+ assert_contains "gcloud warns" "$OUT" "broad-prefix command detected"
44
+
45
+ # Test 5: aws matches the default broad-prefix list
46
+ OUT=$(run_hook '{"tool_input":{"command":"aws s3 ls"}}')
47
+ assert_contains "aws warns" "$OUT" "broad-prefix command detected"
48
+
49
+ # Test 6: helm matches the default broad-prefix list
50
+ OUT=$(run_hook '{"tool_input":{"command":"helm list"}}')
51
+ assert_contains "helm warns" "$OUT" "broad-prefix command detected"
52
+
53
+ # Test 7: terraform matches the default broad-prefix list
54
+ OUT=$(run_hook '{"tool_input":{"command":"terraform plan"}}')
55
+ assert_contains "terraform warns" "$OUT" "broad-prefix command detected"
56
+
57
+ # Test 8: rm -rf matches the default broad-prefix list
58
+ OUT=$(run_hook '{"tool_input":{"command":"rm -rf /tmp/scratch"}}')
59
+ assert_contains "rm -rf warns" "$OUT" "broad-prefix command detected"
60
+
61
+ # Test 9: rm -Rf (capital R) also matches
62
+ OUT=$(run_hook '{"tool_input":{"command":"rm -Rf /tmp/scratch"}}')
63
+ assert_contains "rm -Rf warns" "$OUT" "broad-prefix command detected"
64
+
65
+ # Test 10: rm -f without -r still matches the bracket class [rRf]
66
+ OUT=$(run_hook '{"tool_input":{"command":"rm -f /tmp/scratch"}}')
67
+ assert_contains "rm -f warns" "$OUT" "broad-prefix command detected"
68
+
69
+ # Test 11: dd matches the default broad-prefix list
70
+ OUT=$(run_hook '{"tool_input":{"command":"dd if=/dev/zero of=/tmp/x bs=1M count=10"}}')
71
+ assert_contains "dd warns" "$OUT" "broad-prefix command detected"
72
+
73
+ # Test 12: mkfs matches the default broad-prefix list
74
+ OUT=$(run_hook '{"tool_input":{"command":"mkfs.ext4 /dev/sdz1"}}')
75
+ assert_contains "mkfs warns" "$OUT" "broad-prefix command detected"
76
+
77
+ # Test 13: safe command not in broad-prefix list — silent
78
+ OUT=$(run_hook '{"tool_input":{"command":"ls -la /tmp"}}')
79
+ RC=$?
80
+ assert_exit "safe command exit 0" "$RC" "0"
81
+ assert_not_contains "safe command silent" "$OUT" "broad-prefix command detected"
82
+
83
+ # Test 14: cat is not in the default list — silent
84
+ OUT=$(run_hook '{"tool_input":{"command":"cat /etc/hosts"}}')
85
+ assert_not_contains "cat silent" "$OUT" "broad-prefix command detected"
86
+
87
+ # Test 15: grep is not in the default list — silent
88
+ OUT=$(run_hook '{"tool_input":{"command":"grep -r foo ."}}')
89
+ assert_not_contains "grep silent" "$OUT" "broad-prefix command detected"
90
+
91
+ # Test 16: command must START with the prefix (no false positive on docker as substring)
92
+ OUT=$(run_hook '{"tool_input":{"command":"cat ./mydocker.txt"}}')
93
+ # 'docker' appears but pattern is 'docker( |$)' so 'docker.txt' has '.' after — should NOT match
94
+ assert_not_contains "docker as substring not matched" "$OUT" "broad-prefix command detected"
95
+
96
+ # Test 17: disable env var suppresses everything
97
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps"}}' CC_BROAD_PREFIX_DISABLE=1)
98
+ RC=$?
99
+ assert_exit "disable exit 0" "$RC" "0"
100
+ assert_not_contains "disable silent" "$OUT" "broad-prefix command detected"
101
+
102
+ # Test 18: silent env var skips JSON but keeps stderr advisory
103
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps"}}' CC_BROAD_PREFIX_SILENT=1)
104
+ assert_contains "silent keeps stderr" "$OUT" "broad-prefix command detected"
105
+ assert_not_contains "silent skips JSON" "$OUT" "hookSpecificOutput"
106
+
107
+ # Test 19: custom pattern override via env var
108
+ OUT=$(run_hook '{"tool_input":{"command":"sudo something"}}' 'CC_BROAD_PREFIX_PATTERNS=sudo( |$):rsync( |$)')
109
+ assert_contains "custom pattern sudo warns" "$OUT" "broad-prefix command detected"
110
+
111
+ # Test 20: custom pattern doesn't match default-list command
112
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps"}}' 'CC_BROAD_PREFIX_PATTERNS=sudo( |$):rsync( |$)')
113
+ assert_not_contains "custom pattern excludes docker" "$OUT" "broad-prefix command detected"
114
+
115
+ # Test 21: malformed JSON input — fail-open (exit 0, no crash)
116
+ OUT=$(run_hook 'not-json')
117
+ RC=$?
118
+ assert_exit "malformed input exit 0" "$RC" "0"
119
+ assert_not_contains "malformed input silent" "$OUT" "broad-prefix command detected"
120
+
121
+ # Test 22: missing tool_input — fail-open silently
122
+ OUT=$(run_hook '{"other":"field"}')
123
+ RC=$?
124
+ assert_exit "missing tool_input exit 0" "$RC" "0"
125
+ assert_not_contains "missing tool_input silent" "$OUT" "broad-prefix command detected"
126
+
127
+ # Test 23: command with extra args after broad prefix still matches
128
+ OUT=$(run_hook '{"tool_input":{"command":"docker --host=tcp://example:2375 rm -f $(docker ps -q)"}}')
129
+ assert_contains "docker with --host warns" "$OUT" "broad-prefix command detected"
130
+
131
+ # Test 24: trap mechanics articulation present in warning
132
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps"}}')
133
+ assert_contains "warning mentions docker rm -f trap example" "$OUT" "docker rm -f"
134
+ assert_contains "warning references meta-issue 30519" "$OUT" "#30519"
135
+ assert_contains "warning references bypass-mode meta 39523" "$OUT" "#39523"
136
+
137
+ # Test 25: hookSpecificOutput JSON shape — hookEventName is PreToolUse
138
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps"}}')
139
+ assert_contains "JSON output names PreToolUse event" "$OUT" '"hookEventName": "PreToolUse"'
140
+ assert_contains "JSON output has additionalContext" "$OUT" "additionalContext"
141
+
142
+ # Test 26: warning explicitly recommends 'Approve once' over 'Always'
143
+ OUT=$(run_hook '{"tool_input":{"command":"kubectl delete pod foo"}}')
144
+ assert_contains "warning recommends Approve once" "$OUT" "Approve once"
145
+ assert_contains "warning warns against Always" "$OUT" "Reserve 'Always'"
146
+
147
+ # Test 27: empty command field — silent
148
+ OUT=$(run_hook '{"tool_input":{"command":""}}')
149
+ RC=$?
150
+ assert_exit "empty command exit 0" "$RC" "0"
151
+ assert_not_contains "empty command silent" "$OUT" "broad-prefix command detected"
152
+
153
+ # Test 28: compound command starting with broad prefix matches
154
+ OUT=$(run_hook '{"tool_input":{"command":"docker ps && echo done"}}')
155
+ assert_contains "compound docker warns" "$OUT" "broad-prefix command detected"
156
+
157
+ # Test 29: simulate session-approved cache state still warns (every invocation)
158
+ # Hook fires per-invocation; even if operator already approved-always in a
159
+ # prior session, the hook keeps surfacing the trap in case the env reset.
160
+ OUT1=$(run_hook '{"tool_input":{"command":"docker ps"}}')
161
+ OUT2=$(run_hook '{"tool_input":{"command":"docker rm -f $(docker ps -q)"}}')
162
+ assert_contains "first docker invocation warns" "$OUT1" "broad-prefix command detected"
163
+ assert_contains "second docker invocation also warns" "$OUT2" "broad-prefix command detected"
164
+
165
+ echo ""
166
+ echo "Results: $PASS passed, $FAIL failed"
167
+ [ "$FAIL" = "0" ] && exit 0 || exit 1
@@ -0,0 +1,49 @@
1
+ #!/bin/bash
2
+ # bulk-file-delete-guard.sh の両方向の退行検査。
3
+ # 直したのは「対象を数えられない時に通していた」分岐。誤爆を増やしていないかを見る。
4
+ G="$(cd "$(dirname "$0")/.." && pwd)/examples/bulk-file-delete-guard.sh"
5
+ SB="$(mktemp -d)/regprobe"
6
+
7
+ rm -rf "$SB" 2>/dev/null
8
+ mkdir -p "$SB/many" "$SB/few" "$SB/dir with space"
9
+ for i in $(seq 1 25); do : > "$SB/many/f$i.txt"; done
10
+ for i in 1 2; do : > "$SB/few/f$i.txt"; done
11
+ for i in $(seq 1 25); do : > "$SB/dir with space/f$i.txt"; done
12
+
13
+ pass=0; fail=0
14
+ check() { # 期待 コマンド 説明
15
+ local want="$1" C="$2" L="$3"
16
+ printf '{"tool_name":"Bash","tool_input":{"command":%s}}' "$(printf '%s' "$C" | jq -Rs .)" \
17
+ | timeout 15 bash "$G" >/dev/null 2>&1
18
+ local rc=$?; local got="通す"; [ $rc -eq 2 ] && got="止める"
19
+ if [ "$got" = "$want" ]; then pass=$((pass+1)); printf 'OK %-6s %s\n' "$got" "$L"
20
+ else fail=$((fail+1)); printf 'NG★ 期待=%-6s 実際=%-6s %s\n' "$want" "$got" "$L"; fi
21
+ }
22
+
23
+ echo "=== 止めるべき(25個を消す・書き方を変えただけ) ==="
24
+ check 止める "rm -rf $SB/many" "素の絶対パス"
25
+ check 止める "rm -rf \"$SB/many\"" "引用符(二重)"
26
+ check 止める "rm -rf '$SB/many'" "引用符(単一)"
27
+ check 止める "rm -rf $SB/many/" "末尾スラッシュ"
28
+ check 止める "rm -rf $SB/many/*" "グロブで中身"
29
+ check 止める "rm -rf $SB/ma*" "部分グロブ"
30
+ check 止める "cd $SB && rm -rf many" "cd してから相対"
31
+ check 止める "cd \"$SB\" && rm -rf many" "cd の引数も引用符"
32
+ check 止める "find $SB/many -delete" "find -delete"
33
+ check 止める "find \"$SB/many\" -type f -exec rm {} +" "find -exec rm(引用符)"
34
+ check 止める "rm -rf \"$SB/dir with space\"" "パスに空白(引用符が必須の形)"
35
+
36
+ echo
37
+ echo "=== 通すべき(消す数が少ない・対象が無い・別のコマンド) ==="
38
+ check 通す "rm -rf $SB/few" "閾値未満(2個)"
39
+ check 通す "rm -rf \"$SB/few\"" "閾値未満・引用符"
40
+ check 通す "rm -rf /tmp/does-not-exist-$$" "存在しないパス(警告のみ)"
41
+ check 通す "rm -f $SB/few/f1.txt" "-r が無い(対象外)"
42
+ check 通す "ls -la $SB/many" "削除ではない"
43
+ check 通す "echo 'rm -rf /' > notes.md" "文章に書いただけ"
44
+ check 通す "git status" "無関係"
45
+
46
+ echo
47
+ echo "合格 $pass / 不合格 $fail"
48
+ rm -rf "$SB"
49
+ [ $fail -eq 0 ] || exit 1
@@ -0,0 +1,179 @@
1
+ #!/bin/bash
2
+ # Tests for bypass-mode-effective-verifier.sh (Cluster 6 Axis 7)
3
+ # Covers: three bypass-signal detection paths, silent on non-bypass,
4
+ # disable/silent environment toggles, JSON output shape, fail-open.
5
+
6
+ HOOK="examples/bypass-mode-effective-verifier.sh"
7
+ PASS=0 FAIL=0
8
+
9
+ run_hook() {
10
+ # $1 = JSON payload, optional extra env vars trail as $2..$n
11
+ local payload="$1"; shift
12
+ # Always clear bypass env vars so each test starts clean. Point the settings read
13
+ # at /dev/null by default so the runner's real ~/.claude/settings.json can't leak
14
+ # into the env/hook-input signal tests; tests that exercise Signal 4 pass their own
15
+ # CC_BYPASS_VERIFIER_SETTINGS=<fixture> in "$@", which overrides this default.
16
+ env -u CLAUDE_PERMISSION_MODE -u CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS \
17
+ -u CC_BYPASS_VERIFIER_DISABLE -u CC_BYPASS_VERIFIER_SILENT \
18
+ CC_BYPASS_VERIFIER_SETTINGS=/dev/null \
19
+ "$@" bash "$HOOK" <<< "$payload" 2>&1
20
+ }
21
+
22
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
23
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
24
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
25
+
26
+ # Test 1: no bypass signal — silent
27
+ OUT=$(run_hook '{}')
28
+ RC=$?
29
+ assert_exit "no bypass exit 0" "$RC" "0"
30
+ assert_not_contains "no bypass no warning" "$OUT" "bypass mode ACTIVE"
31
+ assert_not_contains "no bypass no advisory heading" "$OUT" "bypass-mode-effective-verifier"
32
+
33
+ # Test 2: hook-input permission_mode = bypassPermissions detected
34
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}')
35
+ RC=$?
36
+ assert_exit "hook input bypass exit 0" "$RC" "0"
37
+ assert_contains "hook input bypass warns" "$OUT" "bypass mode ACTIVE"
38
+ assert_contains "hook input bypass names signal source" "$OUT" "hook input permission_mode"
39
+ assert_contains "hook input bypass references #29214" "$OUT" "#29214"
40
+ assert_contains "hook input bypass references #36192" "$OUT" "#36192"
41
+
42
+ # Test 3: hook-input permissionMode (camelCase variant) also detected
43
+ OUT=$(run_hook '{"permissionMode":"bypassPermissions"}')
44
+ RC=$?
45
+ assert_exit "camelCase exit 0" "$RC" "0"
46
+ assert_contains "camelCase warns" "$OUT" "bypass mode ACTIVE"
47
+
48
+ # Test 4: env var CLAUDE_PERMISSION_MODE=bypassPermissions detected
49
+ OUT=$(run_hook '{}' CLAUDE_PERMISSION_MODE=bypassPermissions)
50
+ RC=$?
51
+ assert_exit "env CLAUDE_PERMISSION_MODE exit 0" "$RC" "0"
52
+ assert_contains "env CLAUDE_PERMISSION_MODE warns" "$OUT" "bypass mode ACTIVE"
53
+ assert_contains "env CLAUDE_PERMISSION_MODE signal named" "$OUT" "CLAUDE_PERMISSION_MODE=bypassPermissions"
54
+
55
+ # Test 5: env var CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1 detected
56
+ OUT=$(run_hook '{}' CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1)
57
+ RC=$?
58
+ assert_exit "env DANGEROUSLY=1 exit 0" "$RC" "0"
59
+ assert_contains "env DANGEROUSLY=1 warns" "$OUT" "bypass mode ACTIVE"
60
+ assert_contains "env DANGEROUSLY=1 signal named" "$OUT" "CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=1"
61
+
62
+ # Test 6: env var CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=true detected (case variants)
63
+ OUT=$(run_hook '{}' CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=true)
64
+ assert_contains "env DANGEROUSLY=true warns" "$OUT" "bypass mode ACTIVE"
65
+
66
+ OUT=$(run_hook '{}' CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=TRUE)
67
+ assert_contains "env DANGEROUSLY=TRUE warns" "$OUT" "bypass mode ACTIVE"
68
+
69
+ # Test 7: env var CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=0 does NOT trigger
70
+ OUT=$(run_hook '{}' CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=0)
71
+ RC=$?
72
+ assert_exit "env DANGEROUSLY=0 exit 0" "$RC" "0"
73
+ assert_not_contains "env DANGEROUSLY=0 silent" "$OUT" "bypass mode ACTIVE"
74
+
75
+ # Test 8: env var CLAUDE_PERMISSION_MODE=default does NOT trigger
76
+ OUT=$(run_hook '{}' CLAUDE_PERMISSION_MODE=default)
77
+ assert_not_contains "env default mode silent" "$OUT" "bypass mode ACTIVE"
78
+
79
+ OUT=$(run_hook '{}' CLAUDE_PERMISSION_MODE=acceptEdits)
80
+ assert_not_contains "env acceptEdits silent" "$OUT" "bypass mode ACTIVE"
81
+
82
+ # Test 9: CC_BYPASS_VERIFIER_DISABLE=1 silences even with bypass active
83
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}' CC_BYPASS_VERIFIER_DISABLE=1)
84
+ RC=$?
85
+ assert_exit "disabled exit 0" "$RC" "0"
86
+ assert_not_contains "disabled no warning" "$OUT" "bypass mode ACTIVE"
87
+ assert_not_contains "disabled no JSON output" "$OUT" "hookSpecificOutput"
88
+
89
+ # Test 10: CC_BYPASS_VERIFIER_SILENT=1 skips JSON but keeps stderr advisory
90
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}' CC_BYPASS_VERIFIER_SILENT=1)
91
+ RC=$?
92
+ assert_exit "silent exit 0" "$RC" "0"
93
+ assert_contains "silent still emits stderr" "$OUT" "bypass mode ACTIVE"
94
+ assert_not_contains "silent no JSON output" "$OUT" "hookSpecificOutput"
95
+
96
+ # Test 11: JSON output shape is correct when bypass active and not silent
97
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}')
98
+ assert_contains "JSON contains hookSpecificOutput" "$OUT" '"hookSpecificOutput"'
99
+ assert_contains "JSON contains hookEventName" "$OUT" '"hookEventName": "SessionStart"'
100
+ assert_contains "JSON contains additionalContext" "$OUT" '"additionalContext"'
101
+
102
+ # Test 12: empty input handled gracefully (jq parses {} default)
103
+ OUT=$(run_hook '')
104
+ RC=$?
105
+ assert_exit "empty input exit 0" "$RC" "0"
106
+ assert_not_contains "empty input no warning" "$OUT" "bypass mode ACTIVE"
107
+
108
+ # Test 13: invalid JSON handled gracefully (no bypass signal extracted)
109
+ OUT=$(run_hook 'not json')
110
+ RC=$?
111
+ assert_exit "invalid JSON exit 0" "$RC" "0"
112
+ assert_not_contains "invalid JSON no warning" "$OUT" "bypass mode ACTIVE"
113
+
114
+ # Test 14: hook input wins when env says default but JSON says bypass
115
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}' CLAUDE_PERMISSION_MODE=default)
116
+ assert_contains "JSON wins over default env" "$OUT" "bypass mode ACTIVE"
117
+
118
+ # Test 15: multiple signals — first wins (env var, JSON also bypass)
119
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}' CLAUDE_PERMISSION_MODE=bypassPermissions)
120
+ assert_contains "multiple signals still warns" "$OUT" "bypass mode ACTIVE"
121
+
122
+ # Test 16: known broken surfaces are all named in the warning
123
+ OUT=$(run_hook '{"permission_mode":"bypassPermissions"}')
124
+ assert_contains "warning names Edit" "$OUT" "Edit tool"
125
+ assert_contains "warning names Cowork" "$OUT" "Cowork"
126
+ assert_contains "warning names Remote Control" "$OUT" "Remote Control"
127
+ assert_contains "warning names v2.1.77 regression" "$OUT" "v2.1.77"
128
+ assert_contains "warning references meta-issue #39523" "$OUT" "#39523"
129
+
130
+ # --- Signal 4: settings.json detection (#65848) ---
131
+ FIX_DIR=$(mktemp -d)
132
+ trap 'rm -rf "$FIX_DIR"' EXIT
133
+
134
+ # Test 17: settings.json defaultMode=bypassPermissions detected (no env/hook signal)
135
+ printf '%s' '{"permissions":{"defaultMode":"bypassPermissions"}}' > "$FIX_DIR/bypass.json"
136
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/bypass.json")
137
+ RC=$?
138
+ assert_exit "settings defaultMode exit 0" "$RC" "0"
139
+ assert_contains "settings defaultMode warns" "$OUT" "bypass mode ACTIVE"
140
+ assert_contains "settings defaultMode names signal" "$OUT" "settings.json permissions.defaultMode=bypassPermissions"
141
+
142
+ # Test 18: skipDangerousModePermissionPrompt=true surfaced even when not currently bypass
143
+ printf '%s' '{"skipDangerousModePermissionPrompt":true}' > "$FIX_DIR/skip.json"
144
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/skip.json")
145
+ RC=$?
146
+ assert_exit "skip-only exit 0" "$RC" "0"
147
+ assert_contains "skip-only warns suppressed" "$OUT" "dangerous-mode warning SUPPRESSED"
148
+ assert_contains "skip-only references #65848" "$OUT" "#65848"
149
+ assert_not_contains "skip-only not labelled active" "$OUT" "bypass mode ACTIVE"
150
+
151
+ # Test 19: the #65848 repro — both keys set — names active bypass AND the suppressed prompt
152
+ printf '%s' '{"permissions":{"defaultMode":"bypassPermissions"},"skipDangerousModePermissionPrompt":true}' > "$FIX_DIR/both.json"
153
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/both.json")
154
+ assert_contains "both warns active" "$OUT" "bypass mode ACTIVE"
155
+ assert_contains "both surfaces suppression" "$OUT" "skipDangerousModePermissionPrompt=true"
156
+ assert_contains "both references #65848" "$OUT" "#65848"
157
+
158
+ # Test 20: benign settings.json (default mode, no skip) stays silent
159
+ printf '%s' '{"permissions":{"defaultMode":"default"}}' > "$FIX_DIR/benign.json"
160
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/benign.json")
161
+ RC=$?
162
+ assert_exit "benign settings exit 0" "$RC" "0"
163
+ assert_not_contains "benign settings silent" "$OUT" "bypass mode ACTIVE"
164
+ assert_not_contains "benign settings no suppression note" "$OUT" "SUPPRESSED"
165
+
166
+ # Test 21: missing settings file is fail-open (no crash, silent on no other signal)
167
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/does-not-exist.json")
168
+ RC=$?
169
+ assert_exit "missing settings exit 0" "$RC" "0"
170
+ assert_not_contains "missing settings silent" "$OUT" "bypass mode ACTIVE"
171
+
172
+ # Test 22: DISABLE still silences the settings.json path
173
+ OUT=$(run_hook '{}' CC_BYPASS_VERIFIER_SETTINGS="$FIX_DIR/both.json" CC_BYPASS_VERIFIER_DISABLE=1)
174
+ assert_not_contains "disable silences settings path" "$OUT" "bypass mode ACTIVE"
175
+ assert_not_contains "disable silences suppression note" "$OUT" "SUPPRESSED"
176
+
177
+ echo ""
178
+ echo "Tests: $((PASS+FAIL)) | Passed: $PASS | Failed: $FAIL"
179
+ [ "$FAIL" = "0" ] && exit 0 || exit 1