cc-safe-setup 29.8.0 → 30.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1017) hide show
  1. package/.claude-plugin/marketplace.json +72 -19
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CONTRIBUTING.md +7 -2
  4. package/COOKBOOK.md +50 -46
  5. package/LICENSE +21 -0
  6. package/MIGRATION.md +8 -8
  7. package/README.md +419 -512
  8. package/SAFETY_CHECKLIST.md +15 -7
  9. package/SERVICES.md +194 -0
  10. package/SETTINGS_REFERENCE.md +236 -17
  11. package/SKILL.md +5 -5
  12. package/TROUBLESHOOTING.md +35 -14
  13. package/action.yml +12 -4
  14. package/audit/README.md +84 -0
  15. package/audit/audit-checklist.md +152 -0
  16. package/audit/boundary-selftest.sh +85 -0
  17. package/audit/boundary.sh +123 -0
  18. package/audit/count-hooks.py +42 -0
  19. package/audit/find-dead-hooks.sh +82 -0
  20. package/audit/find-unfirable-rules.sh +142 -0
  21. package/audit/fire.sh +97 -0
  22. package/audit/selftest.sh +42 -0
  23. package/audit/unfirable-selftest.sh +81 -0
  24. package/audit-web/index.html +9 -9
  25. package/examples/README.md +54 -17
  26. package/examples/account-billing-log.sh +98 -0
  27. package/examples/account-routing-preflight.sh +123 -0
  28. package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
  29. package/examples/agent-view-quota-decrement.sh +32 -0
  30. package/examples/agent-view-quota-warn.sh +94 -0
  31. package/examples/agents-md-edit-drift-warner.sh +223 -0
  32. package/examples/agents-md-loader.sh +160 -0
  33. package/examples/agents-md-sync-checker.sh +102 -0
  34. package/examples/ai-slop-punctuation-arrest.sh +210 -0
  35. package/examples/allowlist.sh +70 -10
  36. package/examples/always-allow-pattern-suggester.sh +125 -0
  37. package/examples/ansible-vault-guard.sh +2 -1
  38. package/examples/anthropic-base-url-guard.sh +76 -0
  39. package/examples/api-busyloop-guard.sh +123 -0
  40. package/examples/api-endpoint-guard.sh +12 -0
  41. package/examples/api-key-in-url-guard.sh +17 -1
  42. package/examples/api-rate-limit-guard.sh +36 -1
  43. package/examples/api-rate-limit-tracker.sh +12 -0
  44. package/examples/articulated-scope-capture.sh +101 -0
  45. package/examples/askuserquestion-autonomy-gate.sh +102 -0
  46. package/examples/attachment-traversal-guard.sh +118 -0
  47. package/examples/aup-block-pattern-logger.sh +161 -0
  48. package/examples/aup-false-positive-helper.sh +124 -0
  49. package/examples/aup-large-tool-output-warner.sh +282 -0
  50. package/examples/aup-retry-loop-guard.sh +229 -0
  51. package/examples/auth-expiry-reminder.sh +157 -0
  52. package/examples/auth-macos-sleep-detector.sh +185 -0
  53. package/examples/auth-path-detector.sh +171 -0
  54. package/examples/auth-status-checker.sh +157 -0
  55. package/examples/authorized-reconfirmation-detector.sh +195 -0
  56. package/examples/auto-approve-build.sh +39 -0
  57. package/examples/auto-approve-cargo.sh +31 -1
  58. package/examples/auto-approve-docker.sh +35 -0
  59. package/examples/auto-approve-git-read.sh +37 -14
  60. package/examples/auto-approve-go.sh +30 -1
  61. package/examples/auto-approve-gradle.sh +29 -1
  62. package/examples/auto-approve-make.sh +29 -1
  63. package/examples/auto-approve-maven.sh +29 -1
  64. package/examples/auto-approve-python.sh +41 -1
  65. package/examples/auto-approve-readonly-tools.sh +1 -0
  66. package/examples/auto-approve-readonly.sh +110 -33
  67. package/examples/auto-approve-ssh.sh +30 -1
  68. package/examples/auto-approve-test.sh +44 -0
  69. package/examples/auto-checkpoint.sh +1 -1
  70. package/examples/auto-compact-prep.sh +0 -0
  71. package/examples/auto-git-checkpoint.sh +0 -0
  72. package/examples/auto-mode-safe-commands.sh +53 -1
  73. package/examples/auto-mode-safety-enforcer.sh +151 -4
  74. package/examples/auto-push-session-branch.sh +22 -0
  75. package/examples/aws-production-guard.sh +13 -1
  76. package/examples/aws-region-guard.sh +1 -1
  77. package/examples/background-cost-launch-guard.sh +82 -0
  78. package/examples/background-task-guard.sh +12 -0
  79. package/examples/backup-before-refactor.sh +0 -0
  80. package/examples/banned-command-guard.sh +12 -0
  81. package/examples/bash-allowlist-secondary-check.sh +157 -0
  82. package/examples/bash-domain-allowlist.sh +12 -0
  83. package/examples/bash-fanout-bounded-rewriter.sh +191 -0
  84. package/examples/bash-heuristic-approver.sh +112 -10
  85. package/examples/bash-project-fence.sh +194 -0
  86. package/examples/bash-safety-auto-deny.sh +12 -0
  87. package/examples/bash-secret-output-detector.sh +44 -3
  88. package/examples/bash-trace-guard.sh +12 -0
  89. package/examples/bashrc-safety-check.sh +0 -0
  90. package/examples/bg-permission-prompt-warner.sh +182 -0
  91. package/examples/bg-task-cooldown-guard.sh +12 -0
  92. package/examples/binary-read-detector.sh +135 -0
  93. package/examples/binary-upload-guard.sh +12 -0
  94. package/examples/block-database-wipe.sh +35 -10
  95. package/examples/branch-name-check.sh +8 -3
  96. package/examples/branch-naming-convention.sh +0 -0
  97. package/examples/broad-find-guard.sh +12 -0
  98. package/examples/broad-prefix-session-trap-warner.sh +106 -0
  99. package/examples/bulk-file-delete-guard.sh +45 -0
  100. package/examples/bypass-mode-effective-verifier.sh +203 -0
  101. package/examples/cache-creation-drift-detector.sh +120 -0
  102. package/examples/cache-residue-detector.sh +195 -0
  103. package/examples/cache-tier-logger.sh +70 -0
  104. package/examples/cache-ttl-eviction-detector.sh +149 -0
  105. package/examples/cargo-publish-guard.sh +14 -1
  106. package/examples/case-insensitive-path-guard.sh +21 -2
  107. package/examples/case-sensitive-guard.sh +23 -2
  108. package/examples/cch-cache-guard.sh +0 -0
  109. package/examples/cch-sentinel-precommit-guard.sh +47 -0
  110. package/examples/check-abort-controller.sh +1 -1
  111. package/examples/check-accessibility.sh +0 -0
  112. package/examples/check-aria-labels.sh +0 -0
  113. package/examples/check-before-act-enforcer.sh +12 -0
  114. package/examples/check-charset-meta.sh +0 -0
  115. package/examples/check-cookie-flags.sh +0 -0
  116. package/examples/check-cors-config.sh +0 -0
  117. package/examples/check-csp-headers.sh +0 -0
  118. package/examples/check-csrf-protection.sh +0 -0
  119. package/examples/check-debounce.sh +1 -1
  120. package/examples/check-dependency-age.sh +0 -0
  121. package/examples/check-dependency-license.sh +0 -0
  122. package/examples/check-dockerfile-best-practice.sh +0 -0
  123. package/examples/check-error-boundaries.sh +0 -0
  124. package/examples/check-error-class.sh +1 -1
  125. package/examples/check-error-handling.sh +0 -0
  126. package/examples/check-error-logging.sh +1 -1
  127. package/examples/check-error-message.sh +0 -0
  128. package/examples/check-error-stack.sh +0 -0
  129. package/examples/check-favicon.sh +0 -0
  130. package/examples/check-git-hooks-compat.sh +0 -0
  131. package/examples/check-gitattributes.sh +0 -0
  132. package/examples/check-https-redirect.sh +0 -0
  133. package/examples/check-input-validation.sh +0 -0
  134. package/examples/check-lang-attribute.sh +0 -0
  135. package/examples/check-npm-scripts-exist.sh +0 -0
  136. package/examples/check-package-size.sh +0 -0
  137. package/examples/check-port-availability.sh +0 -0
  138. package/examples/check-promise-all.sh +1 -1
  139. package/examples/check-rate-limiting.sh +0 -0
  140. package/examples/check-return-types.sh +0 -0
  141. package/examples/check-semantic-versioning.sh +0 -0
  142. package/examples/check-suspense-fallback.sh +1 -1
  143. package/examples/check-test-exists.sh +0 -0
  144. package/examples/check-test-naming.sh +0 -0
  145. package/examples/check-timeout-cleanup.sh +1 -1
  146. package/examples/check-tls-version.sh +0 -0
  147. package/examples/check-unsubscribe.sh +1 -1
  148. package/examples/check-viewport-meta.sh +0 -0
  149. package/examples/check-worker-terminate.sh +1 -1
  150. package/examples/checkpoint-tamper-guard.sh +12 -0
  151. package/examples/chmod-guard.sh +12 -0
  152. package/examples/chown-guard.sh +24 -0
  153. package/examples/ci-workflow-guard.sh +6 -1
  154. package/examples/claim-verify-detector.sh +109 -0
  155. package/examples/claim-vs-caveat-checker.sh +77 -0
  156. package/examples/classifier-fallback-allow.sh +114 -40
  157. package/examples/claude-cache-gc.sh +1 -0
  158. package/examples/claude-code-version-pin-advisor.sh +183 -0
  159. package/examples/claude-md-reinjector.sh +129 -0
  160. package/examples/claude-md-size-monitor.sh +66 -0
  161. package/examples/claude-update-budget-guard.sh +123 -0
  162. package/examples/claude-update-smart.sh +113 -0
  163. package/examples/claudeignore-enforce-guard.sh +12 -0
  164. package/examples/claudemd-enforcer.sh +0 -0
  165. package/examples/claudemd-tool-prohibition.sh +128 -0
  166. package/examples/clear-command-confirm-guard.sh +32 -15
  167. package/examples/cli-config-pinning-detector.sh +162 -0
  168. package/examples/cliff-countdown-advisor.sh +96 -0
  169. package/examples/clipboard-secret-guard.sh +12 -0
  170. package/examples/closure-word-verify-gate.sh +150 -0
  171. package/examples/cloud-cli-guard.sh +39 -2
  172. package/examples/commit-all-scope-guard.sh +44 -0
  173. package/examples/commit-message-check.sh +1 -1
  174. package/examples/commit-message-quality.sh +6 -1
  175. package/examples/commitment-carry-forward-arrest.sh +361 -0
  176. package/examples/compact-alert-notification.sh +0 -0
  177. package/examples/compact-dispatch-watchdog.sh +149 -0
  178. package/examples/completion-claim-without-verification-detector.sh +207 -0
  179. package/examples/composer-guard.sh +12 -0
  180. package/examples/compound-bash-permission-resolver.sh +156 -0
  181. package/examples/compound-command-allow.sh +1 -1
  182. package/examples/compound-command-deny-enforcer.sh +183 -0
  183. package/examples/compound-inject-guard.sh +12 -0
  184. package/examples/concurrent-edit-lock.sh +12 -0
  185. package/examples/conflict-marker-guard.sh +12 -0
  186. package/examples/consecutive-error-breaker.sh +0 -0
  187. package/examples/console-log-count.sh +1 -0
  188. package/examples/context-compact-advisor.sh +29 -2
  189. package/examples/context-length-budget.sh +69 -0
  190. package/examples/context-threshold-alert.sh +12 -0
  191. package/examples/context-usage-drift-alert.sh +41 -13
  192. package/examples/conversation-history-guard.sh +12 -0
  193. package/examples/core-file-protect-guard.sh +12 -0
  194. package/examples/cors-star-warn.sh +0 -0
  195. package/examples/cost-incident-self-audit.sh +162 -0
  196. package/examples/cowork-claude-md-load-checker.sh +100 -0
  197. package/examples/cowork-fuse-staleness-watcher.sh +140 -0
  198. package/examples/cowork-hook-absence-warner.sh +167 -0
  199. package/examples/cowork-model-picker-advisor.sh +115 -0
  200. package/examples/credential-exfil-guard.sh +65 -4
  201. package/examples/credential-file-cat-guard.sh +17 -1
  202. package/examples/cron-create-receipt.sh +112 -0
  203. package/examples/cron-modification-guard.sh +12 -0
  204. package/examples/cross-product-mcp-spawn-detector.sh +178 -0
  205. package/examples/cwd-project-boundary-guard.sh +0 -0
  206. package/examples/daemon-zombie-worker-surfacer.sh +118 -0
  207. package/examples/daily-cost-guard.sh +164 -0
  208. package/examples/daily-usage-tracker.sh +0 -0
  209. package/examples/dangerous-pip-flag-guard.sh +12 -0
  210. package/examples/db-connect-guard.sh +13 -1
  211. package/examples/denied-action-retry-guard.sh +12 -0
  212. package/examples/deny-bypass-detector.sh +12 -0
  213. package/examples/deny-rule-integrity-verifier.sh +181 -0
  214. package/examples/dependency-install-guard.sh +12 -0
  215. package/examples/deploy-guard.sh +14 -2
  216. package/examples/deploy-path-verify-guard.sh +12 -0
  217. package/examples/deployment-readback-gate.sh +135 -0
  218. package/examples/deployment-readback-gh-adapter.sh +247 -0
  219. package/examples/deployment-verify-guard.sh +25 -2
  220. package/examples/destructive-db-script-write-guard.sh +166 -0
  221. package/examples/destructive-migration-write-guard.sh +163 -0
  222. package/examples/diff-size-guard.sh +12 -0
  223. package/examples/disabled-feature-toggle-advisor.sh +88 -0
  224. package/examples/disk-partition-guard.sh +12 -0
  225. package/examples/dispatch-allowlist-preflight.sh +301 -0
  226. package/examples/dispatch-liveness-watchdog.sh +216 -0
  227. package/examples/dispatch-receipt.sh +174 -0
  228. package/examples/django-migrate-guard.sh +12 -0
  229. package/examples/dns-config-guard.sh +12 -0
  230. package/examples/docker-dangerous-guard.sh +12 -0
  231. package/examples/docker-volume-guard.sh +0 -0
  232. package/examples/dockerfile-latest-guard.sh +1 -0
  233. package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
  234. package/examples/dotenv-commit-guard.sh +12 -0
  235. package/examples/dotenv-read-guard.sh +12 -0
  236. package/examples/dotfile-protection-guard.sh +12 -0
  237. package/examples/dotnet-build-on-edit.sh +1 -1
  238. package/examples/drizzle-migrate-guard.sh +27 -2
  239. package/examples/echo-probe-spam-detector.sh +176 -0
  240. package/examples/edit-counter-test-gate.sh +12 -0
  241. package/examples/edit-error-counter.sh +1 -1
  242. package/examples/edit-guard.sh +12 -0
  243. package/examples/edit-old-string-validator.sh +12 -0
  244. package/examples/edit-quote-ambiguity-guard.sh +97 -0
  245. package/examples/edit-retry-loop-guard.sh +0 -0
  246. package/examples/edit-verify.sh +0 -0
  247. package/examples/env-inline-secret-guard.sh +14 -2
  248. package/examples/env-naming-convention.sh +0 -0
  249. package/examples/env-prod-guard.sh +0 -0
  250. package/examples/env-required-check.sh +0 -0
  251. package/examples/env-source-guard.sh +12 -0
  252. package/examples/env-var-check.sh +24 -1
  253. package/examples/ephemeral-container-detector.sh +147 -0
  254. package/examples/error-memory-guard.sh +12 -0
  255. package/examples/evidence-claim-gate.sh +187 -0
  256. package/examples/exploration-budget-guard.sh +12 -0
  257. package/examples/expo-eject-guard.sh +13 -0
  258. package/examples/extended-thinking-loop-guard.sh +139 -0
  259. package/examples/extended-thinking-resume-warning.sh +119 -0
  260. package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
  261. package/examples/fabricated-command-detector.sh +145 -0
  262. package/examples/false-disk-full-guard.sh +63 -0
  263. package/examples/feature-deprecation-detector.sh +109 -0
  264. package/examples/file-change-tracker.sh +1 -1
  265. package/examples/file-change-undo-tracker.sh +0 -0
  266. package/examples/file-edit-backup.sh +63 -14
  267. package/examples/file-reference-check.sh +0 -0
  268. package/examples/file-size-limit.sh +12 -0
  269. package/examples/financial-operation-guard.sh +12 -0
  270. package/examples/firewall-guard.sh +12 -0
  271. package/examples/fish-shell-wrapper.sh +125 -7
  272. package/examples/five-hundred-milestone.sh +1 -0
  273. package/examples/flask-static-route-guard.sh +89 -0
  274. package/examples/forbidden-response-phrase-detector.sh +161 -0
  275. package/examples/gem-push-guard.sh +13 -0
  276. package/examples/gh-cli-destructive-guard.sh +13 -1
  277. package/examples/git-checkout-safety-guard.sh +12 -0
  278. package/examples/git-checkout-uncommitted-guard.sh +12 -0
  279. package/examples/git-config-guard.sh +12 -0
  280. package/examples/git-crypt-worktree-guard.sh +12 -0
  281. package/examples/git-filter-repo-guard.sh +56 -0
  282. package/examples/git-history-rewrite-guard.sh +12 -0
  283. package/examples/git-hook-bypass-guard.sh +0 -0
  284. package/examples/git-maintenance-guard.sh +83 -0
  285. package/examples/git-merge-conflict-prevent.sh +0 -0
  286. package/examples/git-message-length-check.sh +0 -0
  287. package/examples/git-message-length.sh +0 -0
  288. package/examples/git-operations-require-approval.sh +68 -14
  289. package/examples/git-pack-temp-cleanup-guard.sh +102 -0
  290. package/examples/git-push-blast-radius-guard.sh +218 -0
  291. package/examples/git-remote-guard.sh +24 -3
  292. package/examples/git-rm-orphan-wipe-guard.sh +85 -0
  293. package/examples/git-stash-before-checkout.sh +12 -0
  294. package/examples/git-stash-before-danger.sh +0 -0
  295. package/examples/git-submodule-guard.sh +69 -2
  296. package/examples/git-tag-guard.sh +12 -0
  297. package/examples/github-actions-secret-guard.sh +0 -0
  298. package/examples/gitignore-check.sh +0 -0
  299. package/examples/gitops-drift-guard.sh +12 -0
  300. package/examples/go-mod-tidy-warn.sh +1 -0
  301. package/examples/go-vet-after-edit.sh +12 -0
  302. package/examples/goal-iteration-limit-warner.sh +152 -0
  303. package/examples/grep-nul-false-negative-guard.sh +30 -0
  304. package/examples/growthbook-flag-monitor.sh +257 -0
  305. package/examples/hallucination-url-check.sh +1 -1
  306. package/examples/halt-signal-detector.sh +135 -0
  307. package/examples/handoff-on-clear.sh +65 -0
  308. package/examples/hardcoded-ip-guard.sh +1 -0
  309. package/examples/headless-empty-result-guard.sh +0 -0
  310. package/examples/headless-stop-guard.sh +0 -0
  311. package/examples/helm-install-guard.sh +2 -1
  312. package/examples/home-critical-bash-guard.sh +17 -1
  313. package/examples/hook-debug-wrapper.sh +6 -2
  314. package/examples/hook-permission-fixer.sh +0 -0
  315. package/examples/hook-self-disable-detector.sh +99 -0
  316. package/examples/hook-stdout-sanitizer.sh +6 -2
  317. package/examples/hook-tamper-guard.sh +12 -0
  318. package/examples/idle-session-cost-alert.sh +0 -0
  319. package/examples/image-dimension-guard.sh +109 -0
  320. package/examples/image-file-validator.sh +0 -0
  321. package/examples/iteration-quality-degradation-detector.sh +170 -0
  322. package/examples/java-compile-on-edit.sh +1 -1
  323. package/examples/json-syntax-check.sh +0 -0
  324. package/examples/k8s-production-guard.sh +13 -1
  325. package/examples/kill-process-guard.sh +12 -0
  326. package/examples/kubernetes-guard.sh +13 -1
  327. package/examples/laravel-artisan-guard.sh +13 -0
  328. package/examples/large-file-guard.sh +1 -1
  329. package/examples/log-level-guard.sh +0 -0
  330. package/examples/log-truncation-guard.sh +12 -0
  331. package/examples/long-session-malformed-tool-call-detector.sh +183 -0
  332. package/examples/loop-detector.sh +12 -0
  333. package/examples/magic-number-warn.sh +1 -0
  334. package/examples/main-branch-warn.sh +12 -0
  335. package/examples/markdown-link-check.sh +0 -0
  336. package/examples/max-concurrent-agents.sh +12 -0
  337. package/examples/max-edit-size-guard.sh +13 -0
  338. package/examples/max-file-count-guard.sh +0 -0
  339. package/examples/max-file-delete-count.sh +0 -0
  340. package/examples/max-function-length.sh +1 -0
  341. package/examples/max-import-count.sh +0 -0
  342. package/examples/max-subagent-count.sh +0 -0
  343. package/examples/mcp-config-freeze.sh +12 -0
  344. package/examples/mcp-config-poisoning-audit.sh +150 -0
  345. package/examples/mcp-data-boundary.sh +1 -1
  346. package/examples/mcp-misdiagnosis-arrest.sh +209 -0
  347. package/examples/mcp-orphan-leak-warner.sh +49 -0
  348. package/examples/mcp-permissions-ask-warner.sh +151 -0
  349. package/examples/mcp-routine-approval-detector.sh +154 -0
  350. package/examples/mcp-server-allowlist.sh +12 -0
  351. package/examples/mcp-server-guard.sh +12 -0
  352. package/examples/mcp-startup-bloat-detector.sh +87 -0
  353. package/examples/mcp-stdio-compatibility-test.sh +153 -0
  354. package/examples/mcp-tool-audit-log.sh +0 -0
  355. package/examples/mcp-tool-guard.sh +101 -1
  356. package/examples/mcp-warmup-wait.sh +0 -0
  357. package/examples/memory-chain-audit.sh +56 -0
  358. package/examples/memory-orphan-detector.sh +188 -0
  359. package/examples/memory-write-guard.sh +99 -17
  360. package/examples/migration-verify-guard.sh +12 -0
  361. package/examples/model-swap-suggester.sh +177 -0
  362. package/examples/model-version-alert.sh +5 -1
  363. package/examples/model-version-lock.sh +63 -0
  364. package/examples/move-delete-sequence-guard.sh +33 -2
  365. package/examples/multi-file-plan-routing-gate.sh +192 -0
  366. package/examples/multi-vendor-concurrent-warner.sh +108 -0
  367. package/examples/multi-window-auth-drift-detector.sh +183 -0
  368. package/examples/multiline-command-approver.sh +161 -23
  369. package/examples/nested-background-agent-guard.sh +109 -0
  370. package/examples/nested-spawn-inflight-guard.sh +178 -0
  371. package/examples/network-exfil-guard.sh +12 -0
  372. package/examples/network-guard.sh +12 -0
  373. package/examples/network-interface-guard.sh +12 -0
  374. package/examples/nextjs-env-guard.sh +1 -1
  375. package/examples/no-absolute-import.sh +0 -0
  376. package/examples/no-alert-confirm-prompt.sh +0 -0
  377. package/examples/no-anonymous-default-export.sh +0 -0
  378. package/examples/no-any-type.sh +0 -0
  379. package/examples/no-any-typescript.sh +1 -0
  380. package/examples/no-ask-human.sh +12 -0
  381. package/examples/no-assignment-in-condition.sh +0 -0
  382. package/examples/no-base64-exfil.sh +12 -0
  383. package/examples/no-callback-hell.sh +0 -0
  384. package/examples/no-circular-dependency.sh +0 -0
  385. package/examples/no-cleartext-storage.sh +0 -0
  386. package/examples/no-commented-code.sh +0 -0
  387. package/examples/no-commit-fixup.sh +0 -0
  388. package/examples/no-console-assert.sh +0 -0
  389. package/examples/no-console-error-swallow.sh +0 -0
  390. package/examples/no-console-in-prod.sh +0 -0
  391. package/examples/no-console-log-commit.sh +12 -0
  392. package/examples/no-console-log.sh +0 -0
  393. package/examples/no-console-time.sh +0 -0
  394. package/examples/no-cors-wildcard.sh +4 -1
  395. package/examples/no-curl-upload.sh +0 -0
  396. package/examples/no-dangerouslySetInnerHTML.sh +0 -0
  397. package/examples/no-dangling-await.sh +1 -0
  398. package/examples/no-debug-commit.sh +12 -0
  399. package/examples/no-debug-in-commit.sh +0 -0
  400. package/examples/no-deep-nesting.sh +0 -0
  401. package/examples/no-deep-relative-import.sh +1 -0
  402. package/examples/no-default-credentials.sh +0 -0
  403. package/examples/no-deploy-friday.sh +13 -1
  404. package/examples/no-disabled-test.sh +0 -0
  405. package/examples/no-document-write.sh +0 -0
  406. package/examples/no-empty-function.sh +0 -0
  407. package/examples/no-eval-in-template.sh +0 -0
  408. package/examples/no-eval-template.sh +3 -1
  409. package/examples/no-eval.sh +0 -0
  410. package/examples/no-exec-user-input.sh +0 -0
  411. package/examples/no-fixme-ship.sh +12 -0
  412. package/examples/no-floating-promises.sh +0 -0
  413. package/examples/no-force-flag.sh +22 -5
  414. package/examples/no-force-install.sh +0 -0
  415. package/examples/no-git-amend.sh +12 -0
  416. package/examples/no-git-rebase-public.sh +0 -0
  417. package/examples/no-global-install.sh +12 -0
  418. package/examples/no-global-state.sh +0 -0
  419. package/examples/no-hardcoded-port.sh +1 -0
  420. package/examples/no-hardcoded-url.sh +0 -0
  421. package/examples/no-helmet-missing.sh +0 -0
  422. package/examples/no-http-url.sh +1 -0
  423. package/examples/no-http-without-https.sh +0 -0
  424. package/examples/no-inline-style.sh +0 -0
  425. package/examples/no-inline-styles.sh +1 -0
  426. package/examples/no-innerhtml.sh +0 -0
  427. package/examples/no-install-global.sh +12 -0
  428. package/examples/no-jwt-in-url.sh +0 -0
  429. package/examples/no-large-commit.sh +0 -0
  430. package/examples/no-localhost-expose.sh +0 -0
  431. package/examples/no-magic-number.sh +0 -0
  432. package/examples/no-md5-sha1.sh +0 -0
  433. package/examples/no-mixed-line-endings.sh +8 -1
  434. package/examples/no-mutation-in-reducer.sh +0 -0
  435. package/examples/no-nested-ternary.sh +0 -0
  436. package/examples/no-network-exfil.sh +0 -0
  437. package/examples/no-open-redirect.sh +0 -0
  438. package/examples/no-output-truncation.sh +12 -0
  439. package/examples/no-package-downgrade.sh +0 -0
  440. package/examples/no-package-lock-edit.sh +12 -0
  441. package/examples/no-path-join-user-input.sh +0 -0
  442. package/examples/no-port-bind.sh +0 -0
  443. package/examples/no-process-exit.sh +0 -0
  444. package/examples/no-prototype-pollution.sh +0 -0
  445. package/examples/no-push-without-ci.sh +0 -0
  446. package/examples/no-push-without-tests.sh +12 -0
  447. package/examples/no-raw-password-in-url.sh +0 -0
  448. package/examples/no-root-user-docker.sh +1 -0
  449. package/examples/no-root-write.sh +12 -0
  450. package/examples/no-secrets-in-args.sh +4 -1
  451. package/examples/no-secrets-in-logs.sh +0 -0
  452. package/examples/no-sensitive-log.sh +0 -0
  453. package/examples/no-sleep-in-hooks.sh +0 -0
  454. package/examples/no-star-import-python.sh +1 -0
  455. package/examples/no-string-concat-sql.sh +0 -0
  456. package/examples/no-sudo-guard.sh +12 -0
  457. package/examples/no-sync-fs.sh +0 -0
  458. package/examples/no-todo-in-merge.sh +0 -0
  459. package/examples/no-todo-in-production.sh +1 -0
  460. package/examples/no-todo-without-issue.sh +0 -0
  461. package/examples/no-unused-import.sh +0 -0
  462. package/examples/no-var-keyword.sh +0 -0
  463. package/examples/no-verify-blocker.sh +12 -0
  464. package/examples/no-wget-piped-bash.sh +12 -0
  465. package/examples/no-wildcard-cors.sh +0 -0
  466. package/examples/no-wildcard-delete.sh +0 -0
  467. package/examples/no-wildcard-import.sh +0 -0
  468. package/examples/no-with-statement.sh +0 -0
  469. package/examples/no-write-outside-src.sh +0 -0
  470. package/examples/no-xml-external-entity.sh +0 -0
  471. package/examples/non-english-quality-warner.sh +156 -0
  472. package/examples/notify-waiting.sh +1 -1
  473. package/examples/npm-audit-warn.sh +0 -0
  474. package/examples/npm-global-install-guard.sh +12 -0
  475. package/examples/npm-publish-guard.sh +12 -0
  476. package/examples/npm-script-injection.sh +0 -0
  477. package/examples/npm-supply-chain-guard.sh +0 -0
  478. package/examples/nuxt-config-guard.sh +1 -0
  479. package/examples/oauth-refresh-monitor.sh +210 -0
  480. package/examples/opus-degradation-tracker.sh +187 -0
  481. package/examples/opus48-routine-task-warning.sh +196 -0
  482. package/examples/opus48-thinking-wedge-advisor.sh +143 -0
  483. package/examples/output-credential-scan.sh +1 -1
  484. package/examples/output-secret-mask.sh +31 -9
  485. package/examples/output-token-spike-detector.sh +145 -0
  486. package/examples/package-json-guard.sh +12 -0
  487. package/examples/package-lock-frozen.sh +12 -0
  488. package/examples/parallel-batch-size-limiter.sh +121 -0
  489. package/examples/parallel-cascade-detector.sh +116 -0
  490. package/examples/partial-view-claim-arrest.sh +174 -0
  491. package/examples/path-deny-bash-guard.sh +12 -0
  492. package/examples/path-traversal-guard.sh +12 -0
  493. package/examples/per-prompt-token-cap.sh +124 -0
  494. package/examples/permission-audit-log.sh +1 -1
  495. package/examples/permission-denial-enforcer.sh +12 -0
  496. package/examples/permission-entry-validator.sh +0 -0
  497. package/examples/persisted-1m-model-advisor.sh +88 -0
  498. package/examples/php-lint-on-edit.sh +1 -1
  499. package/examples/pii-upload-guard.sh +12 -0
  500. package/examples/pip-publish-guard.sh +13 -0
  501. package/examples/pip-requirements-guard.sh +12 -0
  502. package/examples/pip-venv-required.sh +12 -0
  503. package/examples/plan-mode-edit-guard.sh +12 -0
  504. package/examples/plan-mode-enforcer.sh +12 -0
  505. package/examples/plan-mode-strict-guard.sh +12 -0
  506. package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
  507. package/examples/plugin-process-cleanup.sh +0 -0
  508. package/examples/polyglot-rm-guard.sh +12 -0
  509. package/examples/post-compact-safety.sh +12 -0
  510. package/examples/post-edit-disk-verify.sh +152 -0
  511. package/examples/powershell-remove-item-guard.sh +85 -0
  512. package/examples/pr-description-check.sh +0 -0
  513. package/examples/pr-duplicate-guard.sh +13 -0
  514. package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
  515. package/examples/pre-compact-knowledge-save.sh +0 -0
  516. package/examples/pre-compact-transcript-backup.sh +0 -0
  517. package/examples/pre-execution-claim-detector.sh +179 -0
  518. package/examples/prefer-builtin-tools.sh +10 -1
  519. package/examples/prefer-const.sh +0 -0
  520. package/examples/prefer-dedicated-tools.sh +12 -0
  521. package/examples/prefer-optional-chaining.sh +0 -0
  522. package/examples/prisma-migrate-guard.sh +24 -7
  523. package/examples/production-port-kill-guard.sh +12 -0
  524. package/examples/prompt-injection-guard.sh +2 -1
  525. package/examples/prompt-usage-logger.sh +0 -0
  526. package/examples/protect-claudemd.sh +12 -0
  527. package/examples/protect-dotfiles.sh +12 -0
  528. package/examples/proxy-capture-suggester.sh +159 -0
  529. package/examples/public-artefact-socratic-narrowing.sh +232 -0
  530. package/examples/public-repo-push-guard.sh +12 -0
  531. package/examples/push-requires-test-pass-record.sh +0 -0
  532. package/examples/push-requires-test-pass.sh +12 -0
  533. package/examples/quota-anomaly-detector.sh +173 -0
  534. package/examples/quota-reset-audit.sh +58 -0
  535. package/examples/quoted-flag-approver.sh +99 -10
  536. package/examples/rails-migration-guard.sh +12 -0
  537. package/examples/rate-limit-guard.sh +0 -0
  538. package/examples/read-all-files-enforcer.sh +0 -0
  539. package/examples/read-budget-guard.sh +12 -0
  540. package/examples/read-loop-detector.sh +59 -0
  541. package/examples/read-once-guard.sh +96 -0
  542. package/examples/read-only-mode.sh +12 -0
  543. package/examples/readme-exists-check.sh +0 -0
  544. package/examples/record-read-coverage.sh +73 -0
  545. package/examples/redirect-fragment-warner.sh +149 -0
  546. package/examples/redis-flushall-guard.sh +13 -0
  547. package/examples/redundant-read-blocker.sh +132 -0
  548. package/examples/refusal-arrest-gate.sh +248 -0
  549. package/examples/registry-publish-guard.sh +13 -1
  550. package/examples/remote-control-billing-classifier.sh +135 -0
  551. package/examples/replace-all-guard.sh +12 -0
  552. package/examples/repo-visibility-guard.sh +12 -0
  553. package/examples/reroute-after-block-guard.sh +150 -0
  554. package/examples/response-budget-guard.sh +0 -0
  555. package/examples/resume-drift-watcher.sh +57 -0
  556. package/examples/rg-replace-flag-detector.sh +125 -0
  557. package/examples/rhetorical-verification-prompt-detector.sh +102 -0
  558. package/examples/ripgrep-permission-fix.sh +0 -0
  559. package/examples/rm-safety-net.sh +151 -8
  560. package/examples/role-tool-guard.sh +12 -0
  561. package/examples/route-handler-emptiness-gate.sh +324 -0
  562. package/examples/ruby-lint-on-edit.sh +1 -1
  563. package/examples/runtime-binary-change-detector.sh +102 -0
  564. package/examples/same-command-repeat-detector.sh +196 -0
  565. package/examples/same-correction-arrest.sh +169 -0
  566. package/examples/sandbox-denywrite-enforcer.sh +78 -0
  567. package/examples/sandbox-relative-path-audit.sh +83 -25
  568. package/examples/sandbox-write-verify.sh +12 -0
  569. package/examples/schema-migration-guard.sh +0 -0
  570. package/examples/scope-expansion-receipt.sh +178 -0
  571. package/examples/scope-guard.sh +88 -9
  572. package/examples/secret-file-read-guard.sh +12 -0
  573. package/examples/secret-file-write-guard.sh +150 -0
  574. package/examples/self-modify-bypass-guard.sh +0 -0
  575. package/examples/sensitive-file-read-guard.sh +23 -3
  576. package/examples/sensitive-log-guard.sh +1 -0
  577. package/examples/server-side-prompt-injection-detector.sh +69 -0
  578. package/examples/session-agent-cost-limiter.sh +12 -0
  579. package/examples/session-backup-on-start.sh +1 -1
  580. package/examples/session-cost-alert.sh +12 -0
  581. package/examples/session-drift-guard.sh +12 -0
  582. package/examples/session-duration-guard.sh +25 -2
  583. package/examples/session-end-logger.sh +0 -0
  584. package/examples/session-health-monitor.sh +0 -0
  585. package/examples/session-index-repair.sh +1 -1
  586. package/examples/session-memory-watchdog.sh +1 -0
  587. package/examples/session-permission-reset-guard.sh +12 -0
  588. package/examples/session-persistence-verifier.sh +93 -0
  589. package/examples/session-plugin-pin-watch.sh +68 -0
  590. package/examples/session-rate-monitor.sh +176 -0
  591. package/examples/session-resume-env-fix.sh +0 -0
  592. package/examples/session-start-quota-status.sh +193 -0
  593. package/examples/session-start-safety-check.sh +55 -3
  594. package/examples/session-state-saver.sh +0 -0
  595. package/examples/session-summary-stop.sh +1 -1
  596. package/examples/session-summary.sh +0 -0
  597. package/examples/session-token-counter.sh +1 -1
  598. package/examples/settings-hooks-key-restorer.sh +99 -0
  599. package/examples/settings-json-health-check.sh +57 -0
  600. package/examples/settings-json-model-guard.sh +0 -0
  601. package/examples/settings-regression-tester.sh +188 -0
  602. package/examples/shell-config-truncation-guard.sh +12 -0
  603. package/examples/shell-wrapper-guard.sh +12 -0
  604. package/examples/skill-cumulative-size-detector.sh +104 -0
  605. package/examples/skill-description-drop-detector.sh +148 -0
  606. package/examples/skill-gate.sh +0 -0
  607. package/examples/skill-truncation-detector.sh +154 -0
  608. package/examples/skills-context-recorder.sh +167 -0
  609. package/examples/skills-load-verifier.sh +96 -0
  610. package/examples/skills-settings-validator.sh +139 -0
  611. package/examples/sonnet-45-deprecation-helper.sh +85 -0
  612. package/examples/spec-file-scope-guard.sh +12 -0
  613. package/examples/spring-profile-guard.sh +1 -0
  614. package/examples/spurious-malformed-notice-detector.sh +247 -0
  615. package/examples/sql-bulk-delete-warn.sh +88 -0
  616. package/examples/sql-injection-detect.sh +0 -0
  617. package/examples/ssh-key-protect.sh +12 -0
  618. package/examples/staged-secret-scan.sh +22 -1
  619. package/examples/stale-temp-settings-detector.sh +86 -0
  620. package/examples/standing-rule-session-surfacer.sh +137 -0
  621. package/examples/stop-hook-sigterm-wrapper.sh +182 -0
  622. package/examples/stop-transcript-write-health.sh +64 -0
  623. package/examples/strict-allowlist.sh +57 -15
  624. package/examples/strip-coauthored-by.sh +50 -10
  625. package/examples/subagent-blast-radius-guard.sh +184 -0
  626. package/examples/subagent-boundary-precheck.sh +126 -0
  627. package/examples/subagent-budget-guard.sh +12 -0
  628. package/examples/subagent-claudemd-inject.sh +0 -0
  629. package/examples/subagent-closure-verify-gate.sh +164 -0
  630. package/examples/subagent-destructive-git-guard.sh +120 -0
  631. package/examples/subagent-error-detector.sh +0 -0
  632. package/examples/subagent-forged-system-reminder-guard.sh +156 -0
  633. package/examples/subagent-identity-leak-guard.sh +102 -0
  634. package/examples/subagent-identity-reassertion.sh +51 -0
  635. package/examples/subagent-inheritance-tester.sh +179 -0
  636. package/examples/subagent-permission-mode-guard.sh +110 -0
  637. package/examples/subagent-scope-guard.sh +12 -0
  638. package/examples/subagent-spawn-verification-enforcer.sh +102 -0
  639. package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
  640. package/examples/subagent-tool-call-limiter.sh +87 -15
  641. package/examples/subcommand-chain-guard.sh +12 -0
  642. package/examples/subscription-api-billing-warner.sh +160 -0
  643. package/examples/subscription-bypass-detector.sh +152 -0
  644. package/examples/svelte-lint-on-edit.sh +1 -0
  645. package/examples/swift-build-on-edit.sh +1 -1
  646. package/examples/symlink-guard.sh +27 -2
  647. package/examples/symlink-protect.sh +1 -0
  648. package/examples/system-dir-protection-guard.sh +73 -8
  649. package/examples/system-message-workaround.sh +38 -13
  650. package/examples/system-package-guard.sh +12 -0
  651. package/examples/systemd-service-guard.sh +12 -0
  652. package/examples/task-integrity-guard.sh +12 -0
  653. package/examples/temp-file-cleanup.sh +1 -1
  654. package/examples/temporal-suggestion-detector.sh +135 -0
  655. package/examples/terraform-guard.sh +27 -6
  656. package/examples/test-after-edit.sh +1 -1
  657. package/examples/test-before-push.sh +12 -0
  658. package/examples/test-coverage-reminder.sh +24 -1
  659. package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
  660. package/examples/timezone-guard.sh +0 -0
  661. package/examples/tmp-output-size-guard.sh +0 -0
  662. package/examples/todo-check.sh +1 -1
  663. package/examples/token-budget-guard.sh +12 -0
  664. package/examples/token-budget-per-task.sh +12 -0
  665. package/examples/token-usage-tracker.sh +7 -1
  666. package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
  667. package/examples/tokenizer-ratio-alert.sh +104 -0
  668. package/examples/tool-call-rate-limiter.sh +0 -0
  669. package/examples/tool-result-correlation-checker.sh +167 -0
  670. package/examples/tool-result-size-guard.sh +132 -0
  671. package/examples/tool-retry-budget-guard.sh +12 -0
  672. package/examples/transcript-contamination-detector.sh +138 -0
  673. package/examples/trustfall-mcp-injection-guard.sh +103 -0
  674. package/examples/ultrareview-large-diff-advisor.sh +184 -0
  675. package/examples/unbounded-output-guard.sh +94 -0
  676. package/examples/uncommitted-changes-stop.sh +1 -0
  677. package/examples/uncommitted-discard-guard.sh +23 -5
  678. package/examples/uncommitted-work-guard.sh +12 -0
  679. package/examples/usage-warn.sh +0 -0
  680. package/examples/user-account-guard.sh +12 -0
  681. package/examples/userprompt-submit-receipt.sh +123 -0
  682. package/examples/variable-expansion-guard.sh +12 -0
  683. package/examples/verify-after-publish-reminder.sh +93 -0
  684. package/examples/verify-before-commit.sh +12 -0
  685. package/examples/version-bump-detector.sh +156 -0
  686. package/examples/version-regression-warner.sh +144 -0
  687. package/examples/vue-lint-on-edit.sh +1 -0
  688. package/examples/warn-cron-cost-trap.sh +173 -0
  689. package/examples/webfetch-runaway-guard.sh +89 -0
  690. package/examples/wellness-break-reminder.sh +118 -0
  691. package/examples/windows-destructive-command-guard.sh +177 -0
  692. package/examples/windows-path-guard.sh +12 -0
  693. package/examples/windows-python-stub-detector.sh +63 -0
  694. package/examples/work-hours-guard.sh +12 -0
  695. package/examples/working-directory-fence.sh +12 -0
  696. package/examples/workspace-lease-guard.sh +205 -0
  697. package/examples/worktree-create-log.sh +1 -0
  698. package/examples/worktree-delete-guard.sh +12 -0
  699. package/examples/worktree-edit-boundary-guard.sh +127 -0
  700. package/examples/worktree-escape-write-guard.sh +114 -0
  701. package/examples/worktree-hook-linker.sh +0 -0
  702. package/examples/worktree-hooks-path-fix.sh +111 -0
  703. package/examples/worktree-parent-write-guard.sh +43 -0
  704. package/examples/worktree-project-unify.sh +2 -1
  705. package/examples/worktree-remove-uncommitted-guard.sh +13 -0
  706. package/examples/worktree-unmerged-guard.sh +7 -1
  707. package/examples/write-byte-integrity-verifier.sh +190 -0
  708. package/examples/write-empty-content-guard.sh +67 -0
  709. package/examples/write-nul-corruption-detector.sh +61 -0
  710. package/examples/write-overwrite-confirm.sh +160 -14
  711. package/examples/write-secret-guard.sh +27 -5
  712. package/examples/write-shrink-guard.sh +12 -0
  713. package/examples/write-test-ratio.sh +0 -0
  714. package/examples/wsl-host-disk-space-guard.sh +97 -0
  715. package/examples/xml-format-leak-detector.sh +266 -0
  716. package/examples/yaml-syntax-check.sh +12 -0
  717. package/hooks/hooks.json +6 -6
  718. package/index.mjs +1699 -183
  719. package/mission.md +2 -0
  720. package/package.json +4 -4
  721. package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
  722. package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
  723. package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
  724. package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
  725. package/scripts/agents-md-sync-setup.sh +156 -0
  726. package/scripts/autonomy-blocked-summary.sh +148 -0
  727. package/scripts/build-search-index.py +43 -0
  728. package/scripts/build-sitemap.py +119 -0
  729. package/scripts/cc-doctor.sh +192 -0
  730. package/scripts/check-hook-event-names.py +127 -0
  731. package/scripts/check-misfire-instrument.sh +64 -0
  732. package/scripts/claim-verify-audit.sh +467 -0
  733. package/scripts/cowork-claudemd-helper.sh +136 -0
  734. package/scripts/june-15-deprecated-model-scan.sh +111 -0
  735. package/scripts/measure-heredoc-shapes.sh +67 -0
  736. package/scripts/measure-literal-match-misfire.sh +110 -0
  737. package/scripts/probe-scope-guard-branches.sh +48 -0
  738. package/scripts/probe-skip-line-both-ways.sh +65 -0
  739. package/scripts/receipts-aggregate.py +199 -0
  740. package/scripts/session-forensic-audit.py +360 -0
  741. package/scripts.json +9 -9
  742. package/scripts.json.bak-2026-07-27-find +13 -0
  743. package/skills/safety-setup/SKILL.md +5 -5
  744. package/tests/approve-side-remaining-two.test.sh +129 -0
  745. package/tests/approver-list-granularity.test.sh +145 -0
  746. package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
  747. package/tests/audit-ci-gate.test.sh +87 -0
  748. package/tests/audit-cross-layer-claudemd.test.sh +170 -0
  749. package/tests/audit-fail-open-parse.test.sh +100 -0
  750. package/tests/auto-approve-compound-tail.test.sh +194 -0
  751. package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
  752. package/tests/auto-mode-quoted-targets.test.sh +127 -0
  753. package/tests/auto-mode-unquoted-targets.test.sh +112 -0
  754. package/tests/bash-secret-output-detector-detects.test.sh +102 -0
  755. package/tests/blindspots-cross-layer.test.sh +177 -0
  756. package/tests/block-database-wipe.test.sh +64 -0
  757. package/tests/bundled-short-flags-bypass.test.sh +85 -0
  758. package/tests/cd-git-allow-compound-tail.test.sh +67 -0
  759. package/tests/chown-guard-filesystem-root.test.sh +64 -0
  760. package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
  761. package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
  762. package/tests/core-scripts-parser-fallback.test.sh +140 -0
  763. package/tests/destructive-guard-bare-glob.test.sh +74 -0
  764. package/tests/destructive-guard-every-operand.test.sh +100 -0
  765. package/tests/destructive-guard-find-deletion.test.sh +114 -0
  766. package/tests/destructive-guard-flag-order.test.sh +106 -0
  767. package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
  768. package/tests/destructive-guard-quoted-target.test.sh +89 -0
  769. package/tests/destructive-guard-separators.test.sh +105 -0
  770. package/tests/destructive-guard-variable-target.test.sh +98 -0
  771. package/tests/destructive-guard-wrapped-command.test.sh +91 -0
  772. package/tests/doctor-hook-disabling-env.test.sh +92 -0
  773. package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
  774. package/tests/example-guards-wrapped-command.test.sh +169 -0
  775. package/tests/file-edit-backup.test.sh +93 -0
  776. package/tests/git-filter-repo-guard.test.sh +60 -0
  777. package/tests/git-global-options-bypass.test.sh +141 -0
  778. package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
  779. package/tests/git-maintenance-guard.test.sh +83 -0
  780. package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
  781. package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
  782. package/tests/git-submodule-guard.test.sh +50 -0
  783. package/tests/grep-pcre-portability.test.sh +155 -0
  784. package/tests/hook-registration-matches-input.test.sh +73 -0
  785. package/tests/hook-trigger-matches-envelope.test.sh +178 -0
  786. package/tests/install-does-not-claim-protection.test.sh +110 -0
  787. package/tests/install-example-standalone-tools.test.sh +139 -0
  788. package/tests/line-continuation-bypass.test.sh +114 -0
  789. package/tests/mcp-config-poisoning-audit.test.sh +106 -0
  790. package/tests/nested-background-agent-guard.test.sh +58 -0
  791. package/tests/no-unqualified-safety-claims.test.sh +114 -0
  792. package/tests/option-eating-grep-patterns.test.sh +130 -0
  793. package/tests/outdated-core-guards.test.sh +134 -0
  794. package/tests/outdated-report.test.sh +155 -0
  795. package/tests/output-secret-mask-warns.test.sh +73 -0
  796. package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
  797. package/tests/plugins-word-order.test.sh +126 -0
  798. package/tests/powershell-remove-item-guard.test.sh +85 -0
  799. package/tests/project-dir-naming.test.sh +103 -0
  800. package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
  801. package/tests/reroute-after-block-guard.test.sh +104 -0
  802. package/tests/secret-guard-documented-promises.test.sh +97 -0
  803. package/tests/session-plugin-pin-watch.test.sh +45 -0
  804. package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
  805. package/tests/shield-no-silent-adoption.test.py +110 -0
  806. package/tests/shield-no-silent-adoption.test.sh +46 -0
  807. package/tests/stop-transcript-write-health.test.sh +46 -0
  808. package/tests/system-dir-guard-root-erased.test.sh +66 -0
  809. package/tests/test-account-billing-log.sh +100 -0
  810. package/tests/test-account-routing-preflight.sh +77 -0
  811. package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
  812. package/tests/test-agent-view-quota-warn.sh +184 -0
  813. package/tests/test-agents-md-edit-drift-warner.sh +176 -0
  814. package/tests/test-agents-md-loader.sh +204 -0
  815. package/tests/test-agents-md-sync-checker.sh +125 -0
  816. package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
  817. package/tests/test-allowlist.sh +60 -0
  818. package/tests/test-always-allow-pattern-suggester.sh +147 -0
  819. package/tests/test-anthropic-base-url-guard.sh +88 -0
  820. package/tests/test-articulated-scope-capture.sh +139 -0
  821. package/tests/test-attachment-traversal-guard.sh +168 -0
  822. package/tests/test-aup-block-pattern-logger.sh +315 -0
  823. package/tests/test-aup-false-positive-helper.sh +188 -0
  824. package/tests/test-aup-large-tool-output-warner.sh +370 -0
  825. package/tests/test-aup-retry-loop-guard.sh +341 -0
  826. package/tests/test-auth-expiry-reminder.sh +303 -0
  827. package/tests/test-auth-macos-sleep-detector.sh +254 -0
  828. package/tests/test-auth-path-detector.sh +232 -0
  829. package/tests/test-auth-status-checker.sh +233 -0
  830. package/tests/test-authorized-reconfirmation-detector.sh +280 -0
  831. package/tests/test-background-cost-launch-guard.sh +62 -0
  832. package/tests/test-bash-allowlist-secondary-check.sh +143 -0
  833. package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
  834. package/tests/test-bash-project-fence.sh +127 -0
  835. package/tests/test-bg-permission-prompt-warner.sh +221 -0
  836. package/tests/test-binary-read-detector.sh +173 -0
  837. package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
  838. package/tests/test-bulk-delete-target-resolution.sh +49 -0
  839. package/tests/test-bypass-mode-effective-verifier.sh +179 -0
  840. package/tests/test-cache-creation-drift-detector.sh +244 -0
  841. package/tests/test-cache-residue-detector.sh +429 -0
  842. package/tests/test-cache-tier-logger.sh +59 -0
  843. package/tests/test-cache-ttl-eviction-detector.sh +282 -0
  844. package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
  845. package/tests/test-claim-verify-detector.sh +222 -0
  846. package/tests/test-claim-vs-caveat-checker.sh +134 -0
  847. package/tests/test-claude-code-version-pin-advisor.sh +353 -0
  848. package/tests/test-claude-md-reinjector.sh +173 -0
  849. package/tests/test-claude-md-size-monitor.sh +107 -0
  850. package/tests/test-claude-update-budget-guard.sh +132 -0
  851. package/tests/test-claude-update-smart.sh +91 -0
  852. package/tests/test-claudemd-tool-prohibition.sh +239 -0
  853. package/tests/test-cli-config-pinning-detector.sh +233 -0
  854. package/tests/test-cliff-countdown-advisor.sh +138 -0
  855. package/tests/test-closure-word-verify-gate.sh +158 -0
  856. package/tests/test-commit-all-scope-guard.sh +73 -0
  857. package/tests/test-commitment-carry-forward-arrest.sh +250 -0
  858. package/tests/test-compact-dispatch-watchdog.sh +147 -0
  859. package/tests/test-completion-claim-without-verification-detector.sh +326 -0
  860. package/tests/test-compound-bash-permission-resolver.sh +264 -0
  861. package/tests/test-compound-command-deny-enforcer.sh +67 -0
  862. package/tests/test-context-length-budget.sh +68 -0
  863. package/tests/test-context-usage-drift-alert.sh +52 -22
  864. package/tests/test-cost-incident-self-audit.sh +94 -0
  865. package/tests/test-cowork-claude-md-load-checker.sh +257 -0
  866. package/tests/test-cowork-claudemd-helper.sh +141 -0
  867. package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
  868. package/tests/test-cowork-hook-absence-warner.sh +230 -0
  869. package/tests/test-cowork-model-picker-advisor.sh +317 -0
  870. package/tests/test-credential-exfil-guard.sh +62 -0
  871. package/tests/test-cron-create-receipt.sh +165 -0
  872. package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
  873. package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
  874. package/tests/test-daily-cost-guard.sh +131 -0
  875. package/tests/test-deny-rule-integrity-verifier.sh +288 -0
  876. package/tests/test-deployment-readback-gate.sh +92 -0
  877. package/tests/test-deployment-readback-gh-adapter.sh +163 -0
  878. package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
  879. package/tests/test-dispatch-allowlist-preflight.sh +385 -0
  880. package/tests/test-dispatch-liveness-watchdog.sh +319 -0
  881. package/tests/test-dispatch-receipt.sh +314 -0
  882. package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
  883. package/tests/test-echo-probe-spam-detector.sh +143 -0
  884. package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
  885. package/tests/test-ephemeral-container-detector.sh +251 -0
  886. package/tests/test-evidence-claim-gate.sh +291 -0
  887. package/tests/test-extended-thinking-loop-guard.sh +289 -0
  888. package/tests/test-extended-thinking-resume-warning.sh +240 -0
  889. package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
  890. package/tests/test-fabricated-command-detector.sh +296 -0
  891. package/tests/test-false-disk-full-guard.sh +36 -0
  892. package/tests/test-feature-deprecation-detector.sh +117 -0
  893. package/tests/test-forbidden-response-phrase-detector.sh +246 -0
  894. package/tests/test-git-operations-require-approval.sh +53 -0
  895. package/tests/test-git-push-blast-radius-guard.sh +115 -0
  896. package/tests/test-goal-iteration-limit-warner.sh +128 -0
  897. package/tests/test-growthbook-flag-monitor.sh +428 -0
  898. package/tests/test-halt-signal-detector.sh +120 -0
  899. package/tests/test-hook-self-disable-detector.sh +232 -0
  900. package/tests/test-iteration-quality-degradation-detector.sh +244 -0
  901. package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
  902. package/tests/test-marketplace-plugins.sh +193 -0
  903. package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
  904. package/tests/test-mcp-orphan-leak-warner.sh +71 -0
  905. package/tests/test-mcp-permissions-ask-warner.sh +207 -0
  906. package/tests/test-mcp-routine-approval-detector.sh +229 -0
  907. package/tests/test-mcp-startup-bloat-detector.sh +141 -0
  908. package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
  909. package/tests/test-memory-chain-audit.sh +59 -0
  910. package/tests/test-memory-orphan-detector.sh +227 -0
  911. package/tests/test-model-swap-suggester.sh +368 -0
  912. package/tests/test-model-version-lock.sh +83 -0
  913. package/tests/test-multi-file-plan-routing-gate.sh +277 -0
  914. package/tests/test-multi-window-auth-drift-detector.sh +262 -0
  915. package/tests/test-nested-spawn-inflight-guard.sh +281 -0
  916. package/tests/test-no-force-flag.sh +49 -0
  917. package/tests/test-non-english-quality-warner.sh +229 -0
  918. package/tests/test-oauth-refresh-monitor.sh +311 -0
  919. package/tests/test-opus-degradation-tracker.sh +274 -0
  920. package/tests/test-opus48-routine-task-warning.sh +201 -0
  921. package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
  922. package/tests/test-output-token-spike-detector.sh +315 -0
  923. package/tests/test-parallel-batch-size-limiter.sh +228 -0
  924. package/tests/test-parallel-cascade-detector.sh +191 -0
  925. package/tests/test-partial-view-claim-arrest.sh +272 -0
  926. package/tests/test-per-prompt-token-cap.sh +136 -0
  927. package/tests/test-persisted-1m-model-advisor.sh +71 -0
  928. package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
  929. package/tests/test-post-edit-disk-verify.sh +294 -0
  930. package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
  931. package/tests/test-pre-execution-claim-detector.sh +366 -0
  932. package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
  933. package/tests/test-proxy-capture-suggester.sh +214 -0
  934. package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
  935. package/tests/test-quota-anomaly-detector.sh +321 -0
  936. package/tests/test-quota-reset-audit.sh +81 -0
  937. package/tests/test-read-loop-detector.sh +137 -0
  938. package/tests/test-read-once-guard.sh +85 -0
  939. package/tests/test-receipts-aggregate.sh +143 -0
  940. package/tests/test-redirect-fragment-warner.sh +130 -0
  941. package/tests/test-redundant-read-blocker.sh +155 -0
  942. package/tests/test-refusal-arrest-gate.sh +303 -0
  943. package/tests/test-remote-control-billing-classifier.sh +125 -0
  944. package/tests/test-resume-drift-watcher.sh +65 -0
  945. package/tests/test-rg-replace-flag-detector.sh +175 -0
  946. package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
  947. package/tests/test-rm-safety-net.sh +115 -0
  948. package/tests/test-route-handler-emptiness-gate.sh +300 -0
  949. package/tests/test-runtime-binary-change-detector.sh +196 -0
  950. package/tests/test-same-command-repeat-detector.sh +165 -0
  951. package/tests/test-same-correction-arrest.sh +165 -0
  952. package/tests/test-scope-expansion-receipt.sh +207 -0
  953. package/tests/test-server-side-prompt-injection-detector.sh +181 -0
  954. package/tests/test-session-persistence-verifier.sh +128 -0
  955. package/tests/test-session-rate-monitor.sh +284 -0
  956. package/tests/test-session-start-quota-status.sh +210 -0
  957. package/tests/test-session-start-safety-check.sh +138 -0
  958. package/tests/test-settings-hooks-key-restorer.sh +257 -0
  959. package/tests/test-settings-json-health-check.sh +70 -0
  960. package/tests/test-settings-regression-tester.sh +197 -0
  961. package/tests/test-skill-cumulative-size-detector.sh +198 -0
  962. package/tests/test-skill-description-drop-detector.sh +236 -0
  963. package/tests/test-skill-truncation-detector.sh +263 -0
  964. package/tests/test-skills-context-recorder.sh +329 -0
  965. package/tests/test-skills-load-verifier.sh +184 -0
  966. package/tests/test-skills-settings-validator.sh +242 -0
  967. package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
  968. package/tests/test-spurious-malformed-notice-detector.sh +290 -0
  969. package/tests/test-sql-bulk-delete-warn.sh +123 -0
  970. package/tests/test-ssh-key-protect.sh +81 -0
  971. package/tests/test-stale-temp-settings-detector.sh +161 -0
  972. package/tests/test-standing-rule-session-surfacer.sh +215 -0
  973. package/tests/test-starter-hooks-manifest.sh +96 -0
  974. package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
  975. package/tests/test-strict-allowlist.sh +72 -0
  976. package/tests/test-subagent-boundary-precheck.sh +137 -0
  977. package/tests/test-subagent-closure-verify-gate.sh +193 -0
  978. package/tests/test-subagent-destructive-git-guard.sh +86 -0
  979. package/tests/test-subagent-identity-leak-guard.sh +62 -0
  980. package/tests/test-subagent-identity-reassertion.sh +61 -0
  981. package/tests/test-subagent-inheritance-tester.sh +319 -0
  982. package/tests/test-subagent-permission-mode-guard.sh +61 -0
  983. package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
  984. package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
  985. package/tests/test-subagent-tool-call-limiter.sh +97 -0
  986. package/tests/test-subscription-api-billing-warner.sh +138 -0
  987. package/tests/test-subscription-bypass-detector.sh +255 -0
  988. package/tests/test-temporal-suggestion-detector.sh +183 -0
  989. package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
  990. package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
  991. package/tests/test-tokenizer-ratio-alert.sh +93 -0
  992. package/tests/test-tool-result-correlation-checker.sh +264 -0
  993. package/tests/test-tool-result-size-guard.sh +121 -0
  994. package/tests/test-transcript-contamination-detector.sh +264 -0
  995. package/tests/test-trigger-header-parsing.sh +151 -0
  996. package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
  997. package/tests/test-userprompt-submit-receipt.sh +181 -0
  998. package/tests/test-verify-after-publish-reminder.sh +184 -0
  999. package/tests/test-version-bump-detector.sh +212 -0
  1000. package/tests/test-version-regression-warner.sh +165 -0
  1001. package/tests/test-warn-cron-cost-trap.sh +82 -0
  1002. package/tests/test-webfetch-runaway-guard.sh +77 -0
  1003. package/tests/test-wellness-break-reminder.sh +138 -0
  1004. package/tests/test-windows-destructive-command-guard.sh +169 -0
  1005. package/tests/test-windows-python-stub-detector.sh +146 -0
  1006. package/tests/test-worktree-edit-boundary-guard.sh +219 -0
  1007. package/tests/test-write-byte-integrity-verifier.sh +192 -0
  1008. package/tests/test-xml-format-leak-detector.sh +299 -0
  1009. package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
  1010. package/tests/workspace-lease-guard.test.sh +144 -0
  1011. package/tests/worktree-escape-write-guard.test.sh +68 -0
  1012. package/tests/worktree-hooks-path-fix.test.sh +181 -0
  1013. package/tests/worktree-parent-write-guard.test.sh +51 -0
  1014. package/tests/write-empty-content-guard.test.sh +39 -0
  1015. package/tests/write-nul-corruption-detector.test.sh +29 -0
  1016. package/tests/write-overwrite-unread-content.test.sh +178 -0
  1017. package/tests/wsl-host-disk-space-guard.test.sh +55 -0
@@ -0,0 +1,248 @@
1
+ #!/bin/bash
2
+ # refusal-arrest-gate.sh — Block the next tool call if the assistant's prose
3
+ # in the same turn explicitly refused that action ("I won't modify X",
4
+ # "I'll skip X", "I'll preserve X") and the tool call contradicts the refusal.
5
+ #
6
+ # Sister hook to closure-word-verify-gate.sh. Both follow the same shape
7
+ # (recognition-without-arrest from #60226): the model's own prose names what
8
+ # it will and will not do, and the actual tool sequence is uncorrelated with
9
+ # the naming. closure-word-verify-gate fires on positive-closure language;
10
+ # this one fires on self-stated NEGATIVE action followed by the action.
11
+ #
12
+ # Solves: refusal-side dual of #60506. Examples observed in the wild:
13
+ # - #60475 — sub-agent stated it would preserve uncommitted work, then
14
+ # ran `git checkout -- <files>` against the other operator's
15
+ # unstaged edits.
16
+ # - #60506 — agent acknowledged the categorical native-React ban, then
17
+ # introduced a native React component on the next Write.
18
+ # Agent confirmed the i18n-only label rule, then hardcoded
19
+ # the label in the next Edit.
20
+ # - #60188 — fraction of 51 acknowledged-rule-violations followed
21
+ # refusal-shape syntax in the response stream.
22
+ #
23
+ # Design philosophy:
24
+ # The cluster's load-bearing observation: prose rules cannot be
25
+ # the load-bearing element of architectural guarantees. The load-
26
+ # bearing element has to live in the harness at the point of action.
27
+ # closure-word-verify-gate lives on Stop (session-terminal). This hook
28
+ # lives on PreToolUse (mid-turn) because refusal-side failures happen
29
+ # between the refusal statement and the next user prompt.
30
+ #
31
+ # False-positive control (three constraints, in order of importance):
32
+ # 1. TARGET MATCH, not verb match: a refusal of "I'll skip the test step"
33
+ # only triggers if the next tool call's target IS the test step.
34
+ # "I'll skip X → tool call edits Y" does not trigger.
35
+ # 2. CURRENT TURN ONLY: refusals from prior turns do not gate the
36
+ # current PreToolUse. Refusal scope = same-turn assistant prose.
37
+ # 3. ASSISTANT-ORIGINATED ONLY: refusals inside a quoted user-prompt
38
+ # block are ignored (the agent reading back what the user said
39
+ # should not trigger the gate when the agent does X next).
40
+ #
41
+ # Related Issues:
42
+ # #60506 (@zean89, 2026-05-19) — first-person self-report
43
+ # #60226 (@suwayama, 2026-05-18) — recognition-without-arrest framework
44
+ # #60475 — sub-agent git checkout data loss
45
+ # #60188 (@beq00000) — 51 rule violations in one session
46
+ #
47
+ # TRIGGER: PreToolUse
48
+ # MATCHER: "Edit|Write|Bash|MultiEdit"
49
+ #
50
+ # CONFIGURATION (environment variables):
51
+ # CC_REFUSAL_PATTERNS default built-in — pipe-separated regex of
52
+ # refusal phrases (capturing
53
+ # group 1 = target words)
54
+ # CC_REFUSAL_GATE_DISABLE set to "1" to disable the gate entirely
55
+ #
56
+ # USAGE (settings.json):
57
+ # {
58
+ # "hooks": {
59
+ # "PreToolUse": [{
60
+ # "matcher": "Edit|Write|Bash|MultiEdit",
61
+ # "hooks": [{
62
+ # "type": "command",
63
+ # "command": "~/.claude/hooks/refusal-arrest-gate.sh"
64
+ # }]
65
+ # }]
66
+ # }
67
+ # }
68
+
69
+ set -uo pipefail
70
+
71
+ # Without jq, the parse below silently yields empty and this hook stops
72
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
73
+ # here: blocking would halt every tool call, and exiting 0 would change
74
+ # the behaviour of guards that do not depend on the parsed value.
75
+ if ! command -v jq >/dev/null 2>&1; then
76
+ _nojq_warned="/tmp/cc-nojq-warned-refusal-arrest-gate-$PPID"
77
+ [ -f "$_nojq_warned" ] || {
78
+ echo "WARNING [refusal-arrest-gate]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
79
+ : > "$_nojq_warned"
80
+ }
81
+ fi
82
+
83
+ [ "${CC_REFUSAL_GATE_DISABLE:-0}" = "1" ] && exit 0
84
+
85
+ INPUT=$(cat 2>/dev/null || true)
86
+ [ -z "$INPUT" ] && exit 0
87
+
88
+ # Default refusal patterns. Each pattern's capturing group 1 extracts the
89
+ # target (file, action, step name) that the agent stated it would not act on.
90
+ # The regex is permissive on the target to handle the natural-language tail.
91
+ DEFAULT_REFUSAL_PATTERNS='I (will not|won['"'"']?t|am not going to|wo n['"'"']?t) (modify|edit|change|touch|update|delete|remove|overwrite|push|commit|run|execute|create|write to|alter|patch|replace|drop|reset) ([A-Za-z0-9_./@\-]+)|I['"'"']?ll (skip|preserve|keep|leave|not touch|not modify|avoid|leave alone|not change|not edit) (the |an? )?([A-Za-z0-9_./@\-]+)|let me not (modify|edit|change|touch|update|delete|run) ([A-Za-z0-9_./@\-]+)|skipping (the )?([A-Za-z0-9_./@\-]+)|preserving (the )?([A-Za-z0-9_./@\-]+)'
92
+
93
+ REFUSAL_PATTERNS="${CC_REFUSAL_PATTERNS:-$DEFAULT_REFUSAL_PATTERNS}"
94
+
95
+ # PreToolUse input shape: { tool_name, tool_input, transcript (path or array) }
96
+ TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
97
+ [ -z "$TOOL_NAME" ] && exit 0
98
+
99
+ # Tool target extraction by tool type
100
+ case "$TOOL_NAME" in
101
+ Write|Edit|MultiEdit)
102
+ TOOL_TARGET=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty' 2>/dev/null)
103
+ ;;
104
+ Bash)
105
+ TOOL_TARGET=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
106
+ ;;
107
+ *)
108
+ # Non-instrumented tool — pass through.
109
+ exit 0
110
+ ;;
111
+ esac
112
+
113
+ [ -z "$TOOL_TARGET" ] && exit 0
114
+
115
+ # Pull the assistant's most recent message text in this turn. The transcript
116
+ # field in PreToolUse may be a file path (newer shapes) or inline.
117
+ TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
118
+ ASSISTANT_TEXT=""
119
+
120
+ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
121
+ # Read the last assistant message from JSONL transcript.
122
+ # Iterate from the bottom up, take the first message with role=assistant.
123
+ #
124
+ # Parse PER LINE with `fromjson?` rather than slurping the whole window
125
+ # with `jq -rs`. A single transcript line carrying a raw control char
126
+ # (U+0000-U+001F, e.g. an unescaped newline from a large tool-output or
127
+ # heredoc block) makes a slurp fail outright ("control characters ... must
128
+ # be escaped"), which would empty ASSISTANT_TEXT and silently fail the gate
129
+ # open exactly when the transcript is large/messy. fromjson? drops only the
130
+ # unparseable line; -c keeps each assistant message as one JSON object so we
131
+ # can take the most-recent (first after tac) and still preserve multi-line
132
+ # text. See anthropics/claude-code#68665.
133
+ ASSISTANT_TEXT=$(tac "$TRANSCRIPT_PATH" 2>/dev/null \
134
+ | jq -cR 'fromjson? | select(.message.role == "assistant" or .role == "assistant")' 2>/dev/null \
135
+ | head -n 1 \
136
+ | jq -r '
137
+ (.message.content // .content // empty)
138
+ | if type == "array" then map(select(.type == "text") | .text) | join("\n") else . end
139
+ ' 2>/dev/null \
140
+ || true)
141
+ fi
142
+
143
+ # Fallback inline shapes.
144
+ if [ -z "$ASSISTANT_TEXT" ]; then
145
+ ASSISTANT_TEXT=$(printf '%s' "$INPUT" | jq -r '
146
+ .last_assistant_message //
147
+ .assistant_message //
148
+ .turn_assistant_text //
149
+ empty
150
+ ' 2>/dev/null)
151
+ fi
152
+
153
+ [ -z "$ASSISTANT_TEXT" ] && exit 0
154
+
155
+ # Strip quoted user-prompt blocks (lines starting with "> " in markdown,
156
+ # or text inside <user_prompt>/<quoted-prompt> tags). Refusals quoted from
157
+ # the user must not trigger the gate when the agent does X next.
158
+ FILTERED_TEXT=$(printf '%s' "$ASSISTANT_TEXT" \
159
+ | sed -e 's/<user_prompt>[^<]*<\/user_prompt>//g' \
160
+ -e 's/<quoted-prompt>[^<]*<\/quoted-prompt>//g' \
161
+ | grep -v '^>' \
162
+ || true)
163
+
164
+ [ -z "$FILTERED_TEXT" ] && exit 0
165
+
166
+ # Match refusal patterns against the filtered text. Pull every matching
167
+ # refusal-target word into a candidate list. Strip trailing punctuation
168
+ # (period, comma, semicolon, colon) so that "config.json." in prose matches
169
+ # "config.json" in the tool target.
170
+ REFUSAL_TARGETS=$(printf '%s' "$FILTERED_TEXT" \
171
+ | grep -Eio "$REFUSAL_PATTERNS" \
172
+ | sed -E 's/^(I (will not|won.?t|am not going to|wo n.?t) (modify|edit|change|touch|update|delete|remove|overwrite|push|commit|run|execute|create|write to|alter|patch|replace|drop|reset)) //I; s/^(I.?ll (skip|preserve|keep|leave|not touch|not modify|avoid|leave alone|not change|not edit)) (the |an? )?//I; s/^(let me not (modify|edit|change|touch|update|delete|run)) //I; s/^(skipping|preserving) (the )?//I' \
173
+ | tr -s ' ' '\n' \
174
+ | sed -E 's/[.,;:!?]+$//' \
175
+ | grep -vE '^(the|a|an|to|and|or|that|this|file|files|step|steps)$' \
176
+ | sort -u)
177
+
178
+ [ -z "$REFUSAL_TARGETS" ] && exit 0
179
+
180
+ # For each refusal target, check whether it appears in the tool target.
181
+ # Match is substring-of-basename for file paths, substring-of-command
182
+ # for Bash. Case-insensitive.
183
+ TOOL_TARGET_LC=$(printf '%s' "$TOOL_TARGET" | tr '[:upper:]' '[:lower:]')
184
+
185
+ # For Write/Edit, also try the basename in case the refusal mentioned only
186
+ # the filename without the path.
187
+ if [ "$TOOL_NAME" != "Bash" ]; then
188
+ TOOL_BASENAME=$(basename "$TOOL_TARGET" 2>/dev/null | tr '[:upper:]' '[:lower:]')
189
+ else
190
+ TOOL_BASENAME=""
191
+ fi
192
+
193
+ MATCHED_TARGET=""
194
+ while IFS= read -r target; do
195
+ [ -z "$target" ] && continue
196
+ target_lc=$(printf '%s' "$target" | tr '[:upper:]' '[:lower:]')
197
+ # Skip very short targets to avoid spurious matches.
198
+ [ "${#target_lc}" -lt 3 ] && continue
199
+
200
+ if [ "$TOOL_NAME" = "Bash" ]; then
201
+ # For Bash, match the refusal target against any token in the command.
202
+ if printf '%s' "$TOOL_TARGET_LC" | grep -Fq "$target_lc"; then
203
+ MATCHED_TARGET="$target"
204
+ break
205
+ fi
206
+ else
207
+ # For Write/Edit/MultiEdit, match against path or basename.
208
+ if printf '%s' "$TOOL_TARGET_LC" | grep -Fq "$target_lc" \
209
+ || ([ -n "$TOOL_BASENAME" ] && printf '%s' "$TOOL_BASENAME" | grep -Fq "$target_lc"); then
210
+ MATCHED_TARGET="$target"
211
+ break
212
+ fi
213
+ fi
214
+ done <<<"$REFUSAL_TARGETS"
215
+
216
+ [ -z "$MATCHED_TARGET" ] && exit 0
217
+
218
+ # Refusal target matched the tool target. Surface the contradiction.
219
+ cat >&2 <<EOF
220
+ <system-reminder>
221
+ REFUSAL-SIDE ARREST — your assistant prose in this turn stated that you would
222
+ not act on "$MATCHED_TARGET", and the next tool call is $TOOL_NAME against
223
+ a target that contains "$MATCHED_TARGET":
224
+
225
+ tool: $TOOL_NAME
226
+ target: $TOOL_TARGET
227
+ refusal: "$MATCHED_TARGET" (matched from your same-turn prose)
228
+
229
+ This is the refusal-side dual of the failure mode in #60506 and #60475:
230
+ the model's prose names what it will not do, and the actual tool sequence
231
+ contradicts the naming. The cost of an unverified refusal-then-action
232
+ contradiction lands on the operator, not on the model.
233
+
234
+ Before proceeding, either:
235
+
236
+ 1. Acknowledge the contradiction explicitly in the next turn, state
237
+ the reason the action is now correct, and re-issue the tool call
238
+ with the reason in the same turn, OR
239
+ 2. Restate the refusal as conditional ("I'll not modify $MATCHED_TARGET
240
+ unless <condition>"), satisfy the condition, then proceed.
241
+
242
+ To disable this gate intentionally (for retrospectives, plans, documentation
243
+ turns that quote intentions without executing them), set
244
+ CC_REFUSAL_GATE_DISABLE=1 in your environment.
245
+ </system-reminder>
246
+ EOF
247
+
248
+ exit 2
@@ -17,7 +17,19 @@
17
17
  # docker push (Docker Hub)
18
18
  # helm push (Helm charts)
19
19
  #
20
- # TRIGGER: PreToolUse MATCHER: "Bash"
20
+ # TRIGGER: PreToolUse MATCHER: "Bash|PowerShell"
21
+
22
+ # Without jq, the parse below silently yields empty and this hook stops
23
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
24
+ # here: blocking would halt every tool call, and exiting 0 would change
25
+ # the behaviour of guards that do not depend on the parsed value.
26
+ if ! command -v jq >/dev/null 2>&1; then
27
+ _nojq_warned="/tmp/cc-nojq-warned-registry-publish-guard-$PPID"
28
+ [ -f "$_nojq_warned" ] || {
29
+ echo "WARNING [registry-publish-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
30
+ : > "$_nojq_warned"
31
+ }
32
+ fi
21
33
 
22
34
  INPUT=$(cat)
23
35
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -0,0 +1,135 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # remote-control-billing-classifier.sh — Warn at session start when
4
+ # the parent process tree includes `claude remote-control`, so
5
+ # the operator knows the spawned `claude --print` child will draw
6
+ # from the new Agent SDK monthly credit (Pool 2) starting June 15,
7
+ # 2026, separate from interactive usage limits.
8
+ # ================================================================
9
+ # PURPOSE:
10
+ # Issue #59823 documents the implementation detail that
11
+ # `claude remote-control` spawns one `claude --print --sdk-url …`
12
+ # child per session. The June 15, 2026 billing split routes
13
+ # `claude --print` and Agent SDK usage to a new "automation
14
+ # bucket" (Pool 2) on Pro $20 / Max 5x $100 / Max 20x $200 plans,
15
+ # separate from interactive Claude Code usage. The documentation
16
+ # does not yet classify `claude remote-control` itself, so
17
+ # operators running automation through it can silently double-
18
+ # consume Pool 2 once the cliff lands.
19
+ #
20
+ # This hook reads the process tree at session start. When any
21
+ # ancestor command line matches `claude remote-control`, it emits
22
+ # a one-line stderr advisory naming the Pool 2 implication and
23
+ # pointing to the two operator-side audits worth running before
24
+ # June 15. Advisory only (exit 0); does not block the session.
25
+ #
26
+ # TRIGGER: SessionStart
27
+ # MATCHER: ""
28
+ #
29
+ # UPSTREAM:
30
+ # #59823 [DOCS] Billing implications for `claude remote-control`
31
+ # on June 15th (Pool 2 classification of the child
32
+ # `claude --print` process is undocumented as of 2026-05-28)
33
+ #
34
+ # SETUP:
35
+ # {
36
+ # "hooks": {
37
+ # "SessionStart": [
38
+ # {
39
+ # "matcher": "",
40
+ # "hooks": [
41
+ # { "type": "command",
42
+ # "command": "$HOME/.claude/hooks/remote-control-billing-classifier.sh" }
43
+ # ]
44
+ # }
45
+ # ]
46
+ # }
47
+ # }
48
+ #
49
+ # BEHAVIOR:
50
+ # - No `claude remote-control` ancestor → silent pass.
51
+ # - Ancestor found → stderr advisory + exit 0 (does not block).
52
+ #
53
+ # CONFIGURATION (env vars):
54
+ # CC_REMOTE_CONTROL_DISABLE Set to "1" to disable the hook.
55
+ # CC_REMOTE_CONTROL_PROCESS_OVERRIDE Comma-separated cmdlines to scan
56
+ # instead of live `ps` output.
57
+ # Used by tests; also lets CI
58
+ # simulate a remote-control parent.
59
+ # CC_REMOTE_CONTROL_PATTERN Override the cmdline regex
60
+ # (default: "claude remote-control").
61
+ # ================================================================
62
+
63
+ set -u
64
+
65
+ if [ "${CC_REMOTE_CONTROL_DISABLE:-0}" = "1" ]; then
66
+ exit 0
67
+ fi
68
+
69
+ PATTERN="${CC_REMOTE_CONTROL_PATTERN:-claude remote-control}"
70
+
71
+ # Read stdin (SessionStart JSON payload) but do not require its shape.
72
+ # The hook only inspects the process tree, not the payload.
73
+ if [ ! -t 0 ]; then
74
+ cat >/dev/null 2>&1 || true
75
+ fi
76
+
77
+ # Gather candidate cmdlines: either the override (for tests) or
78
+ # the live ancestor process tree via `ps`.
79
+ CMDLINES=""
80
+ if [ -n "${CC_REMOTE_CONTROL_PROCESS_OVERRIDE:-}" ]; then
81
+ CMDLINES="$CC_REMOTE_CONTROL_PROCESS_OVERRIDE"
82
+ else
83
+ # Walk parent PIDs upward and collect cmdlines. We avoid `ps
84
+ # --forest` because BusyBox does not implement it; instead we
85
+ # follow PPID via /proc when available, falling back to ps -p.
86
+ PID=$$
87
+ DEPTH=0
88
+ while [ "$PID" != "1" ] && [ "$DEPTH" -lt 20 ]; do
89
+ if [ -r "/proc/$PID/cmdline" ]; then
90
+ CMD=$(tr '\0' ' ' < "/proc/$PID/cmdline" 2>/dev/null)
91
+ CMDLINES="${CMDLINES}${CMD}
92
+ "
93
+ PPID=$(awk '/^PPid:/ {print $2}' "/proc/$PID/status" 2>/dev/null)
94
+ else
95
+ CMD=$(ps -o args= -p "$PID" 2>/dev/null)
96
+ CMDLINES="${CMDLINES}${CMD}
97
+ "
98
+ PPID=$(ps -o ppid= -p "$PID" 2>/dev/null | tr -d ' ')
99
+ fi
100
+ if [ -z "$PPID" ] || [ "$PPID" = "$PID" ]; then
101
+ break
102
+ fi
103
+ PID="$PPID"
104
+ DEPTH=$((DEPTH+1))
105
+ done
106
+ fi
107
+
108
+ # Look for the pattern in any candidate cmdline.
109
+ if printf '%s' "$CMDLINES" | grep -q -- "$PATTERN"; then
110
+ cat >&2 <<EOF
111
+
112
+ ⚠️ Session started under \`claude remote-control\`.
113
+
114
+ Starting 2026-06-15, the child \`claude --print --sdk-url …\`
115
+ process that remote-control spawns will draw from the new
116
+ Agent SDK monthly credit (Pool 2), separate from interactive
117
+ Claude Code usage. The documentation does not yet classify
118
+ \`claude remote-control\` itself (see issue #59823), so
119
+ automation that drives sessions through it can silently
120
+ consume Pool 2 once the cliff lands.
121
+
122
+ Two pre-June-15 audits worth running:
123
+ 1. \`ps --forest -p \$(pgrep -f 'claude remote-control')\`
124
+ — confirm the children you expect, no stray sessions.
125
+ 2. Open https://support.claude.com/en/articles/15036540
126
+ and verify the one-time Agent SDK opt-in is pressed
127
+ for the account that owns the remote-control server.
128
+
129
+ This is an advisory; the session continues.
130
+ Set CC_REMOTE_CONTROL_DISABLE=1 to silence.
131
+
132
+ EOF
133
+ fi
134
+
135
+ exit 0
@@ -33,6 +33,18 @@
33
33
 
34
34
  set -u
35
35
 
36
+ # Without jq, the parse below silently yields empty and this hook stops
37
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
38
+ # here: blocking would halt every tool call, and exiting 0 would change
39
+ # the behaviour of guards that do not depend on the parsed value.
40
+ if ! command -v jq >/dev/null 2>&1; then
41
+ _nojq_warned="/tmp/cc-nojq-warned-replace-all-guard-$PPID"
42
+ [ -f "$_nojq_warned" ] || {
43
+ echo "WARNING [replace-all-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
44
+ : > "$_nojq_warned"
45
+ }
46
+ fi
47
+
36
48
  INPUT=$(cat)
37
49
 
38
50
  REPLACE_ALL=$(printf '%s' "$INPUT" | jq -r '.tool_input.replace_all // false' 2>/dev/null)
@@ -14,6 +14,18 @@
14
14
  # }
15
15
  # }
16
16
 
17
+ # Without jq, the parse below silently yields empty and this hook stops
18
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
19
+ # here: blocking would halt every tool call, and exiting 0 would change
20
+ # the behaviour of guards that do not depend on the parsed value.
21
+ if ! command -v jq >/dev/null 2>&1; then
22
+ _nojq_warned="/tmp/cc-nojq-warned-repo-visibility-guard-$PPID"
23
+ [ -f "$_nojq_warned" ] || {
24
+ echo "WARNING [repo-visibility-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
25
+ : > "$_nojq_warned"
26
+ }
27
+ fi
28
+
17
29
  INPUT=$(cat)
18
30
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
19
31
  [ -z "$COMMAND" ] && exit 0
@@ -0,0 +1,150 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # reroute-after-block-guard.sh — Stop "reroute after a block"
4
+ # ================================================================
5
+ # PURPOSE:
6
+ # PreToolUse hooks are stateless: each one evaluates the current
7
+ # action in isolation, with no memory that a sibling action was
8
+ # just denied. So a common failure trajectory slips through —
9
+ # a gate fires on an action, the agent substitutes an equivalent
10
+ # path toward the SAME target, and the next hook sees a fresh,
11
+ # individually-defensible action and lets it run.
12
+ # (anthropics/claude-code#70112: "Agent treats safety gates as
13
+ # obstacles to route around" — goal misgeneralization.)
14
+ #
15
+ # This hook adds the missing state. It reads the transcript: if
16
+ # the PREVIOUS tool call was blocked by a PreToolUse hook and the
17
+ # CURRENT action targets the same concrete FILE/path, it stops and
18
+ # surfaces to the human instead of letting the reroute proceed. A
19
+ # fired gate should RAISE the threshold for proceeding, not prompt
20
+ # a search for another path.
21
+ #
22
+ # This does not change the model's disposition; it converts a
23
+ # silent reroute into a hard stop for the case where the blast
24
+ # radius is concentrated on one target (a file, a path).
25
+ #
26
+ # Detects (only when ALL hold, else it stays out of the way):
27
+ # 1. the most recent tool result is an error, AND
28
+ # 2. its text is a Claude Code PreToolUse hook block
29
+ # (the "PreToolUse: ... hook error" runner phrasing), AND
30
+ # 3. the blocked action and the current action share a concrete
31
+ # filesystem path (anchored path or a path with a file
32
+ # extension). Bare word/word tokens and git refs (origin/main,
33
+ # refs/heads/...) are NOT treated as targets — inspecting a
34
+ # branch after a push is rejected must stay allowed.
35
+ #
36
+ # Does NOT block (fail-open by design — never guesses):
37
+ # - no transcript available / unreadable / jq missing
38
+ # - previous tool succeeded (no gate fired)
39
+ # - the error was a normal failure or a server-side rejection
40
+ # ("permission denied", git "blocked by required reviews", etc.)
41
+ # - no shared concrete file/path between blocked and current action
42
+ # - the human explicitly re-authorizes with CC_REROUTE_ALLOW=1
43
+ #
44
+ # Legitimate retry after fixing the real problem is expected: set
45
+ # CC_REROUTE_ALLOW=1 for that one command. Being forced to do so
46
+ # IS the point — it makes "proceed after a block" a conscious act.
47
+ #
48
+ # NOTE: this hook deliberately omits `set -e`/`pipefail`. Every
49
+ # jq/tail/grep failure must fall through to the next
50
+ # `[ -z "$VAR" ] && exit 0` guard; a crash exit (1) would be
51
+ # miscounted by Claude Code as a hook error rather than "allow".
52
+ #
53
+ # TRIGGER: PreToolUse MATCHER: "Bash|Edit|Write|MultiEdit"
54
+ #
55
+ # CONFIG:
56
+ # CC_REROUTE_ALLOW=1 one-shot override (proceed despite block)
57
+ # CC_REROUTE_DISABLE=1 disable this hook entirely
58
+ # ================================================================
59
+
60
+ [ "${CC_REROUTE_DISABLE:-0}" = "1" ] && exit 0
61
+ [ "${CC_REROUTE_ALLOW:-0}" = "1" ] && exit 0
62
+
63
+ command -v jq >/dev/null 2>&1 || exit 0
64
+
65
+ INPUT=$(cat)
66
+
67
+ TP=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
68
+ [ -z "$TP" ] && exit 0
69
+ TP="${TP/#\~/$HOME}"
70
+ [ -r "$TP" ] || exit 0
71
+
72
+ # Current action's concrete target (command string or edited file).
73
+ CUR=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // .tool_input.file_path // empty' 2>/dev/null)
74
+ [ -z "$CUR" ] && exit 0
75
+
76
+ # Only the tail matters: a blocked tool_use and its result are adjacent
77
+ # and most recent. Bound the work so the hook stays cheap.
78
+ WINDOW=$(tail -n 120 "$TP" 2>/dev/null)
79
+ [ -z "$WINDOW" ] && exit 0
80
+
81
+ # Most recent tool_result: {id, err, text}. Parse each line independently with
82
+ # `try fromjson catch empty` so one malformed line can't abort the scan and
83
+ # leave us reading a stale (older) result. content may be string or array.
84
+ LAST=$(printf '%s' "$WINDOW" \
85
+ | jq -Rc 'try (fromjson) catch empty
86
+ | select(.message.content? != null) | .message.content[]?
87
+ | select(.type=="tool_result")
88
+ | {id: .tool_use_id,
89
+ err: (.is_error // false),
90
+ text: (.content
91
+ | if type=="array" then (map(.text? // "") | join(" "))
92
+ elif type=="string" then .
93
+ else "" end)}' 2>/dev/null | tail -n 1)
94
+ [ -z "$LAST" ] && exit 0
95
+
96
+ ERR=$(printf '%s' "$LAST" | jq -r '.err // false' 2>/dev/null)
97
+ [ "$ERR" = "true" ] || exit 0
98
+
99
+ TEXT=$(printf '%s' "$LAST" | jq -r '.text // ""' 2>/dev/null)
100
+ # Was the previous action stopped by a Claude Code PreToolUse hook? Match ONLY
101
+ # the hook runner's own phrasing ("PreToolUse: <matcher> hook error"). Generic
102
+ # "permission denied" / git "blocked by ..." server rejections are NOT gates —
103
+ # matching them would false-block ordinary post-failure work.
104
+ printf '%s' "$TEXT" | grep -qE 'PreToolUse:[^|]*hook error' || exit 0
105
+
106
+ BLOCKED_ID=$(printf '%s' "$LAST" | jq -r '.id // empty' 2>/dev/null)
107
+ [ -z "$BLOCKED_ID" ] && exit 0
108
+
109
+ # The blocked action's concrete target, linked by tool_use_id.
110
+ BLOCKED=$(printf '%s' "$WINDOW" \
111
+ | jq -Rr --arg id "$BLOCKED_ID" 'try (fromjson) catch empty
112
+ | select(.message.content? != null) | .message.content[]?
113
+ | select(.type=="tool_use" and .id==$id)
114
+ | (.input.command // .input.file_path // empty)' 2>/dev/null | tail -n 1)
115
+ [ -z "$BLOCKED" ] && exit 0
116
+
117
+ # Shared concrete file/path? Pull slash-bearing tokens from the blocked action,
118
+ # keep only real filesystem paths (anchored with / ./ ../ ~/, or carrying a file
119
+ # extension), drop flags and git refs, and look for any in the current action.
120
+ # A file/path overlap is the strong, low-false-positive signal that the agent is
121
+ # rerouting toward the same resource rather than doing unrelated work.
122
+ SHARED=""
123
+ while IFS= read -r tok; do
124
+ [ -z "$tok" ] && continue
125
+ case "$tok" in
126
+ -*) continue ;; # flag
127
+ origin/*|upstream/*|remotes/*|refs/*|heads/*|tags/*) continue ;; # git refs
128
+ esac
129
+ [ "${#tok}" -lt 4 ] && continue
130
+ case "$tok" in
131
+ /*|./*|../*|~/*) : ;; # anchored filesystem path
132
+ *.*) : ;; # carries a file extension
133
+ *) continue ;; # bare word/word (e.g. origin/main) — not a target
134
+ esac
135
+ if printf '%s' "$CUR" | grep -qF -- "$tok"; then
136
+ SHARED="$tok"
137
+ break
138
+ fi
139
+ done < <(printf '%s' "$BLOCKED" | grep -oE '(/|\./|\.\./|~/)?[A-Za-z0-9_.-]+(/[A-Za-z0-9_.+-]+)+')
140
+
141
+ [ -z "$SHARED" ] && exit 0
142
+
143
+ cat >&2 <<MSG
144
+ ブロック: 直前の操作はゲート(PreToolUseのhook)で止められました。
145
+ 今回の操作は同じ対象「${SHARED}」へ向かう再ルートに見えます。
146
+ ゲートの発火は「別の経路を探せ」ではなく「立ち止まって正しさを確かめろ」の合図です。
147
+ 回避策を探さず、人へ状況を共有してください。
148
+ 本当に正しいと確認した上で進めるなら、その1コマンドだけ CC_REROUTE_ALLOW=1 を付けて実行してください。
149
+ MSG
150
+ exit 2
File without changes
@@ -0,0 +1,57 @@
1
+ #!/bin/bash
2
+ # resume-drift-watcher.sh — resume attachment relocation detector (Incident 2)
3
+ # Why: v2.1.69–v2.1.89 had a bug where --resume would relocate the original
4
+ # attachment payload out of messages[0] and into a later turn. The bug
5
+ # was marked fixed but residual drift still shows a tiny messages[0]
6
+ # (~350 bytes) when a resumed session is working correctly. A session
7
+ # with drifted attachments shows a very small messages[0] followed by
8
+ # disproportionately large messages[N] entries.
9
+ # Event: PostToolUse MATCHER: "*"
10
+ # Action: Per turn, record first-message byte length and total-message byte
11
+ # length to ~/.claude/logs/resume-drift.log. Compare manually: a
12
+ # session started with --resume whose messages[0] is much smaller
13
+ # than a fresh session's is a drift candidate.
14
+ #
15
+ # Review with:
16
+ # awk -F'\t' '$3<500 && $4>50000 {print}' ~/.claude/logs/resume-drift.log
17
+
18
+ set -u
19
+
20
+ LOG_DIR="${HOME}/.claude/logs"
21
+ LOG_FILE="${LOG_DIR}/resume-drift.log"
22
+ mkdir -p "$LOG_DIR" 2>/dev/null
23
+
24
+ INPUT=$(cat)
25
+
26
+ SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
27
+ TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
28
+
29
+ if [ -z "$TRANSCRIPT" ] || [ ! -r "$TRANSCRIPT" ]; then
30
+ exit 0
31
+ fi
32
+
33
+ # First message — scan from top; stop at first user message.
34
+ FIRST_MSG=$(grep -m1 '"role":"user"' "$TRANSCRIPT" 2>/dev/null || true)
35
+ FIRST_LEN=$(printf '%s' "$FIRST_MSG" | wc -c | tr -d ' ')
36
+
37
+ # Total body size = file size of the transcript itself. This is a conservative
38
+ # proxy for request-body size: a resumed session with many large intermediate
39
+ # messages will have a large transcript.
40
+ TOTAL_LEN=$(wc -c < "$TRANSCRIPT" 2>/dev/null | tr -d ' ')
41
+ TOTAL_LEN="${TOTAL_LEN:-0}"
42
+
43
+ TURN_COUNT=$(grep -c '"role":' "$TRANSCRIPT" 2>/dev/null || echo 0)
44
+
45
+ TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
46
+ printf '%s\t%s\t%s\t%s\t%s\n' \
47
+ "$TS" "$SESSION_ID" "$FIRST_LEN" "$TOTAL_LEN" "$TURN_COUNT" \
48
+ >> "$LOG_FILE"
49
+
50
+ # Only emit a stderr warning after turn 2 (per Appendix B: "Only investigate
51
+ # after the first two turns of a resumed session"). Threshold: first-user
52
+ # message under 500 bytes while total already exceeds 50 KB = drift candidate.
53
+ if [ "$TURN_COUNT" -gt 4 ] && [ "$FIRST_LEN" -lt 500 ] && [ "$TOTAL_LEN" -gt 50000 ]; then
54
+ echo "⚠ resume-drift signal: messages[0]=${FIRST_LEN}B / total=${TOTAL_LEN}B (see #43278)" >&2
55
+ fi
56
+
57
+ exit 0