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,86 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-destructive-git-guard.sh (Issue #57463 / #46444 / #53765 prevention)
3
+ HOOK="examples/subagent-destructive-git-guard.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: Empty prompt should silently pass
11
+ OUT=$(echo '{"tool_input":{"prompt":""}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_not_contains "empty prompt no warning" "$OUT" "destructive-git boundary"
14
+ assert_exit "empty prompt exit 0" "$RC" "0"
15
+
16
+ # Test 2: Vague prompt should warn on all 3 checks
17
+ OUT=$(echo '{"tool_input":{"prompt":"please rename Tailwind classes across all .tsx files"}}' | bash "$HOOK" 2>&1)
18
+ RC=$?
19
+ assert_contains "vague warns destructive forbidden" "$OUT" "Destructive git commands not forbidden"
20
+ assert_contains "vague warns safe alternative" "$OUT" "No safe alternative named"
21
+ assert_contains "vague warns working tree check" "$OUT" "No working-tree state check"
22
+ assert_contains "vague references 57463" "$OUT" "#57463"
23
+ assert_contains "vague references 46444" "$OUT" "#46444"
24
+ assert_contains "vague references 53765" "$OUT" "#53765"
25
+ assert_exit "vague exit 0 advisory" "$RC" "0"
26
+
27
+ # Test 3: Destructive forbidden named, other 2 missing
28
+ OUT=$(echo '{"tool_input":{"prompt":"Do not use git checkout or git reset. Rename classes."}}' | bash "$HOOK" 2>&1)
29
+ assert_not_contains "destructive only no destructive warning" "$OUT" "Destructive git commands not forbidden"
30
+ assert_contains "destructive only warns alternative" "$OUT" "No safe alternative named"
31
+ assert_contains "destructive only warns tree check" "$OUT" "No working-tree state check"
32
+
33
+ # Test 4: Safe alternative named, other 2 missing
34
+ OUT=$(echo '{"tool_input":{"prompt":"Use git stash before any change. Rename classes."}}' | bash "$HOOK" 2>&1)
35
+ assert_contains "alternative only warns destructive" "$OUT" "Destructive git commands not forbidden"
36
+ assert_not_contains "alternative only no alternative warning" "$OUT" "No safe alternative named"
37
+ assert_contains "alternative only warns tree check" "$OUT" "No working-tree state check"
38
+
39
+ # Test 5: Working tree check named, other 2 missing
40
+ OUT=$(echo '{"tool_input":{"prompt":"Run git status first before any change. Rename classes."}}' | bash "$HOOK" 2>&1)
41
+ assert_contains "tree check only warns destructive" "$OUT" "Destructive git commands not forbidden"
42
+ assert_contains "tree check only warns alternative" "$OUT" "No safe alternative named"
43
+ assert_not_contains "tree check only no tree check warning" "$OUT" "No working-tree state check"
44
+
45
+ # Test 6: All 3 boundary instructions present, no warning
46
+ OUT=$(echo '{"tool_input":{"prompt":"Do not use git checkout, git reset, or git restore. Use git stash before any change. Run git status first to verify working tree state. Rename Tailwind classes across .tsx files."}}' | bash "$HOOK" 2>&1)
47
+ RC=$?
48
+ assert_not_contains "well-formed no warning" "$OUT" "destructive-git boundary"
49
+ assert_exit "well-formed exit 0" "$RC" "0"
50
+
51
+ # Test 7: Japanese prompt with all 3 instructions, no warning
52
+ OUT=$(echo '{"tool_input":{"prompt":"git checkout / git reset / git restore は禁止。stash の利用を優先。git status を最初に実行して作業の場の状態を確認してから、Tailwind class を rename する。"}}' | bash "$HOOK" 2>&1)
53
+ RC=$?
54
+ assert_not_contains "Japanese well-formed no warning" "$OUT" "destructive-git boundary"
55
+ assert_exit "Japanese well-formed exit 0" "$RC" "0"
56
+
57
+ # Test 8: Strict mode blocks vague prompts
58
+ OUT=$(echo '{"tool_input":{"prompt":"rename classes"}}' | CC_SUBAGENT_DESTRUCTIVE_GIT_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
59
+ RC=$?
60
+ assert_contains "strict mode warns" "$OUT" "destructive-git boundary"
61
+ assert_exit "strict mode blocks (exit 2)" "$RC" "2"
62
+
63
+ # Test 9: Missing prompt field should silently pass
64
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
65
+ RC=$?
66
+ assert_not_contains "missing prompt no warning" "$OUT" "destructive-git boundary"
67
+ assert_exit "missing prompt exit 0" "$RC" "0"
68
+
69
+ # Test 10: Strict mode passes when boundary is set
70
+ OUT=$(echo '{"tool_input":{"prompt":"Do not use git checkout. Use git stash. Check git status first. Rename."}}' | CC_SUBAGENT_DESTRUCTIVE_GIT_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
71
+ RC=$?
72
+ assert_not_contains "strict well-formed no warning" "$OUT" "destructive-git boundary"
73
+ assert_exit "strict well-formed exit 0" "$RC" "0"
74
+
75
+ # Test 11: "destructive git" general phrase satisfies check 1
76
+ OUT=$(echo '{"tool_input":{"prompt":"No destructive git commands allowed. Use git stash. Check git status first."}}' | bash "$HOOK" 2>&1)
77
+ RC=$?
78
+ assert_not_contains "general phrase satisfies destructive check" "$OUT" "Destructive git commands not forbidden"
79
+
80
+ # Test 12: "ask the parent before" satisfies safe alternative check
81
+ OUT=$(echo '{"tool_input":{"prompt":"Do not use git checkout. Ask the parent before any destructive operation. Check git status first."}}' | bash "$HOOK" 2>&1)
82
+ RC=$?
83
+ assert_not_contains "ask parent satisfies alternative" "$OUT" "No safe alternative named"
84
+
85
+ echo "Results: $PASS passed, $FAIL failed"
86
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-identity-leak-guard.sh (Issue #55488 prevention)
3
+ HOOK="examples/subagent-identity-leak-guard.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: Empty prompt should silently pass
11
+ OUT=$(echo '{"tool_input":{"prompt":""}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_not_contains "empty prompt no warning" "$OUT" "Subagent identity boundary"
14
+ assert_exit "empty prompt exit 0" "$RC" "0"
15
+
16
+ # Test 2: Vague prompt should warn on all 3 checks
17
+ OUT=$(echo '{"tool_input":{"prompt":"please investigate the auth flow"}}' | bash "$HOOK" 2>&1)
18
+ RC=$?
19
+ assert_contains "vague prompt warns role" "$OUT" "No explicit role assignment"
20
+ assert_contains "vague prompt warns impersonation" "$OUT" "No prohibition against impersonating"
21
+ assert_contains "vague prompt warns history" "$OUT" "No prohibition against exposing"
22
+ assert_contains "vague prompt references issue" "$OUT" "#55488"
23
+ assert_exit "vague prompt exit 0 advisory" "$RC" "0"
24
+
25
+ # Test 3: Role assignment present, other 2 missing
26
+ OUT=$(echo '{"tool_input":{"prompt":"You are the backend agent. Investigate src/auth/login.ts."}}' | bash "$HOOK" 2>&1)
27
+ assert_not_contains "role only no role warning" "$OUT" "No explicit role"
28
+ assert_contains "role only warns impersonation" "$OUT" "No prohibition against impersonating"
29
+ assert_contains "role only warns history" "$OUT" "No prohibition against exposing"
30
+
31
+ # Test 4: Impersonation prohibition present, other 2 missing
32
+ OUT=$(echo '{"tool_input":{"prompt":"Do not identify as the parent. Do something useful."}}' | bash "$HOOK" 2>&1)
33
+ assert_contains "impersonation only warns role" "$OUT" "No explicit role"
34
+ assert_not_contains "impersonation only no impersonation warning" "$OUT" "No prohibition against impersonating"
35
+ assert_contains "impersonation only warns history" "$OUT" "No prohibition against exposing"
36
+
37
+ # Test 5: History prohibition present, other 2 missing
38
+ OUT=$(echo '{"tool_input":{"prompt":"Do not share the parent agent conversation history. Run a task."}}' | bash "$HOOK" 2>&1)
39
+ assert_contains "history only warns role" "$OUT" "No explicit role"
40
+ assert_contains "history only warns impersonation" "$OUT" "No prohibition against impersonating"
41
+ assert_not_contains "history only no history warning" "$OUT" "No prohibition against exposing"
42
+
43
+ # Test 6: All 3 boundary instructions present, no warning
44
+ OUT=$(echo '{"tool_input":{"prompt":"You are the backend agent. Do not identify as the parent or team-lead. Do not share the parent main agent conversation history. Investigate src/auth/login.ts."}}' | bash "$HOOK" 2>&1)
45
+ RC=$?
46
+ assert_not_contains "well-formed no warning" "$OUT" "Subagent identity boundary"
47
+ assert_exit "well-formed exit 0" "$RC" "0"
48
+
49
+ # Test 7: Strict mode (CC_SUBAGENT_IDENTITY_REQUIRE_ALL=1) blocks vague prompts
50
+ OUT=$(echo '{"tool_input":{"prompt":"investigate something"}}' | CC_SUBAGENT_IDENTITY_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
51
+ RC=$?
52
+ assert_contains "strict mode warns" "$OUT" "Subagent identity boundary"
53
+ assert_exit "strict mode blocks (exit 2)" "$RC" "2"
54
+
55
+ # Test 8: Missing prompt field should silently pass
56
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
57
+ RC=$?
58
+ assert_not_contains "missing prompt no warning" "$OUT" "Subagent identity boundary"
59
+ assert_exit "missing prompt exit 0" "$RC" "0"
60
+
61
+ echo "Results: $PASS passed, $FAIL failed"
62
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-identity-reassertion.sh — Issue #55488 mitigation hook
3
+ HOOK="examples/subagent-identity-reassertion.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit_code() { if [ "$2" -eq "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: Agent tool with subagent_type emits reminder block
11
+ OUT=$(echo '{"tool_name":"Agent","tool_input":{"subagent_type":"general-purpose","name":"backend"}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_contains "Agent tool emits reminder header" "$OUT" "subagent-identity-reassertion"
14
+ assert_contains "reminder includes subagent label" "$OUT" "backend (general-purpose)"
15
+ assert_contains "reminder mentions Issue #55488" "$OUT" "#55488"
16
+ assert_contains "reminder includes parent-relay guard" "$OUT" "route sensitive DMs through the parent"
17
+ assert_contains "reminder includes context audit guard" "$OUT" "parent context does not contain secrets"
18
+ assert_contains "reminder includes identity-lock guard" "$OUT" "Confirm"
19
+ assert_exit_code "Agent tool exit 0" "$RC" 0
20
+
21
+ # Test 2: Bash tool skips silently with exit 0 (non-Agent fast path)
22
+ OUT=$(echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | bash "$HOOK" 2>&1)
23
+ RC=$?
24
+ assert_not_contains "Bash tool emits no reminder" "$OUT" "subagent-identity-reassertion"
25
+ assert_exit_code "Bash tool exit 0" "$RC" 0
26
+
27
+ # Test 3: Empty tool_name skips silently
28
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
29
+ RC=$?
30
+ assert_not_contains "empty input emits no reminder" "$OUT" "subagent-identity-reassertion"
31
+ assert_exit_code "empty input exit 0" "$RC" 0
32
+
33
+ # Test 4: Agent without subagent_type still emits reminder with default label
34
+ OUT=$(echo '{"tool_name":"Agent","tool_input":{}}' | bash "$HOOK" 2>&1)
35
+ RC=$?
36
+ assert_contains "Agent without subagent_type still warns" "$OUT" "subagent-identity-reassertion"
37
+ assert_contains "default role label is subagent" "$OUT" "Spawning subagent"
38
+ assert_exit_code "Agent without subagent_type exit 0" "$RC" 0
39
+
40
+ # Test 5: Agent with only subagent_type (no name)
41
+ OUT=$(echo '{"tool_name":"Agent","tool_input":{"subagent_type":"general-purpose"}}' | bash "$HOOK" 2>&1)
42
+ RC=$?
43
+ assert_contains "Agent with only subagent_type" "$OUT" "Spawning general-purpose"
44
+ assert_exit_code "exit 0" "$RC" 0
45
+
46
+ # Test 6: Read tool (another non-Agent) skips silently
47
+ OUT=$(echo '{"tool_name":"Read","tool_input":{"file_path":"/tmp/x"}}' | bash "$HOOK" 2>&1)
48
+ RC=$?
49
+ assert_not_contains "Read tool emits no reminder" "$OUT" "subagent-identity-reassertion"
50
+ assert_exit_code "Read tool exit 0" "$RC" 0
51
+
52
+ # Test 7: Malformed JSON falls through silently (jq returns empty)
53
+ OUT=$(echo 'not json' | bash "$HOOK" 2>&1)
54
+ RC=$?
55
+ assert_not_contains "malformed JSON does not warn" "$OUT" "subagent-identity-reassertion"
56
+ # Note: jq exits with non-zero on malformed JSON, but `// empty` + set -euo
57
+ # may cause exit 1 here. Accept exit 0 or 1 (silent failure is acceptable).
58
+ [ "$RC" -le 1 ] && PASS=$((PASS+1)) || { FAIL=$((FAIL+1)); echo "FAIL: malformed JSON exit code $RC > 1"; }
59
+
60
+ echo "Results: $PASS passed, $FAIL failed"
61
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,319 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-inheritance-tester.sh — verifies that subagent
3
+ # frontmatter gaps (missing tools:, memory: misuse, missing name:,
4
+ # no frontmatter) are surfaced, and that parent Deny rules escalate
5
+ # the warning text for missing tool bindings.
6
+
7
+ HOOK="examples/subagent-inheritance-tester.sh"
8
+ PASS=0 FAIL=0
9
+
10
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3' in: $2)"; fi; }
11
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3' in: $2)"; fi; }
12
+ assert_exit() { if [ "$2" -eq "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (exit $2, expected $3)"; fi; }
13
+
14
+ TMPDIR=$(mktemp -d)
15
+ PROJ_DIR="$TMPDIR/project"
16
+ HOME_AGENTS="$TMPDIR/home/.claude/agents"
17
+ PROJ_AGENTS="$PROJ_DIR/.claude/agents"
18
+ mkdir -p "$HOME_AGENTS" "$PROJ_AGENTS"
19
+
20
+ # Run the hook with isolated $HOME and a synthetic project cwd.
21
+ run_hook() {
22
+ local cwd="$1"
23
+ local input
24
+ input=$(jq -n --arg c "$cwd" '{cwd: $c}')
25
+ printf '%s' "$input" | HOME="$TMPDIR/home" bash "$HOOK" 2>&1
26
+ }
27
+
28
+ # ---- Test 1: empty input + no agents → exit 0 silently ----
29
+ rm -rf "$TMPDIR/home/.claude/agents"
30
+ OUT=$(echo '{}' | HOME="$TMPDIR/home" bash "$HOOK" 2>&1)
31
+ RC=$?
32
+ assert_exit "no agents dir exits 0" "$RC" 0
33
+ assert_not_contains "no agents dir no output" "$OUT" "subagent-inheritance"
34
+ mkdir -p "$HOME_AGENTS"
35
+
36
+ # ---- Test 2: well-formed agent with tools: → no warning ----
37
+ cat > "$HOME_AGENTS/good.md" <<'EOF'
38
+ ---
39
+ name: good-agent
40
+ description: Tightly scoped helper
41
+ tools: Read, Grep
42
+ model: sonnet
43
+ ---
44
+ You are a focused helper.
45
+ EOF
46
+ OUT=$(run_hook "$PROJ_DIR")
47
+ RC=$?
48
+ assert_exit "well-formed agent exits 0" "$RC" 0
49
+ assert_not_contains "well-formed agent no warning" "$OUT" "subagent-inheritance"
50
+
51
+ # ---- Test 3: agent without frontmatter → warning ----
52
+ cat > "$HOME_AGENTS/no-frontmatter.md" <<'EOF'
53
+ You are an agent without YAML frontmatter.
54
+ EOF
55
+ OUT=$(run_hook "$PROJ_DIR")
56
+ RC=$?
57
+ assert_exit "no-frontmatter exits 0 (warn-only)" "$RC" 0
58
+ assert_contains "no-frontmatter warned" "$OUT" "no YAML frontmatter"
59
+
60
+ # ---- Test 4: agent missing tools: → warning ----
61
+ rm -f "$HOME_AGENTS/no-frontmatter.md"
62
+ cat > "$HOME_AGENTS/missing-tools.md" <<'EOF'
63
+ ---
64
+ name: missing-tools
65
+ description: Agent with no explicit tools list
66
+ model: sonnet
67
+ ---
68
+ Body.
69
+ EOF
70
+ OUT=$(run_hook "$PROJ_DIR")
71
+ RC=$?
72
+ assert_exit "missing-tools exits 0" "$RC" 0
73
+ assert_contains "missing-tools warned about default tool set" "$OUT" "no explicit 'tools:' list"
74
+
75
+ # ---- Test 5: agent with memory: field → warned about #57507 ----
76
+ cat > "$HOME_AGENTS/memory-only.md" <<'EOF'
77
+ ---
78
+ name: memory-only
79
+ description: Author thought memory: would scope this agent
80
+ memory: scoped
81
+ tools: Read
82
+ ---
83
+ Body.
84
+ EOF
85
+ OUT=$(run_hook "$PROJ_DIR")
86
+ RC=$?
87
+ assert_exit "memory-only exits 0" "$RC" 0
88
+ assert_contains "memory-only flagged" "$OUT" "57507"
89
+ assert_contains "memory-only mentions silently ignored" "$OUT" "silently ignored"
90
+ rm -f "$HOME_AGENTS/memory-only.md"
91
+
92
+ # ---- Test 6: agent missing name: → warning ----
93
+ cat > "$HOME_AGENTS/no-name.md" <<'EOF'
94
+ ---
95
+ description: Missing required name key
96
+ tools: Read
97
+ ---
98
+ Body.
99
+ EOF
100
+ OUT=$(run_hook "$PROJ_DIR")
101
+ RC=$?
102
+ assert_exit "no-name exits 0" "$RC" 0
103
+ assert_contains "no-name warned" "$OUT" "missing required 'name:'"
104
+ rm -f "$HOME_AGENTS/no-name.md"
105
+
106
+ # ---- Test 7: parent Deny rules escalate missing-tools warning ----
107
+ mkdir -p "$TMPDIR/home/.claude"
108
+ cat > "$TMPDIR/home/.claude/settings.json" <<'EOF'
109
+ {
110
+ "permissions": {
111
+ "deny": ["Read(./.env)", "Read(./.env.*)"]
112
+ }
113
+ }
114
+ EOF
115
+ OUT=$(run_hook "$PROJ_DIR")
116
+ RC=$?
117
+ assert_exit "deny-rules + missing tools exits 0" "$RC" 0
118
+ assert_contains "deny-rules escalation cites #57068" "$OUT" "57068"
119
+ assert_contains "deny-rules listed in output" "$OUT" "Read(./.env)"
120
+
121
+ # ---- Test 8: BLOCK=1 with issues → exit 2 ----
122
+ OUT=$(CC_SUBAGENT_INHERITANCE_BLOCK=1 run_hook "$PROJ_DIR")
123
+ RC=$?
124
+ assert_exit "block mode with issues exits 2" "$RC" 2
125
+ assert_contains "block mode still emits warning text" "$OUT" "subagent-inheritance"
126
+
127
+ # ---- Test 9: BLOCK=1 with no issues → exit 0 ----
128
+ rm -f "$HOME_AGENTS/missing-tools.md"
129
+ OUT=$(CC_SUBAGENT_INHERITANCE_BLOCK=1 run_hook "$PROJ_DIR")
130
+ RC=$?
131
+ assert_exit "block mode without issues exits 0" "$RC" 0
132
+ assert_not_contains "block mode no issues no warning" "$OUT" "subagent-inheritance"
133
+
134
+ # ---- Test 10: project-level .claude/agents/ scanned via cwd ----
135
+ cat > "$PROJ_AGENTS/proj-agent.md" <<'EOF'
136
+ ---
137
+ name: proj-agent
138
+ description: Project agent with no tools
139
+ ---
140
+ Body.
141
+ EOF
142
+ OUT=$(run_hook "$PROJ_DIR")
143
+ RC=$?
144
+ assert_exit "project agent dir exits 0" "$RC" 0
145
+ assert_contains "project agent dir scanned" "$OUT" "proj-agent.md"
146
+ rm -f "$PROJ_AGENTS/proj-agent.md"
147
+
148
+ # ---- Test 11: backup files (.bak) skipped ----
149
+ cat > "$HOME_AGENTS/old.md.bak" <<'EOF'
150
+ broken file
151
+ EOF
152
+ OUT=$(run_hook "$PROJ_DIR")
153
+ RC=$?
154
+ assert_exit "backup file skipped exits 0" "$RC" 0
155
+ assert_not_contains "backup file not warned" "$OUT" "old.md.bak"
156
+ rm -f "$HOME_AGENTS/old.md.bak"
157
+
158
+ # ---- Test 12: extra paths via env var ----
159
+ mkdir -p "$TMPDIR/extra"
160
+ cat > "$TMPDIR/extra/extra-agent.md" <<'EOF'
161
+ ---
162
+ description: extra path agent missing name and tools
163
+ ---
164
+ Body.
165
+ EOF
166
+ OUT=$(CC_SUBAGENT_INHERITANCE_PATHS="$TMPDIR/extra" run_hook "$PROJ_DIR")
167
+ RC=$?
168
+ assert_exit "extra path agent exits 0" "$RC" 0
169
+ assert_contains "extra path agent scanned" "$OUT" "extra-agent.md"
170
+
171
+ # ---- Test 13: real-world #57068 repro — Deny .env + agent w/o tools ----
172
+ cat > "$HOME_AGENTS/57068-repro.md" <<'EOF'
173
+ ---
174
+ name: helpful
175
+ description: General helper
176
+ ---
177
+ You may help with anything.
178
+ EOF
179
+ OUT=$(run_hook "$PROJ_DIR")
180
+ RC=$?
181
+ assert_exit "#57068 repro exits 0" "$RC" 0
182
+ assert_contains "#57068 repro escalates with deny" "$OUT" "57068"
183
+ assert_contains "#57068 repro names the file" "$OUT" "57068-repro.md"
184
+ rm -f "$HOME_AGENTS/57068-repro.md"
185
+
186
+ # ---- Test 14: real-world #57507 repro — memory: present ----
187
+ cat > "$HOME_AGENTS/57507-repro.md" <<'EOF'
188
+ ---
189
+ name: scoped
190
+ description: Author tried to bind via memory:
191
+ memory:
192
+ scope: subagent-only
193
+ tools: Read
194
+ ---
195
+ Body.
196
+ EOF
197
+ OUT=$(run_hook "$PROJ_DIR")
198
+ RC=$?
199
+ assert_exit "#57507 repro exits 0" "$RC" 0
200
+ assert_contains "#57507 repro flags memory:" "$OUT" "57507"
201
+ rm -f "$HOME_AGENTS/57507-repro.md"
202
+
203
+ # ---- Test 15: empty frontmatter block ----
204
+ printf -- '---\n---\nbody only\n' > "$HOME_AGENTS/empty-fm.md"
205
+ OUT=$(run_hook "$PROJ_DIR")
206
+ RC=$?
207
+ assert_exit "empty frontmatter exits 0" "$RC" 0
208
+ assert_contains "empty frontmatter warned" "$OUT" "empty-fm.md"
209
+ rm -f "$HOME_AGENTS/empty-fm.md"
210
+
211
+ # ---- Test 16: settings without deny → no escalation text ----
212
+ cat > "$TMPDIR/home/.claude/settings.json" <<'EOF'
213
+ {}
214
+ EOF
215
+ cat > "$HOME_AGENTS/missing-tools-2.md" <<'EOF'
216
+ ---
217
+ name: ok-name
218
+ description: missing tools
219
+ ---
220
+ Body.
221
+ EOF
222
+ OUT=$(run_hook "$PROJ_DIR")
223
+ RC=$?
224
+ assert_exit "no-deny + missing tools exits 0" "$RC" 0
225
+ assert_contains "no-deny still warns about default tool set" "$OUT" "Pin to least-privilege"
226
+ # Per-line warning should not escalate (no #57068 inline). Reference list
227
+ # at the bottom always cites both issues, so check only the issue line.
228
+ ISSUE_LINE=$(echo "$OUT" | grep "missing-tools-2.md" || true)
229
+ assert_not_contains "no-deny issue line does not cite #57068" "$ISSUE_LINE" "57068"
230
+ rm -f "$HOME_AGENTS/missing-tools-2.md"
231
+
232
+ # ---- Test 17: malformed JSON input → still scans HOME via $CLAUDE_PROJECT_DIR fallback ----
233
+ cat > "$HOME_AGENTS/needs-tools.md" <<'EOF'
234
+ ---
235
+ name: needs-tools
236
+ description: missing tools
237
+ ---
238
+ Body.
239
+ EOF
240
+ OUT=$(printf 'not-json' | HOME="$TMPDIR/home" bash "$HOOK" 2>&1)
241
+ RC=$?
242
+ assert_exit "non-json input exits 0" "$RC" 0
243
+ assert_contains "non-json input still scans home agents" "$OUT" "needs-tools.md"
244
+
245
+ # ---- Test 18: well-formed + tools list → no warning even with deny ----
246
+ rm -f "$HOME_AGENTS/needs-tools.md"
247
+ cat > "$TMPDIR/home/.claude/settings.json" <<'EOF'
248
+ {
249
+ "permissions": {
250
+ "deny": ["Read(./.env)"]
251
+ }
252
+ }
253
+ EOF
254
+ cat > "$HOME_AGENTS/scoped.md" <<'EOF'
255
+ ---
256
+ name: scoped
257
+ description: properly scoped
258
+ tools: Read, Grep, Bash
259
+ ---
260
+ Body.
261
+ EOF
262
+ OUT=$(run_hook "$PROJ_DIR")
263
+ RC=$?
264
+ assert_exit "scoped+deny exits 0" "$RC" 0
265
+ assert_not_contains "scoped+deny no warning" "$OUT" "subagent-inheritance"
266
+ rm -f "$HOME_AGENTS/scoped.md"
267
+ rm -f "$TMPDIR/home/.claude/settings.json"
268
+
269
+ # ---- Test 19: many agents, mixed states → each issue named ----
270
+ cat > "$HOME_AGENTS/good-1.md" <<'EOF'
271
+ ---
272
+ name: g1
273
+ tools: Read
274
+ ---
275
+ Body.
276
+ EOF
277
+ cat > "$HOME_AGENTS/bad-1.md" <<'EOF'
278
+ ---
279
+ name: b1
280
+ description: missing tools
281
+ ---
282
+ Body.
283
+ EOF
284
+ cat > "$HOME_AGENTS/bad-2.md" <<'EOF'
285
+ ---
286
+ name: b2
287
+ memory: legacy
288
+ tools: Read
289
+ ---
290
+ Body.
291
+ EOF
292
+ OUT=$(run_hook "$PROJ_DIR")
293
+ RC=$?
294
+ assert_exit "mixed agents exits 0" "$RC" 0
295
+ assert_contains "mixed agents flag bad-1" "$OUT" "bad-1.md"
296
+ assert_contains "mixed agents flag bad-2" "$OUT" "bad-2.md"
297
+ assert_not_contains "mixed agents skip good-1" "$OUT" "good-1.md"
298
+ rm -f "$HOME_AGENTS/good-1.md" "$HOME_AGENTS/bad-1.md" "$HOME_AGENTS/bad-2.md"
299
+
300
+ # ---- Test 20: Japanese description with English frontmatter keys ----
301
+ cat > "$HOME_AGENTS/jp.md" <<'EOF'
302
+ ---
303
+ name: jp-agent
304
+ description: 日本語の説明 — tools 列が無い
305
+ ---
306
+ 本文
307
+ EOF
308
+ OUT=$(run_hook "$PROJ_DIR")
309
+ RC=$?
310
+ assert_exit "jp agent exits 0" "$RC" 0
311
+ assert_contains "jp agent flagged" "$OUT" "jp.md"
312
+
313
+ # Cleanup
314
+ rm -rf "$TMPDIR"
315
+
316
+ echo ""
317
+ echo "PASS: $PASS"
318
+ echo "FAIL: $FAIL"
319
+ [ "$FAIL" -eq 0 ] && echo "OK" || exit 1
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-permission-mode-guard.sh (Issue #55691 prevention)
3
+ HOOK="examples/subagent-permission-mode-guard.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: No mode parameter, silent pass
11
+ OUT=$(echo '{"tool_input":{"prompt":"do something"}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_not_contains "no mode no warning" "$OUT" "Subagent permission mode"
14
+ assert_not_contains "no mode no early warn" "$OUT" "may be silently overridden"
15
+ assert_exit "no mode exit 0" "$RC" "0"
16
+
17
+ # Test 2: Mode parameter with no prompt
18
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":""}}' | bash "$HOOK" 2>&1)
19
+ RC=$?
20
+ assert_contains "empty prompt with mode warns" "$OUT" "may be silently overridden"
21
+ assert_contains "empty prompt with mode references issue" "$OUT" "#55691"
22
+ assert_exit "empty prompt with mode exit 0" "$RC" "0"
23
+
24
+ # Test 3: Mode parameter with vague prompt warns 2 items
25
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":"please investigate the auth flow"}}' | bash "$HOOK" 2>&1)
26
+ RC=$?
27
+ assert_contains "vague warns frontmatter" "$OUT" "frontmatter override risk"
28
+ assert_contains "vague warns verification" "$OUT" "verification of the actual effective mode"
29
+ assert_contains "vague references issue" "$OUT" "#55691"
30
+ assert_exit "vague exit 0 advisory" "$RC" "0"
31
+
32
+ # Test 4: Frontmatter mention only
33
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":"check if the frontmatter has permissionMode and run."}}' | bash "$HOOK" 2>&1)
34
+ assert_not_contains "frontmatter only no frontmatter warning" "$OUT" "frontmatter override risk"
35
+ assert_contains "frontmatter only warns verification" "$OUT" "verification of the actual"
36
+
37
+ # Test 5: Verification mention only
38
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":"run the task and verify the mode is active."}}' | bash "$HOOK" 2>&1)
39
+ assert_contains "verify only warns frontmatter" "$OUT" "frontmatter override risk"
40
+ assert_not_contains "verify only no verify warning" "$OUT" "verification of the actual"
41
+
42
+ # Test 6: All instructions present, no warning
43
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":"check if the frontmatter has permissionMode set, then run the task and verify the effective permission is bypassPermissions."}}' | bash "$HOOK" 2>&1)
44
+ RC=$?
45
+ assert_not_contains "well-formed no warning" "$OUT" "Subagent permission mode boundary"
46
+ assert_exit "well-formed exit 0" "$RC" "0"
47
+
48
+ # Test 7: Strict mode blocks vague
49
+ OUT=$(echo '{"tool_input":{"mode":"bypassPermissions","prompt":"investigate something"}}' | CC_SUBAGENT_MODE_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
50
+ RC=$?
51
+ assert_contains "strict mode warns" "$OUT" "Subagent permission mode boundary"
52
+ assert_exit "strict mode blocks (exit 2)" "$RC" "2"
53
+
54
+ # Test 8: Empty input, no mode
55
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
56
+ RC=$?
57
+ assert_not_contains "empty input no warning" "$OUT" "Subagent permission mode"
58
+ assert_exit "empty input exit 0" "$RC" "0"
59
+
60
+ echo "Results: $PASS passed, $FAIL failed"
61
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,60 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-spawn-verification-enforcer.sh (Issue #55666 prevention)
3
+ HOOK="examples/subagent-spawn-verification-enforcer.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: Empty prompt should silently pass
11
+ OUT=$(echo '{"tool_input":{"prompt":""}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_not_contains "empty prompt no warning" "$OUT" "Subagent output verification"
14
+ assert_exit "empty prompt exit 0" "$RC" "0"
15
+
16
+ # Test 2: Vague prompt should warn on all 3 checks
17
+ OUT=$(echo '{"tool_input":{"prompt":"please investigate the auth flow"}}' | bash "$HOOK" 2>&1)
18
+ RC=$?
19
+ assert_contains "vague warns artifact" "$OUT" "No concrete artifact"
20
+ assert_contains "vague warns verification" "$OUT" "No artifact verification"
21
+ assert_contains "vague warns recommended" "$OUT" "Recommended:"
22
+ assert_contains "vague references issue" "$OUT" "#55666"
23
+ assert_exit "vague exit 0 advisory" "$RC" "0"
24
+
25
+ # Test 3: Artifact named, other 2 missing
26
+ OUT=$(echo '{"tool_input":{"prompt":"Write to /tmp/result.txt with the analysis."}}' | bash "$HOOK" 2>&1)
27
+ assert_not_contains "artifact only no artifact warning" "$OUT" "No concrete artifact"
28
+ assert_contains "artifact only warns verification" "$OUT" "No artifact verification"
29
+
30
+ # Test 4: Verification named, other 2 missing
31
+ OUT=$(echo '{"tool_input":{"prompt":"Investigate. I will verify the result."}}' | bash "$HOOK" 2>&1)
32
+ assert_contains "verify only warns artifact" "$OUT" "No concrete artifact"
33
+ assert_not_contains "verify only no verify warning" "$OUT" "No artifact verification"
34
+
35
+ # Test 5: Distrust phrase named, other 2 missing
36
+ OUT=$(echo '{"tool_input":{"prompt":"Do something. Do not trust reply-only success."}}' | bash "$HOOK" 2>&1)
37
+ assert_contains "distrust only warns artifact" "$OUT" "No concrete artifact"
38
+ assert_contains "distrust only warns verification" "$OUT" "No artifact verification"
39
+ assert_not_contains "distrust only no recommended warning" "$OUT" "Recommended:"
40
+
41
+ # Test 6: All 3 instructions present, no warning
42
+ OUT=$(echo '{"tool_input":{"prompt":"Write to /tmp/result.txt. I will verify the file exists. Do not reply success without producing the artifact."}}' | bash "$HOOK" 2>&1)
43
+ RC=$?
44
+ assert_not_contains "well-formed no warning" "$OUT" "Subagent output verification"
45
+ assert_exit "well-formed exit 0" "$RC" "0"
46
+
47
+ # Test 7: Strict mode blocks vague prompts
48
+ OUT=$(echo '{"tool_input":{"prompt":"investigate something"}}' | CC_SUBAGENT_VERIFY_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
49
+ RC=$?
50
+ assert_contains "strict mode warns" "$OUT" "Subagent output verification"
51
+ assert_exit "strict mode blocks (exit 2)" "$RC" "2"
52
+
53
+ # Test 8: Missing prompt field should silently pass
54
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
55
+ RC=$?
56
+ assert_not_contains "missing prompt no warning" "$OUT" "Subagent output verification"
57
+ assert_exit "missing prompt exit 0" "$RC" "0"
58
+
59
+ echo "Results: $PASS passed, $FAIL failed"
60
+ [ "$FAIL" -eq 0 ]