cc-safe-setup 29.8.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 (1017) 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-dispatch-watchdog.sh +149 -0
  178. package/examples/completion-claim-without-verification-detector.sh +207 -0
  179. package/examples/composer-guard.sh +12 -0
  180. package/examples/compound-bash-permission-resolver.sh +156 -0
  181. package/examples/compound-command-allow.sh +1 -1
  182. package/examples/compound-command-deny-enforcer.sh +183 -0
  183. package/examples/compound-inject-guard.sh +12 -0
  184. package/examples/concurrent-edit-lock.sh +12 -0
  185. package/examples/conflict-marker-guard.sh +12 -0
  186. package/examples/consecutive-error-breaker.sh +0 -0
  187. package/examples/console-log-count.sh +1 -0
  188. package/examples/context-compact-advisor.sh +29 -2
  189. package/examples/context-length-budget.sh +69 -0
  190. package/examples/context-threshold-alert.sh +12 -0
  191. package/examples/context-usage-drift-alert.sh +41 -13
  192. package/examples/conversation-history-guard.sh +12 -0
  193. package/examples/core-file-protect-guard.sh +12 -0
  194. package/examples/cors-star-warn.sh +0 -0
  195. package/examples/cost-incident-self-audit.sh +162 -0
  196. package/examples/cowork-claude-md-load-checker.sh +100 -0
  197. package/examples/cowork-fuse-staleness-watcher.sh +140 -0
  198. package/examples/cowork-hook-absence-warner.sh +167 -0
  199. package/examples/cowork-model-picker-advisor.sh +115 -0
  200. package/examples/credential-exfil-guard.sh +65 -4
  201. package/examples/credential-file-cat-guard.sh +17 -1
  202. package/examples/cron-create-receipt.sh +112 -0
  203. package/examples/cron-modification-guard.sh +12 -0
  204. package/examples/cross-product-mcp-spawn-detector.sh +178 -0
  205. package/examples/cwd-project-boundary-guard.sh +0 -0
  206. package/examples/daemon-zombie-worker-surfacer.sh +118 -0
  207. package/examples/daily-cost-guard.sh +164 -0
  208. package/examples/daily-usage-tracker.sh +0 -0
  209. package/examples/dangerous-pip-flag-guard.sh +12 -0
  210. package/examples/db-connect-guard.sh +13 -1
  211. package/examples/denied-action-retry-guard.sh +12 -0
  212. package/examples/deny-bypass-detector.sh +12 -0
  213. package/examples/deny-rule-integrity-verifier.sh +181 -0
  214. package/examples/dependency-install-guard.sh +12 -0
  215. package/examples/deploy-guard.sh +14 -2
  216. package/examples/deploy-path-verify-guard.sh +12 -0
  217. package/examples/deployment-readback-gate.sh +135 -0
  218. package/examples/deployment-readback-gh-adapter.sh +247 -0
  219. package/examples/deployment-verify-guard.sh +25 -2
  220. package/examples/destructive-db-script-write-guard.sh +166 -0
  221. package/examples/destructive-migration-write-guard.sh +163 -0
  222. package/examples/diff-size-guard.sh +12 -0
  223. package/examples/disabled-feature-toggle-advisor.sh +88 -0
  224. package/examples/disk-partition-guard.sh +12 -0
  225. package/examples/dispatch-allowlist-preflight.sh +301 -0
  226. package/examples/dispatch-liveness-watchdog.sh +216 -0
  227. package/examples/dispatch-receipt.sh +174 -0
  228. package/examples/django-migrate-guard.sh +12 -0
  229. package/examples/dns-config-guard.sh +12 -0
  230. package/examples/docker-dangerous-guard.sh +12 -0
  231. package/examples/docker-volume-guard.sh +0 -0
  232. package/examples/dockerfile-latest-guard.sh +1 -0
  233. package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
  234. package/examples/dotenv-commit-guard.sh +12 -0
  235. package/examples/dotenv-read-guard.sh +12 -0
  236. package/examples/dotfile-protection-guard.sh +12 -0
  237. package/examples/dotnet-build-on-edit.sh +1 -1
  238. package/examples/drizzle-migrate-guard.sh +27 -2
  239. package/examples/echo-probe-spam-detector.sh +176 -0
  240. package/examples/edit-counter-test-gate.sh +12 -0
  241. package/examples/edit-error-counter.sh +1 -1
  242. package/examples/edit-guard.sh +12 -0
  243. package/examples/edit-old-string-validator.sh +12 -0
  244. package/examples/edit-quote-ambiguity-guard.sh +97 -0
  245. package/examples/edit-retry-loop-guard.sh +0 -0
  246. package/examples/edit-verify.sh +0 -0
  247. package/examples/env-inline-secret-guard.sh +14 -2
  248. package/examples/env-naming-convention.sh +0 -0
  249. package/examples/env-prod-guard.sh +0 -0
  250. package/examples/env-required-check.sh +0 -0
  251. package/examples/env-source-guard.sh +12 -0
  252. package/examples/env-var-check.sh +24 -1
  253. package/examples/ephemeral-container-detector.sh +147 -0
  254. package/examples/error-memory-guard.sh +12 -0
  255. package/examples/evidence-claim-gate.sh +187 -0
  256. package/examples/exploration-budget-guard.sh +12 -0
  257. package/examples/expo-eject-guard.sh +13 -0
  258. package/examples/extended-thinking-loop-guard.sh +139 -0
  259. package/examples/extended-thinking-resume-warning.sh +119 -0
  260. package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
  261. package/examples/fabricated-command-detector.sh +145 -0
  262. package/examples/false-disk-full-guard.sh +63 -0
  263. package/examples/feature-deprecation-detector.sh +109 -0
  264. package/examples/file-change-tracker.sh +1 -1
  265. package/examples/file-change-undo-tracker.sh +0 -0
  266. package/examples/file-edit-backup.sh +63 -14
  267. package/examples/file-reference-check.sh +0 -0
  268. package/examples/file-size-limit.sh +12 -0
  269. package/examples/financial-operation-guard.sh +12 -0
  270. package/examples/firewall-guard.sh +12 -0
  271. package/examples/fish-shell-wrapper.sh +125 -7
  272. package/examples/five-hundred-milestone.sh +1 -0
  273. package/examples/flask-static-route-guard.sh +89 -0
  274. package/examples/forbidden-response-phrase-detector.sh +161 -0
  275. package/examples/gem-push-guard.sh +13 -0
  276. package/examples/gh-cli-destructive-guard.sh +13 -1
  277. package/examples/git-checkout-safety-guard.sh +12 -0
  278. package/examples/git-checkout-uncommitted-guard.sh +12 -0
  279. package/examples/git-config-guard.sh +12 -0
  280. package/examples/git-crypt-worktree-guard.sh +12 -0
  281. package/examples/git-filter-repo-guard.sh +56 -0
  282. package/examples/git-history-rewrite-guard.sh +12 -0
  283. package/examples/git-hook-bypass-guard.sh +0 -0
  284. package/examples/git-maintenance-guard.sh +83 -0
  285. package/examples/git-merge-conflict-prevent.sh +0 -0
  286. package/examples/git-message-length-check.sh +0 -0
  287. package/examples/git-message-length.sh +0 -0
  288. package/examples/git-operations-require-approval.sh +68 -14
  289. package/examples/git-pack-temp-cleanup-guard.sh +102 -0
  290. package/examples/git-push-blast-radius-guard.sh +218 -0
  291. package/examples/git-remote-guard.sh +24 -3
  292. package/examples/git-rm-orphan-wipe-guard.sh +85 -0
  293. package/examples/git-stash-before-checkout.sh +12 -0
  294. package/examples/git-stash-before-danger.sh +0 -0
  295. package/examples/git-submodule-guard.sh +69 -2
  296. package/examples/git-tag-guard.sh +12 -0
  297. package/examples/github-actions-secret-guard.sh +0 -0
  298. package/examples/gitignore-check.sh +0 -0
  299. package/examples/gitops-drift-guard.sh +12 -0
  300. package/examples/go-mod-tidy-warn.sh +1 -0
  301. package/examples/go-vet-after-edit.sh +12 -0
  302. package/examples/goal-iteration-limit-warner.sh +152 -0
  303. package/examples/grep-nul-false-negative-guard.sh +30 -0
  304. package/examples/growthbook-flag-monitor.sh +257 -0
  305. package/examples/hallucination-url-check.sh +1 -1
  306. package/examples/halt-signal-detector.sh +135 -0
  307. package/examples/handoff-on-clear.sh +65 -0
  308. package/examples/hardcoded-ip-guard.sh +1 -0
  309. package/examples/headless-empty-result-guard.sh +0 -0
  310. package/examples/headless-stop-guard.sh +0 -0
  311. package/examples/helm-install-guard.sh +2 -1
  312. package/examples/home-critical-bash-guard.sh +17 -1
  313. package/examples/hook-debug-wrapper.sh +6 -2
  314. package/examples/hook-permission-fixer.sh +0 -0
  315. package/examples/hook-self-disable-detector.sh +99 -0
  316. package/examples/hook-stdout-sanitizer.sh +6 -2
  317. package/examples/hook-tamper-guard.sh +12 -0
  318. package/examples/idle-session-cost-alert.sh +0 -0
  319. package/examples/image-dimension-guard.sh +109 -0
  320. package/examples/image-file-validator.sh +0 -0
  321. package/examples/iteration-quality-degradation-detector.sh +170 -0
  322. package/examples/java-compile-on-edit.sh +1 -1
  323. package/examples/json-syntax-check.sh +0 -0
  324. package/examples/k8s-production-guard.sh +13 -1
  325. package/examples/kill-process-guard.sh +12 -0
  326. package/examples/kubernetes-guard.sh +13 -1
  327. package/examples/laravel-artisan-guard.sh +13 -0
  328. package/examples/large-file-guard.sh +1 -1
  329. package/examples/log-level-guard.sh +0 -0
  330. package/examples/log-truncation-guard.sh +12 -0
  331. package/examples/long-session-malformed-tool-call-detector.sh +183 -0
  332. package/examples/loop-detector.sh +12 -0
  333. package/examples/magic-number-warn.sh +1 -0
  334. package/examples/main-branch-warn.sh +12 -0
  335. package/examples/markdown-link-check.sh +0 -0
  336. package/examples/max-concurrent-agents.sh +12 -0
  337. package/examples/max-edit-size-guard.sh +13 -0
  338. package/examples/max-file-count-guard.sh +0 -0
  339. package/examples/max-file-delete-count.sh +0 -0
  340. package/examples/max-function-length.sh +1 -0
  341. package/examples/max-import-count.sh +0 -0
  342. package/examples/max-subagent-count.sh +0 -0
  343. package/examples/mcp-config-freeze.sh +12 -0
  344. package/examples/mcp-config-poisoning-audit.sh +150 -0
  345. package/examples/mcp-data-boundary.sh +1 -1
  346. package/examples/mcp-misdiagnosis-arrest.sh +209 -0
  347. package/examples/mcp-orphan-leak-warner.sh +49 -0
  348. package/examples/mcp-permissions-ask-warner.sh +151 -0
  349. package/examples/mcp-routine-approval-detector.sh +154 -0
  350. package/examples/mcp-server-allowlist.sh +12 -0
  351. package/examples/mcp-server-guard.sh +12 -0
  352. package/examples/mcp-startup-bloat-detector.sh +87 -0
  353. package/examples/mcp-stdio-compatibility-test.sh +153 -0
  354. package/examples/mcp-tool-audit-log.sh +0 -0
  355. package/examples/mcp-tool-guard.sh +101 -1
  356. package/examples/mcp-warmup-wait.sh +0 -0
  357. package/examples/memory-chain-audit.sh +56 -0
  358. package/examples/memory-orphan-detector.sh +188 -0
  359. package/examples/memory-write-guard.sh +99 -17
  360. package/examples/migration-verify-guard.sh +12 -0
  361. package/examples/model-swap-suggester.sh +177 -0
  362. package/examples/model-version-alert.sh +5 -1
  363. package/examples/model-version-lock.sh +63 -0
  364. package/examples/move-delete-sequence-guard.sh +33 -2
  365. package/examples/multi-file-plan-routing-gate.sh +192 -0
  366. package/examples/multi-vendor-concurrent-warner.sh +108 -0
  367. package/examples/multi-window-auth-drift-detector.sh +183 -0
  368. package/examples/multiline-command-approver.sh +161 -23
  369. package/examples/nested-background-agent-guard.sh +109 -0
  370. package/examples/nested-spawn-inflight-guard.sh +178 -0
  371. package/examples/network-exfil-guard.sh +12 -0
  372. package/examples/network-guard.sh +12 -0
  373. package/examples/network-interface-guard.sh +12 -0
  374. package/examples/nextjs-env-guard.sh +1 -1
  375. package/examples/no-absolute-import.sh +0 -0
  376. package/examples/no-alert-confirm-prompt.sh +0 -0
  377. package/examples/no-anonymous-default-export.sh +0 -0
  378. package/examples/no-any-type.sh +0 -0
  379. package/examples/no-any-typescript.sh +1 -0
  380. package/examples/no-ask-human.sh +12 -0
  381. package/examples/no-assignment-in-condition.sh +0 -0
  382. package/examples/no-base64-exfil.sh +12 -0
  383. package/examples/no-callback-hell.sh +0 -0
  384. package/examples/no-circular-dependency.sh +0 -0
  385. package/examples/no-cleartext-storage.sh +0 -0
  386. package/examples/no-commented-code.sh +0 -0
  387. package/examples/no-commit-fixup.sh +0 -0
  388. package/examples/no-console-assert.sh +0 -0
  389. package/examples/no-console-error-swallow.sh +0 -0
  390. package/examples/no-console-in-prod.sh +0 -0
  391. package/examples/no-console-log-commit.sh +12 -0
  392. package/examples/no-console-log.sh +0 -0
  393. package/examples/no-console-time.sh +0 -0
  394. package/examples/no-cors-wildcard.sh +4 -1
  395. package/examples/no-curl-upload.sh +0 -0
  396. package/examples/no-dangerouslySetInnerHTML.sh +0 -0
  397. package/examples/no-dangling-await.sh +1 -0
  398. package/examples/no-debug-commit.sh +12 -0
  399. package/examples/no-debug-in-commit.sh +0 -0
  400. package/examples/no-deep-nesting.sh +0 -0
  401. package/examples/no-deep-relative-import.sh +1 -0
  402. package/examples/no-default-credentials.sh +0 -0
  403. package/examples/no-deploy-friday.sh +13 -1
  404. package/examples/no-disabled-test.sh +0 -0
  405. package/examples/no-document-write.sh +0 -0
  406. package/examples/no-empty-function.sh +0 -0
  407. package/examples/no-eval-in-template.sh +0 -0
  408. package/examples/no-eval-template.sh +3 -1
  409. package/examples/no-eval.sh +0 -0
  410. package/examples/no-exec-user-input.sh +0 -0
  411. package/examples/no-fixme-ship.sh +12 -0
  412. package/examples/no-floating-promises.sh +0 -0
  413. package/examples/no-force-flag.sh +22 -5
  414. package/examples/no-force-install.sh +0 -0
  415. package/examples/no-git-amend.sh +12 -0
  416. package/examples/no-git-rebase-public.sh +0 -0
  417. package/examples/no-global-install.sh +12 -0
  418. package/examples/no-global-state.sh +0 -0
  419. package/examples/no-hardcoded-port.sh +1 -0
  420. package/examples/no-hardcoded-url.sh +0 -0
  421. package/examples/no-helmet-missing.sh +0 -0
  422. package/examples/no-http-url.sh +1 -0
  423. package/examples/no-http-without-https.sh +0 -0
  424. package/examples/no-inline-style.sh +0 -0
  425. package/examples/no-inline-styles.sh +1 -0
  426. package/examples/no-innerhtml.sh +0 -0
  427. package/examples/no-install-global.sh +12 -0
  428. package/examples/no-jwt-in-url.sh +0 -0
  429. package/examples/no-large-commit.sh +0 -0
  430. package/examples/no-localhost-expose.sh +0 -0
  431. package/examples/no-magic-number.sh +0 -0
  432. package/examples/no-md5-sha1.sh +0 -0
  433. package/examples/no-mixed-line-endings.sh +8 -1
  434. package/examples/no-mutation-in-reducer.sh +0 -0
  435. package/examples/no-nested-ternary.sh +0 -0
  436. package/examples/no-network-exfil.sh +0 -0
  437. package/examples/no-open-redirect.sh +0 -0
  438. package/examples/no-output-truncation.sh +12 -0
  439. package/examples/no-package-downgrade.sh +0 -0
  440. package/examples/no-package-lock-edit.sh +12 -0
  441. package/examples/no-path-join-user-input.sh +0 -0
  442. package/examples/no-port-bind.sh +0 -0
  443. package/examples/no-process-exit.sh +0 -0
  444. package/examples/no-prototype-pollution.sh +0 -0
  445. package/examples/no-push-without-ci.sh +0 -0
  446. package/examples/no-push-without-tests.sh +12 -0
  447. package/examples/no-raw-password-in-url.sh +0 -0
  448. package/examples/no-root-user-docker.sh +1 -0
  449. package/examples/no-root-write.sh +12 -0
  450. package/examples/no-secrets-in-args.sh +4 -1
  451. package/examples/no-secrets-in-logs.sh +0 -0
  452. package/examples/no-sensitive-log.sh +0 -0
  453. package/examples/no-sleep-in-hooks.sh +0 -0
  454. package/examples/no-star-import-python.sh +1 -0
  455. package/examples/no-string-concat-sql.sh +0 -0
  456. package/examples/no-sudo-guard.sh +12 -0
  457. package/examples/no-sync-fs.sh +0 -0
  458. package/examples/no-todo-in-merge.sh +0 -0
  459. package/examples/no-todo-in-production.sh +1 -0
  460. package/examples/no-todo-without-issue.sh +0 -0
  461. package/examples/no-unused-import.sh +0 -0
  462. package/examples/no-var-keyword.sh +0 -0
  463. package/examples/no-verify-blocker.sh +12 -0
  464. package/examples/no-wget-piped-bash.sh +12 -0
  465. package/examples/no-wildcard-cors.sh +0 -0
  466. package/examples/no-wildcard-delete.sh +0 -0
  467. package/examples/no-wildcard-import.sh +0 -0
  468. package/examples/no-with-statement.sh +0 -0
  469. package/examples/no-write-outside-src.sh +0 -0
  470. package/examples/no-xml-external-entity.sh +0 -0
  471. package/examples/non-english-quality-warner.sh +156 -0
  472. package/examples/notify-waiting.sh +1 -1
  473. package/examples/npm-audit-warn.sh +0 -0
  474. package/examples/npm-global-install-guard.sh +12 -0
  475. package/examples/npm-publish-guard.sh +12 -0
  476. package/examples/npm-script-injection.sh +0 -0
  477. package/examples/npm-supply-chain-guard.sh +0 -0
  478. package/examples/nuxt-config-guard.sh +1 -0
  479. package/examples/oauth-refresh-monitor.sh +210 -0
  480. package/examples/opus-degradation-tracker.sh +187 -0
  481. package/examples/opus48-routine-task-warning.sh +196 -0
  482. package/examples/opus48-thinking-wedge-advisor.sh +143 -0
  483. package/examples/output-credential-scan.sh +1 -1
  484. package/examples/output-secret-mask.sh +31 -9
  485. package/examples/output-token-spike-detector.sh +145 -0
  486. package/examples/package-json-guard.sh +12 -0
  487. package/examples/package-lock-frozen.sh +12 -0
  488. package/examples/parallel-batch-size-limiter.sh +121 -0
  489. package/examples/parallel-cascade-detector.sh +116 -0
  490. package/examples/partial-view-claim-arrest.sh +174 -0
  491. package/examples/path-deny-bash-guard.sh +12 -0
  492. package/examples/path-traversal-guard.sh +12 -0
  493. package/examples/per-prompt-token-cap.sh +124 -0
  494. package/examples/permission-audit-log.sh +1 -1
  495. package/examples/permission-denial-enforcer.sh +12 -0
  496. package/examples/permission-entry-validator.sh +0 -0
  497. package/examples/persisted-1m-model-advisor.sh +88 -0
  498. package/examples/php-lint-on-edit.sh +1 -1
  499. package/examples/pii-upload-guard.sh +12 -0
  500. package/examples/pip-publish-guard.sh +13 -0
  501. package/examples/pip-requirements-guard.sh +12 -0
  502. package/examples/pip-venv-required.sh +12 -0
  503. package/examples/plan-mode-edit-guard.sh +12 -0
  504. package/examples/plan-mode-enforcer.sh +12 -0
  505. package/examples/plan-mode-strict-guard.sh +12 -0
  506. package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
  507. package/examples/plugin-process-cleanup.sh +0 -0
  508. package/examples/polyglot-rm-guard.sh +12 -0
  509. package/examples/post-compact-safety.sh +12 -0
  510. package/examples/post-edit-disk-verify.sh +152 -0
  511. package/examples/powershell-remove-item-guard.sh +85 -0
  512. package/examples/pr-description-check.sh +0 -0
  513. package/examples/pr-duplicate-guard.sh +13 -0
  514. package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
  515. package/examples/pre-compact-knowledge-save.sh +0 -0
  516. package/examples/pre-compact-transcript-backup.sh +0 -0
  517. package/examples/pre-execution-claim-detector.sh +179 -0
  518. package/examples/prefer-builtin-tools.sh +10 -1
  519. package/examples/prefer-const.sh +0 -0
  520. package/examples/prefer-dedicated-tools.sh +12 -0
  521. package/examples/prefer-optional-chaining.sh +0 -0
  522. package/examples/prisma-migrate-guard.sh +24 -7
  523. package/examples/production-port-kill-guard.sh +12 -0
  524. package/examples/prompt-injection-guard.sh +2 -1
  525. package/examples/prompt-usage-logger.sh +0 -0
  526. package/examples/protect-claudemd.sh +12 -0
  527. package/examples/protect-dotfiles.sh +12 -0
  528. package/examples/proxy-capture-suggester.sh +159 -0
  529. package/examples/public-artefact-socratic-narrowing.sh +232 -0
  530. package/examples/public-repo-push-guard.sh +12 -0
  531. package/examples/push-requires-test-pass-record.sh +0 -0
  532. package/examples/push-requires-test-pass.sh +12 -0
  533. package/examples/quota-anomaly-detector.sh +173 -0
  534. package/examples/quota-reset-audit.sh +58 -0
  535. package/examples/quoted-flag-approver.sh +99 -10
  536. package/examples/rails-migration-guard.sh +12 -0
  537. package/examples/rate-limit-guard.sh +0 -0
  538. package/examples/read-all-files-enforcer.sh +0 -0
  539. package/examples/read-budget-guard.sh +12 -0
  540. package/examples/read-loop-detector.sh +59 -0
  541. package/examples/read-once-guard.sh +96 -0
  542. package/examples/read-only-mode.sh +12 -0
  543. package/examples/readme-exists-check.sh +0 -0
  544. package/examples/record-read-coverage.sh +73 -0
  545. package/examples/redirect-fragment-warner.sh +149 -0
  546. package/examples/redis-flushall-guard.sh +13 -0
  547. package/examples/redundant-read-blocker.sh +132 -0
  548. package/examples/refusal-arrest-gate.sh +248 -0
  549. package/examples/registry-publish-guard.sh +13 -1
  550. package/examples/remote-control-billing-classifier.sh +135 -0
  551. package/examples/replace-all-guard.sh +12 -0
  552. package/examples/repo-visibility-guard.sh +12 -0
  553. package/examples/reroute-after-block-guard.sh +150 -0
  554. package/examples/response-budget-guard.sh +0 -0
  555. package/examples/resume-drift-watcher.sh +57 -0
  556. package/examples/rg-replace-flag-detector.sh +125 -0
  557. package/examples/rhetorical-verification-prompt-detector.sh +102 -0
  558. package/examples/ripgrep-permission-fix.sh +0 -0
  559. package/examples/rm-safety-net.sh +151 -8
  560. package/examples/role-tool-guard.sh +12 -0
  561. package/examples/route-handler-emptiness-gate.sh +324 -0
  562. package/examples/ruby-lint-on-edit.sh +1 -1
  563. package/examples/runtime-binary-change-detector.sh +102 -0
  564. package/examples/same-command-repeat-detector.sh +196 -0
  565. package/examples/same-correction-arrest.sh +169 -0
  566. package/examples/sandbox-denywrite-enforcer.sh +78 -0
  567. package/examples/sandbox-relative-path-audit.sh +83 -25
  568. package/examples/sandbox-write-verify.sh +12 -0
  569. package/examples/schema-migration-guard.sh +0 -0
  570. package/examples/scope-expansion-receipt.sh +178 -0
  571. package/examples/scope-guard.sh +88 -9
  572. package/examples/secret-file-read-guard.sh +12 -0
  573. package/examples/secret-file-write-guard.sh +150 -0
  574. package/examples/self-modify-bypass-guard.sh +0 -0
  575. package/examples/sensitive-file-read-guard.sh +23 -3
  576. package/examples/sensitive-log-guard.sh +1 -0
  577. package/examples/server-side-prompt-injection-detector.sh +69 -0
  578. package/examples/session-agent-cost-limiter.sh +12 -0
  579. package/examples/session-backup-on-start.sh +1 -1
  580. package/examples/session-cost-alert.sh +12 -0
  581. package/examples/session-drift-guard.sh +12 -0
  582. package/examples/session-duration-guard.sh +25 -2
  583. package/examples/session-end-logger.sh +0 -0
  584. package/examples/session-health-monitor.sh +0 -0
  585. package/examples/session-index-repair.sh +1 -1
  586. package/examples/session-memory-watchdog.sh +1 -0
  587. package/examples/session-permission-reset-guard.sh +12 -0
  588. package/examples/session-persistence-verifier.sh +93 -0
  589. package/examples/session-plugin-pin-watch.sh +68 -0
  590. package/examples/session-rate-monitor.sh +176 -0
  591. package/examples/session-resume-env-fix.sh +0 -0
  592. package/examples/session-start-quota-status.sh +193 -0
  593. package/examples/session-start-safety-check.sh +55 -3
  594. package/examples/session-state-saver.sh +0 -0
  595. package/examples/session-summary-stop.sh +1 -1
  596. package/examples/session-summary.sh +0 -0
  597. package/examples/session-token-counter.sh +1 -1
  598. package/examples/settings-hooks-key-restorer.sh +99 -0
  599. package/examples/settings-json-health-check.sh +57 -0
  600. package/examples/settings-json-model-guard.sh +0 -0
  601. package/examples/settings-regression-tester.sh +188 -0
  602. package/examples/shell-config-truncation-guard.sh +12 -0
  603. package/examples/shell-wrapper-guard.sh +12 -0
  604. package/examples/skill-cumulative-size-detector.sh +104 -0
  605. package/examples/skill-description-drop-detector.sh +148 -0
  606. package/examples/skill-gate.sh +0 -0
  607. package/examples/skill-truncation-detector.sh +154 -0
  608. package/examples/skills-context-recorder.sh +167 -0
  609. package/examples/skills-load-verifier.sh +96 -0
  610. package/examples/skills-settings-validator.sh +139 -0
  611. package/examples/sonnet-45-deprecation-helper.sh +85 -0
  612. package/examples/spec-file-scope-guard.sh +12 -0
  613. package/examples/spring-profile-guard.sh +1 -0
  614. package/examples/spurious-malformed-notice-detector.sh +247 -0
  615. package/examples/sql-bulk-delete-warn.sh +88 -0
  616. package/examples/sql-injection-detect.sh +0 -0
  617. package/examples/ssh-key-protect.sh +12 -0
  618. package/examples/staged-secret-scan.sh +22 -1
  619. package/examples/stale-temp-settings-detector.sh +86 -0
  620. package/examples/standing-rule-session-surfacer.sh +137 -0
  621. package/examples/stop-hook-sigterm-wrapper.sh +182 -0
  622. package/examples/stop-transcript-write-health.sh +64 -0
  623. package/examples/strict-allowlist.sh +57 -15
  624. package/examples/strip-coauthored-by.sh +50 -10
  625. package/examples/subagent-blast-radius-guard.sh +184 -0
  626. package/examples/subagent-boundary-precheck.sh +126 -0
  627. package/examples/subagent-budget-guard.sh +12 -0
  628. package/examples/subagent-claudemd-inject.sh +0 -0
  629. package/examples/subagent-closure-verify-gate.sh +164 -0
  630. package/examples/subagent-destructive-git-guard.sh +120 -0
  631. package/examples/subagent-error-detector.sh +0 -0
  632. package/examples/subagent-forged-system-reminder-guard.sh +156 -0
  633. package/examples/subagent-identity-leak-guard.sh +102 -0
  634. package/examples/subagent-identity-reassertion.sh +51 -0
  635. package/examples/subagent-inheritance-tester.sh +179 -0
  636. package/examples/subagent-permission-mode-guard.sh +110 -0
  637. package/examples/subagent-scope-guard.sh +12 -0
  638. package/examples/subagent-spawn-verification-enforcer.sh +102 -0
  639. package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
  640. package/examples/subagent-tool-call-limiter.sh +87 -15
  641. package/examples/subcommand-chain-guard.sh +12 -0
  642. package/examples/subscription-api-billing-warner.sh +160 -0
  643. package/examples/subscription-bypass-detector.sh +152 -0
  644. package/examples/svelte-lint-on-edit.sh +1 -0
  645. package/examples/swift-build-on-edit.sh +1 -1
  646. package/examples/symlink-guard.sh +27 -2
  647. package/examples/symlink-protect.sh +1 -0
  648. package/examples/system-dir-protection-guard.sh +73 -8
  649. package/examples/system-message-workaround.sh +38 -13
  650. package/examples/system-package-guard.sh +12 -0
  651. package/examples/systemd-service-guard.sh +12 -0
  652. package/examples/task-integrity-guard.sh +12 -0
  653. package/examples/temp-file-cleanup.sh +1 -1
  654. package/examples/temporal-suggestion-detector.sh +135 -0
  655. package/examples/terraform-guard.sh +27 -6
  656. package/examples/test-after-edit.sh +1 -1
  657. package/examples/test-before-push.sh +12 -0
  658. package/examples/test-coverage-reminder.sh +24 -1
  659. package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
  660. package/examples/timezone-guard.sh +0 -0
  661. package/examples/tmp-output-size-guard.sh +0 -0
  662. package/examples/todo-check.sh +1 -1
  663. package/examples/token-budget-guard.sh +12 -0
  664. package/examples/token-budget-per-task.sh +12 -0
  665. package/examples/token-usage-tracker.sh +7 -1
  666. package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
  667. package/examples/tokenizer-ratio-alert.sh +104 -0
  668. package/examples/tool-call-rate-limiter.sh +0 -0
  669. package/examples/tool-result-correlation-checker.sh +167 -0
  670. package/examples/tool-result-size-guard.sh +132 -0
  671. package/examples/tool-retry-budget-guard.sh +12 -0
  672. package/examples/transcript-contamination-detector.sh +138 -0
  673. package/examples/trustfall-mcp-injection-guard.sh +103 -0
  674. package/examples/ultrareview-large-diff-advisor.sh +184 -0
  675. package/examples/unbounded-output-guard.sh +94 -0
  676. package/examples/uncommitted-changes-stop.sh +1 -0
  677. package/examples/uncommitted-discard-guard.sh +23 -5
  678. package/examples/uncommitted-work-guard.sh +12 -0
  679. package/examples/usage-warn.sh +0 -0
  680. package/examples/user-account-guard.sh +12 -0
  681. package/examples/userprompt-submit-receipt.sh +123 -0
  682. package/examples/variable-expansion-guard.sh +12 -0
  683. package/examples/verify-after-publish-reminder.sh +93 -0
  684. package/examples/verify-before-commit.sh +12 -0
  685. package/examples/version-bump-detector.sh +156 -0
  686. package/examples/version-regression-warner.sh +144 -0
  687. package/examples/vue-lint-on-edit.sh +1 -0
  688. package/examples/warn-cron-cost-trap.sh +173 -0
  689. package/examples/webfetch-runaway-guard.sh +89 -0
  690. package/examples/wellness-break-reminder.sh +118 -0
  691. package/examples/windows-destructive-command-guard.sh +177 -0
  692. package/examples/windows-path-guard.sh +12 -0
  693. package/examples/windows-python-stub-detector.sh +63 -0
  694. package/examples/work-hours-guard.sh +12 -0
  695. package/examples/working-directory-fence.sh +12 -0
  696. package/examples/workspace-lease-guard.sh +205 -0
  697. package/examples/worktree-create-log.sh +1 -0
  698. package/examples/worktree-delete-guard.sh +12 -0
  699. package/examples/worktree-edit-boundary-guard.sh +127 -0
  700. package/examples/worktree-escape-write-guard.sh +114 -0
  701. package/examples/worktree-hook-linker.sh +0 -0
  702. package/examples/worktree-hooks-path-fix.sh +111 -0
  703. package/examples/worktree-parent-write-guard.sh +43 -0
  704. package/examples/worktree-project-unify.sh +2 -1
  705. package/examples/worktree-remove-uncommitted-guard.sh +13 -0
  706. package/examples/worktree-unmerged-guard.sh +7 -1
  707. package/examples/write-byte-integrity-verifier.sh +190 -0
  708. package/examples/write-empty-content-guard.sh +67 -0
  709. package/examples/write-nul-corruption-detector.sh +61 -0
  710. package/examples/write-overwrite-confirm.sh +160 -14
  711. package/examples/write-secret-guard.sh +27 -5
  712. package/examples/write-shrink-guard.sh +12 -0
  713. package/examples/write-test-ratio.sh +0 -0
  714. package/examples/wsl-host-disk-space-guard.sh +97 -0
  715. package/examples/xml-format-leak-detector.sh +266 -0
  716. package/examples/yaml-syntax-check.sh +12 -0
  717. package/hooks/hooks.json +6 -6
  718. package/index.mjs +1699 -183
  719. package/mission.md +2 -0
  720. package/package.json +4 -4
  721. package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
  722. package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
  723. package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
  724. package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
  725. package/scripts/agents-md-sync-setup.sh +156 -0
  726. package/scripts/autonomy-blocked-summary.sh +148 -0
  727. package/scripts/build-search-index.py +43 -0
  728. package/scripts/build-sitemap.py +119 -0
  729. package/scripts/cc-doctor.sh +192 -0
  730. package/scripts/check-hook-event-names.py +127 -0
  731. package/scripts/check-misfire-instrument.sh +64 -0
  732. package/scripts/claim-verify-audit.sh +467 -0
  733. package/scripts/cowork-claudemd-helper.sh +136 -0
  734. package/scripts/june-15-deprecated-model-scan.sh +111 -0
  735. package/scripts/measure-heredoc-shapes.sh +67 -0
  736. package/scripts/measure-literal-match-misfire.sh +110 -0
  737. package/scripts/probe-scope-guard-branches.sh +48 -0
  738. package/scripts/probe-skip-line-both-ways.sh +65 -0
  739. package/scripts/receipts-aggregate.py +199 -0
  740. package/scripts/session-forensic-audit.py +360 -0
  741. package/scripts.json +9 -9
  742. package/scripts.json.bak-2026-07-27-find +13 -0
  743. package/skills/safety-setup/SKILL.md +5 -5
  744. package/tests/approve-side-remaining-two.test.sh +129 -0
  745. package/tests/approver-list-granularity.test.sh +145 -0
  746. package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
  747. package/tests/audit-ci-gate.test.sh +87 -0
  748. package/tests/audit-cross-layer-claudemd.test.sh +170 -0
  749. package/tests/audit-fail-open-parse.test.sh +100 -0
  750. package/tests/auto-approve-compound-tail.test.sh +194 -0
  751. package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
  752. package/tests/auto-mode-quoted-targets.test.sh +127 -0
  753. package/tests/auto-mode-unquoted-targets.test.sh +112 -0
  754. package/tests/bash-secret-output-detector-detects.test.sh +102 -0
  755. package/tests/blindspots-cross-layer.test.sh +177 -0
  756. package/tests/block-database-wipe.test.sh +64 -0
  757. package/tests/bundled-short-flags-bypass.test.sh +85 -0
  758. package/tests/cd-git-allow-compound-tail.test.sh +67 -0
  759. package/tests/chown-guard-filesystem-root.test.sh +64 -0
  760. package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
  761. package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
  762. package/tests/core-scripts-parser-fallback.test.sh +140 -0
  763. package/tests/destructive-guard-bare-glob.test.sh +74 -0
  764. package/tests/destructive-guard-every-operand.test.sh +100 -0
  765. package/tests/destructive-guard-find-deletion.test.sh +114 -0
  766. package/tests/destructive-guard-flag-order.test.sh +106 -0
  767. package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
  768. package/tests/destructive-guard-quoted-target.test.sh +89 -0
  769. package/tests/destructive-guard-separators.test.sh +105 -0
  770. package/tests/destructive-guard-variable-target.test.sh +98 -0
  771. package/tests/destructive-guard-wrapped-command.test.sh +91 -0
  772. package/tests/doctor-hook-disabling-env.test.sh +92 -0
  773. package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
  774. package/tests/example-guards-wrapped-command.test.sh +169 -0
  775. package/tests/file-edit-backup.test.sh +93 -0
  776. package/tests/git-filter-repo-guard.test.sh +60 -0
  777. package/tests/git-global-options-bypass.test.sh +141 -0
  778. package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
  779. package/tests/git-maintenance-guard.test.sh +83 -0
  780. package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
  781. package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
  782. package/tests/git-submodule-guard.test.sh +50 -0
  783. package/tests/grep-pcre-portability.test.sh +155 -0
  784. package/tests/hook-registration-matches-input.test.sh +73 -0
  785. package/tests/hook-trigger-matches-envelope.test.sh +178 -0
  786. package/tests/install-does-not-claim-protection.test.sh +110 -0
  787. package/tests/install-example-standalone-tools.test.sh +139 -0
  788. package/tests/line-continuation-bypass.test.sh +114 -0
  789. package/tests/mcp-config-poisoning-audit.test.sh +106 -0
  790. package/tests/nested-background-agent-guard.test.sh +58 -0
  791. package/tests/no-unqualified-safety-claims.test.sh +114 -0
  792. package/tests/option-eating-grep-patterns.test.sh +130 -0
  793. package/tests/outdated-core-guards.test.sh +134 -0
  794. package/tests/outdated-report.test.sh +155 -0
  795. package/tests/output-secret-mask-warns.test.sh +73 -0
  796. package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
  797. package/tests/plugins-word-order.test.sh +126 -0
  798. package/tests/powershell-remove-item-guard.test.sh +85 -0
  799. package/tests/project-dir-naming.test.sh +103 -0
  800. package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
  801. package/tests/reroute-after-block-guard.test.sh +104 -0
  802. package/tests/secret-guard-documented-promises.test.sh +97 -0
  803. package/tests/session-plugin-pin-watch.test.sh +45 -0
  804. package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
  805. package/tests/shield-no-silent-adoption.test.py +110 -0
  806. package/tests/shield-no-silent-adoption.test.sh +46 -0
  807. package/tests/stop-transcript-write-health.test.sh +46 -0
  808. package/tests/system-dir-guard-root-erased.test.sh +66 -0
  809. package/tests/test-account-billing-log.sh +100 -0
  810. package/tests/test-account-routing-preflight.sh +77 -0
  811. package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
  812. package/tests/test-agent-view-quota-warn.sh +184 -0
  813. package/tests/test-agents-md-edit-drift-warner.sh +176 -0
  814. package/tests/test-agents-md-loader.sh +204 -0
  815. package/tests/test-agents-md-sync-checker.sh +125 -0
  816. package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
  817. package/tests/test-allowlist.sh +60 -0
  818. package/tests/test-always-allow-pattern-suggester.sh +147 -0
  819. package/tests/test-anthropic-base-url-guard.sh +88 -0
  820. package/tests/test-articulated-scope-capture.sh +139 -0
  821. package/tests/test-attachment-traversal-guard.sh +168 -0
  822. package/tests/test-aup-block-pattern-logger.sh +315 -0
  823. package/tests/test-aup-false-positive-helper.sh +188 -0
  824. package/tests/test-aup-large-tool-output-warner.sh +370 -0
  825. package/tests/test-aup-retry-loop-guard.sh +341 -0
  826. package/tests/test-auth-expiry-reminder.sh +303 -0
  827. package/tests/test-auth-macos-sleep-detector.sh +254 -0
  828. package/tests/test-auth-path-detector.sh +232 -0
  829. package/tests/test-auth-status-checker.sh +233 -0
  830. package/tests/test-authorized-reconfirmation-detector.sh +280 -0
  831. package/tests/test-background-cost-launch-guard.sh +62 -0
  832. package/tests/test-bash-allowlist-secondary-check.sh +143 -0
  833. package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
  834. package/tests/test-bash-project-fence.sh +127 -0
  835. package/tests/test-bg-permission-prompt-warner.sh +221 -0
  836. package/tests/test-binary-read-detector.sh +173 -0
  837. package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
  838. package/tests/test-bulk-delete-target-resolution.sh +49 -0
  839. package/tests/test-bypass-mode-effective-verifier.sh +179 -0
  840. package/tests/test-cache-creation-drift-detector.sh +244 -0
  841. package/tests/test-cache-residue-detector.sh +429 -0
  842. package/tests/test-cache-tier-logger.sh +59 -0
  843. package/tests/test-cache-ttl-eviction-detector.sh +282 -0
  844. package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
  845. package/tests/test-claim-verify-detector.sh +222 -0
  846. package/tests/test-claim-vs-caveat-checker.sh +134 -0
  847. package/tests/test-claude-code-version-pin-advisor.sh +353 -0
  848. package/tests/test-claude-md-reinjector.sh +173 -0
  849. package/tests/test-claude-md-size-monitor.sh +107 -0
  850. package/tests/test-claude-update-budget-guard.sh +132 -0
  851. package/tests/test-claude-update-smart.sh +91 -0
  852. package/tests/test-claudemd-tool-prohibition.sh +239 -0
  853. package/tests/test-cli-config-pinning-detector.sh +233 -0
  854. package/tests/test-cliff-countdown-advisor.sh +138 -0
  855. package/tests/test-closure-word-verify-gate.sh +158 -0
  856. package/tests/test-commit-all-scope-guard.sh +73 -0
  857. package/tests/test-commitment-carry-forward-arrest.sh +250 -0
  858. package/tests/test-compact-dispatch-watchdog.sh +147 -0
  859. package/tests/test-completion-claim-without-verification-detector.sh +326 -0
  860. package/tests/test-compound-bash-permission-resolver.sh +264 -0
  861. package/tests/test-compound-command-deny-enforcer.sh +67 -0
  862. package/tests/test-context-length-budget.sh +68 -0
  863. package/tests/test-context-usage-drift-alert.sh +52 -22
  864. package/tests/test-cost-incident-self-audit.sh +94 -0
  865. package/tests/test-cowork-claude-md-load-checker.sh +257 -0
  866. package/tests/test-cowork-claudemd-helper.sh +141 -0
  867. package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
  868. package/tests/test-cowork-hook-absence-warner.sh +230 -0
  869. package/tests/test-cowork-model-picker-advisor.sh +317 -0
  870. package/tests/test-credential-exfil-guard.sh +62 -0
  871. package/tests/test-cron-create-receipt.sh +165 -0
  872. package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
  873. package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
  874. package/tests/test-daily-cost-guard.sh +131 -0
  875. package/tests/test-deny-rule-integrity-verifier.sh +288 -0
  876. package/tests/test-deployment-readback-gate.sh +92 -0
  877. package/tests/test-deployment-readback-gh-adapter.sh +163 -0
  878. package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
  879. package/tests/test-dispatch-allowlist-preflight.sh +385 -0
  880. package/tests/test-dispatch-liveness-watchdog.sh +319 -0
  881. package/tests/test-dispatch-receipt.sh +314 -0
  882. package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
  883. package/tests/test-echo-probe-spam-detector.sh +143 -0
  884. package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
  885. package/tests/test-ephemeral-container-detector.sh +251 -0
  886. package/tests/test-evidence-claim-gate.sh +291 -0
  887. package/tests/test-extended-thinking-loop-guard.sh +289 -0
  888. package/tests/test-extended-thinking-resume-warning.sh +240 -0
  889. package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
  890. package/tests/test-fabricated-command-detector.sh +296 -0
  891. package/tests/test-false-disk-full-guard.sh +36 -0
  892. package/tests/test-feature-deprecation-detector.sh +117 -0
  893. package/tests/test-forbidden-response-phrase-detector.sh +246 -0
  894. package/tests/test-git-operations-require-approval.sh +53 -0
  895. package/tests/test-git-push-blast-radius-guard.sh +115 -0
  896. package/tests/test-goal-iteration-limit-warner.sh +128 -0
  897. package/tests/test-growthbook-flag-monitor.sh +428 -0
  898. package/tests/test-halt-signal-detector.sh +120 -0
  899. package/tests/test-hook-self-disable-detector.sh +232 -0
  900. package/tests/test-iteration-quality-degradation-detector.sh +244 -0
  901. package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
  902. package/tests/test-marketplace-plugins.sh +193 -0
  903. package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
  904. package/tests/test-mcp-orphan-leak-warner.sh +71 -0
  905. package/tests/test-mcp-permissions-ask-warner.sh +207 -0
  906. package/tests/test-mcp-routine-approval-detector.sh +229 -0
  907. package/tests/test-mcp-startup-bloat-detector.sh +141 -0
  908. package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
  909. package/tests/test-memory-chain-audit.sh +59 -0
  910. package/tests/test-memory-orphan-detector.sh +227 -0
  911. package/tests/test-model-swap-suggester.sh +368 -0
  912. package/tests/test-model-version-lock.sh +83 -0
  913. package/tests/test-multi-file-plan-routing-gate.sh +277 -0
  914. package/tests/test-multi-window-auth-drift-detector.sh +262 -0
  915. package/tests/test-nested-spawn-inflight-guard.sh +281 -0
  916. package/tests/test-no-force-flag.sh +49 -0
  917. package/tests/test-non-english-quality-warner.sh +229 -0
  918. package/tests/test-oauth-refresh-monitor.sh +311 -0
  919. package/tests/test-opus-degradation-tracker.sh +274 -0
  920. package/tests/test-opus48-routine-task-warning.sh +201 -0
  921. package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
  922. package/tests/test-output-token-spike-detector.sh +315 -0
  923. package/tests/test-parallel-batch-size-limiter.sh +228 -0
  924. package/tests/test-parallel-cascade-detector.sh +191 -0
  925. package/tests/test-partial-view-claim-arrest.sh +272 -0
  926. package/tests/test-per-prompt-token-cap.sh +136 -0
  927. package/tests/test-persisted-1m-model-advisor.sh +71 -0
  928. package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
  929. package/tests/test-post-edit-disk-verify.sh +294 -0
  930. package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
  931. package/tests/test-pre-execution-claim-detector.sh +366 -0
  932. package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
  933. package/tests/test-proxy-capture-suggester.sh +214 -0
  934. package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
  935. package/tests/test-quota-anomaly-detector.sh +321 -0
  936. package/tests/test-quota-reset-audit.sh +81 -0
  937. package/tests/test-read-loop-detector.sh +137 -0
  938. package/tests/test-read-once-guard.sh +85 -0
  939. package/tests/test-receipts-aggregate.sh +143 -0
  940. package/tests/test-redirect-fragment-warner.sh +130 -0
  941. package/tests/test-redundant-read-blocker.sh +155 -0
  942. package/tests/test-refusal-arrest-gate.sh +303 -0
  943. package/tests/test-remote-control-billing-classifier.sh +125 -0
  944. package/tests/test-resume-drift-watcher.sh +65 -0
  945. package/tests/test-rg-replace-flag-detector.sh +175 -0
  946. package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
  947. package/tests/test-rm-safety-net.sh +115 -0
  948. package/tests/test-route-handler-emptiness-gate.sh +300 -0
  949. package/tests/test-runtime-binary-change-detector.sh +196 -0
  950. package/tests/test-same-command-repeat-detector.sh +165 -0
  951. package/tests/test-same-correction-arrest.sh +165 -0
  952. package/tests/test-scope-expansion-receipt.sh +207 -0
  953. package/tests/test-server-side-prompt-injection-detector.sh +181 -0
  954. package/tests/test-session-persistence-verifier.sh +128 -0
  955. package/tests/test-session-rate-monitor.sh +284 -0
  956. package/tests/test-session-start-quota-status.sh +210 -0
  957. package/tests/test-session-start-safety-check.sh +138 -0
  958. package/tests/test-settings-hooks-key-restorer.sh +257 -0
  959. package/tests/test-settings-json-health-check.sh +70 -0
  960. package/tests/test-settings-regression-tester.sh +197 -0
  961. package/tests/test-skill-cumulative-size-detector.sh +198 -0
  962. package/tests/test-skill-description-drop-detector.sh +236 -0
  963. package/tests/test-skill-truncation-detector.sh +263 -0
  964. package/tests/test-skills-context-recorder.sh +329 -0
  965. package/tests/test-skills-load-verifier.sh +184 -0
  966. package/tests/test-skills-settings-validator.sh +242 -0
  967. package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
  968. package/tests/test-spurious-malformed-notice-detector.sh +290 -0
  969. package/tests/test-sql-bulk-delete-warn.sh +123 -0
  970. package/tests/test-ssh-key-protect.sh +81 -0
  971. package/tests/test-stale-temp-settings-detector.sh +161 -0
  972. package/tests/test-standing-rule-session-surfacer.sh +215 -0
  973. package/tests/test-starter-hooks-manifest.sh +96 -0
  974. package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
  975. package/tests/test-strict-allowlist.sh +72 -0
  976. package/tests/test-subagent-boundary-precheck.sh +137 -0
  977. package/tests/test-subagent-closure-verify-gate.sh +193 -0
  978. package/tests/test-subagent-destructive-git-guard.sh +86 -0
  979. package/tests/test-subagent-identity-leak-guard.sh +62 -0
  980. package/tests/test-subagent-identity-reassertion.sh +61 -0
  981. package/tests/test-subagent-inheritance-tester.sh +319 -0
  982. package/tests/test-subagent-permission-mode-guard.sh +61 -0
  983. package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
  984. package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
  985. package/tests/test-subagent-tool-call-limiter.sh +97 -0
  986. package/tests/test-subscription-api-billing-warner.sh +138 -0
  987. package/tests/test-subscription-bypass-detector.sh +255 -0
  988. package/tests/test-temporal-suggestion-detector.sh +183 -0
  989. package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
  990. package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
  991. package/tests/test-tokenizer-ratio-alert.sh +93 -0
  992. package/tests/test-tool-result-correlation-checker.sh +264 -0
  993. package/tests/test-tool-result-size-guard.sh +121 -0
  994. package/tests/test-transcript-contamination-detector.sh +264 -0
  995. package/tests/test-trigger-header-parsing.sh +151 -0
  996. package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
  997. package/tests/test-userprompt-submit-receipt.sh +181 -0
  998. package/tests/test-verify-after-publish-reminder.sh +184 -0
  999. package/tests/test-version-bump-detector.sh +212 -0
  1000. package/tests/test-version-regression-warner.sh +165 -0
  1001. package/tests/test-warn-cron-cost-trap.sh +82 -0
  1002. package/tests/test-webfetch-runaway-guard.sh +77 -0
  1003. package/tests/test-wellness-break-reminder.sh +138 -0
  1004. package/tests/test-windows-destructive-command-guard.sh +169 -0
  1005. package/tests/test-windows-python-stub-detector.sh +146 -0
  1006. package/tests/test-worktree-edit-boundary-guard.sh +219 -0
  1007. package/tests/test-write-byte-integrity-verifier.sh +192 -0
  1008. package/tests/test-xml-format-leak-detector.sh +299 -0
  1009. package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
  1010. package/tests/workspace-lease-guard.test.sh +144 -0
  1011. package/tests/worktree-escape-write-guard.test.sh +68 -0
  1012. package/tests/worktree-hooks-path-fix.test.sh +181 -0
  1013. package/tests/worktree-parent-write-guard.test.sh +51 -0
  1014. package/tests/write-empty-content-guard.test.sh +39 -0
  1015. package/tests/write-nul-corruption-detector.test.sh +29 -0
  1016. package/tests/write-overwrite-unread-content.test.sh +178 -0
  1017. package/tests/wsl-host-disk-space-guard.test.sh +55 -0
@@ -0,0 +1,124 @@
1
+ #!/bin/bash
2
+ # aup-false-positive-helper.sh — Surface the AUP false-positive cluster awareness when Opus models are pinned
3
+ #
4
+ # Background:
5
+ # Starting mid-May 2026 (acceleration peak 2026-05-21 through 2026-05-27), the Anthropic
6
+ # server-side Usage Policy classifier began over-triggering on benign Claude Code prompts.
7
+ # GitHub issue tracker accumulated 25+ open reports in 10 days from independent users:
8
+ # - #60366 (16r): single-word "hi" greeting blocked
9
+ # - #62190 (10r): non-deterministic blocks on greetings, coding, "ok"/"yes"
10
+ # - #61056 (4r), #61638 (3r), #61185 (2r), and 20+ low-reaction reports
11
+ # github-actions[bot] auto-flagged at least three duplicate chains, confirming the
12
+ # shape of the cluster at Anthropic's own intake.
13
+ #
14
+ # Independent reports converge on a clear signature:
15
+ # - Affected: Opus 4.7, Opus 4.6, Opus 1M context variants
16
+ # - Unaffected: Sonnet 4.6, Sonnet 4.7
17
+ # - Languages: false positives observed on English, Russian, Polish, and Spanish
18
+ # - Domains: kernel security audits, biomedical research, FPGA waveform analysis,
19
+ # compression algorithm work, and plain greetings — context-independent
20
+ # - Behavior: non-deterministic on identical input (same prompt blocks one minute,
21
+ # passes the next), strongly indicating an unstable classifier rather than the
22
+ # prompt being the cause
23
+ #
24
+ # The block surfaces as one of two stock error strings:
25
+ # "API Error: Claude Code is unable to respond to this request, which appears to
26
+ # violate our Usage Policy (...). This request triggered cyber-related safeguards."
27
+ # or:
28
+ # "This request triggered safety guardrails. Rephrase your prompt or rewind to continue."
29
+ #
30
+ # This is a server-side defect; there is no client-side fix. The hook exists to surface
31
+ # the four operator-side workarounds when a user is most likely to hit the block (Opus
32
+ # pinned, false-positive flood window still active).
33
+ #
34
+ # Reference: https://gist.github.com/yurukusa/4fa4751044be45bd83345601ee79c2db (4 operator-side paths through the
35
+ # false-positive flood — model swap, prompt warmup, CVP application, retry harness)
36
+ #
37
+ # What this hook does:
38
+ # On SessionStart, inspect ANTHROPIC_MODEL and emit a one-line advisory matching one
39
+ # of four states:
40
+ # - ANTHROPIC_MODEL unset → silent (default routing)
41
+ # - ANTHROPIC_MODEL pinned to a Sonnet variant → silent (unaffected model)
42
+ # - ANTHROPIC_MODEL pinned to an Opus variant + CC_AUP_FALSE_POSITIVE_HELPER_REMIND=1
43
+ # → emit one-time advisory
44
+ # - ANTHROPIC_MODEL pinned to an Opus variant + REMIND unset
45
+ # → silent (opt-in only)
46
+ #
47
+ # Silent by default. CC_AUP_FALSE_POSITIVE_HELPER_REMIND=1 opts in to the awareness
48
+ # note. CC_AUP_FALSE_POSITIVE_HELPER_QUIET=1 suppresses permanently after acknowledgement.
49
+ #
50
+ # When this hook does NOT fire a warning:
51
+ # - CC_AUP_FALSE_POSITIVE_HELPER_QUIET=1
52
+ # - ANTHROPIC_MODEL is unset or pinned to a non-Opus model
53
+ # - CC_AUP_FALSE_POSITIVE_HELPER_REMIND is unset (opt-in only)
54
+ #
55
+ # Hook config (settings.json):
56
+ # {
57
+ # "hooks": {
58
+ # "SessionStart": [{
59
+ # "matcher": "",
60
+ # "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/aup-false-positive-helper.sh" }]
61
+ # }]
62
+ # }
63
+ # }
64
+ #
65
+ # Env vars:
66
+ # CC_AUP_FALSE_POSITIVE_HELPER_QUIET=1 — never emit anything
67
+ # CC_AUP_FALSE_POSITIVE_HELPER_REMIND=1 — emit advisory when Opus is pinned (opt-in)
68
+
69
+ # Silence path
70
+ if [ "${CC_AUP_FALSE_POSITIVE_HELPER_QUIET:-0}" = "1" ]; then
71
+ exit 0
72
+ fi
73
+
74
+ # Model unset → use default routing, no specific advisory needed
75
+ if [ -z "${ANTHROPIC_MODEL:-}" ]; then
76
+ exit 0
77
+ fi
78
+
79
+ # Pinned to a model that is NOT an Opus variant → unaffected by the cluster
80
+ case "$ANTHROPIC_MODEL" in
81
+ *opus*|*Opus*|*OPUS*) : ;; # Opus variant — continue to advisory
82
+ *) exit 0 ;; # Sonnet, Haiku, or other — silent
83
+ esac
84
+
85
+ # Opt-in gate: only emit when the user explicitly requested awareness
86
+ if [ "${CC_AUP_FALSE_POSITIVE_HELPER_REMIND:-0}" != "1" ]; then
87
+ exit 0
88
+ fi
89
+
90
+ # Opt-in advisory path: ANTHROPIC_MODEL pinned to Opus, user wants the awareness note
91
+ cat >&2 <<EOF
92
+ [aup-false-positive-helper] ANTHROPIC_MODEL is pinned to "$ANTHROPIC_MODEL".
93
+
94
+ Between 2026-05-18 and the current session window, the Anthropic Usage Policy classifier
95
+ has over-triggered on benign prompts when Opus models (4.7, 4.6, 1M variants) are pinned.
96
+ Sonnet variants are reportedly unaffected. The block surfaces as:
97
+
98
+ "API Error: ... This request triggered cyber-related safeguards."
99
+
100
+ Four operator-side mitigations while the server-side classifier remains unstable:
101
+
102
+ 1. Swap to Sonnet for sensitive sessions
103
+ export ANTHROPIC_MODEL=claude-sonnet-4-7
104
+ (or any Sonnet variant; the cluster signature points to an Opus-specific path)
105
+
106
+ 2. Warm up the session with project context before security/kernel/research prompts
107
+ A short context-establishing turn often passes where a cold sensitive prompt blocks
108
+
109
+ 3. Apply for the Cyber Verification Program (CVP) if your work routinely involves
110
+ legitimate cyber/kernel/biomedical/FPGA terminology
111
+ https://www.anthropic.com/legal/cyber-verification-program
112
+
113
+ 4. The classifier is non-deterministic — a single retry on identical input frequently
114
+ succeeds. If a benign prompt blocks once, retry before rewording
115
+
116
+ To suppress this advisory:
117
+ export CC_AUP_FALSE_POSITIVE_HELPER_QUIET=1
118
+
119
+ GitHub tracker (25+ independent reports, 2026-05-18 through 2026-05-27):
120
+ https://github.com/anthropics/claude-code/issues/60366
121
+ https://github.com/anthropics/claude-code/issues/62190
122
+ EOF
123
+
124
+ exit 0
@@ -0,0 +1,282 @@
1
+ #!/bin/bash
2
+ # aup-large-tool-output-warner.sh — Warn before Bash commands that may produce large
3
+ # sensitive-looking outputs that can trigger the Cluster 9 Usage Policy classifier
4
+ #
5
+ # Background:
6
+ # Cluster 9 (Usage Policy classifier over-trigger) has a known trigger surface that
7
+ # the first four defense hooks do not address: a single tool result containing a
8
+ # large volume of security-shaped content (IP blocklists, firewall rules, packet
9
+ # captures, kernel log dumps) can flip the classifier even when the surrounding
10
+ # conversation is unambiguously benign.
11
+ #
12
+ # Direct evidence from issue #61185 (filipghoulin, 2026-05-23):
13
+ # "What triggered it: A lab-review skill dispatched a sub-agent that ran
14
+ # `cat /etc/banip/banip.blocklist` on an OpenWRT router. The blocklist has
15
+ # ~17,000 entries. That volume of content in a single tool result, combined
16
+ # with the security shape of the content, appears to have flipped the
17
+ # classifier into a permanent block state for the whole session."
18
+ #
19
+ # Reference: ~/ops/customer-pain-cluster-9-secondary-pains-2026-05-30.md (axis 4)
20
+ #
21
+ # The first three hooks address awareness, evidence collection, and session-start
22
+ # model swap. The fourth hook (aup-retry-loop-guard.sh) breaks intra-session retry
23
+ # cycles. None of them act *before* the offending tool call: by the time the
24
+ # classifier has fired on the large output, the session is already wedged and
25
+ # compact / clear may themselves block (see #61185 k33bs report). The only place
26
+ # to address this trigger surface is the PreToolUse boundary.
27
+ #
28
+ # What this hook does:
29
+ # On PreToolUse for the Bash tool, parse the proposed command. When the command
30
+ # shape matches one of the five well-known large-output patterns AND the path or
31
+ # command target carries a security-shaped sentinel (blocklist, firewall, iptables,
32
+ # denylist, allowlist, banlist, ipset, etc. — or sits under a known security path
33
+ # like /etc/banip/, /var/log/, /proc/net/), emit a non-blocking stderr advisory
34
+ # recommending a narrower variant.
35
+ #
36
+ # The hook never blocks the command. Exit is always 0. The advisory is informational
37
+ # — the operator can ignore it and continue. The point is to put the recommendation
38
+ # in front of the operator BEFORE the large output exists, not after the session is
39
+ # already wedged.
40
+ #
41
+ # Detection categories (intentionally narrow to keep false-positive rate low):
42
+ # A) `cat <path>` where path is under /etc/banip/, /var/log/, or ends in .blocklist
43
+ # / .denylist / .allowlist / .banlist / .iplist / .firewall / iptables-save
44
+ # B) `find <broad_path>` without `head`, `tail`, `-print -quit`, or `-quit`
45
+ # (broad recursion on security-shaped paths)
46
+ # C) `journalctl` without `-n`, `--lines`, or `--since` (full system log dump)
47
+ # D) `dmesg` without a pipe to head/tail/wc/grep with a follow-up size cap
48
+ # E) `grep -r` / `grep -R` on a security-shaped path without a pipe to head/tail
49
+ #
50
+ # Plus a separate strong-signal path: ANY command (Bash or otherwise) whose
51
+ # argument string contains a sentinel substring from a curated security-content
52
+ # wordlist gets a sentinel-only advisory, on top of the category match.
53
+ #
54
+ # When this hook does NOT emit anything:
55
+ # - CC_AUP_LARGE_OUTPUT_WARNER_DISABLE=1
56
+ # - CC_AUP_LARGE_OUTPUT_WARNER_QUIET=1
57
+ # - tool_name is not "Bash" (other tools are not parsed by this hook)
58
+ # - command is missing, empty, or unreadable
59
+ # - command already includes a size-cap pipe (head, tail, -n NNN, etc.)
60
+ # - the same command pattern already fired an advisory in this session
61
+ #
62
+ # Hook config (settings.json):
63
+ # {
64
+ # "hooks": {
65
+ # "PreToolUse": [{
66
+ # "matcher": "Bash",
67
+ # "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/aup-large-tool-output-warner.sh" }]
68
+ # }]
69
+ # }
70
+ # }
71
+ #
72
+ # Env vars:
73
+ # CC_AUP_LARGE_OUTPUT_WARNER_DISABLE=1 — never emit
74
+ # CC_AUP_LARGE_OUTPUT_WARNER_QUIET=1 — silent
75
+ # CC_AUP_LARGE_OUTPUT_WARNER_STATE_DIR=<p> — one-shot state dir (default $HOME/.claude)
76
+ # CC_AUP_LARGE_OUTPUT_WARNER_SESSION_ID=<id> — session id override (tests / automation)
77
+ #
78
+ # Design notes:
79
+ # - PreToolUse only. The classifier fires on the *output* of the tool call, so by
80
+ # the time PostToolUse runs the damage is done. The advisory has to land before
81
+ # the command executes.
82
+ # - Never blocks. The hook recommends a narrower variant but the operator may have
83
+ # a legitimate reason for the full output (audit, evidence collection, etc.).
84
+ # - One-shot per (session, pattern_hash). If the operator runs `cat
85
+ # /etc/banip/banip.blocklist` three times in a session, only the first call
86
+ # triggers the advisory. This prevents the hook from becoming its own noise loop.
87
+ # - Conservative category set. Five patterns rather than fifteen. A false positive
88
+ # here doesn't break anything (the command still runs), but it does add cognitive
89
+ # load. The set covers #61185's pattern plus the four closest neighbors from
90
+ # #60366's comment chain.
91
+ # - Sentinel wordlist is the high-confidence path. When the command target itself
92
+ # contains "blocklist" / "iptables-save" / etc., the advisory fires even if the
93
+ # command shape isn't on the five-category list — because the sentinel itself
94
+ # carries the cluster-9 trigger signature regardless of how the file is read.
95
+
96
+ set -u
97
+
98
+ # Disable path
99
+ if [ "${CC_AUP_LARGE_OUTPUT_WARNER_DISABLE:-0}" = "1" ]; then
100
+ exit 0
101
+ fi
102
+
103
+ # Quiet path
104
+ if [ "${CC_AUP_LARGE_OUTPUT_WARNER_QUIET:-0}" = "1" ]; then
105
+ exit 0
106
+ fi
107
+
108
+ # Read PreToolUse JSON payload from stdin
109
+ INPUT=$(cat 2>/dev/null) || exit 0
110
+ [ -n "$INPUT" ] || exit 0
111
+
112
+ # Parse tool_name and command via jq when available; fall back to grep heuristics.
113
+ TOOL_NAME=""
114
+ COMMAND=""
115
+ if command -v jq >/dev/null 2>&1; then
116
+ TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
117
+ COMMAND=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
118
+ else
119
+ # Best-effort fallback when jq is unavailable. Match "tool_name": "Bash" and
120
+ # "command": "..." in the JSON payload. This is intentionally lenient — the
121
+ # detection categories below double-check the command shape.
122
+ TOOL_NAME=$(printf '%s' "$INPUT" | grep -oE '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*"tool_name"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/')
123
+ COMMAND=$(printf '%s' "$INPUT" | grep -oE '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*"command"[[:space:]]*:[[:space:]]*"([^"]*)".*/\1/')
124
+ fi
125
+
126
+ # Only act on Bash
127
+ [ "$TOOL_NAME" = "Bash" ] || exit 0
128
+ [ -n "$COMMAND" ] || exit 0
129
+
130
+ # Skip if the command already has a size-cap somewhere in the pipeline.
131
+ # Common cap shapes: `| head -N`, `| tail -N`, `head -N <file>`, `tail -N <file>`,
132
+ # `find ... -print -quit`, `find ... -quit`, `journalctl -n N`, `journalctl --lines N`,
133
+ # `journalctl --since ...`, `grep ... | head`, `dmesg | head`, `wc -l`.
134
+ if printf '%s' "$COMMAND" | grep -qE '(\|[[:space:]]*head\b|\|[[:space:]]*tail\b|head[[:space:]]+-n[[:space:]]+[0-9]+|tail[[:space:]]+-n[[:space:]]+[0-9]+|head[[:space:]]+-[0-9]+|tail[[:space:]]+-[0-9]+|-print[[:space:]]+-quit\b|[[:space:]]-quit\b|--lines[[:space:]]+[0-9]+|[[:space:]]-n[[:space:]]+[0-9]+|--since\b|\|[[:space:]]*wc\b|^[[:space:]]*wc\b|^[[:space:]]*grep[[:space:]]+-c\b)'; then
135
+ exit 0
136
+ fi
137
+
138
+ # Sentinel wordlist for security-shaped content. Case-insensitive substring match
139
+ # against the full command string. These are the substrings that, by themselves,
140
+ # strongly indicate the classifier will see the output as "security-shaped."
141
+ SENTINEL=""
142
+ case " $(printf '%s' "$COMMAND" | tr '[:upper:]' '[:lower:]') " in
143
+ *blocklist*) SENTINEL="blocklist" ;;
144
+ *denylist*) SENTINEL="denylist" ;;
145
+ *banlist*) SENTINEL="banlist" ;;
146
+ *iplist*) SENTINEL="iplist" ;;
147
+ *iptables-save*) SENTINEL="iptables-save" ;;
148
+ *ipset[[:space:]]save*) SENTINEL="ipset save" ;;
149
+ */etc/banip/*) SENTINEL="/etc/banip/" ;;
150
+ */etc/fail2ban/*) SENTINEL="/etc/fail2ban/" ;;
151
+ */var/log/auth*) SENTINEL="/var/log/auth*" ;;
152
+ */var/log/secure*) SENTINEL="/var/log/secure*" ;;
153
+ *firewall.conf*) SENTINEL="firewall.conf" ;;
154
+ esac
155
+
156
+ # Category match. Even without a sentinel, the following shapes are likely to
157
+ # produce large outputs that look security-shaped to the classifier.
158
+ CATEGORY=""
159
+ CATEGORY_DESC=""
160
+ if printf '%s' "$COMMAND" | grep -qE '^[[:space:]]*cat[[:space:]]+(/etc/banip/|/var/log/|/proc/net/)'; then
161
+ CATEGORY="A"
162
+ CATEGORY_DESC="cat on a security-shaped system path"
163
+ elif printf '%s' "$COMMAND" | grep -qE '^[[:space:]]*cat[[:space:]]+[^|]*\.(blocklist|denylist|allowlist|banlist|iplist|firewall)([[:space:]]|$)'; then
164
+ CATEGORY="A"
165
+ CATEGORY_DESC="cat on a security-shaped file extension"
166
+ elif printf '%s' "$COMMAND" | grep -qE '(^|[[:space:];&|])find[[:space:]]+(/etc/banip/|/var/log/|/proc/net/|/etc/fail2ban/)'; then
167
+ CATEGORY="B"
168
+ CATEGORY_DESC="find recursing under a security-shaped path"
169
+ elif printf '%s' "$COMMAND" | grep -qE '(^|[[:space:];&|])journalctl([[:space:]]|$)'; then
170
+ CATEGORY="C"
171
+ CATEGORY_DESC="journalctl without a line/since cap"
172
+ elif printf '%s' "$COMMAND" | grep -qE '(^|[[:space:];&|])dmesg([[:space:]]|$)'; then
173
+ CATEGORY="D"
174
+ CATEGORY_DESC="dmesg without a size cap"
175
+ elif printf '%s' "$COMMAND" | grep -qE '(^|[[:space:];&|])grep[[:space:]]+(-r|-R|--recursive)[[:space:]]+(.*)(/etc/banip/|/var/log/|/proc/net/|/etc/fail2ban/)'; then
176
+ CATEGORY="E"
177
+ CATEGORY_DESC="grep -r/-R on a security-shaped path"
178
+ fi
179
+
180
+ # If neither a sentinel nor a category match, the command is out of scope.
181
+ if [ -z "$SENTINEL" ] && [ -z "$CATEGORY" ]; then
182
+ exit 0
183
+ fi
184
+
185
+ # One-shot per (session, pattern_hash). Pattern hash = first 40 chars of command
186
+ # stripped of timestamps and whitespace runs. This keeps the same pattern from
187
+ # firing twice in a row (e.g. operator runs the same cat three times) while still
188
+ # allowing a different pattern (cat foo.blocklist vs cat bar.denylist) to fire.
189
+ STATE_DIR="${CC_AUP_LARGE_OUTPUT_WARNER_STATE_DIR:-$HOME/.claude}"
190
+ mkdir -p "$STATE_DIR" 2>/dev/null || exit 0
191
+ STATE_FILE="$STATE_DIR/aup-large-tool-output-warner.fired"
192
+
193
+ SESSION_ID="${CC_AUP_LARGE_OUTPUT_WARNER_SESSION_ID:-}"
194
+ if [ -z "$SESSION_ID" ]; then
195
+ SESSION_ID="${CLAUDECODE_SESSION_ID:-}"
196
+ fi
197
+ if [ -z "$SESSION_ID" ] && command -v tty >/dev/null 2>&1; then
198
+ TTY_PATH=$(tty 2>/dev/null)
199
+ if [ -n "$TTY_PATH" ] && [ "$TTY_PATH" != "not a tty" ]; then
200
+ SESSION_ID=$(printf '%s' "$TTY_PATH" | tr '/' '_')
201
+ fi
202
+ fi
203
+ [ -n "$SESSION_ID" ] || SESSION_ID="ppid-${PPID:-0}"
204
+
205
+ # Pattern hash: collapse whitespace, take first 60 chars.
206
+ PATTERN_HASH=$(printf '%s' "$COMMAND" | tr -s '[:space:]' ' ' | cut -c1-60 | tr ' /' '__')
207
+ FIRED_KEY="${SESSION_ID}::${PATTERN_HASH}"
208
+
209
+ if [ -f "$STATE_FILE" ] && grep -Fq -- "$FIRED_KEY" "$STATE_FILE" 2>/dev/null; then
210
+ exit 0
211
+ fi
212
+
213
+ # Bound the state file to ~100 lines to avoid unbounded growth.
214
+ if [ -f "$STATE_FILE" ]; then
215
+ tail -n 100 "$STATE_FILE" > "${STATE_FILE}.tmp" 2>/dev/null \
216
+ && mv "${STATE_FILE}.tmp" "$STATE_FILE" 2>/dev/null || true
217
+ fi
218
+ printf '%s\n' "$FIRED_KEY" >> "$STATE_FILE" 2>/dev/null || true
219
+
220
+ # Compose the advisory.
221
+ ADVISORY_REASON=""
222
+ if [ -n "$SENTINEL" ] && [ -n "$CATEGORY" ]; then
223
+ ADVISORY_REASON="security-content sentinel \"$SENTINEL\" + $CATEGORY_DESC"
224
+ elif [ -n "$SENTINEL" ]; then
225
+ ADVISORY_REASON="security-content sentinel \"$SENTINEL\" in the command"
226
+ else
227
+ ADVISORY_REASON="$CATEGORY_DESC"
228
+ fi
229
+
230
+ # Trim command excerpt for the advisory (avoid dumping a 500-char one-liner).
231
+ CMD_EXCERPT=$(printf '%s' "$COMMAND" | cut -c1-120)
232
+ if [ "${#COMMAND}" -gt 120 ]; then
233
+ CMD_EXCERPT="${CMD_EXCERPT}..."
234
+ fi
235
+
236
+ cat >&2 <<EOF
237
+ [aup-large-tool-output-warner] About to run a Bash command that may produce a
238
+ large security-shaped output. Trigger: $ADVISORY_REASON.
239
+
240
+ Command excerpt:
241
+ $CMD_EXCERPT
242
+
243
+ Why this matters:
244
+ Cluster 9 (Usage Policy classifier over-trigger) has fired on tool results
245
+ carrying high-volume security-shaped content even when the surrounding
246
+ conversation is benign. Issue #61185 documents a session-wedging block
247
+ triggered by a single \`cat /etc/banip/banip.blocklist\` returning ~17,000
248
+ IP entries — after which /compact and /clear also blocked, leaving no
249
+ recovery path within the session.
250
+
251
+ The command is NOT being blocked. This is an advisory only — the operator may
252
+ have a legitimate reason for the full output (audit trail, evidence package,
253
+ forensics). If a summary is sufficient, narrower variants reduce the trigger
254
+ surface without losing the answer:
255
+
256
+ Line count only: wc -l <path>
257
+ First N lines: head -200 <path>
258
+ Last N lines: tail -200 <path>
259
+ Matching subset: grep -c <pattern> <path> (count only)
260
+ grep -E <pattern> <path> | head -200
261
+ journalctl: journalctl --since "1 hour ago" -n 200
262
+ find: find <path> -type f | head -200
263
+ dmesg: dmesg | tail -200
264
+
265
+ For multi-thousand-entry blocklists, prefer the count + a sampled head/tail
266
+ over the full dump.
267
+
268
+ To silence this advisory for the current session only:
269
+ export CC_AUP_LARGE_OUTPUT_WARNER_QUIET=1
270
+
271
+ Related hooks (already active in this defense suite):
272
+ aup-false-positive-helper.sh — SessionStart awareness, 4 operator-side options
273
+ aup-block-pattern-logger.sh — PostToolUse evidence collection
274
+ aup-retry-loop-guard.sh — PostToolUse intra-session retry breaker
275
+ model-swap-suggester.sh — SessionStart cross-session swap recommendation
276
+
277
+ GitHub references:
278
+ https://github.com/anthropics/claude-code/issues/60366 (cluster anchor)
279
+ https://github.com/anthropics/claude-code/issues/61185 (large-output trigger)
280
+ EOF
281
+
282
+ exit 0
@@ -0,0 +1,229 @@
1
+ #!/bin/bash
2
+ # aup-retry-loop-guard.sh — Detect retry-loop pattern during Cluster 9 blocks and recommend exit
3
+ #
4
+ # Background:
5
+ # Cluster 9 (Usage Policy classifier over-trigger) has a secondary failure mode that the
6
+ # first three defense hooks do not address: even when an operator has been blocked and is
7
+ # actively retrying the same input (the non-deterministic classifier sometimes passes on
8
+ # retry — see #60366, #62190), each retry burns transcript context. For paying users on
9
+ # Pro / Max quota, the retry loop drains the daily quota faster than the productive work
10
+ # would have, leading to the "session quota MAX reached early" symptom.
11
+ #
12
+ # Direct evidence from issue #61664 (Japanese paid user, 2026-05-23):
13
+ # "ブロック発生時も context/credit は消費される"
14
+ # "ブロック→巻き戻し→同じ処理の再実行 で context を浪費"
15
+ # "昨日まで丸 1 日使っても使用量上限に達しなかったが、本日は早々に MAX に到達"
16
+ #
17
+ # The first three hooks address awareness (helper), evidence collection (logger), and
18
+ # session-start swap recommendations (suggester). None of them break a retry loop that
19
+ # is already in progress within a single session.
20
+ #
21
+ # Reference: ~/ops/customer-pain-cluster-9-secondary-pains-2026-05-30.md (axis 1)
22
+ #
23
+ # What this hook does:
24
+ # On PostToolUse, read the aup-block-history.log (written by aup-block-pattern-logger.sh)
25
+ # and check whether the last N blocks within a short window (default 5 minutes) all
26
+ # targeted the same tool. When that pattern is detected, emit a non-blocking stderr
27
+ # advisory recommending one of two cycle-breaking actions:
28
+ # - `/exit` to end the session before more context is burned, then restart with Sonnet
29
+ # - immediate `export ANTHROPIC_MODEL=claude-sonnet-4-7` for the current session
30
+ #
31
+ # Distinct from model-swap-suggester (SessionStart, 60-min window): retry-loop-guard
32
+ # runs PostToolUse, looks at a 5-min window, and addresses the intra-session retry
33
+ # cycle that burns context — not the cross-session model selection decision.
34
+ #
35
+ # When this hook does NOT emit anything:
36
+ # - CC_AUP_RETRY_LOOP_GUARD_DISABLE=1
37
+ # - CC_AUP_RETRY_LOOP_GUARD_QUIET=1
38
+ # - aup-block log missing, empty, or unreadable
39
+ # - Fewer than threshold blocks in the configured window
40
+ # - Blocks in window span multiple tools (single-tool retry loop is the diagnostic signal)
41
+ # - The current advisory has already fired within the same session (one-shot per session)
42
+ #
43
+ # Hook config (settings.json):
44
+ # {
45
+ # "hooks": {
46
+ # "PostToolUse": [{
47
+ # "matcher": "",
48
+ # "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/aup-retry-loop-guard.sh" }]
49
+ # }]
50
+ # }
51
+ # }
52
+ #
53
+ # Env vars:
54
+ # CC_AUP_RETRY_LOOP_GUARD_DISABLE=1 — never emit
55
+ # CC_AUP_RETRY_LOOP_GUARD_QUIET=1 — silent
56
+ # CC_AUP_RETRY_LOOP_GUARD_THRESHOLD=<n> — block count threshold (default 3)
57
+ # CC_AUP_RETRY_LOOP_GUARD_WINDOW_MIN=<n> — lookback window in minutes (default 5)
58
+ # CC_AUP_RETRY_LOOP_GUARD_TARGET=<model> — target Sonnet model (default claude-sonnet-4-7)
59
+ # CC_AUP_RETRY_LOOP_GUARD_STATE_DIR=<path> — one-shot state directory (default $HOME/.claude)
60
+ # CC_AUP_RETRY_LOOP_GUARD_SESSION_ID=<id> — session identifier override for one-shot logic
61
+ # CC_AUP_BLOCK_LOG_PATH=<path> — log path (shared with logger; default $HOME/.claude/aup-block-history.log)
62
+ #
63
+ # Design notes:
64
+ # - Single-tool restriction: the diagnostic for a retry loop is "same tool, same kind, in
65
+ # a short window." A burst of blocks across different tools is more consistent with a
66
+ # general session sensitivity than a retry cycle, and breaking the session for the
67
+ # latter is more disruptive than helpful.
68
+ # - One-shot per session: the advisory fires at most once per session. The state file
69
+ # lives in $CC_AUP_RETRY_LOOP_GUARD_STATE_DIR/aup-retry-loop-guard.lock with the
70
+ # session PID. Subsequent invocations from the same session see the lock and stay
71
+ # silent so the advisory doesn't become its own noise loop.
72
+ # - Never blocks. All failure paths exit 0 — a corrupt log or missing date utility
73
+ # cannot break the tool call cycle.
74
+
75
+ set -u
76
+
77
+ # Disable path
78
+ if [ "${CC_AUP_RETRY_LOOP_GUARD_DISABLE:-0}" = "1" ]; then
79
+ exit 0
80
+ fi
81
+
82
+ # Quiet path
83
+ if [ "${CC_AUP_RETRY_LOOP_GUARD_QUIET:-0}" = "1" ]; then
84
+ exit 0
85
+ fi
86
+
87
+ LOG_PATH="${CC_AUP_BLOCK_LOG_PATH:-$HOME/.claude/aup-block-history.log}"
88
+ [ -f "$LOG_PATH" ] || exit 0
89
+ [ -r "$LOG_PATH" ] || exit 0
90
+ [ -s "$LOG_PATH" ] || exit 0
91
+
92
+ THRESHOLD="${CC_AUP_RETRY_LOOP_GUARD_THRESHOLD:-3}"
93
+ WINDOW_MIN="${CC_AUP_RETRY_LOOP_GUARD_WINDOW_MIN:-5}"
94
+ TARGET="${CC_AUP_RETRY_LOOP_GUARD_TARGET:-claude-sonnet-4-7}"
95
+ STATE_DIR="${CC_AUP_RETRY_LOOP_GUARD_STATE_DIR:-$HOME/.claude}"
96
+
97
+ case "$THRESHOLD" in
98
+ ''|*[!0-9]*) THRESHOLD=3 ;;
99
+ esac
100
+ case "$WINDOW_MIN" in
101
+ ''|*[!0-9]*) WINDOW_MIN=5 ;;
102
+ esac
103
+
104
+ NOW=$(date -u '+%s' 2>/dev/null) || exit 0
105
+ CUTOFF=$((NOW - WINDOW_MIN * 60))
106
+
107
+ ts_to_epoch() {
108
+ local ts="$1"
109
+ date -u -d "$ts" '+%s' 2>/dev/null \
110
+ || date -j -u -f '%Y-%m-%dT%H:%M:%SZ' "$ts" '+%s' 2>/dev/null
111
+ }
112
+
113
+ # Collect blocks in window. The log schema is:
114
+ # ISO8601_UTC | MODEL | TOOL | PATTERN_KIND | EXCERPT
115
+ # We track the tools that fired in the window. If all in-window blocks targeted the same
116
+ # tool and there are at least THRESHOLD of them, the pattern is a retry loop.
117
+ COUNT=0
118
+ UNIQUE_TOOLS=""
119
+ LAST_TOOL=""
120
+ LAST_KIND=""
121
+ while IFS='|' read -r LOG_TS _LOG_MODEL LOG_TOOL LOG_KIND _LOG_EXCERPT; do
122
+ [ -z "$LOG_TS" ] && continue
123
+ [ -z "$LOG_TOOL" ] && continue
124
+ LOG_EPOCH=$(ts_to_epoch "$LOG_TS")
125
+ [ -z "$LOG_EPOCH" ] && continue
126
+ case "$LOG_EPOCH" in
127
+ *[!0-9]*) continue ;;
128
+ esac
129
+ if [ "$LOG_EPOCH" -ge "$CUTOFF" ] 2>/dev/null; then
130
+ COUNT=$((COUNT + 1))
131
+ LAST_TOOL="$LOG_TOOL"
132
+ LAST_KIND="$LOG_KIND"
133
+ case "$UNIQUE_TOOLS" in
134
+ *"|$LOG_TOOL|"*) : ;;
135
+ *) UNIQUE_TOOLS="${UNIQUE_TOOLS}|${LOG_TOOL}|" ;;
136
+ esac
137
+ fi
138
+ done < "$LOG_PATH"
139
+
140
+ if [ "$COUNT" -lt "$THRESHOLD" ] 2>/dev/null; then
141
+ exit 0
142
+ fi
143
+
144
+ # Count unique tools. Multi-tool bursts are not retry loops.
145
+ TOOL_COUNT=$(printf '%s' "$UNIQUE_TOOLS" | tr -cd '|' | wc -c)
146
+ TOOL_COUNT=$((TOOL_COUNT / 2))
147
+ if [ "$TOOL_COUNT" -ne 1 ] 2>/dev/null; then
148
+ exit 0
149
+ fi
150
+
151
+ # One-shot per session. Session identifier resolution, in order of preference:
152
+ # 1. CC_AUP_RETRY_LOOP_GUARD_SESSION_ID env var (explicit override; tests, automation)
153
+ # 2. CLAUDECODE_SESSION_ID env var (Claude Code may export this in the future)
154
+ # 3. Controlling tty path (stable across child shells in an interactive session)
155
+ # 4. PPID fallback (last resort; less stable across subshell hops)
156
+ SESSION_ID="${CC_AUP_RETRY_LOOP_GUARD_SESSION_ID:-}"
157
+ if [ -z "$SESSION_ID" ]; then
158
+ SESSION_ID="${CLAUDECODE_SESSION_ID:-}"
159
+ fi
160
+ if [ -z "$SESSION_ID" ] && command -v tty >/dev/null 2>&1; then
161
+ TTY_PATH=$(tty 2>/dev/null)
162
+ if [ -n "$TTY_PATH" ] && [ "$TTY_PATH" != "not a tty" ]; then
163
+ SESSION_ID=$(printf '%s' "$TTY_PATH" | tr '/' '_')
164
+ fi
165
+ fi
166
+ if [ -z "$SESSION_ID" ]; then
167
+ SESSION_ID="ppid-${PPID:-0}"
168
+ fi
169
+
170
+ mkdir -p "$STATE_DIR" 2>/dev/null || exit 0
171
+ STATE_FILE="$STATE_DIR/aup-retry-loop-guard.lock"
172
+
173
+ if [ -f "$STATE_FILE" ]; then
174
+ PRIOR=$(cat "$STATE_FILE" 2>/dev/null | head -1)
175
+ if [ "$PRIOR" = "$SESSION_ID" ]; then
176
+ exit 0
177
+ fi
178
+ fi
179
+
180
+ # Trim stale entries: keep only the most recent 10 session IDs to bound the file.
181
+ if [ -f "$STATE_FILE" ]; then
182
+ tail -n 10 "$STATE_FILE" > "${STATE_FILE}.tmp" 2>/dev/null \
183
+ && mv "${STATE_FILE}.tmp" "$STATE_FILE" 2>/dev/null || true
184
+ fi
185
+ printf '%s\n' "$SESSION_ID" >> "$STATE_FILE" 2>/dev/null || true
186
+
187
+ # Emit the advisory. The recommendation tier is:
188
+ # 1. `/exit` immediately to stop burning context, then restart fresh with Sonnet pinned.
189
+ # 2. If you must continue this session, swap the model in-place; the same prompt may
190
+ # pass on Sonnet without retry.
191
+ cat >&2 <<EOF
192
+ [aup-retry-loop-guard] Retry-loop pattern detected: $COUNT Usage Policy block(s) on
193
+ tool "$LAST_TOOL" within the last $WINDOW_MIN minute(s). Pattern kind: $LAST_KIND.
194
+
195
+ This shape — same tool, same block, repeated within a short window — is the retry-loop
196
+ signature reported in issue #61664: each retry consumes session context, even when the
197
+ attempt itself blocks. Pro / Max quota holders report hitting their daily quota MAX in
198
+ hours instead of a full day during this loop.
199
+
200
+ Recommended cycle-breaker (pick one):
201
+
202
+ Option A — exit and restart fresh (safest for quota)
203
+ 1. /exit
204
+ 2. export ANTHROPIC_MODEL=$TARGET
205
+ 3. claude # new session, no inherited context, Sonnet path
206
+
207
+ Option B — swap in-place (continues current session)
208
+ export ANTHROPIC_MODEL=$TARGET
209
+ # the next prompt may pass; Sonnet is unaffected by the Cluster 9 signature
210
+
211
+ The Cluster 9 classifier is non-deterministic, so retrying identical input on the same
212
+ Opus pin sometimes works — but the context cost per retry typically exceeds the value
213
+ of the eventual successful turn. Breaking the cycle now preserves more daily quota for
214
+ productive work.
215
+
216
+ Related hooks (already active in this defense suite):
217
+ aup-false-positive-helper.sh — generic awareness at session start
218
+ aup-block-pattern-logger.sh — evidence shape recorded at $LOG_PATH
219
+ model-swap-suggester.sh — session-start swap recommendation (60-min window)
220
+
221
+ To silence this advisory for the current session only:
222
+ export CC_AUP_RETRY_LOOP_GUARD_QUIET=1
223
+
224
+ GitHub references:
225
+ https://github.com/anthropics/claude-code/issues/60366 (cluster anchor)
226
+ https://github.com/anthropics/claude-code/issues/61664 (retry-loop quota burn)
227
+ EOF
228
+
229
+ exit 0