cc-safe-setup 29.8.0 → 30.0.5

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 +421 -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 +1718 -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
@@ -5,11 +5,32 @@ Your hook isn't working. Here's how to fix it, starting with the most common cau
5
5
  ## Quick Diagnosis
6
6
 
7
7
  ```bash
8
- npx cc-safe-setup --doctor
8
+ npx github:yurukusa/cc-safe-setup --doctor
9
9
  ```
10
10
 
11
11
  This checks jq, settings.json, file permissions, shebangs, and common misconfigurations. If it says "All checks passed" but hooks still don't fire, read on.
12
12
 
13
+ ## "No hooks fire at all on Windows" (Git for Windows PATH bug)
14
+
15
+ If you are on the Windows Desktop app with Git for Windows installed, and **every** `"type": "command"` hook silently does nothing — including these guards — regardless of the command, this is likely an upstream shell-resolution bug, not your config.
16
+
17
+ Symptoms (visible if you run the CLI with `--output-format stream-json` and watch the `hook_response` events):
18
+
19
+ ```
20
+ Error occurred while executing hook command: Executable not found in $PATH: "C:\Program Files\Git\bin"
21
+ Failed to run: EFTYPE: inappropriate file type or format, uv_spawn
22
+ ```
23
+
24
+ Note the path is missing the trailing `\bash.exe`. The hook runner enumerates `$PATH`, hits the bare `C:\Program Files\Git\bin` entry that the Git for Windows installer adds, and tries to spawn that **directory** as the shell instead of appending `\bash.exe`. It fails during shell auto-detection, before your command ever runs — so the failure is identical no matter what the hook does, and nothing is surfaced in the normal UI.
25
+
26
+ How to confirm it is this and not a config problem:
27
+
28
+ - The `--doctor` above says everything is fine, yet no hook has any effect.
29
+ - Registering a trivial hook (`echo fired >> C:\Users\you\hook.log` on `SessionStart`) produces no log line.
30
+ - The stream-json error names the `Git\bin` directory (without `bash.exe`).
31
+
32
+ This is tracked upstream at [anthropics/claude-code#73971](https://github.com/anthropics/claude-code/issues/73971) (has-repro). Until it is fixed there, a machine hitting this cannot run command hooks, so do not assume these guards are protecting a Windows machine with this symptom — verify with the log test above first. WSL2 sessions resolve the shell differently and are not affected the same way; running Claude Code under WSL2 is the reliable path on Windows while the upstream fix is pending.
33
+
13
34
  ## "Hook doesn't block anything"
14
35
 
15
36
  ### 1. Did you restart Claude Code?
@@ -25,7 +46,7 @@ cat ~/.claude/settings.json | jq '.hooks'
25
46
  You should see your hook's path under the correct trigger. If not:
26
47
 
27
48
  ```bash
28
- npx cc-safe-setup # Re-registers all hooks
49
+ npx github:yurukusa/cc-safe-setup # Re-registers all hooks
29
50
  ```
30
51
 
31
52
  ### 3. Is the hook file executable?
@@ -180,7 +201,7 @@ This is a known Claude Code limitation, not a hook issue. `Bash(git:*)` doesn't
180
201
  Fix:
181
202
 
182
203
  ```bash
183
- npx cc-safe-setup --install-example compound-command-approver
204
+ npx github:yurukusa/cc-safe-setup --install-example compound-command-approver
184
205
  ```
185
206
 
186
207
  ## "Hooks slow down Claude Code"
@@ -188,7 +209,7 @@ npx cc-safe-setup --install-example compound-command-approver
188
209
  ### 1. Check execution time
189
210
 
190
211
  ```bash
191
- npx cc-safe-setup --install-example hook-debug-wrapper
212
+ npx github:yurukusa/cc-safe-setup --install-example hook-debug-wrapper
192
213
  # Then wrap your slow hook to see timing
193
214
  ```
194
215
 
@@ -206,7 +227,7 @@ Hooks with `"matcher": ""` run on every single tool call. Move heavy checks to s
206
227
  ### 3. Use --lint to find issues
207
228
 
208
229
  ```bash
209
- npx cc-safe-setup --lint
230
+ npx github:yurukusa/cc-safe-setup --lint
210
231
  ```
211
232
 
212
233
  Reports performance warnings and configuration issues.
@@ -216,7 +237,7 @@ Reports performance warnings and configuration issues.
216
237
  ### 1. Compare settings
217
238
 
218
239
  ```bash
219
- npx cc-safe-setup --diff teammate-settings.json
240
+ npx github:yurukusa/cc-safe-setup --diff teammate-settings.json
220
241
  ```
221
242
 
222
243
  Shows exactly what's different between your setups.
@@ -224,9 +245,9 @@ Shows exactly what's different between your setups.
224
245
  ### 2. Export and share
225
246
 
226
247
  ```bash
227
- npx cc-safe-setup --export # Creates cc-safe-setup-export.json
248
+ npx github:yurukusa/cc-safe-setup --export # Creates cc-safe-setup-export.json
228
249
  # Send to teammate
229
- npx cc-safe-setup --import cc-safe-setup-export.json
250
+ npx github:yurukusa/cc-safe-setup --import cc-safe-setup-export.json
230
251
  ```
231
252
 
232
253
  ### 3. Different jq versions
@@ -243,7 +264,7 @@ LOG="$HOME/.claude/blocked-commands.log"
243
264
  echo "[$(date -Iseconds)] BLOCKED: reason | cmd: $COMMAND" >> "$LOG"
244
265
  ```
245
266
 
246
- Then view with: `npx cc-safe-setup --watch` or `npx cc-safe-setup --stats`
267
+ Then view with: `npx github:yurukusa/cc-safe-setup --watch` or `npx github:yurukusa/cc-safe-setup --stats`
247
268
 
248
269
  ## "claude -p returns empty output when Stop hook is configured"
249
270
 
@@ -253,7 +274,7 @@ This is a known Claude Code v2.1.83 bug ([#38651](https://github.com/anthropics/
253
274
 
254
275
  ```bash
255
276
  # Quick toggle: comment out Stop hooks before -p commands
256
- npx cc-safe-setup --status # See which hooks are active
277
+ npx github:yurukusa/cc-safe-setup --status # See which hooks are active
257
278
  # Manually comment out Stop hooks in ~/.claude/settings.json
258
279
  # Run your -p command
259
280
  # Uncomment Stop hooks after
@@ -299,8 +320,8 @@ The hook has a strict whitelist. If a command isn't on the list, it passes throu
299
320
 
300
321
  ```bash
301
322
  # Install token tracking hooks
302
- npx cc-safe-setup --install-example prompt-usage-logger
303
- npx cc-safe-setup --install-example compact-alert-notification
323
+ npx github:yurukusa/cc-safe-setup --install-example prompt-usage-logger
324
+ npx github:yurukusa/cc-safe-setup --install-example compact-alert-notification
304
325
  ```
305
326
 
306
327
  After a session, check:
@@ -363,8 +384,8 @@ If you see `input length = 0`, that hook is not receiving stdin.
363
384
 
364
385
  ## Still Stuck?
365
386
 
366
- 1. Wrap the hook with debug wrapper: `npx cc-safe-setup --install-example hook-debug-wrapper`
387
+ 1. Wrap the hook with debug wrapper: `npx github:yurukusa/cc-safe-setup --install-example hook-debug-wrapper`
367
388
  2. Check `~/.claude/hook-debug.log` for detailed I/O traces
368
- 3. Run `npx cc-safe-setup --doctor` for automated checks
389
+ 3. Run `npx github:yurukusa/cc-safe-setup --doctor` for automated checks
369
390
  4. Open an issue: [cc-safe-setup issues](https://github.com/yurukusa/cc-safe-setup/issues)
370
391
  5. Read the full guide: **[Hook Design Guide (Zenn Book)](https://zenn.dev/yurukusa/books/6076c23b1cb18b)** — 14 chapters, Chapter 3 free
package/action.yml CHANGED
@@ -29,8 +29,11 @@ runs:
29
29
  shell: bash
30
30
  run: |
31
31
  echo "::group::Claude Code Safety Audit"
32
- npx cc-safe-setup@latest --audit --json 2>/dev/null > /tmp/audit-json.txt || true
33
- npx cc-safe-setup@latest --audit 2>&1 | tee /tmp/audit-output.txt
32
+ # Run the repository, not the npm entry. The published npm package is frozen at
33
+ # 29.8.0 (2026-04-20) and misses guards added since, so `npx cc-safe-setup@latest`
34
+ # would let this action pass a repository that the current checks refuse.
35
+ npx -y github:yurukusa/cc-safe-setup --audit --json 2>/dev/null > /tmp/audit-json.txt || true
36
+ npx -y github:yurukusa/cc-safe-setup --audit 2>&1 | tee /tmp/audit-output.txt
34
37
  echo "::endgroup::"
35
38
 
36
39
  # Parse JSON output
@@ -39,11 +42,16 @@ runs:
39
42
  GRADE=$(python3 -c "import json; print(json.load(open('/tmp/audit-json.txt'))['grade'])" 2>/dev/null || echo "?")
40
43
  RISK_COUNT=$(python3 -c "import json; print(len(json.load(open('/tmp/audit-json.txt'))['risks']))" 2>/dev/null || echo "0")
41
44
  else
42
- SCORE=$(grep -oP 'Safety Score: \K\d+' /tmp/audit-output.txt || echo "0")
45
+ # Fallback: strip ANSI colour codes first, otherwise the escape
46
+ # sequence between "Safety Score: " and the number defeats the match.
47
+ SCORE=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/audit-output.txt | grep -oP 'Safety Score: \K\d+' | head -1)
43
48
  GRADE="?"
44
49
  RISK_COUNT="?"
45
50
  fi
46
51
 
52
+ # Guard against an empty parse so the threshold comparison stays numeric.
53
+ [ -z "$SCORE" ] && SCORE="0"
54
+
47
55
  THRESHOLD="${{ inputs.threshold }}"
48
56
 
49
57
  echo "score=$SCORE" >> $GITHUB_OUTPUT
@@ -53,7 +61,7 @@ runs:
53
61
  echo "Safety Score: $SCORE/100 (Grade: $GRADE, Risks: $RISK_COUNT, Threshold: $THRESHOLD)"
54
62
 
55
63
  if [ "$SCORE" -lt "$THRESHOLD" ]; then
56
- echo "::error::Safety score $SCORE is below threshold $THRESHOLD. Run 'npx cc-safe-setup --audit --fix' to improve."
64
+ echo "::error::Safety score $SCORE is below threshold $THRESHOLD. Run 'npx github:yurukusa/cc-safe-setup --audit --fix' to improve."
57
65
  exit 1
58
66
  else
59
67
  echo "::notice::Safety score $SCORE meets threshold $THRESHOLD ✓"
@@ -0,0 +1,84 @@
1
+ # The Claude Code Safety Audit — course resources
2
+
3
+ Eight scripts and one sheet. Everything here runs against whatever Claude Code
4
+ setup you already have. Nothing here requires my hooks or my repository.
5
+
6
+ | File | What it does |
7
+ |---|---|
8
+ | `fire.sh` | Hands one hook the operation it is supposed to refuse, and prints the decision. `--bare` repeats it with no `jq`, no `python3` and no `node` on `PATH`. |
9
+ | `boundary.sh` | Takes one thing your hook should refuse and fires the hook at its neighbours — backups, case changes, a trailing space — and at things it must let through. Counts holes and overreach separately. |
10
+ | `count-hooks.py` | Reads all three settings files and reports how many hook groups are registered in each, plus the merge. |
11
+ | `find-dead-hooks.sh` | Lists registrations whose script is not on disk. Those produce no error and no symptom. |
12
+ | `find-unfirable-rules.sh` | Lists rules whose pattern cannot match anything, in the scripts your settings register and in inline commands. Two mechanisms: a pattern starting with a dash, which `grep` reads as options; and lookaround in an engine that has none. |
13
+ | `audit-checklist.md` | The 50-point sheet, in six sections. |
14
+ | `selftest.sh` | Proves `find-dead-hooks.sh` actually detects a missing registration, using a throwaway directory. Run it once if you want evidence that the detector works before you trust its silence. |
15
+ | `boundary-selftest.sh` | The same evidence for `boundary.sh`: builds a guard with a known hole and a guard without one, and checks that the report separates them. |
16
+ | `unfirable-selftest.sh` | The same evidence for `find-unfirable-rules.sh`: two rules that cannot match, two correct spellings of the same patterns, and the same pair written inline. Checks that it reports the first of each and not the second. |
17
+
18
+ ## The three exit codes
19
+
20
+ Claude Code hands a hook the tool call as JSON on standard input and reads its
21
+ exit code.
22
+
23
+ | Code | Meaning |
24
+ |---|---|
25
+ | `0` | allow the operation |
26
+ | `2` | refuse it, and show what the hook wrote to standard error |
27
+ | anything else | the hook itself failed, and the operation proceeds |
28
+
29
+ A warning printed to standard error does not stop anything. Only `2` does.
30
+
31
+ ## Quick start
32
+
33
+ ```bash
34
+ chmod +x fire.sh boundary.sh find-dead-hooks.sh selftest.sh boundary-selftest.sh
35
+
36
+ # 1. What is registered?
37
+ python3 count-hooks.py
38
+
39
+ # 2. Are any registrations pointing at nothing?
40
+ ./find-dead-hooks.sh
41
+
42
+ # 3. Does a guard you rely on actually refuse?
43
+ ./fire.sh <your-hook> Bash "command=<the dangerous command>"
44
+
45
+ # 4. Does it still refuse on a machine without a JSON parser?
46
+ ./fire.sh --bare <your-hook> Bash "command=<the dangerous command>"
47
+
48
+ # 5. Does it also refuse the neighbours of that operation?
49
+ ./boundary.sh <your-hook> Read file_path <the file it must protect>
50
+ ```
51
+
52
+ Step 4 is the one that changes most people's score. Step 5 is the one that
53
+ changes it a second time, after you have fixed what steps 3 and 4 found.
54
+
55
+ ## Why step 5 exists
56
+
57
+ Steps 3 and 4 answer "does the guard refuse this exact operation". That is
58
+ necessary and it is not enough. A path-matching guard draws a border, and the
59
+ holes are never in the middle of the protected area — they are just outside it,
60
+ on names nobody thought to type.
61
+
62
+ The hook shipped in this repository refused `id_rsa` and allowed `id_rsa.bak`.
63
+ After that was fixed it still allowed `id_rsa~`, `id_rsa.old.2`, and `id_rsa`
64
+ with a trailing space. Each of those is the same file to whoever reads it and a
65
+ different string to the matcher. All three were found by `boundary.sh` on a
66
+ guard that had just been widened by hand and looked finished.
67
+
68
+ `boundary.sh` also fires at things the guard must **let through** — the `.pub`
69
+ half of the key, a `.md` file that merely names it — and counts those separately
70
+ as overreach. A guard that refuses everything is not safe, it is unusable, and
71
+ there is no way to notice you have built one by testing refusals alone.
72
+
73
+ Rows marked `policy` are printed and not scored. Whether a key outside the
74
+ `.ssh` directory should be refused is your decision, not this script's.
75
+
76
+ ## A note on steps 3 and 5
77
+
78
+ Both run the hook with a throwaway `HOME`, so a hook that writes state into its
79
+ config directory will not touch yours while you are testing. Neither sandboxes
80
+ anything else: a hook that itself runs destructive commands would still run
81
+ them. Read a hook before you fire it — they are short.
82
+
83
+ No file is ever opened. A `PreToolUse` hook only sees the arguments of the tool
84
+ call, so the paths you pass do not need to exist, and no real key is read.
@@ -0,0 +1,152 @@
1
+ # Claude Code Safety Audit Checklist
2
+
3
+ **50-point assessment for Claude Code environments.**
4
+ Complete this checklist to identify gaps in your safety configuration.
5
+ Score: each ✅ = 1 point. Target: 40+ for production use, 45+ for autonomous operation.
6
+
7
+ ---
8
+
9
+ ## Hooks (15 points)
10
+
11
+ Your first line of defense. Hooks intercept dangerous operations before they execute.
12
+
13
+ | # | Check | Status | Notes |
14
+ |---|-------|--------|-------|
15
+ | 1 | **Destructive command guard** — `rm -rf`, `git reset --hard`, `git clean -fd` are blocked | ☐ | |
16
+ | 2 | **Force push guard** — `git push --force` (and `--force-with-lease` on shared branches) is blocked | ☐ | |
17
+ | 3 | **Main branch push guard** — direct `git push` to main/master is blocked | ☐ | |
18
+ | 4 | **Sensitive file write guard** — writes to `.env`, credentials, key files are blocked | ☐ | |
19
+ | 5 | **Sensitive file edit guard** — edits to `.env`, credentials, key files are blocked (separate from Write) | ☐ | |
20
+ | 6 | **Package publish guard** — `npm publish`, `docker push`, etc. require human execution | ☐ | |
21
+ | 7 | **External API write guard** — outbound POST/PUT/DELETE requests are blocked or flagged | ☐ | |
22
+ | 8 | **SQL destruction guard** — `DROP TABLE`, `TRUNCATE`, unscoped `DELETE` are blocked | ☐ | |
23
+ | 9 | **Sudo guard** — `sudo` commands are blocked | ☐ | |
24
+ | 10 | **Permission change guard** — `chmod 777`, recursive `chmod`/`chown` are blocked | ☐ | |
25
+ | 11 | **Infrastructure file warning** — edits to Dockerfile, CI config, package.json trigger a warning | ☐ | |
26
+ | 12 | **Long command warning** — commands over 500 characters are flagged for review | ☐ | |
27
+ | 13 | **Hooks are tested** — you have verified each hook actually blocks by triggering it intentionally | ☐ | |
28
+ | 14 | **Hooks survive updates** — hooks are in version control or backed up outside `~/.claude/` | ☐ | |
29
+ | 15 | **Hook failure mode is visible** — if a hook cannot read its input (no `jq`/`python3`/`node`), it says so on stderr instead of exiting 0 in silence. Refusing every call is an outage, not a guard | ☐ | |
30
+
31
+ ## Git Protection (10 points)
32
+
33
+ Git is both your safety net and your biggest risk vector.
34
+
35
+ | # | Check | Status | Notes |
36
+ |---|-------|--------|-------|
37
+ | 16 | **Work happens on feature branches** — CLAUDE.md explicitly requires branching | ☐ | |
38
+ | 17 | **Commits have meaningful messages** — convention is documented (conventional commits, etc.) | ☐ | |
39
+ | 18 | **Pre-commit tests** — tests run before or immediately after each commit | ☐ | |
40
+ | 19 | **Backup branch before risky changes** — documented procedure for `git checkout -b backup/...`, **and you have used it at least once** | ☐ | |
41
+ | 20 | **No orphaned branches** — process exists to clean up merged/stale branches | ☐ | |
42
+ | 21 | **`.gitignore` covers sensitive files as a class** — `.env`, `*.pem`, `*.key`, `credentials.*` are all listed (check 28 covers `.env` alone) | ☐ | |
43
+ | 22 | **`.gitignore` covers generated files** — `node_modules/`, `__pycache__/`, `dist/`, build artifacts are listed | ☐ | |
44
+ | 23 | **Git hooks complement Claude hooks** — pre-commit and pre-push hooks exist at the repository level | ☐ | |
45
+ | 24 | **Rebase/merge strategy is documented** — team knows whether to rebase or merge | ☐ | |
46
+ | 25 | **Force push is disabled server-side** — branch protection rules on GitHub/GitLab block force push to main | ☐ | |
47
+
48
+ ## Credentials & Secrets (8 points)
49
+
50
+ One leaked secret can cost more than your entire project.
51
+
52
+ | # | Check | Status | Notes |
53
+ |---|-------|--------|-------|
54
+ | 26 | **No hardcoded secrets in source** — grep your codebase for API keys, passwords, tokens | ☐ | |
55
+ | 27 | **Environment variables for all secrets** — documented in `.env.example` (without values) | ☐ | |
56
+ | 28 | **`.env` is gitignored** — confirmed in `.gitignore`, verified with `git status` | ☐ | |
57
+ | 29 | **Secret scanning is active** — GitHub secret scanning, `gitleaks`, or equivalent is enabled | ☐ | |
58
+ | 30 | **API tokens have minimum scope** — each token has only the permissions it needs | ☐ | |
59
+ | 31 | **Token expiration is set** — tokens expire and have a documented renewal process | ☐ | |
60
+ | 32 | **Service account keys are secured** — GCP/AWS/Azure keys are not in the project directory | ☐ | |
61
+ | 33 | **Git history is clean** — no secrets were ever committed (check with `git log -p -S "password"`) | ☐ | |
62
+
63
+ ## Token & Cost Management (7 points)
64
+
65
+ Uncontrolled token usage can drain your budget overnight.
66
+
67
+ | # | Check | Status | Notes |
68
+ |---|-------|--------|-------|
69
+ | 34 | **CLAUDE.md is under 500 lines** — bloated instructions waste tokens on every message | ☐ | |
70
+ | 35 | **No redundant context** — instructions are not duplicated across CLAUDE.md, settings, and hooks | ☐ | |
71
+ | 36 | **Large file reads are targeted** — `Read` calls use `offset` and `limit` for files over 200 lines | ☐ | |
72
+ | 37 | **Subagents are used for exploration** — research tasks are offloaded, not done in the main context | ☐ | |
73
+ | 38 | **Session cost is monitored** — you check `/cost` or equivalent regularly | ☐ | |
74
+ | 39 | **Spending limits are configured** — Anthropic Console or API usage limits are set | ☐ | |
75
+ | 40 | **Compact triggers are understood** — you know when context compaction happens and what it loses | ☐ | |
76
+
77
+ ## Autonomous Operation (5 points)
78
+
79
+ Running Claude Code unattended requires extra safeguards.
80
+
81
+ | # | Check | Status | Notes |
82
+ |---|-------|--------|-------|
83
+ | 41 | **All external writes are blocked** — `curl POST`, `gh issue create`, API calls are hook-blocked | ☐ | |
84
+ | 42 | **Configuration files are protected** — CLAUDE.md and settings.json cannot be self-modified | ☐ | |
85
+ | 43 | **Remote access is blocked** — `ssh`, `scp`, `rsync` to remote hosts are hook-blocked | ☐ | |
86
+ | 44 | **Service management is blocked** — `systemctl`, `service` commands are hook-blocked | ☐ | |
87
+ | 45 | **Error escalation path exists** — after N failures, the agent logs the issue and moves on (not infinite retry) | ☐ | |
88
+
89
+ ## Team & Multi-Agent (5 points)
90
+
91
+ When multiple people or agents share a codebase, coordination failures become the primary risk.
92
+
93
+ | # | Check | Status | Notes |
94
+ |---|-------|--------|-------|
95
+ | 46 | **Shared hooks in version control** — `.claude/settings.json` is committed and reviewed via PR | ☐ | |
96
+ | 47 | **CLAUDE.md changes require review** — project instructions are not unilaterally changed | ☐ | |
97
+ | 48 | **File lock awareness** — multi-agent setups have a mechanism to detect concurrent edits | ☐ | |
98
+ | 49 | **PR review is mandatory** — branch protection rules enforce at least one approving review | ☐ | |
99
+ | 50 | **Personal overrides don't weaken safety** — `.claude/settings.local.json` cannot disable project-level hooks | ☐ | |
100
+
101
+ ---
102
+
103
+ ## Scoring Guide
104
+
105
+ | Score | Rating | Recommendation |
106
+ |-------|--------|----------------|
107
+ | **45–50** | Excellent | Ready for autonomous and team use |
108
+ | **40–44** | Good | Safe for supervised use. Address gaps before going autonomous |
109
+ | **30–39** | Fair | Significant gaps. Do not run unattended |
110
+ | **20–29** | Poor | High risk of data loss or secret exposure. Fix immediately |
111
+ | **< 20** | Critical | Stop using Claude Code on this project until remediated |
112
+
113
+ ## How to Use This Checklist
114
+
115
+ 1. **Initial audit:** Go through all 50 items. Mark each ✅ or ❌
116
+ 2. **Prioritize fixes:** Credentials & Hooks failures are highest priority
117
+ 3. **Re-audit monthly:** New dependencies, team members, and workflows introduce new risks
118
+ 4. **After incidents:** Re-run the relevant section to find the root cause
119
+
120
+ ## Quick Verification Commands
121
+
122
+ ```bash
123
+ # Check if .env is gitignored
124
+ git check-ignore .env; echo "exit $?" # 0 = ignored (pass), 1 = NOT ignored (fail)
125
+
126
+ # Search for hardcoded secrets in source
127
+ # One --include per extension: a braced list is passed to grep literally and
128
+ # matches nothing, so the command returns a reassuring zero. Verified 2026-08-27.
129
+ grep -rn "password\|api_key\|secret\|token" \
130
+ --include="*.js" --include="*.ts" --include="*.py" --include="*.go" --include="*.rb" . \
131
+ | grep -v node_modules | grep -v test
132
+
133
+ # Verify hooks are loaded
134
+ # `claude --print-settings` is not a flag the CLI has (checked 2026-08-27 against
135
+ # 2.1.246; it exits 1 and prints usage). Read the three settings files instead:
136
+ for f in ~/.claude/settings.json .claude/settings.json .claude/settings.local.json; do
137
+ [ -f "$f" ] && echo "$f: $(jq '[.hooks[]?[]?] | length' "$f")"
138
+ done
139
+
140
+ # Check for secrets in git history
141
+ # A git pathspec does not brace-expand either. List the globs. Verified 2026-08-27.
142
+ git log -p --all -S "API_KEY" --diff-filter=A -- "*.js" "*.ts" "*.py" "*.go" "*.rb"
143
+
144
+ # Verify branch protection (GitHub)
145
+ # Run inside the repository; gh fills in {owner}/{repo} from the remote.
146
+ # "Branch not protected" is a failing check 25/49, not an error.
147
+ gh api repos/{owner}/{repo}/branches/main/protection | jq '.required_pull_request_reviews'
148
+ ```
149
+
150
+ ---
151
+
152
+ *Part of [Claude Code Safety Mastery](https://yurukusa.gumroad.com/l/pcctdn). Use this checklist to protect your projects, your secrets, and your budget.*
@@ -0,0 +1,85 @@
1
+ #!/bin/bash
2
+ # boundary-selftest.sh - prove that boundary.sh actually distinguishes a guard
3
+ # with a hole from a guard without one.
4
+ #
5
+ # A detector that reports "holes: 0" is worthless until you have watched it
6
+ # report a hole it was supposed to find. This builds two guards in a throwaway
7
+ # directory - one anchored so tightly that backups walk through, one widened -
8
+ # and checks that boundary.sh separates them in both directions.
9
+ set -u
10
+ HERE=$(cd "$(dirname "$0")" && pwd)
11
+ T=$(mktemp -d)
12
+ trap 'rm -rf "$T"' EXIT
13
+ PASS=0; FAIL=0
14
+ check() { # check <description> <expected> <actual>
15
+ if [ "$2" = "$3" ]; then echo " PASS: $1"; PASS=$((PASS + 1))
16
+ else echo " FAIL: $1 (expected $2, got $3)"; FAIL=$((FAIL + 1)); fi
17
+ }
18
+
19
+ # A guard that refuses the exact name and nothing near it.
20
+ cat > "$T/narrow.sh" <<'SH'
21
+ #!/bin/bash
22
+ F=$(cat | grep -o '"file_path":"[^"]*"' | sed 's/.*:"//; s/"$//')
23
+ [ -z "$F" ] && exit 0
24
+ echo "$F" | grep -qE 'id_rsa$' && { echo "BLOCKED" >&2; exit 2; }
25
+ exit 0
26
+ SH
27
+
28
+ # The same guard, widened to cover backups, and still letting .pub through.
29
+ # The -i is not decoration: the first draft of this fixture omitted it and
30
+ # boundary.sh correctly reported ID_RSA as a hole. Case folding is one of the
31
+ # neighbours, so a fixture that means to be clean has to fold case too.
32
+ cat > "$T/wide.sh" <<'SH'
33
+ #!/bin/bash
34
+ F=$(cat | grep -o '"file_path":"[^"]*"' | sed 's/.*:"//; s/"$//')
35
+ [ -z "$F" ] && exit 0
36
+ echo "$F" | grep -qiE '\.pub[[:space:]]*$' && exit 0
37
+ echo "$F" | grep -qiE 'id_rsa(([._-](bak|old|orig|save|copy|backup|[0-9]+))|~){0,3}[[:space:]]*$' \
38
+ && { echo "BLOCKED" >&2; exit 2; }
39
+ exit 0
40
+ SH
41
+
42
+ # A guard that refuses everything. Safe-looking and unusable; the "allow" rows
43
+ # exist to catch exactly this, so the detector must call it overreach.
44
+ cat > "$T/paranoid.sh" <<'SH'
45
+ #!/bin/bash
46
+ cat >/dev/null
47
+ echo "BLOCKED" >&2
48
+ exit 2
49
+ SH
50
+ chmod +x "$T"/*.sh
51
+
52
+ echo "=== control 1: a narrow guard must be reported as having holes ==="
53
+ out=$(bash "$HERE/boundary.sh" "$T/narrow.sh" Read file_path /home/me/.ssh/id_rsa 2>&1); rc=$?
54
+ printf '%s\n' "$out" | grep -E '^holes|^overreach'
55
+ holes=$(printf '%s\n' "$out" | sed -n 's/^holes *: *\([0-9]*\).*/\1/p')
56
+ over=$(printf '%s\n' "$out" | sed -n 's/^overreach *: *\([0-9]*\).*/\1/p')
57
+ check "narrow guard reports at least one hole" "yes" "$([ "${holes:-0}" -ge 1 ] && echo yes || echo no)"
58
+ check "narrow guard reports no overreach" "0" "${over:-x}"
59
+ check "narrow guard exits non-zero" "yes" "$([ "$rc" -ne 0 ] && echo yes || echo no)"
60
+
61
+ echo "=== control 2: the widened guard must come back clean ==="
62
+ out=$(bash "$HERE/boundary.sh" "$T/wide.sh" Read file_path /home/me/.ssh/id_rsa 2>&1); rc=$?
63
+ printf '%s\n' "$out" | grep -E '^holes|^overreach'
64
+ holes=$(printf '%s\n' "$out" | sed -n 's/^holes *: *\([0-9]*\).*/\1/p')
65
+ over=$(printf '%s\n' "$out" | sed -n 's/^overreach *: *\([0-9]*\).*/\1/p')
66
+ check "widened guard reports no holes" "0" "${holes:-x}"
67
+ check "widened guard reports no overreach" "0" "${over:-x}"
68
+ check "widened guard exits zero" "0" "$rc"
69
+
70
+ echo "=== control 3: a guard that refuses everything must be reported as overreach ==="
71
+ out=$(bash "$HERE/boundary.sh" "$T/paranoid.sh" Read file_path /home/me/.ssh/id_rsa 2>&1)
72
+ over=$(printf '%s\n' "$out" | sed -n 's/^overreach *: *\([0-9]*\).*/\1/p')
73
+ holes=$(printf '%s\n' "$out" | sed -n 's/^holes *: *\([0-9]*\).*/\1/p')
74
+ check "refuse-everything guard reports overreach" "yes" "$([ "${over:-0}" -ge 1 ] && echo yes || echo no)"
75
+ check "refuse-everything guard reports no holes" "0" "${holes:-x}"
76
+
77
+ echo "=== control 4: the target itself is fired, not just its neighbours ==="
78
+ out=$(bash "$HERE/boundary.sh" "$T/wide.sh" Read file_path /home/me/.ssh/id_rsa 2>&1)
79
+ check "the thing itself appears as a row" "yes" \
80
+ "$(printf '%s\n' "$out" | grep -qE 'the thing itself .*refused' && echo yes || echo no)"
81
+
82
+ echo
83
+ echo "=========================="
84
+ echo "Results: $PASS passed, $FAIL failed"
85
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,123 @@
1
+ #!/bin/bash
2
+ # boundary.sh — take one thing your hook is meant to refuse, and fire the hook
3
+ # at the neighbours of that thing.
4
+ #
5
+ # Why this exists: fire.sh answers "does the guard refuse this exact operation".
6
+ # That is necessary and it is not enough. Every path-matching guard draws a
7
+ # border, and the holes are never in the middle of the protected area - they
8
+ # are just outside the border, on names nobody thought to type. A guard that
9
+ # refuses ~/.ssh/id_rsa and allows ~/.ssh/id_rsa.bak is not protecting the key,
10
+ # because the backup of a key is the key.
11
+ #
12
+ # The second half matters as much as the first. A guard that refuses everything
13
+ # is not safe, it is unusable, and you only find out you have built one by
14
+ # firing it at things it must let through. So this prints both directions.
15
+ #
16
+ # Usage:
17
+ # ./boundary.sh <hook-script> <tool-name> <field> <value> [--bare]
18
+ #
19
+ # Examples:
20
+ # ./boundary.sh ~/.claude/hooks/key-guard.sh Read file_path /home/me/.ssh/id_rsa
21
+ # ./boundary.sh ~/.claude/hooks/env-guard.sh Read file_path /home/me/app/.env
22
+ #
23
+ # What it prints, per neighbour:
24
+ # refused / allowed / hook error, and a note where the answer is not a matter
25
+ # of taste. It deliberately does NOT score you pass/fail on the ambiguous
26
+ # rows: whether /tmp/id_rsa should be refused is your policy, not ours.
27
+ #
28
+ # Every run uses a throwaway HOME, and no file is ever read - the hook is judged
29
+ # on the tool-call arguments alone, which is all a PreToolUse hook ever sees.
30
+ # That means the paths below do not need to exist, and no real key is touched.
31
+ set -u
32
+
33
+ HERE=$(cd "$(dirname "$0")" && pwd)
34
+ BARE=""
35
+ ARGS=()
36
+ for a in "$@"; do
37
+ if [ "$a" = "--bare" ]; then BARE="--bare"; else ARGS+=("$a"); fi
38
+ done
39
+ set -- "${ARGS[@]+"${ARGS[@]}"}"
40
+
41
+ if [ $# -lt 4 ]; then
42
+ sed -n '2,32p' "$0" | sed 's/^# \{0,1\}//'
43
+ exit 64
44
+ fi
45
+
46
+ HOOK="$1"; TOOL="$2"; FIELD="$3"; VALUE="$4"
47
+ [ -f "$HOOK" ] || { echo "boundary.sh: no such hook: $HOOK" >&2; exit 64; }
48
+
49
+ dir=$(dirname "$VALUE")
50
+ base=$(basename "$VALUE")
51
+ stem="${base%.*}"
52
+ ext=""
53
+ case "$base" in *.*) ext=".${base##*.}" ;; esac
54
+
55
+ # Neighbours are grouped by what the answer means, not by how they are spelled.
56
+ # must - refusing this is the whole point; allowing it is a hole
57
+ # should - a copy of a secret is a secret; allowing it is almost always a hole
58
+ # allow - refusing this makes the guard unusable
59
+ # policy - reasonable people differ; printed for your eyes, not scored
60
+ CASES=()
61
+ add() { CASES+=("$1|$2|$3"); }
62
+
63
+ add must "the thing itself" "$VALUE"
64
+ add should "backup, dot suffix" "${VALUE}.bak"
65
+ add should "backup, word suffix" "${VALUE}_old"
66
+ add should "backup, editor style" "${VALUE}~"
67
+ add should "backup, two suffixes" "${VALUE}.old.2"
68
+ add should "same name, uppercased" "${dir}/$(printf '%s' "$base" | tr '[:lower:]' '[:upper:]')"
69
+ add should "same file, redundant dot segment" "${dir}/./${base}"
70
+ add should "same file, trailing space" "${VALUE} "
71
+ add policy "same name, another directory" "/tmp/${base}"
72
+ add policy "the directory itself" "${dir}/"
73
+ add policy "relative path" "$(printf '%s' "$VALUE" | sed 's#^/[^/]*/[^/]*/##')"
74
+ # .pub is checked whether or not the target has an extension: for key files it
75
+ # is the single most common false positive, and id_rsa has no extension at all.
76
+ if [ -n "$ext" ]; then
77
+ add allow "public half, .pub" "${dir}/${stem}.pub"
78
+ else
79
+ add allow "public half, .pub" "${VALUE}.pub"
80
+ fi
81
+ add allow "prose that names it" "${dir}/${stem}.md"
82
+ add allow "source file that names it" "${dir}/${stem}_generator.py"
83
+ add allow "an ordinary project file" "${dir}/README.md"
84
+
85
+ printf 'hook : %s\n' "$HOOK"
86
+ printf 'tool : %s field: %s\n' "$TOOL" "$FIELD"
87
+ printf 'target: %s\n' "$VALUE"
88
+ [ -n "$BARE" ] && printf 'mode : --bare (no jq, no python3, no node)\n'
89
+ printf '\n%-6s %-30s %-8s %s\n' "GROUP" "NEIGHBOUR" "RESULT" "VALUE"
90
+ printf -- '------ ------------------------------ -------- -----\n'
91
+
92
+ holes=0; overreach=0; errors=0
93
+ for c in "${CASES[@]}"; do
94
+ group="${c%%|*}"; rest="${c#*|}"
95
+ label="${rest%%|*}"; val="${rest#*|}"
96
+ ${BARE:+:} true # keep shellcheck quiet about the optional flag
97
+ out=$(bash "$HERE/fire.sh" ${BARE:+--bare} "$HOOK" "$TOOL" "$FIELD=$val" 2>&1)
98
+ code=$?
99
+ case "$code" in
100
+ 2) result="refused" ;;
101
+ 0) result="allowed" ;;
102
+ *) result="ERROR($code)"; errors=$((errors + 1)) ;;
103
+ esac
104
+ case "$group:$result" in
105
+ must:allowed|should:allowed) result="$result <- hole"; holes=$((holes + 1)) ;;
106
+ allow:refused) result="$result <- over"; overreach=$((overreach + 1)) ;;
107
+ esac
108
+ printf '%-6s %-30s %-8s %s\n' "$group" "$label" "$result" "$val"
109
+ done
110
+
111
+ printf '\n'
112
+ printf 'holes : %d (must/should rows the hook let through)\n' "$holes"
113
+ printf 'overreach : %d (allow rows the hook refused)\n' "$overreach"
114
+ [ "$errors" -gt 0 ] && printf 'errors : %d (the hook itself failed; it is not protecting you either)\n' "$errors"
115
+ printf '\n'
116
+ printf 'The "policy" rows are not counted either way. Whether a key outside\n'
117
+ printf '~/.ssh, or the directory itself, should be refused is your decision.\n'
118
+ if [ "$holes" -eq 0 ] && [ "$overreach" -eq 0 ]; then
119
+ printf '\nNothing to fix on these neighbours. That is worth knowing, and it is\n'
120
+ printf 'not proof the guard is complete - it is proof it survives these rows.\n'
121
+ fi
122
+ [ "$holes" -gt 0 ] && exit 1
123
+ exit 0
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env python3
2
+ """count-hooks.py — how many hook groups are actually registered, per scope.
3
+
4
+ Why this exists: the usual advice is to run `claude --print-settings`. That flag
5
+ does not exist (checked on 2026-08-27 against 2.1.246); it exits 1 with a
6
+ one-line "error: unknown option". The settings that matter live in up to three
7
+ files, and Claude Code merges them. Counting only one under-reports. The settings that matter live in up to three files, and
8
+ Claude Code merges them. Counting only one of them under-reports.
9
+
10
+ Run it from your project directory.
11
+ """
12
+ import collections
13
+ import json
14
+ import os
15
+
16
+ SCOPES = [
17
+ ("user ", os.path.expanduser("~/.claude/settings.json")),
18
+ ("project", os.path.join(os.getcwd(), ".claude", "settings.json")),
19
+ ("local ", os.path.join(os.getcwd(), ".claude", "settings.local.json")),
20
+ ]
21
+
22
+ total = collections.Counter()
23
+ for label, path in SCOPES:
24
+ if not os.path.exists(path):
25
+ print(f" {label} (no file) {path}")
26
+ continue
27
+ try:
28
+ data = json.load(open(path, encoding="utf-8"))
29
+ except Exception as exc: # a malformed file is a finding, not a crash
30
+ print(f" {label} UNREADABLE: {exc} {path}")
31
+ continue
32
+ hooks = data.get("hooks") or {}
33
+ counts = {event: len(groups) for event, groups in hooks.items()}
34
+ total.update(counts)
35
+ print(f" {label} {counts if counts else 'no hooks'}")
36
+
37
+ print()
38
+ print(" merged :", dict(total))
39
+ print(" total :", sum(total.values()), "hook groups")
40
+ print()
41
+ print(" A count above zero means they are registered.")
42
+ print(" It does not mean any of them fires. Use fire.sh for that.")