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,127 @@
1
+ #!/bin/bash
2
+ # worktree-edit-boundary-guard.sh — Warn or block when Edit/Write/NotebookEdit
3
+ # targets a path outside the active git worktree boundary.
4
+ #
5
+ # Solves: anthropics/claude-code#59628 — Claude Code sessions launched inside
6
+ # a git worktree receive a system-prompt declaration ("you are operating in a
7
+ # git worktree") but the harness does NOT prevent Edit/Write/NotebookEdit calls
8
+ # whose resolved absolute path points into the parent main checkout. An agent
9
+ # using cd-style context or absolute paths can dirty the main branch's working
10
+ # tree without prompt, warning, or confirmation. The worktree boundary is a
11
+ # claim in the system prompt; it is not an enforced isolation at the tool layer.
12
+ #
13
+ # This hook closes that gap from the operator side: when the current working
14
+ # directory is inside a worktree (detected via `git rev-parse --git-common-dir`
15
+ # differing from `git rev-parse --git-dir`), and the target file_path resolves
16
+ # outside the worktree's working tree, emit a warning (default) or block (opt-in
17
+ # via env). Pass-through outside worktrees, outside repos, or when target path
18
+ # is inside the worktree.
19
+ #
20
+ # Configuration:
21
+ # CC_WORKTREE_BOUNDARY_MODE=warn (default) — emit stderr, exit 0 (advisory)
22
+ # CC_WORKTREE_BOUNDARY_MODE=block — emit stderr, exit 2 (block)
23
+ # CC_WORKTREE_BOUNDARY_QUIET=1 — suppress all output (still exits)
24
+ #
25
+ # Usage: settings.json PreToolUse hook with matcher "Edit|Write|NotebookEdit".
26
+ #
27
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write|NotebookEdit"
28
+
29
+ set -u
30
+
31
+ # Without jq, the parse below silently yields empty and this hook stops
32
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
33
+ # here: blocking would halt every tool call, and exiting 0 would change
34
+ # the behaviour of guards that do not depend on the parsed value.
35
+ if ! command -v jq >/dev/null 2>&1; then
36
+ _nojq_warned="/tmp/cc-nojq-warned-worktree-edit-boundary-guard-$PPID"
37
+ [ -f "$_nojq_warned" ] || {
38
+ echo "WARNING [worktree-edit-boundary-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
39
+ : > "$_nojq_warned"
40
+ }
41
+ fi
42
+
43
+ INPUT=$(cat)
44
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
45
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
46
+
47
+ # Only edit-style tools
48
+ case "$TOOL" in
49
+ Edit|Write|NotebookEdit) ;;
50
+ *) exit 0 ;;
51
+ esac
52
+
53
+ [ -z "$FILE" ] && exit 0
54
+
55
+ # Detect worktree: git-dir vs git-common-dir
56
+ # In a worktree, git-dir points to .git/worktrees/<name>, git-common-dir to the main .git
57
+ GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) || exit 0
58
+ GIT_COMMON=$(git rev-parse --git-common-dir 2>/dev/null) || exit 0
59
+
60
+ # Resolve both to absolute paths for comparison
61
+ GIT_DIR_ABS=$(cd "$GIT_DIR" 2>/dev/null && pwd -P) || exit 0
62
+ GIT_COMMON_ABS=$(cd "$GIT_COMMON" 2>/dev/null && pwd -P) || exit 0
63
+
64
+ # Not a worktree if git-dir == git-common-dir
65
+ [ "$GIT_DIR_ABS" = "$GIT_COMMON_ABS" ] && exit 0
66
+
67
+ # We are in a worktree. Determine the worktree boundary (top of working tree).
68
+ WORKTREE_TOP=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
69
+ WORKTREE_TOP_ABS=$(cd "$WORKTREE_TOP" 2>/dev/null && pwd -P) || exit 0
70
+
71
+ # Resolve target path. If relative, anchor to current working directory.
72
+ # We do NOT require the file to exist (Write may create new files).
73
+ if [[ "$FILE" = /* ]]; then
74
+ TARGET="$FILE"
75
+ else
76
+ TARGET="$PWD/$FILE"
77
+ fi
78
+
79
+ # Normalize: resolve .. and . segments without requiring the path to exist.
80
+ # Use python if available for portability, otherwise fall back to readlink -m.
81
+ if command -v python3 >/dev/null 2>&1; then
82
+ TARGET_ABS=$(python3 -c "import os,sys; print(os.path.normpath(sys.argv[1]))" "$TARGET" 2>/dev/null)
83
+ elif command -v readlink >/dev/null 2>&1 && readlink -m / >/dev/null 2>&1; then
84
+ TARGET_ABS=$(readlink -m "$TARGET" 2>/dev/null)
85
+ else
86
+ # Last resort: assume already absolute and unnormalized; let the prefix test handle it
87
+ TARGET_ABS="$TARGET"
88
+ fi
89
+
90
+ [ -z "$TARGET_ABS" ] && exit 0
91
+
92
+ # Check if target is inside the worktree boundary
93
+ # Append slash to avoid prefix-collision (e.g., /repo-main being matched by /repo)
94
+ case "$TARGET_ABS/" in
95
+ "$WORKTREE_TOP_ABS"/*)
96
+ # Inside worktree — allowed
97
+ exit 0
98
+ ;;
99
+ esac
100
+
101
+ # Target is outside worktree boundary
102
+ MODE="${CC_WORKTREE_BOUNDARY_MODE:-warn}"
103
+ QUIET="${CC_WORKTREE_BOUNDARY_QUIET:-0}"
104
+
105
+ if [ "$QUIET" != "1" ]; then
106
+ echo "WORKTREE BOUNDARY: target outside active worktree." >&2
107
+ echo "" >&2
108
+ echo " Worktree: $WORKTREE_TOP_ABS" >&2
109
+ echo " Target: $TARGET_ABS" >&2
110
+ echo " Tool: $TOOL" >&2
111
+ echo "" >&2
112
+ echo "This Edit/Write call would land outside the worktree boundary the" >&2
113
+ echo "system prompt declared. The parent main checkout (or another worktree)" >&2
114
+ echo "may be modified without further confirmation. See anthropics/claude-code#59628." >&2
115
+ echo "" >&2
116
+ if [ "$MODE" = "block" ]; then
117
+ echo "Mode: BLOCK (CC_WORKTREE_BOUNDARY_MODE=block). Edit refused." >&2
118
+ else
119
+ echo "Mode: WARN (advisory). To block instead, set CC_WORKTREE_BOUNDARY_MODE=block." >&2
120
+ fi
121
+ fi
122
+
123
+ if [ "$MODE" = "block" ]; then
124
+ exit 2
125
+ fi
126
+
127
+ exit 0
@@ -0,0 +1,114 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # worktree-escape-write-guard.sh — Block Edit/Write that escape the
4
+ # active worktree and silently land on the main checkout
5
+ # ================================================================
6
+ # PURPOSE:
7
+ # When a session runs in a git worktree under .claude/worktrees/<name>,
8
+ # the model can resolve a repo-root-relative reference (e.g. an
9
+ # auto-memory/notes line listing "packages/x/y.ts") against the
10
+ # canonical repo root instead of the worktree root. The absolute path
11
+ # "<repo>/packages/x/y.ts" is a valid, EXISTING file — just the wrong
12
+ # copy. Edits then succeed silently on the MAIN checkout while cwd and
13
+ # gitBranch keep reporting the worktree the whole time. The worktree
14
+ # branch stays empty; nearly all work lands on the main branch, with
15
+ # no warning. The author usually notices long after.
16
+ #
17
+ # This is a data-loss-class accident: work you believe is isolated in a
18
+ # worktree is written to (and committed on) the main checkout, and can
19
+ # be lost outright if that branch is later rebased or force-pushed.
20
+ #
21
+ # HOW IT WORKS: PreToolUse hook on Edit|Write|MultiEdit. If cwd is inside
22
+ # a worktree (.claude/worktrees/<name>), it derives the worktree root
23
+ # and the repo root from cwd alone, then blocks any ABSOLUTE file_path
24
+ # that is under the repo root but OUTSIDE the worktree root (i.e. the
25
+ # main checkout's copy). Relative paths resolve against cwd (the
26
+ # worktree) and are allowed. Absolute paths fully outside the repo are
27
+ # not this guard's concern (other guards cover that).
28
+ #
29
+ # See: https://github.com/anthropics/claude-code/issues/70069
30
+ #
31
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write|MultiEdit"
32
+ #
33
+ # Configuration:
34
+ # CC_WORKTREE_DIR_MARKER — path segment identifying worktrees.
35
+ # Default: ".claude/worktrees"
36
+ # ================================================================
37
+
38
+ set -euo pipefail
39
+
40
+ # Without jq, the parse below silently yields empty and this hook stops
41
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
42
+ # here: blocking would halt every tool call, and exiting 0 would change
43
+ # the behaviour of guards that do not depend on the parsed value.
44
+ if ! command -v jq >/dev/null 2>&1; then
45
+ _nojq_warned="/tmp/cc-nojq-warned-worktree-escape-write-guard-$PPID"
46
+ [ -f "$_nojq_warned" ] || {
47
+ echo "WARNING [worktree-escape-write-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
48
+ : > "$_nojq_warned"
49
+ }
50
+ fi
51
+
52
+ INPUT=$(cat)
53
+
54
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
55
+ case "$TOOL" in
56
+ Edit|Write|MultiEdit) ;;
57
+ *) exit 0 ;;
58
+ esac
59
+
60
+ CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
61
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
62
+ [ -z "$CWD" ] && exit 0
63
+ [ -z "$FILE" ] && exit 0
64
+
65
+ MARKER="${CC_WORKTREE_DIR_MARKER:-.claude/worktrees}"
66
+
67
+ # Only act when the session is inside a worktree.
68
+ case "$CWD" in
69
+ *"/$MARKER/"*) ;;
70
+ *) exit 0 ;;
71
+ esac
72
+
73
+ # Derive repo root (prefix before the marker) and worktree root
74
+ # (prefix + marker + the first segment after it = the worktree name).
75
+ REPO_ROOT="${CWD%%/$MARKER/*}"
76
+ REST="${CWD#*/$MARKER/}" # "<name>" or "<name>/sub/dir"
77
+ WT_NAME="${REST%%/*}"
78
+ WT_ROOT="$REPO_ROOT/$MARKER/$WT_NAME"
79
+
80
+ # Relative file_path resolves against cwd (the worktree) — safe.
81
+ case "$FILE" in
82
+ /*) ;; # absolute — keep checking
83
+ *) exit 0 ;;
84
+ esac
85
+
86
+ # Absolute paths that stay within the worktree are fine.
87
+ case "$FILE" in
88
+ "$WT_ROOT"|"$WT_ROOT"/*) exit 0 ;;
89
+ esac
90
+
91
+ # Absolute path under the repo root but outside the worktree = the bug.
92
+ case "$FILE" in
93
+ "$REPO_ROOT"/*)
94
+ echo "BLOCKED: Edit/Write escapes the active worktree onto the main checkout." >&2
95
+ echo "" >&2
96
+ echo " Worktree (cwd): $WT_ROOT" >&2
97
+ echo " Target file: $FILE" >&2
98
+ echo "" >&2
99
+ echo "This path is under the repository root but OUTSIDE the worktree." >&2
100
+ echo "It points at the MAIN checkout's copy of the file, not the worktree's." >&2
101
+ echo "Writing here silently commits your work to the main branch while the" >&2
102
+ echo "worktree branch stays empty (Claude Code issue #70069)." >&2
103
+ echo "" >&2
104
+ echo "Fix: rewrite the path under the worktree root, e.g." >&2
105
+ echo " $WT_ROOT/<path-relative-to-repo>" >&2
106
+ echo "" >&2
107
+ echo "Override (only if you truly mean the main checkout): set" >&2
108
+ echo "CC_WORKTREE_DIR_MARKER to a non-matching value for this command." >&2
109
+ exit 2
110
+ ;;
111
+ esac
112
+
113
+ # Absolute path entirely outside the repo — not this guard's concern.
114
+ exit 0
File without changes
@@ -0,0 +1,111 @@
1
+ #!/bin/bash
2
+ # worktree-hooks-path-fix.sh — Unset bogus per-worktree core.hooksPath that
3
+ # Claude Code's EnterWorktree harness writes, so Husky / lefthook / pre-commit
4
+ # hooks fire in worktrees the same way they do in the main checkout.
5
+ #
6
+ # Solves: #60620 — Claude Code's EnterWorktree harness writes an absolute
7
+ # `core.hooksPath` into the per-worktree `config.worktree` file. The absolute
8
+ # path points at the *main checkout's* hooks directory, not the worktree's,
9
+ # and because `extensions.worktreeConfig = true` is also enabled, the
10
+ # worktree-scoped value overrides any correct shared `core.hooksPath`
11
+ # (e.g. Husky's repo-relative `frontend/.husky/_`).
12
+ #
13
+ # Net effect: every Husky / lefthook / pre-commit hook the project author
14
+ # installed is dormant inside Claude-created worktrees. Git silently runs
15
+ # zero hooks (most common case) or runs the wrong directory's hooks against
16
+ # the worktree's index (less common but still a silent context drift).
17
+ #
18
+ # Operator-side fix: at SessionStart, detect that we're inside a
19
+ # Claude-created worktree (path matches `.claude/worktrees/`), read the
20
+ # worktree's `config.worktree` for `core.hooksPath`, and unset it if it is
21
+ # an absolute path that does not resolve relative to the worktree root.
22
+ # The shared config's repo-relative `core.hooksPath` (set by Husky's
23
+ # `prepare` script) then takes over and resolves correctly from any
24
+ # worktree.
25
+ #
26
+ # This is a harness-bug workaround, not a model-drift hook. The
27
+ # recognition-without-arrest family at #60226 is a different shape; this
28
+ # Issue's failure fires before any model interaction.
29
+ #
30
+ # Related Issues:
31
+ # #60620 — Claude Code agent harness writes broken per-worktree
32
+ # core.hooksPath (the direct origin of this hook)
33
+ # #27474 — earlier failure mode in the same family (writes corrupted
34
+ # shared .git/config; closed but related)
35
+ # #60475 — sibling-session git checkout clobber (workspace-lease-guard
36
+ # addresses a different worktree failure)
37
+ #
38
+ # CONFIG:
39
+ # CC_WORKTREE_HOOKS_FIX_DISABLE=1 set to disable the hook entirely
40
+ # CC_WORKTREE_HOOKS_FIX_VERBOSE=1 emit a NOTICE on every fix
41
+ #
42
+ # TRIGGER: SessionStart
43
+ # MATCHER: "*"
44
+
45
+ set -u
46
+
47
+ [ "${CC_WORKTREE_HOOKS_FIX_DISABLE:-0}" = "1" ] && exit 0
48
+
49
+ # Identify the working tree. Prefer CLAUDE_PROJECT_DIR, fall back to PWD.
50
+ WORKING_TREE="${CLAUDE_PROJECT_DIR:-${PWD:-}}"
51
+ [ -z "$WORKING_TREE" ] && exit 0
52
+
53
+ # Confirm we are inside a git worktree (not the main checkout, not non-git).
54
+ WORKTREE_ROOT=$(git -C "$WORKING_TREE" rev-parse --show-toplevel 2>/dev/null)
55
+ [ -z "$WORKTREE_ROOT" ] && exit 0
56
+
57
+ # Detect whether this is a worktree (vs the main checkout). git rev-parse
58
+ # --git-common-dir differs from --git-dir only inside a linked worktree.
59
+ GIT_COMMON_DIR=$(git -C "$WORKTREE_ROOT" rev-parse --git-common-dir 2>/dev/null)
60
+ GIT_DIR=$(git -C "$WORKTREE_ROOT" rev-parse --git-dir 2>/dev/null)
61
+ [ -z "$GIT_DIR" ] && exit 0
62
+
63
+ # Resolve both to absolute paths for comparison
64
+ GIT_COMMON_DIR_ABS=$(cd "$WORKTREE_ROOT" && readlink -f "$GIT_COMMON_DIR" 2>/dev/null || echo "$GIT_COMMON_DIR")
65
+ GIT_DIR_ABS=$(cd "$WORKTREE_ROOT" && readlink -f "$GIT_DIR" 2>/dev/null || echo "$GIT_DIR")
66
+
67
+ # Not a linked worktree — nothing to fix
68
+ [ "$GIT_COMMON_DIR_ABS" = "$GIT_DIR_ABS" ] && exit 0
69
+
70
+ # Only act on worktrees that look Claude-created. The path pattern
71
+ # `.claude/worktrees/` is the standard surface for `EnterWorktree`.
72
+ case "$WORKTREE_ROOT" in
73
+ */.claude/worktrees/*) ;;
74
+ *) exit 0 ;;
75
+ esac
76
+
77
+ # Read the worktree-scoped core.hooksPath
78
+ WORKTREE_HOOKS_PATH=$(git -C "$WORKTREE_ROOT" config --worktree --get core.hooksPath 2>/dev/null || true)
79
+ [ -z "$WORKTREE_HOOKS_PATH" ] && exit 0
80
+
81
+ # If the value is already a relative path resolving inside the worktree,
82
+ # leave it alone. Only intervene when it is an absolute path. Both POSIX-
83
+ # style (/) and Windows-style (C:\, D:\, etc.) absolute paths qualify.
84
+ case "$WORKTREE_HOOKS_PATH" in
85
+ /*|[A-Za-z]:[\\/]*) ;; # absolute — proceed
86
+ *) exit 0 ;; # relative — already correct, leave alone
87
+ esac
88
+
89
+ # If the absolute path happens to resolve inside the worktree root, leave
90
+ # it alone — the harness wrote something that works for this case.
91
+ case "$WORKTREE_HOOKS_PATH" in
92
+ "$WORKTREE_ROOT"/*) exit 0 ;;
93
+ esac
94
+
95
+ # Otherwise: the worktree config has an absolute hooksPath pointing
96
+ # outside the worktree, which silently shadows the shared config's
97
+ # relative hooksPath. Unset it.
98
+ if git -C "$WORKTREE_ROOT" config --worktree --unset core.hooksPath 2>/dev/null; then
99
+ if [ "${CC_WORKTREE_HOOKS_FIX_VERBOSE:-0}" = "1" ] || [ -n "${CLAUDE_PROJECT_DIR:-}" ]; then
100
+ cat >&2 <<EOF
101
+ NOTICE: worktree-hooks-path-fix unset a bogus core.hooksPath in this worktree.
102
+ Worktree: ${WORKTREE_ROOT}
103
+ Was pointing: ${WORKTREE_HOOKS_PATH}
104
+ Effect: Husky / lefthook / pre-commit hooks installed via the
105
+ shared config will now fire correctly in this worktree
106
+ (Issue #60620 workaround).
107
+ EOF
108
+ fi
109
+ fi
110
+
111
+ exit 0
@@ -0,0 +1,43 @@
1
+ #!/bin/bash
2
+ # Without jq, the parse below silently yields empty and this hook stops
3
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
4
+ # here: blocking would halt every tool call, and exiting 0 would change
5
+ # the behaviour of guards that do not depend on the parsed value.
6
+ if ! command -v jq >/dev/null 2>&1; then
7
+ _nojq_warned="/tmp/cc-nojq-warned-worktree-parent-write-guard-$PPID"
8
+ [ -f "$_nojq_warned" ] || {
9
+ echo "WARNING [worktree-parent-write-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
10
+ : > "$_nojq_warned"
11
+ }
12
+ fi
13
+
14
+ INPUT=$(cat)
15
+ TARGET=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty' 2>/dev/null)
16
+ [[ -z "$TARGET" ]] && exit 0
17
+ CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
18
+ [[ -z "$CWD" ]] && CWD="$PWD"
19
+ case "$CWD" in
20
+ *"/.claude/worktrees/"*) ;;
21
+ *) exit 0 ;;
22
+ esac
23
+ PARENT="${CWD%%/.claude/worktrees/*}"
24
+ REST="${CWD#*/.claude/worktrees/}" # <name>/maybe/more
25
+ WTNAME="${REST%%/*}" # <name>
26
+ WT="$PARENT/.claude/worktrees/$WTNAME"
27
+ case "$TARGET" in
28
+ /*) ABS="$TARGET" ;;
29
+ *) ABS="$CWD/$TARGET" ;;
30
+ esac
31
+ case "$ABS" in
32
+ "$WT"/*|"$WT")
33
+ exit 0 ;; # correctly inside the worktree — OK
34
+ "$PARENT"/*|"$PARENT")
35
+ echo "BLOCKED: write target is in the PARENT repo, not the active worktree." >&2
36
+ echo " cwd (worktree): $CWD" >&2
37
+ echo " target: $ABS" >&2
38
+ echo " Expected under: $WT/" >&2
39
+ echo " This is the silent nested-worktree parent-write (#62547/#60679/#69026)." >&2
40
+ echo " Fix: write under the worktree path, or create worktrees OUTSIDE the repo." >&2
41
+ exit 2 ;;
42
+ esac
43
+ exit 0
@@ -1,9 +1,10 @@
1
+ #!/bin/bash
1
2
  MAIN_TREE=$(git worktree list --porcelain 2>/dev/null | head -1 | sed 's/worktree //')
2
3
  [ -z "$MAIN_TREE" ] && exit 0
3
4
  CUR_DIR=$(pwd)
4
5
  [ "$CUR_DIR" = "$MAIN_TREE" ] && exit 0
5
6
  to_project_dir() {
6
- echo "$HOME/.claude/projects/$(echo "$1" | sed 's|/|-|g; s|^-||')"
7
+ echo "$HOME/.claude/projects/$(echo "$1" | sed 's|/|-|g')"
7
8
  }
8
9
  MAIN_PROJECT=$(to_project_dir "$MAIN_TREE")
9
10
  CUR_PROJECT=$(to_project_dir "$CUR_DIR")
@@ -1,3 +1,16 @@
1
+ #!/bin/bash
2
+ # Without jq, the parse below silently yields empty and this hook stops
3
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
4
+ # here: blocking would halt every tool call, and exiting 0 would change
5
+ # the behaviour of guards that do not depend on the parsed value.
6
+ if ! command -v jq >/dev/null 2>&1; then
7
+ _nojq_warned="/tmp/cc-nojq-warned-worktree-remove-uncommitted-guard-$PPID"
8
+ [ -f "$_nojq_warned" ] || {
9
+ echo "WARNING [worktree-remove-uncommitted-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
10
+ : > "$_nojq_warned"
11
+ }
12
+ fi
13
+
1
14
  INFO=$(cat)
2
15
  PATH_WT=$(echo "$INFO" | jq -r '.path // empty' 2>/dev/null)
3
16
  [ -z "$PATH_WT" ] && exit 0
@@ -36,7 +36,13 @@ if ! echo "$COMMAND" | grep -qE 'git\s+worktree\s+(remove|prune)|rm\s+.*worktree
36
36
  fi
37
37
 
38
38
  # Extract worktree path
39
- WORKTREE_PATH=$(echo "$COMMAND" | grep -oP 'git\s+worktree\s+remove\s+\K[^\s]+')
39
+ # -P は GNU 拡張で、macOS の BSD grep では grep がエラーになり WORKTREE_PATH が空になる。
40
+ # すぐ下の「空なら exit 0」で、未マージのコミットを持つ worktree でも素通しになる。
41
+ # 実測: 未マージのコミットを持つ worktree への git worktree remove で、-P ありは 2、無しは 0。
42
+ # \K に POSIX の等価物は無いので、コマンド語から一致させて前置きを sed で落とす。
43
+ WORKTREE_PATH=$(echo "$COMMAND" \
44
+ | grep -oE 'git[[:space:]]+worktree[[:space:]]+remove[[:space:]]+[^[:space:]]+' \
45
+ | sed -E 's/^git[[:space:]]+worktree[[:space:]]+remove[[:space:]]+//')
40
46
 
41
47
  if [ -z "$WORKTREE_PATH" ]; then
42
48
  # Maybe it's rm -rf on a worktree directory
@@ -0,0 +1,190 @@
1
+ #!/bin/bash
2
+ # write-byte-integrity-verifier.sh — Detect silent file truncation after Write/Edit
3
+ #
4
+ # Solves: github.com/anthropics/claude-code/issues/58551
5
+ # "Write and Edit tools truncate files on virtiofs mounts in Claude Code"
6
+ #
7
+ # Reporter (2026-05-13) found that on virtiofs-backed mounts (common in
8
+ # devcontainers and Claude Cowork sandboxes), Write and Edit tools
9
+ # silently truncate or null-pad files:
10
+ # - Shrink case: file of N bytes, Write shorter content M, result is
11
+ # new content from 0..M then \x00 from M..N (size unchanged, tail
12
+ # padded with NULs instead of file being truncated to M).
13
+ # - Grow case: Edit makes file longer, but file is silently chopped
14
+ # at some boundary K < intended length.
15
+ # Both modes leave the file in a corrupted state with no error returned
16
+ # to the tool caller, so the assistant believes the write succeeded.
17
+ #
18
+ # WHY THIS MATTERS:
19
+ # The assistant's belief ("Write returned success, file has the new content")
20
+ # diverges from filesystem reality ("file is null-padded or tail-chopped").
21
+ # This is the textbook claim-verify gap, and on virtiofs it is reproducible.
22
+ # When the assistant's next Read returns the old/corrupted content, the
23
+ # assistant may retry, overwrite further, or report nonsense to the user.
24
+ #
25
+ # TRIGGER: PostToolUse MATCHER: Write|Edit
26
+ #
27
+ # HOW IT WORKS:
28
+ # After a successful Write/Edit:
29
+ # 1. Find the target file path from tool_input.
30
+ # 2. Use `wc -c` to get the on-disk byte count.
31
+ # 3. For Write: compare against the byte count of tool_input.content.
32
+ # 4. For Edit: read the file once and confirm tool_input.new_string is
33
+ # present (substring check) and tool_input.old_string is absent.
34
+ # 5. Detect null-padding by checking if the last 4 bytes are all \x00
35
+ # while the rest of the file does not naturally end in nulls.
36
+ # On mismatch: emit a clear warning to stderr describing the divergence,
37
+ # the file path, the expected vs. actual byte counts, and the recommended
38
+ # next steps (re-read the file, re-write if confirmed corrupted, escalate
39
+ # if on virtiofs).
40
+ #
41
+ # CONFIGURATION:
42
+ # CC_WRITE_INTEGRITY_DISABLE=1 — disable the hook entirely
43
+ # CC_WRITE_INTEGRITY_ACTION — "warn" (default) or "block" (exit 2)
44
+ # CC_WRITE_INTEGRITY_LOG — log file path
45
+ # (default /tmp/cc-write-integrity.log)
46
+ # CC_WRITE_INTEGRITY_SKIP_GLOB — pipe-separated globs to skip
47
+ # (default: "*.log|*.lock|*.tmp")
48
+ #
49
+ # Usage:
50
+ # {
51
+ # "hooks": {
52
+ # "PostToolUse": [{
53
+ # "matcher": "Write|Edit",
54
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/write-byte-integrity-verifier.sh" }]
55
+ # }]
56
+ # }
57
+ # }
58
+
59
+ # Allow opt-out
60
+ if [ "${CC_WRITE_INTEGRITY_DISABLE:-0}" = "1" ]; then
61
+ exit 0
62
+ fi
63
+
64
+ # Without jq, the parse below silently yields empty and this hook stops
65
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
66
+ # here: blocking would halt every tool call, and exiting 0 would change
67
+ # the behaviour of guards that do not depend on the parsed value.
68
+ if ! command -v jq >/dev/null 2>&1; then
69
+ _nojq_warned="/tmp/cc-nojq-warned-write-byte-integrity-verifier-$PPID"
70
+ [ -f "$_nojq_warned" ] || {
71
+ echo "WARNING [write-byte-integrity-verifier]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
72
+ : > "$_nojq_warned"
73
+ }
74
+ fi
75
+
76
+ INPUT=$(cat)
77
+
78
+ # Get tool name; only handle Write and Edit
79
+ TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
80
+ case "$TOOL" in
81
+ Write|Edit) ;;
82
+ *) exit 0 ;;
83
+ esac
84
+
85
+ # Pull file path
86
+ FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
87
+ if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
88
+ exit 0
89
+ fi
90
+
91
+ # Skip files matching configured globs
92
+ SKIP="${CC_WRITE_INTEGRITY_SKIP_GLOB:-*.log|*.lock|*.tmp}"
93
+ IFS='|' read -ra PATTERNS <<< "$SKIP"
94
+ for pat in "${PATTERNS[@]}"; do
95
+ pat=$(echo "$pat" | xargs) # trim
96
+ [ -z "$pat" ] && continue
97
+ case "$FILE_PATH" in
98
+ $pat) exit 0 ;;
99
+ esac
100
+ done
101
+
102
+ ACTION="${CC_WRITE_INTEGRITY_ACTION:-warn}"
103
+ LOG_FILE="${CC_WRITE_INTEGRITY_LOG:-/tmp/cc-write-integrity.log}"
104
+
105
+ # Read disk size
106
+ DISK_SIZE=$(wc -c < "$FILE_PATH" 2>/dev/null || echo "")
107
+ if [ -z "$DISK_SIZE" ]; then
108
+ exit 0
109
+ fi
110
+
111
+ WARNINGS=()
112
+
113
+ if [ "$TOOL" = "Write" ]; then
114
+ # Compare disk size vs intended content size
115
+ CONTENT_SIZE=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // empty' 2>/dev/null | wc -c)
116
+ # jq's `-r` adds a trailing newline; subtract 1 if content was non-empty
117
+ HAS_CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // empty' 2>/dev/null)
118
+ if [ -n "$HAS_CONTENT" ] && [ "$CONTENT_SIZE" -gt 0 ]; then
119
+ EXPECTED=$((CONTENT_SIZE - 1))
120
+ else
121
+ EXPECTED=0
122
+ fi
123
+ if [ "$DISK_SIZE" -ne "$EXPECTED" ]; then
124
+ # Possible shrink-pad case: disk size larger than expected
125
+ if [ "$DISK_SIZE" -gt "$EXPECTED" ]; then
126
+ # Check trailing bytes for nulls
127
+ TAIL_BYTES=$(tail -c 4 "$FILE_PATH" 2>/dev/null | od -An -tx1 | tr -d ' \n')
128
+ if [ "$TAIL_BYTES" = "00000000" ]; then
129
+ WARNINGS+=("Write target appears null-padded: on-disk size $DISK_SIZE bytes exceeds intended $EXPECTED bytes, trailing 4 bytes are 0x00. Possible virtiofs shrink-pad bug (#58551).")
130
+ else
131
+ WARNINGS+=("Write target byte count mismatch: on-disk $DISK_SIZE vs intended $EXPECTED. Tail bytes are not null but size differs; investigate.")
132
+ fi
133
+ else
134
+ # Tail-chop case: disk size smaller than expected
135
+ WARNINGS+=("Write target appears tail-chopped: on-disk size $DISK_SIZE bytes is less than intended $EXPECTED bytes. Possible virtiofs grow-chop bug (#58551).")
136
+ fi
137
+ fi
138
+ elif [ "$TOOL" = "Edit" ]; then
139
+ # For Edit, confirm new_string is in file and old_string is gone
140
+ NEW_STRING=$(printf '%s' "$INPUT" | jq -r '.tool_input.new_string // empty' 2>/dev/null)
141
+ OLD_STRING=$(printf '%s' "$INPUT" | jq -r '.tool_input.old_string // empty' 2>/dev/null)
142
+ REPLACE_ALL=$(printf '%s' "$INPUT" | jq -r '.tool_input.replace_all // false' 2>/dev/null)
143
+
144
+ if [ -n "$NEW_STRING" ]; then
145
+ if ! grep -F -q -- "$NEW_STRING" "$FILE_PATH" 2>/dev/null; then
146
+ WARNINGS+=("Edit completed but new_string not found in $FILE_PATH. The Edit may have been silently truncated (#58551) or applied incorrectly.")
147
+ fi
148
+ fi
149
+ if [ -n "$OLD_STRING" ] && [ "$REPLACE_ALL" != "true" ]; then
150
+ # In a non-replace_all Edit, old_string MAY still appear if it was a partial
151
+ # of a unique substring; skip strict check to avoid false positives.
152
+ :
153
+ fi
154
+ # Check for null-padding regardless
155
+ TAIL_BYTES=$(tail -c 4 "$FILE_PATH" 2>/dev/null | od -An -tx1 | tr -d ' \n')
156
+ if [ "$TAIL_BYTES" = "00000000" ]; then
157
+ # Avoid false positive: skip binary files
158
+ if file "$FILE_PATH" 2>/dev/null | grep -q "text"; then
159
+ WARNINGS+=("Edit target ends with 4 null bytes ($FILE_PATH). Text files normally do not. Possible virtiofs null-pad bug (#58551).")
160
+ fi
161
+ fi
162
+ fi
163
+
164
+ # No warnings → silent pass
165
+ if [ ${#WARNINGS[@]} -eq 0 ]; then
166
+ exit 0
167
+ fi
168
+
169
+ # Log + emit
170
+ TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
171
+ for w in "${WARNINGS[@]}"; do
172
+ echo "[$TIMESTAMP] file=$FILE_PATH tool=$TOOL action=$ACTION reason=$w" >> "$LOG_FILE"
173
+ done
174
+
175
+ MSG="⚠️ write-byte-integrity-verifier: potential file corruption after $TOOL"
176
+ for w in "${WARNINGS[@]}"; do
177
+ MSG+=$'\n'" - $w"
178
+ done
179
+ MSG+=$'\n'" Recommended: re-Read this file, confirm the intended content is on disk;"
180
+ MSG+=$'\n'" if corrupted, re-Write from your in-memory copy. On virtiofs mounts"
181
+ MSG+=$'\n'" (Claude Cowork sandbox / some devcontainers), consider working in /tmp"
182
+ MSG+=$'\n'" or a non-virtiofs path. Reference: github.com/anthropics/claude-code/issues/58551"
183
+
184
+ if [ "$ACTION" = "block" ]; then
185
+ printf '%s\n' "$MSG" >&2
186
+ exit 2
187
+ else
188
+ printf '%s\n' "$MSG" >&2
189
+ exit 0
190
+ fi