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,366 @@
1
+ #!/bin/bash
2
+ # Tests for pre-execution-claim-detector.sh
3
+ HOOK="$(dirname "$0")/../examples/pre-execution-claim-detector.sh"
4
+ PASS=0
5
+ FAIL=0
6
+
7
+ mktempd() {
8
+ mktemp -d "${TMPDIR:-/tmp}/cc-pre-claim-test.XXXXXX"
9
+ }
10
+
11
+ run_test() {
12
+ local desc="$1"
13
+ local result="$2"
14
+ if [ "$result" = "pass" ]; then
15
+ echo " PASS: $desc"
16
+ PASS=$((PASS + 1))
17
+ else
18
+ echo " FAIL: $desc"
19
+ FAIL=$((FAIL + 1))
20
+ fi
21
+ }
22
+
23
+ # Helper: create a transcript with the given assistant text
24
+ make_transcript() {
25
+ local file="$1"
26
+ local text="$2"
27
+ local model="${3:-claude-opus-4-8}"
28
+ # Escape the text for JSON embedding
29
+ printf '{"type":"user","message":{"content":"hi"}}\n' > "$file"
30
+ jq -cn --arg t "$text" --arg m "$model" \
31
+ '{type:"assistant",message:{model:$m,content:[{type:"text",text:$t}]}}' >> "$file"
32
+ }
33
+
34
+ echo "Testing pre-execution-claim-detector.sh"
35
+ echo "======================================="
36
+
37
+ # Test 1: opt-in env unset → silent exit, no log
38
+ TEST_DIR=$(mktempd)
39
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
40
+ LOG="$TEST_DIR/log.jsonl"
41
+ make_transcript "$TRANSCRIPT" "the result was: \$891"
42
+ echo "{\"session_id\":\"s1\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
43
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" bash "$HOOK" 2>/dev/null
44
+ EXIT=$?
45
+ if [ "$EXIT" = "0" ] && [ ! -f "$LOG" ]; then
46
+ run_test "opt-in env unset → silent, no log" pass
47
+ else
48
+ run_test "opt-in env unset → silent, no log" fail
49
+ fi
50
+ rm -rf "$TEST_DIR"
51
+
52
+ # Test 2: opt-in but DISABLE=1 → silent
53
+ TEST_DIR=$(mktempd)
54
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
55
+ LOG="$TEST_DIR/log.jsonl"
56
+ make_transcript "$TRANSCRIPT" "the result was: \$891"
57
+ echo "{\"session_id\":\"s2\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
58
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" \
59
+ CC_OPUS48_PRE_CLAIM_DETECT=1 \
60
+ CC_OPUS48_PRE_CLAIM_DISABLE=1 \
61
+ bash "$HOOK" 2>/dev/null
62
+ if [ ! -f "$LOG" ]; then
63
+ run_test "DETECT=1 + DISABLE=1 → silent (disable wins)" pass
64
+ else
65
+ run_test "DETECT=1 + DISABLE=1 → silent (disable wins)" fail
66
+ fi
67
+ rm -rf "$TEST_DIR"
68
+
69
+ # Test 3: missing transcript → silent exit
70
+ TEST_DIR=$(mktempd)
71
+ LOG="$TEST_DIR/log.jsonl"
72
+ echo '{"session_id":"s3","tool_name":"Bash","transcript_path":"/nonexistent/file.jsonl"}' | \
73
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 bash "$HOOK" 2>/dev/null
74
+ EXIT=$?
75
+ if [ "$EXIT" = "0" ] && [ ! -f "$LOG" ]; then
76
+ run_test "missing transcript → silent exit" pass
77
+ else
78
+ run_test "missing transcript → silent exit" fail
79
+ fi
80
+ rm -rf "$TEST_DIR"
81
+
82
+ # Test 4: Pattern 1 (claim-prefix) matches "the result was:"
83
+ TEST_DIR=$(mktempd)
84
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
85
+ LOG="$TEST_DIR/log.jsonl"
86
+ STDERR_FILE="$TEST_DIR/stderr"
87
+ make_transcript "$TRANSCRIPT" "the result was: foo bar"
88
+ echo "{\"session_id\":\"s4\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
89
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
90
+ bash "$HOOK" 2>"$STDERR_FILE"
91
+ if [ -f "$LOG" ] && grep -q '"pattern":"claim-prefix"' "$LOG" && \
92
+ grep -q "Cluster 22" "$STDERR_FILE"; then
93
+ run_test "Pattern 1: 'the result was:' → claim-prefix match" pass
94
+ else
95
+ run_test "Pattern 1: 'the result was:' → claim-prefix match" fail
96
+ fi
97
+ rm -rf "$TEST_DIR"
98
+
99
+ # Test 5: Pattern 1 case-insensitive match
100
+ TEST_DIR=$(mktempd)
101
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
102
+ LOG="$TEST_DIR/log.jsonl"
103
+ make_transcript "$TRANSCRIPT" "The Output Shows: something"
104
+ echo "{\"session_id\":\"s5\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
105
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
106
+ bash "$HOOK" 2>/dev/null
107
+ if [ -f "$LOG" ] && grep -q '"pattern":"claim-prefix"' "$LOG"; then
108
+ run_test "Pattern 1: case-insensitive 'The Output Shows:'" pass
109
+ else
110
+ run_test "Pattern 1: case-insensitive 'The Output Shows:'" fail
111
+ fi
112
+ rm -rf "$TEST_DIR"
113
+
114
+ # Test 6: Pattern 2 (action-then-value): "I confirmed X and Y"
115
+ TEST_DIR=$(mktempd)
116
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
117
+ LOG="$TEST_DIR/log.jsonl"
118
+ make_transcript "$TRANSCRIPT" "I confirmed the deployment and everything looks healthy"
119
+ echo "{\"session_id\":\"s6\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
120
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
121
+ bash "$HOOK" 2>/dev/null
122
+ if [ -f "$LOG" ] && grep -q '"pattern":"action-then-value"' "$LOG"; then
123
+ run_test "Pattern 2: 'I confirmed X and Y' → action-then-value" pass
124
+ else
125
+ run_test "Pattern 2: 'I confirmed X and Y' → action-then-value" fail
126
+ fi
127
+ rm -rf "$TEST_DIR"
128
+
129
+ # Test 7: Pattern 3 (bare price claim, no hedge)
130
+ TEST_DIR=$(mktempd)
131
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
132
+ LOG="$TEST_DIR/log.jsonl"
133
+ make_transcript "$TRANSCRIPT" "The flight costs \$891 per person."
134
+ echo "{\"session_id\":\"s7\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
135
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
136
+ bash "$HOOK" 2>/dev/null
137
+ if [ -f "$LOG" ] && grep -q '"pattern":"bare-price-claim"' "$LOG"; then
138
+ run_test "Pattern 3: bare price '\$891' without hedge → bare-price-claim" pass
139
+ else
140
+ run_test "Pattern 3: bare price '\$891' without hedge → bare-price-claim" fail
141
+ fi
142
+ rm -rf "$TEST_DIR"
143
+
144
+ # Test 8: Pattern 3 suppressed when hedge precedes
145
+ TEST_DIR=$(mktempd)
146
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
147
+ LOG="$TEST_DIR/log.jsonl"
148
+ make_transcript "$TRANSCRIPT" "Let me check the flight prices. I'll search for the \$891 fare to see if it's still available."
149
+ echo "{\"session_id\":\"s8\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
150
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
151
+ bash "$HOOK" 2>/dev/null
152
+ if [ ! -f "$LOG" ]; then
153
+ run_test "Pattern 3 hedge suppresses bare-price ('let me check' preceded \$891)" pass
154
+ else
155
+ run_test "Pattern 3 hedge suppresses bare-price ('let me check' preceded \$891)" fail
156
+ fi
157
+ rm -rf "$TEST_DIR"
158
+
159
+ # Test 9: Pattern 4 (bare SHA-like 40 hex chars)
160
+ TEST_DIR=$(mktempd)
161
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
162
+ LOG="$TEST_DIR/log.jsonl"
163
+ make_transcript "$TRANSCRIPT" "The latest commit is a1b2c3d4e5f6789012345678901234567890abcd on main."
164
+ echo "{\"session_id\":\"s9\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
165
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
166
+ bash "$HOOK" 2>/dev/null
167
+ if [ -f "$LOG" ] && grep -q '"pattern":"bare-sha-claim"' "$LOG"; then
168
+ run_test "Pattern 4: bare SHA → bare-sha-claim" pass
169
+ else
170
+ run_test "Pattern 4: bare SHA → bare-sha-claim" fail
171
+ fi
172
+ rm -rf "$TEST_DIR"
173
+
174
+ # Test 10: Pattern 4 suppressed when "let me run" precedes
175
+ TEST_DIR=$(mktempd)
176
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
177
+ LOG="$TEST_DIR/log.jsonl"
178
+ make_transcript "$TRANSCRIPT" "Let me run git log. The SHA might be a1b2c3d4e5f6789012345678901234567890abcd if uncommitted."
179
+ echo "{\"session_id\":\"s10\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
180
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
181
+ bash "$HOOK" 2>/dev/null
182
+ if [ ! -f "$LOG" ]; then
183
+ run_test "Pattern 4 hedge suppresses bare-sha ('let me run' precedes)" pass
184
+ else
185
+ run_test "Pattern 4 hedge suppresses bare-sha ('let me run' precedes)" fail
186
+ fi
187
+ rm -rf "$TEST_DIR"
188
+
189
+ # Test 11: Pattern 5 (file-path-then-block) — `path` followed by ``` block
190
+ TEST_DIR=$(mktempd)
191
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
192
+ LOG="$TEST_DIR/log.jsonl"
193
+ make_transcript "$TRANSCRIPT" "The file \`/etc/config.yaml\` contains:
194
+ \`\`\`yaml
195
+ key: value
196
+ \`\`\`"
197
+ echo "{\"session_id\":\"s11\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
198
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
199
+ bash "$HOOK" 2>/dev/null
200
+ if [ -f "$LOG" ] && grep -q '"pattern":"file-path-then-block"' "$LOG"; then
201
+ run_test "Pattern 5: backtick file path + code block → file-path-then-block" pass
202
+ else
203
+ run_test "Pattern 5: backtick file path + code block → file-path-then-block" fail
204
+ fi
205
+ rm -rf "$TEST_DIR"
206
+
207
+ # Test 12: benign assistant text → no match
208
+ TEST_DIR=$(mktempd)
209
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
210
+ LOG="$TEST_DIR/log.jsonl"
211
+ make_transcript "$TRANSCRIPT" "I'll now run the analysis. Let me check the configuration first."
212
+ echo "{\"session_id\":\"s12\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
213
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
214
+ bash "$HOOK" 2>/dev/null
215
+ if [ ! -f "$LOG" ]; then
216
+ run_test "benign text → no match" pass
217
+ else
218
+ run_test "benign text → no match" fail
219
+ fi
220
+ rm -rf "$TEST_DIR"
221
+
222
+ # Test 13: QUIET=1 suppresses entirely
223
+ TEST_DIR=$(mktempd)
224
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
225
+ LOG="$TEST_DIR/log.jsonl"
226
+ make_transcript "$TRANSCRIPT" "the result was: foo"
227
+ echo "{\"session_id\":\"s13\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
228
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" \
229
+ CC_OPUS48_PRE_CLAIM_DETECT=1 \
230
+ CC_OPUS48_PRE_CLAIM_QUIET=1 \
231
+ bash "$HOOK" 2>/dev/null
232
+ if [ ! -f "$LOG" ]; then
233
+ run_test "QUIET=1 → silent (no log)" pass
234
+ else
235
+ run_test "QUIET=1 → silent (no log)" fail
236
+ fi
237
+ rm -rf "$TEST_DIR"
238
+
239
+ # Test 14: stderr advisory includes anchor issue #64065
240
+ TEST_DIR=$(mktempd)
241
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
242
+ LOG="$TEST_DIR/log.jsonl"
243
+ STDERR_FILE="$TEST_DIR/stderr"
244
+ make_transcript "$TRANSCRIPT" "the file contains: x"
245
+ echo "{\"session_id\":\"s14\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
246
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
247
+ bash "$HOOK" 2>"$STDERR_FILE"
248
+ if grep -q "#64065" "$STDERR_FILE"; then
249
+ run_test "stderr includes anchor #64065" pass
250
+ else
251
+ run_test "stderr includes anchor #64065" fail
252
+ fi
253
+ rm -rf "$TEST_DIR"
254
+
255
+ # Test 15: stderr advisory includes Opus 4.7 fallback
256
+ TEST_DIR=$(mktempd)
257
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
258
+ LOG="$TEST_DIR/log.jsonl"
259
+ STDERR_FILE="$TEST_DIR/stderr"
260
+ make_transcript "$TRANSCRIPT" "the response was: y"
261
+ echo "{\"session_id\":\"s15\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
262
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
263
+ bash "$HOOK" 2>"$STDERR_FILE"
264
+ if grep -q "claude-opus-4-7" "$STDERR_FILE"; then
265
+ run_test "stderr includes Opus 4.7 fallback path" pass
266
+ else
267
+ run_test "stderr includes Opus 4.7 fallback path" fail
268
+ fi
269
+ rm -rf "$TEST_DIR"
270
+
271
+ # Test 16: log records model from transcript
272
+ TEST_DIR=$(mktempd)
273
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
274
+ LOG="$TEST_DIR/log.jsonl"
275
+ make_transcript "$TRANSCRIPT" "the result was: q" "claude-opus-4-8"
276
+ echo "{\"session_id\":\"s16\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
277
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
278
+ bash "$HOOK" 2>/dev/null
279
+ if grep -q '"model":"claude-opus-4-8"' "$LOG"; then
280
+ run_test "log records model from transcript" pass
281
+ else
282
+ run_test "log records model from transcript" fail
283
+ fi
284
+ rm -rf "$TEST_DIR"
285
+
286
+ # Test 17: log records tool_name from input
287
+ TEST_DIR=$(mktempd)
288
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
289
+ LOG="$TEST_DIR/log.jsonl"
290
+ make_transcript "$TRANSCRIPT" "the result was: q"
291
+ echo "{\"session_id\":\"s17\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
292
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
293
+ bash "$HOOK" 2>/dev/null
294
+ if grep -q '"tool":"Bash"' "$LOG"; then
295
+ run_test "log records tool name from input" pass
296
+ else
297
+ run_test "log records tool name from input" fail
298
+ fi
299
+ rm -rf "$TEST_DIR"
300
+
301
+ # Test 18: corrupted JSON input → exit 0 quietly
302
+ TEST_DIR=$(mktempd)
303
+ LOG="$TEST_DIR/log.jsonl"
304
+ echo 'not json {{{' | \
305
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
306
+ bash "$HOOK" 2>/dev/null
307
+ EXIT=$?
308
+ if [ "$EXIT" = "0" ] && [ ! -f "$LOG" ]; then
309
+ run_test "corrupted JSON → exit 0, no log" pass
310
+ else
311
+ run_test "corrupted JSON → exit 0, no log (exit=$EXIT)" fail
312
+ fi
313
+ rm -rf "$TEST_DIR"
314
+
315
+ # Test 19: empty transcript → silent
316
+ TEST_DIR=$(mktempd)
317
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
318
+ LOG="$TEST_DIR/log.jsonl"
319
+ touch "$TRANSCRIPT"
320
+ echo "{\"session_id\":\"s19\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
321
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
322
+ bash "$HOOK" 2>/dev/null
323
+ EXIT=$?
324
+ if [ "$EXIT" = "0" ] && [ ! -f "$LOG" ]; then
325
+ run_test "empty transcript → silent" pass
326
+ else
327
+ run_test "empty transcript → silent" fail
328
+ fi
329
+ rm -rf "$TEST_DIR"
330
+
331
+ # Test 20: only-user-message transcript → silent (no assistant text)
332
+ TEST_DIR=$(mktempd)
333
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
334
+ LOG="$TEST_DIR/log.jsonl"
335
+ echo '{"type":"user","message":{"content":"the result was: \$891"}}' > "$TRANSCRIPT"
336
+ echo "{\"session_id\":\"s20\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
337
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
338
+ bash "$HOOK" 2>/dev/null
339
+ if [ ! -f "$LOG" ]; then
340
+ run_test "only-user-message → no match (skip user text)" pass
341
+ else
342
+ run_test "only-user-message → no match (skip user text)" fail
343
+ fi
344
+ rm -rf "$TEST_DIR"
345
+
346
+ # Test 21: log includes ISO 8601 UTC timestamp
347
+ TEST_DIR=$(mktempd)
348
+ TRANSCRIPT="$TEST_DIR/t.jsonl"
349
+ LOG="$TEST_DIR/log.jsonl"
350
+ make_transcript "$TRANSCRIPT" "the file was: yes"
351
+ echo "{\"session_id\":\"s21\",\"tool_name\":\"Bash\",\"transcript_path\":\"$TRANSCRIPT\"}" | \
352
+ CC_OPUS48_PRE_CLAIM_LOG="$LOG" CC_OPUS48_PRE_CLAIM_DETECT=1 \
353
+ bash "$HOOK" 2>/dev/null
354
+ if grep -qE '"ts":"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z"' "$LOG"; then
355
+ run_test "log includes ISO 8601 UTC timestamp" pass
356
+ else
357
+ run_test "log includes ISO 8601 UTC timestamp" fail
358
+ fi
359
+ rm -rf "$TEST_DIR"
360
+
361
+ echo ""
362
+ echo "Results: $PASS passed, $FAIL failed"
363
+ if [ "$FAIL" -gt 0 ]; then
364
+ exit 1
365
+ fi
366
+ exit 0
@@ -0,0 +1,100 @@
1
+ #!/bin/bash
2
+ # Tests for two gaps measured on Claude Code 2.1.246 (2026-08-29):
3
+ # 1. sensitive-file-read-guard let id_rsa.bak / id_rsa_old through, because
4
+ # the private-key pattern was anchored with a bare "$". A backup of a key
5
+ # is exactly as sensitive as the key.
6
+ # 2. credential-file-cat-guard covered .pypirc and .npmrc but not
7
+ # .git-credentials, which stores "https://user:token@host" in plain text.
8
+ # Both guards must keep passing the files they were always meant to pass, so
9
+ # the allow cases below are as important as the block cases.
10
+ #
11
+ # Run: bash tests/test-private-key-backup-and-git-credentials.sh
12
+ set -uo pipefail
13
+
14
+ READ_HOOK="$(dirname "$0")/../examples/sensitive-file-read-guard.sh"
15
+ CAT_HOOK="$(dirname "$0")/../examples/credential-file-cat-guard.sh"
16
+ PASS=0 FAIL=0
17
+
18
+ run_read() {
19
+ local desc="$1" expected_exit="$2" path="$3"
20
+ local actual_exit
21
+ echo "{\"tool_name\":\"Read\",\"tool_input\":{\"file_path\":\"${path}\"}}" \
22
+ | bash "$READ_HOOK" >/dev/null 2>/dev/null
23
+ actual_exit=$?
24
+ if [ "$actual_exit" -eq "$expected_exit" ]; then
25
+ echo " PASS: $desc"; PASS=$((PASS + 1))
26
+ else
27
+ echo " FAIL: $desc (expected exit $expected_exit, got $actual_exit)"; FAIL=$((FAIL + 1))
28
+ fi
29
+ }
30
+
31
+ run_cat() {
32
+ local desc="$1" expected_exit="$2" cmd="$3"
33
+ local actual_exit
34
+ echo "{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":${cmd}}}" \
35
+ | bash "$CAT_HOOK" >/dev/null 2>/dev/null
36
+ actual_exit=$?
37
+ if [ "$actual_exit" -eq "$expected_exit" ]; then
38
+ echo " PASS: $desc"; PASS=$((PASS + 1))
39
+ else
40
+ echo " FAIL: $desc (expected exit $expected_exit, got $actual_exit)"; FAIL=$((FAIL + 1))
41
+ fi
42
+ }
43
+
44
+ echo "Testing private-key backups and .git-credentials"
45
+ echo "==============================================="
46
+
47
+ # --- BLOCK: private key backups ---
48
+ run_read "id_rsa.bak blocks" 2 "/home/u/.ssh/id_rsa.bak"
49
+ run_read "id_rsa_old blocks" 2 "/home/u/.ssh/id_rsa_old"
50
+ run_read "id_rsa.orig blocks" 2 "/home/u/.ssh/id_rsa.orig"
51
+ run_read "id_rsa.save blocks" 2 "/home/u/.ssh/id_rsa.save"
52
+ run_read "id_rsa-copy blocks" 2 "/home/u/.ssh/id_rsa-copy"
53
+ run_read "id_ed25519.backup blocks" 2 "/home/u/.ssh/id_ed25519.backup"
54
+ run_read "id_ecdsa.2 blocks" 2 "/home/u/.ssh/id_ecdsa.2"
55
+
56
+ # --- BLOCK: the three that survived the first widening ---
57
+ # Found by audit/boundary.sh after the first fix looked complete. Each one is
58
+ # the same file to whoever reads it and a different string to the matcher.
59
+ run_read "id_rsa~ (editor backup) blocks" 2 "/home/u/.ssh/id_rsa~"
60
+ run_read "id_rsa.old.2 (two suffixes) blocks" 2 "/home/u/.ssh/id_rsa.old.2"
61
+ run_read "id_rsa with trailing space blocks" 2 "/home/u/.ssh/id_rsa "
62
+ run_read "ID_RSA (uppercased) blocks" 2 "/home/u/.ssh/ID_RSA"
63
+ run_read "id_ed25519~ blocks" 2 "/home/u/.ssh/id_ed25519~"
64
+ # ...and the public key must survive all of that, trailing space included.
65
+ run_read "id_rsa.pub with trailing space allows" 0 "/home/u/.ssh/id_rsa.pub "
66
+
67
+ # --- BLOCK: the original cases must not regress ---
68
+ run_read "id_rsa still blocks" 2 "/home/u/.ssh/id_rsa"
69
+ run_read "id_ed25519 still blocks" 2 "/home/u/.ssh/id_ed25519"
70
+ run_read "aws credentials still blocks" 2 "/home/u/.aws/credentials"
71
+
72
+ # --- ALLOW: public keys and everything else must still pass ---
73
+ run_read "id_rsa.pub allows" 0 "/home/u/.ssh/id_rsa.pub"
74
+ run_read "id_ed25519.pub allows" 0 "/home/u/.ssh/id_ed25519.pub"
75
+ run_read "ssh config allows" 0 "/home/u/.ssh/config"
76
+ run_read "known_hosts allows" 0 "/home/u/.ssh/known_hosts"
77
+ run_read "project file allows" 0 "/home/u/app/README.md"
78
+ # A filename that merely starts with a key name is not a key.
79
+ run_read "id_rsa_generator.py allows" 0 "/home/u/tools/id_rsa_generator.py"
80
+ run_read "id_rsa.md allows" 0 "/home/u/docs/id_rsa.md"
81
+
82
+ # --- BLOCK: .git-credentials ---
83
+ run_cat "cat ~/.git-credentials blocks" 2 '"cat ~/.git-credentials"'
84
+ run_cat "head .git-credentials blocks" 2 '"head -1 /home/u/.git-credentials"'
85
+ run_cat "grep in .git-credentials blocks" 2 '"grep github /home/u/.git-credentials"'
86
+
87
+ # --- BLOCK: the original cases must not regress ---
88
+ run_cat "cat ~/.npmrc still blocks" 2 '"cat ~/.npmrc"'
89
+ run_cat "cat ~/.netrc still blocks" 2 '"cat ~/.netrc"'
90
+ run_cat "cat ~/.pypirc still blocks" 2 '"cat ~/.pypirc"'
91
+
92
+ # --- ALLOW: ordinary reads must still pass ---
93
+ run_cat "cat README.md allows" 0 '"cat README.md"'
94
+ run_cat "cat .git/config allows" 0 '"cat .git/config"'
95
+ run_cat "git config --list allows" 0 '"git config --list"'
96
+
97
+ echo
98
+ echo "=========================="
99
+ echo "Results: $PASS passed, $FAIL failed"
100
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,214 @@
1
+ #!/bin/bash
2
+ # Tests for proxy-capture-suggester.sh
3
+ HOOK="$(dirname "$0")/../examples/proxy-capture-suggester.sh"
4
+ PASS=0
5
+ FAIL=0
6
+
7
+ run_test() {
8
+ local desc="$1"
9
+ local result="$2"
10
+ if [ "$result" = "pass" ]; then
11
+ echo " PASS: $desc"
12
+ PASS=$((PASS + 1))
13
+ else
14
+ echo " FAIL: $desc"
15
+ FAIL=$((FAIL + 1))
16
+ fi
17
+ }
18
+
19
+ # Helper: run hook with a clean env. The caller passes overrides as VAR=value tokens.
20
+ run_hook() {
21
+ env -i HOME="$HOME" PATH="$PATH" "$@" bash "$HOOK" 2>&1
22
+ }
23
+
24
+ echo "Testing proxy-capture-suggester.sh"
25
+ echo "===================================="
26
+
27
+ # Test 1: Default (ENABLE unset) → silent, no advisory
28
+ OUT=$(run_hook)
29
+ EXIT=$?
30
+ if [ "$EXIT" = "0" ] && [ -z "$OUT" ]; then
31
+ run_test "ENABLE unset → silent (default off, opt-in only)" pass
32
+ else
33
+ run_test "ENABLE unset (exit=$EXIT, out_len=${#OUT})" fail
34
+ fi
35
+
36
+ # Test 2: QUIET=1 silences even when ENABLE=1
37
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 CC_PROXY_CAPTURE_SUGGESTER_QUIET=1)
38
+ EXIT=$?
39
+ if [ "$EXIT" = "0" ] && [ -z "$OUT" ]; then
40
+ run_test "QUIET=1 silences even with ENABLE=1" pass
41
+ else
42
+ run_test "QUIET=1 (exit=$EXIT, out_len=${#OUT})" fail
43
+ fi
44
+
45
+ # Test 3: ENABLE=1 + no proxy → full four-tool advisory emitted
46
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
47
+ EXIT=$?
48
+ if [ "$EXIT" = "0" ] && echo "$OUT" | grep -q "Compliance audit intent declared"; then
49
+ run_test "ENABLE=1, no proxy → full advisory emitted" pass
50
+ else
51
+ run_test "Full advisory (exit=$EXIT)" fail
52
+ fi
53
+
54
+ # Test 4: ENABLE=1 + HTTPS_PROXY set + no log dir → short advisory about audit sink
55
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080)
56
+ EXIT=$?
57
+ if [ "$EXIT" = "0" ] && echo "$OUT" | grep -q "ANTHROPIC_LOG_DIR is unset"; then
58
+ run_test "ENABLE=1 + proxy + no log dir → audit-sink advisory" pass
59
+ else
60
+ run_test "Audit-sink advisory (exit=$EXIT, OUT excerpt: $(echo "$OUT" | head -1))" fail
61
+ fi
62
+
63
+ # Test 5: ENABLE=1 + HTTPS_PROXY set + ANTHROPIC_LOG_DIR set → silent
64
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080 ANTHROPIC_LOG_DIR=/tmp/audit)
65
+ EXIT=$?
66
+ if [ "$EXIT" = "0" ] && [ -z "$OUT" ]; then
67
+ run_test "ENABLE=1 + proxy + log dir → silent (fully configured)" pass
68
+ else
69
+ run_test "Fully configured silent (exit=$EXIT, out_len=${#OUT})" fail
70
+ fi
71
+
72
+ # Test 6: Lowercase https_proxy honored
73
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 https_proxy=http://127.0.0.1:8080)
74
+ EXIT=$?
75
+ if [ "$EXIT" = "0" ] && echo "$OUT" | grep -q "ANTHROPIC_LOG_DIR is unset"; then
76
+ run_test "Lowercase https_proxy detected as active" pass
77
+ else
78
+ run_test "Lowercase https_proxy detection (exit=$EXIT)" fail
79
+ fi
80
+
81
+ # Test 7: ALL_PROXY honored as a proxy signal
82
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 ALL_PROXY=http://127.0.0.1:8080)
83
+ EXIT=$?
84
+ if [ "$EXIT" = "0" ] && echo "$OUT" | grep -q "ANTHROPIC_LOG_DIR is unset"; then
85
+ run_test "ALL_PROXY detected as active" pass
86
+ else
87
+ run_test "ALL_PROXY detection (exit=$EXIT)" fail
88
+ fi
89
+
90
+ # Test 8: Empty HTTPS_PROXY does NOT count as active (treated as unset)
91
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=)
92
+ EXIT=$?
93
+ if [ "$EXIT" = "0" ] && echo "$OUT" | grep -q "Compliance audit intent declared"; then
94
+ run_test "Empty HTTPS_PROXY treated as unset → full advisory" pass
95
+ else
96
+ run_test "Empty HTTPS_PROXY (exit=$EXIT, OUT excerpt: $(echo "$OUT" | head -1))" fail
97
+ fi
98
+
99
+ # Test 9: Advisory enumerates four distinct proxy tools
100
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
101
+ if echo "$OUT" | grep -q "mitmproxy" \
102
+ && echo "$OUT" | grep -qi "burp" \
103
+ && echo "$OUT" | grep -qi "charles" \
104
+ && echo "$OUT" | grep -q "ANTHROPIC_LOG"; then
105
+ run_test "Advisory enumerates four audit paths" pass
106
+ else
107
+ run_test "Four-tool enumeration (mitm=$(echo "$OUT" | grep -c mitmproxy), burp=$(echo "$OUT" | grep -ci burp))" fail
108
+ fi
109
+
110
+ # Test 10: Advisory includes a concrete HTTPS_PROXY bridge command
111
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
112
+ if echo "$OUT" | grep -q "export HTTPS_PROXY="; then
113
+ run_test "Advisory shows concrete HTTPS_PROXY bridge command" pass
114
+ else
115
+ run_test "HTTPS_PROXY bridge command" fail
116
+ fi
117
+
118
+ # Test 11: Advisory references the v2.1.150 cluster issue (#62061)
119
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
120
+ if echo "$OUT" | grep -q "62061"; then
121
+ run_test "Advisory references upstream cluster issue #62061" pass
122
+ else
123
+ run_test "Issue #62061 reference" fail
124
+ fi
125
+
126
+ # Test 12: Advisory mentions partner hooks for cluster coverage
127
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
128
+ if echo "$OUT" | grep -q "cache-residue-detector" \
129
+ && echo "$OUT" | grep -q "server-side-prompt-injection-detector"; then
130
+ run_test "Advisory names both partner hooks (cache-residue + server-side detector)" pass
131
+ else
132
+ run_test "Partner hook references" fail
133
+ fi
134
+
135
+ # Test 13: Advisory tells the user how to suppress via QUIET=1
136
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
137
+ if echo "$OUT" | grep -q "CC_PROXY_CAPTURE_SUGGESTER_QUIET"; then
138
+ run_test "Advisory tells user how to suppress via QUIET=1" pass
139
+ else
140
+ run_test "QUIET suppression instruction" fail
141
+ fi
142
+
143
+ # Test 14: ENABLE=0 explicitly → silent (treats non-1 values as off)
144
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=0)
145
+ EXIT=$?
146
+ if [ "$EXIT" = "0" ] && [ -z "$OUT" ]; then
147
+ run_test "ENABLE=0 → silent (only ENABLE=1 opts in)" pass
148
+ else
149
+ run_test "ENABLE=0 silences (exit=$EXIT, out_len=${#OUT})" fail
150
+ fi
151
+
152
+ # Test 15: ENABLE=true (non-1) → silent (strict ENABLE=1 gate)
153
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=true)
154
+ EXIT=$?
155
+ if [ "$EXIT" = "0" ] && [ -z "$OUT" ]; then
156
+ run_test "ENABLE=true → silent (strict ENABLE=1 only)" pass
157
+ else
158
+ run_test "ENABLE=true silences (exit=$EXIT, out_len=${#OUT})" fail
159
+ fi
160
+
161
+ # Test 16: Hook never blocks the session — all paths exit 0
162
+ EXIT_CODES=""
163
+ for case in "default" "quiet" "enable-no-proxy" "enable-proxy" "enable-proxy-log" "lowercase" "all-proxy" "empty-proxy" "enable-zero" "enable-true"; do
164
+ case "$case" in
165
+ "default") OUT=$(run_hook); EXIT=$? ;;
166
+ "quiet") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 CC_PROXY_CAPTURE_SUGGESTER_QUIET=1); EXIT=$? ;;
167
+ "enable-no-proxy") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1); EXIT=$? ;;
168
+ "enable-proxy") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080); EXIT=$? ;;
169
+ "enable-proxy-log") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080 ANTHROPIC_LOG_DIR=/tmp/x); EXIT=$? ;;
170
+ "lowercase") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 https_proxy=http://x); EXIT=$? ;;
171
+ "all-proxy") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 ALL_PROXY=http://x); EXIT=$? ;;
172
+ "empty-proxy") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=); EXIT=$? ;;
173
+ "enable-zero") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=0); EXIT=$? ;;
174
+ "enable-true") OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=true); EXIT=$? ;;
175
+ esac
176
+ EXIT_CODES="$EXIT_CODES $EXIT"
177
+ done
178
+ NONZERO=$(echo "$EXIT_CODES" | tr ' ' '\n' | grep -v "^$" | grep -v "^0$" | head -1)
179
+ if [ -z "$NONZERO" ]; then
180
+ run_test "Hook never blocks (all 10 paths exit 0)" pass
181
+ else
182
+ run_test "Hook never blocks (exit codes: $EXIT_CODES)" fail
183
+ fi
184
+
185
+ # Test 17: Idempotent — two invocations with same env produce identical output
186
+ OUT1=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
187
+ OUT2=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
188
+ if [ "$OUT1" = "$OUT2" ]; then
189
+ run_test "Idempotent: two invocations produce identical output" pass
190
+ else
191
+ run_test "Idempotent output" fail
192
+ fi
193
+
194
+ # Test 18: Audit-sink advisory includes concrete ANTHROPIC_LOG_DIR export command
195
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080)
196
+ if echo "$OUT" | grep -q 'export ANTHROPIC_LOG_DIR='; then
197
+ run_test "Audit-sink advisory has concrete export command" pass
198
+ else
199
+ run_test "Audit-sink export command" fail
200
+ fi
201
+
202
+ # Test 19: Audit-sink advisory mentions all three GUI tools' save mechanisms
203
+ OUT=$(run_hook CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 HTTPS_PROXY=http://127.0.0.1:8080)
204
+ if echo "$OUT" | grep -q "save-stream-file" \
205
+ && echo "$OUT" | grep -qi "burp" \
206
+ && echo "$OUT" | grep -qi "charles"; then
207
+ run_test "Audit-sink advisory enumerates three save mechanisms" pass
208
+ else
209
+ run_test "Save mechanism enumeration" fail
210
+ fi
211
+
212
+ echo "===================================="
213
+ echo "Results: $PASS passed, $FAIL failed"
214
+ [ "$FAIL" = "0" ] && exit 0 || exit 1