cc-safe-setup 29.8.0 → 30.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +421 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-dispatch-watchdog.sh +149 -0
- package/examples/completion-claim-without-verification-detector.sh +207 -0
- package/examples/composer-guard.sh +12 -0
- package/examples/compound-bash-permission-resolver.sh +156 -0
- package/examples/compound-command-allow.sh +1 -1
- package/examples/compound-command-deny-enforcer.sh +183 -0
- package/examples/compound-inject-guard.sh +12 -0
- package/examples/concurrent-edit-lock.sh +12 -0
- package/examples/conflict-marker-guard.sh +12 -0
- package/examples/consecutive-error-breaker.sh +0 -0
- package/examples/console-log-count.sh +1 -0
- package/examples/context-compact-advisor.sh +29 -2
- package/examples/context-length-budget.sh +69 -0
- package/examples/context-threshold-alert.sh +12 -0
- package/examples/context-usage-drift-alert.sh +41 -13
- package/examples/conversation-history-guard.sh +12 -0
- package/examples/core-file-protect-guard.sh +12 -0
- package/examples/cors-star-warn.sh +0 -0
- package/examples/cost-incident-self-audit.sh +162 -0
- package/examples/cowork-claude-md-load-checker.sh +100 -0
- package/examples/cowork-fuse-staleness-watcher.sh +140 -0
- package/examples/cowork-hook-absence-warner.sh +167 -0
- package/examples/cowork-model-picker-advisor.sh +115 -0
- package/examples/credential-exfil-guard.sh +65 -4
- package/examples/credential-file-cat-guard.sh +17 -1
- package/examples/cron-create-receipt.sh +112 -0
- package/examples/cron-modification-guard.sh +12 -0
- package/examples/cross-product-mcp-spawn-detector.sh +178 -0
- package/examples/cwd-project-boundary-guard.sh +0 -0
- package/examples/daemon-zombie-worker-surfacer.sh +118 -0
- package/examples/daily-cost-guard.sh +164 -0
- package/examples/daily-usage-tracker.sh +0 -0
- package/examples/dangerous-pip-flag-guard.sh +12 -0
- package/examples/db-connect-guard.sh +13 -1
- package/examples/denied-action-retry-guard.sh +12 -0
- package/examples/deny-bypass-detector.sh +12 -0
- package/examples/deny-rule-integrity-verifier.sh +181 -0
- package/examples/dependency-install-guard.sh +12 -0
- package/examples/deploy-guard.sh +14 -2
- package/examples/deploy-path-verify-guard.sh +12 -0
- package/examples/deployment-readback-gate.sh +135 -0
- package/examples/deployment-readback-gh-adapter.sh +247 -0
- package/examples/deployment-verify-guard.sh +25 -2
- package/examples/destructive-db-script-write-guard.sh +166 -0
- package/examples/destructive-migration-write-guard.sh +163 -0
- package/examples/diff-size-guard.sh +12 -0
- package/examples/disabled-feature-toggle-advisor.sh +88 -0
- package/examples/disk-partition-guard.sh +12 -0
- package/examples/dispatch-allowlist-preflight.sh +301 -0
- package/examples/dispatch-liveness-watchdog.sh +216 -0
- package/examples/dispatch-receipt.sh +174 -0
- package/examples/django-migrate-guard.sh +12 -0
- package/examples/dns-config-guard.sh +12 -0
- package/examples/docker-dangerous-guard.sh +12 -0
- package/examples/docker-volume-guard.sh +0 -0
- package/examples/dockerfile-latest-guard.sh +1 -0
- package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
- package/examples/dotenv-commit-guard.sh +12 -0
- package/examples/dotenv-read-guard.sh +12 -0
- package/examples/dotfile-protection-guard.sh +12 -0
- package/examples/dotnet-build-on-edit.sh +1 -1
- package/examples/drizzle-migrate-guard.sh +27 -2
- package/examples/echo-probe-spam-detector.sh +176 -0
- package/examples/edit-counter-test-gate.sh +12 -0
- package/examples/edit-error-counter.sh +1 -1
- package/examples/edit-guard.sh +12 -0
- package/examples/edit-old-string-validator.sh +12 -0
- package/examples/edit-quote-ambiguity-guard.sh +97 -0
- package/examples/edit-retry-loop-guard.sh +0 -0
- package/examples/edit-verify.sh +0 -0
- package/examples/env-inline-secret-guard.sh +14 -2
- package/examples/env-naming-convention.sh +0 -0
- package/examples/env-prod-guard.sh +0 -0
- package/examples/env-required-check.sh +0 -0
- package/examples/env-source-guard.sh +12 -0
- package/examples/env-var-check.sh +24 -1
- package/examples/ephemeral-container-detector.sh +147 -0
- package/examples/error-memory-guard.sh +12 -0
- package/examples/evidence-claim-gate.sh +187 -0
- package/examples/exploration-budget-guard.sh +12 -0
- package/examples/expo-eject-guard.sh +13 -0
- package/examples/extended-thinking-loop-guard.sh +139 -0
- package/examples/extended-thinking-resume-warning.sh +119 -0
- package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
- package/examples/fabricated-command-detector.sh +145 -0
- package/examples/false-disk-full-guard.sh +63 -0
- package/examples/feature-deprecation-detector.sh +109 -0
- package/examples/file-change-tracker.sh +1 -1
- package/examples/file-change-undo-tracker.sh +0 -0
- package/examples/file-edit-backup.sh +63 -14
- package/examples/file-reference-check.sh +0 -0
- package/examples/file-size-limit.sh +12 -0
- package/examples/financial-operation-guard.sh +12 -0
- package/examples/firewall-guard.sh +12 -0
- package/examples/fish-shell-wrapper.sh +125 -7
- package/examples/five-hundred-milestone.sh +1 -0
- package/examples/flask-static-route-guard.sh +89 -0
- package/examples/forbidden-response-phrase-detector.sh +161 -0
- package/examples/gem-push-guard.sh +13 -0
- package/examples/gh-cli-destructive-guard.sh +13 -1
- package/examples/git-checkout-safety-guard.sh +12 -0
- package/examples/git-checkout-uncommitted-guard.sh +12 -0
- package/examples/git-config-guard.sh +12 -0
- package/examples/git-crypt-worktree-guard.sh +12 -0
- package/examples/git-filter-repo-guard.sh +56 -0
- package/examples/git-history-rewrite-guard.sh +12 -0
- package/examples/git-hook-bypass-guard.sh +0 -0
- package/examples/git-maintenance-guard.sh +83 -0
- package/examples/git-merge-conflict-prevent.sh +0 -0
- package/examples/git-message-length-check.sh +0 -0
- package/examples/git-message-length.sh +0 -0
- package/examples/git-operations-require-approval.sh +68 -14
- package/examples/git-pack-temp-cleanup-guard.sh +102 -0
- package/examples/git-push-blast-radius-guard.sh +218 -0
- package/examples/git-remote-guard.sh +24 -3
- package/examples/git-rm-orphan-wipe-guard.sh +85 -0
- package/examples/git-stash-before-checkout.sh +12 -0
- package/examples/git-stash-before-danger.sh +0 -0
- package/examples/git-submodule-guard.sh +69 -2
- package/examples/git-tag-guard.sh +12 -0
- package/examples/github-actions-secret-guard.sh +0 -0
- package/examples/gitignore-check.sh +0 -0
- package/examples/gitops-drift-guard.sh +12 -0
- package/examples/go-mod-tidy-warn.sh +1 -0
- package/examples/go-vet-after-edit.sh +12 -0
- package/examples/goal-iteration-limit-warner.sh +152 -0
- package/examples/grep-nul-false-negative-guard.sh +30 -0
- package/examples/growthbook-flag-monitor.sh +257 -0
- package/examples/hallucination-url-check.sh +1 -1
- package/examples/halt-signal-detector.sh +135 -0
- package/examples/handoff-on-clear.sh +65 -0
- package/examples/hardcoded-ip-guard.sh +1 -0
- package/examples/headless-empty-result-guard.sh +0 -0
- package/examples/headless-stop-guard.sh +0 -0
- package/examples/helm-install-guard.sh +2 -1
- package/examples/home-critical-bash-guard.sh +17 -1
- package/examples/hook-debug-wrapper.sh +6 -2
- package/examples/hook-permission-fixer.sh +0 -0
- package/examples/hook-self-disable-detector.sh +99 -0
- package/examples/hook-stdout-sanitizer.sh +6 -2
- package/examples/hook-tamper-guard.sh +12 -0
- package/examples/idle-session-cost-alert.sh +0 -0
- package/examples/image-dimension-guard.sh +109 -0
- package/examples/image-file-validator.sh +0 -0
- package/examples/iteration-quality-degradation-detector.sh +170 -0
- package/examples/java-compile-on-edit.sh +1 -1
- package/examples/json-syntax-check.sh +0 -0
- package/examples/k8s-production-guard.sh +13 -1
- package/examples/kill-process-guard.sh +12 -0
- package/examples/kubernetes-guard.sh +13 -1
- package/examples/laravel-artisan-guard.sh +13 -0
- package/examples/large-file-guard.sh +1 -1
- package/examples/log-level-guard.sh +0 -0
- package/examples/log-truncation-guard.sh +12 -0
- package/examples/long-session-malformed-tool-call-detector.sh +183 -0
- package/examples/loop-detector.sh +12 -0
- package/examples/magic-number-warn.sh +1 -0
- package/examples/main-branch-warn.sh +12 -0
- package/examples/markdown-link-check.sh +0 -0
- package/examples/max-concurrent-agents.sh +12 -0
- package/examples/max-edit-size-guard.sh +13 -0
- package/examples/max-file-count-guard.sh +0 -0
- package/examples/max-file-delete-count.sh +0 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +0 -0
- package/examples/max-subagent-count.sh +0 -0
- package/examples/mcp-config-freeze.sh +12 -0
- package/examples/mcp-config-poisoning-audit.sh +150 -0
- package/examples/mcp-data-boundary.sh +1 -1
- package/examples/mcp-misdiagnosis-arrest.sh +209 -0
- package/examples/mcp-orphan-leak-warner.sh +49 -0
- package/examples/mcp-permissions-ask-warner.sh +151 -0
- package/examples/mcp-routine-approval-detector.sh +154 -0
- package/examples/mcp-server-allowlist.sh +12 -0
- package/examples/mcp-server-guard.sh +12 -0
- package/examples/mcp-startup-bloat-detector.sh +87 -0
- package/examples/mcp-stdio-compatibility-test.sh +153 -0
- package/examples/mcp-tool-audit-log.sh +0 -0
- package/examples/mcp-tool-guard.sh +101 -1
- package/examples/mcp-warmup-wait.sh +0 -0
- package/examples/memory-chain-audit.sh +56 -0
- package/examples/memory-orphan-detector.sh +188 -0
- package/examples/memory-write-guard.sh +99 -17
- package/examples/migration-verify-guard.sh +12 -0
- package/examples/model-swap-suggester.sh +177 -0
- package/examples/model-version-alert.sh +5 -1
- package/examples/model-version-lock.sh +63 -0
- package/examples/move-delete-sequence-guard.sh +33 -2
- package/examples/multi-file-plan-routing-gate.sh +192 -0
- package/examples/multi-vendor-concurrent-warner.sh +108 -0
- package/examples/multi-window-auth-drift-detector.sh +183 -0
- package/examples/multiline-command-approver.sh +161 -23
- package/examples/nested-background-agent-guard.sh +109 -0
- package/examples/nested-spawn-inflight-guard.sh +178 -0
- package/examples/network-exfil-guard.sh +12 -0
- package/examples/network-guard.sh +12 -0
- package/examples/network-interface-guard.sh +12 -0
- package/examples/nextjs-env-guard.sh +1 -1
- package/examples/no-absolute-import.sh +0 -0
- package/examples/no-alert-confirm-prompt.sh +0 -0
- package/examples/no-anonymous-default-export.sh +0 -0
- package/examples/no-any-type.sh +0 -0
- package/examples/no-any-typescript.sh +1 -0
- package/examples/no-ask-human.sh +12 -0
- package/examples/no-assignment-in-condition.sh +0 -0
- package/examples/no-base64-exfil.sh +12 -0
- package/examples/no-callback-hell.sh +0 -0
- package/examples/no-circular-dependency.sh +0 -0
- package/examples/no-cleartext-storage.sh +0 -0
- package/examples/no-commented-code.sh +0 -0
- package/examples/no-commit-fixup.sh +0 -0
- package/examples/no-console-assert.sh +0 -0
- package/examples/no-console-error-swallow.sh +0 -0
- package/examples/no-console-in-prod.sh +0 -0
- package/examples/no-console-log-commit.sh +12 -0
- package/examples/no-console-log.sh +0 -0
- package/examples/no-console-time.sh +0 -0
- package/examples/no-cors-wildcard.sh +4 -1
- package/examples/no-curl-upload.sh +0 -0
- package/examples/no-dangerouslySetInnerHTML.sh +0 -0
- package/examples/no-dangling-await.sh +1 -0
- package/examples/no-debug-commit.sh +12 -0
- package/examples/no-debug-in-commit.sh +0 -0
- package/examples/no-deep-nesting.sh +0 -0
- package/examples/no-deep-relative-import.sh +1 -0
- package/examples/no-default-credentials.sh +0 -0
- package/examples/no-deploy-friday.sh +13 -1
- package/examples/no-disabled-test.sh +0 -0
- package/examples/no-document-write.sh +0 -0
- package/examples/no-empty-function.sh +0 -0
- package/examples/no-eval-in-template.sh +0 -0
- package/examples/no-eval-template.sh +3 -1
- package/examples/no-eval.sh +0 -0
- package/examples/no-exec-user-input.sh +0 -0
- package/examples/no-fixme-ship.sh +12 -0
- package/examples/no-floating-promises.sh +0 -0
- package/examples/no-force-flag.sh +22 -5
- package/examples/no-force-install.sh +0 -0
- package/examples/no-git-amend.sh +12 -0
- package/examples/no-git-rebase-public.sh +0 -0
- package/examples/no-global-install.sh +12 -0
- package/examples/no-global-state.sh +0 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +0 -0
- package/examples/no-helmet-missing.sh +0 -0
- package/examples/no-http-url.sh +1 -0
- package/examples/no-http-without-https.sh +0 -0
- package/examples/no-inline-style.sh +0 -0
- package/examples/no-inline-styles.sh +1 -0
- package/examples/no-innerhtml.sh +0 -0
- package/examples/no-install-global.sh +12 -0
- package/examples/no-jwt-in-url.sh +0 -0
- package/examples/no-large-commit.sh +0 -0
- package/examples/no-localhost-expose.sh +0 -0
- package/examples/no-magic-number.sh +0 -0
- package/examples/no-md5-sha1.sh +0 -0
- package/examples/no-mixed-line-endings.sh +8 -1
- package/examples/no-mutation-in-reducer.sh +0 -0
- package/examples/no-nested-ternary.sh +0 -0
- package/examples/no-network-exfil.sh +0 -0
- package/examples/no-open-redirect.sh +0 -0
- package/examples/no-output-truncation.sh +12 -0
- package/examples/no-package-downgrade.sh +0 -0
- package/examples/no-package-lock-edit.sh +12 -0
- package/examples/no-path-join-user-input.sh +0 -0
- package/examples/no-port-bind.sh +0 -0
- package/examples/no-process-exit.sh +0 -0
- package/examples/no-prototype-pollution.sh +0 -0
- package/examples/no-push-without-ci.sh +0 -0
- package/examples/no-push-without-tests.sh +12 -0
- package/examples/no-raw-password-in-url.sh +0 -0
- package/examples/no-root-user-docker.sh +1 -0
- package/examples/no-root-write.sh +12 -0
- package/examples/no-secrets-in-args.sh +4 -1
- package/examples/no-secrets-in-logs.sh +0 -0
- package/examples/no-sensitive-log.sh +0 -0
- package/examples/no-sleep-in-hooks.sh +0 -0
- package/examples/no-star-import-python.sh +1 -0
- package/examples/no-string-concat-sql.sh +0 -0
- package/examples/no-sudo-guard.sh +12 -0
- package/examples/no-sync-fs.sh +0 -0
- package/examples/no-todo-in-merge.sh +0 -0
- package/examples/no-todo-in-production.sh +1 -0
- package/examples/no-todo-without-issue.sh +0 -0
- package/examples/no-unused-import.sh +0 -0
- package/examples/no-var-keyword.sh +0 -0
- package/examples/no-verify-blocker.sh +12 -0
- package/examples/no-wget-piped-bash.sh +12 -0
- package/examples/no-wildcard-cors.sh +0 -0
- package/examples/no-wildcard-delete.sh +0 -0
- package/examples/no-wildcard-import.sh +0 -0
- package/examples/no-with-statement.sh +0 -0
- package/examples/no-write-outside-src.sh +0 -0
- package/examples/no-xml-external-entity.sh +0 -0
- package/examples/non-english-quality-warner.sh +156 -0
- package/examples/notify-waiting.sh +1 -1
- package/examples/npm-audit-warn.sh +0 -0
- package/examples/npm-global-install-guard.sh +12 -0
- package/examples/npm-publish-guard.sh +12 -0
- package/examples/npm-script-injection.sh +0 -0
- package/examples/npm-supply-chain-guard.sh +0 -0
- package/examples/nuxt-config-guard.sh +1 -0
- package/examples/oauth-refresh-monitor.sh +210 -0
- package/examples/opus-degradation-tracker.sh +187 -0
- package/examples/opus48-routine-task-warning.sh +196 -0
- package/examples/opus48-thinking-wedge-advisor.sh +143 -0
- package/examples/output-credential-scan.sh +1 -1
- package/examples/output-secret-mask.sh +31 -9
- package/examples/output-token-spike-detector.sh +145 -0
- package/examples/package-json-guard.sh +12 -0
- package/examples/package-lock-frozen.sh +12 -0
- package/examples/parallel-batch-size-limiter.sh +121 -0
- package/examples/parallel-cascade-detector.sh +116 -0
- package/examples/partial-view-claim-arrest.sh +174 -0
- package/examples/path-deny-bash-guard.sh +12 -0
- package/examples/path-traversal-guard.sh +12 -0
- package/examples/per-prompt-token-cap.sh +124 -0
- package/examples/permission-audit-log.sh +1 -1
- package/examples/permission-denial-enforcer.sh +12 -0
- package/examples/permission-entry-validator.sh +0 -0
- package/examples/persisted-1m-model-advisor.sh +88 -0
- package/examples/php-lint-on-edit.sh +1 -1
- package/examples/pii-upload-guard.sh +12 -0
- package/examples/pip-publish-guard.sh +13 -0
- package/examples/pip-requirements-guard.sh +12 -0
- package/examples/pip-venv-required.sh +12 -0
- package/examples/plan-mode-edit-guard.sh +12 -0
- package/examples/plan-mode-enforcer.sh +12 -0
- package/examples/plan-mode-strict-guard.sh +12 -0
- package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
- package/examples/plugin-process-cleanup.sh +0 -0
- package/examples/polyglot-rm-guard.sh +12 -0
- package/examples/post-compact-safety.sh +12 -0
- package/examples/post-edit-disk-verify.sh +152 -0
- package/examples/powershell-remove-item-guard.sh +85 -0
- package/examples/pr-description-check.sh +0 -0
- package/examples/pr-duplicate-guard.sh +13 -0
- package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
- package/examples/pre-compact-knowledge-save.sh +0 -0
- package/examples/pre-compact-transcript-backup.sh +0 -0
- package/examples/pre-execution-claim-detector.sh +179 -0
- package/examples/prefer-builtin-tools.sh +10 -1
- package/examples/prefer-const.sh +0 -0
- package/examples/prefer-dedicated-tools.sh +12 -0
- package/examples/prefer-optional-chaining.sh +0 -0
- package/examples/prisma-migrate-guard.sh +24 -7
- package/examples/production-port-kill-guard.sh +12 -0
- package/examples/prompt-injection-guard.sh +2 -1
- package/examples/prompt-usage-logger.sh +0 -0
- package/examples/protect-claudemd.sh +12 -0
- package/examples/protect-dotfiles.sh +12 -0
- package/examples/proxy-capture-suggester.sh +159 -0
- package/examples/public-artefact-socratic-narrowing.sh +232 -0
- package/examples/public-repo-push-guard.sh +12 -0
- package/examples/push-requires-test-pass-record.sh +0 -0
- package/examples/push-requires-test-pass.sh +12 -0
- package/examples/quota-anomaly-detector.sh +173 -0
- package/examples/quota-reset-audit.sh +58 -0
- package/examples/quoted-flag-approver.sh +99 -10
- package/examples/rails-migration-guard.sh +12 -0
- package/examples/rate-limit-guard.sh +0 -0
- package/examples/read-all-files-enforcer.sh +0 -0
- package/examples/read-budget-guard.sh +12 -0
- package/examples/read-loop-detector.sh +59 -0
- package/examples/read-once-guard.sh +96 -0
- package/examples/read-only-mode.sh +12 -0
- package/examples/readme-exists-check.sh +0 -0
- package/examples/record-read-coverage.sh +73 -0
- package/examples/redirect-fragment-warner.sh +149 -0
- package/examples/redis-flushall-guard.sh +13 -0
- package/examples/redundant-read-blocker.sh +132 -0
- package/examples/refusal-arrest-gate.sh +248 -0
- package/examples/registry-publish-guard.sh +13 -1
- package/examples/remote-control-billing-classifier.sh +135 -0
- package/examples/replace-all-guard.sh +12 -0
- package/examples/repo-visibility-guard.sh +12 -0
- package/examples/reroute-after-block-guard.sh +150 -0
- package/examples/response-budget-guard.sh +0 -0
- package/examples/resume-drift-watcher.sh +57 -0
- package/examples/rg-replace-flag-detector.sh +125 -0
- package/examples/rhetorical-verification-prompt-detector.sh +102 -0
- package/examples/ripgrep-permission-fix.sh +0 -0
- package/examples/rm-safety-net.sh +151 -8
- package/examples/role-tool-guard.sh +12 -0
- package/examples/route-handler-emptiness-gate.sh +324 -0
- package/examples/ruby-lint-on-edit.sh +1 -1
- package/examples/runtime-binary-change-detector.sh +102 -0
- package/examples/same-command-repeat-detector.sh +196 -0
- package/examples/same-correction-arrest.sh +169 -0
- package/examples/sandbox-denywrite-enforcer.sh +78 -0
- package/examples/sandbox-relative-path-audit.sh +83 -25
- package/examples/sandbox-write-verify.sh +12 -0
- package/examples/schema-migration-guard.sh +0 -0
- package/examples/scope-expansion-receipt.sh +178 -0
- package/examples/scope-guard.sh +88 -9
- package/examples/secret-file-read-guard.sh +12 -0
- package/examples/secret-file-write-guard.sh +150 -0
- package/examples/self-modify-bypass-guard.sh +0 -0
- package/examples/sensitive-file-read-guard.sh +23 -3
- package/examples/sensitive-log-guard.sh +1 -0
- package/examples/server-side-prompt-injection-detector.sh +69 -0
- package/examples/session-agent-cost-limiter.sh +12 -0
- package/examples/session-backup-on-start.sh +1 -1
- package/examples/session-cost-alert.sh +12 -0
- package/examples/session-drift-guard.sh +12 -0
- package/examples/session-duration-guard.sh +25 -2
- package/examples/session-end-logger.sh +0 -0
- package/examples/session-health-monitor.sh +0 -0
- package/examples/session-index-repair.sh +1 -1
- package/examples/session-memory-watchdog.sh +1 -0
- package/examples/session-permission-reset-guard.sh +12 -0
- package/examples/session-persistence-verifier.sh +93 -0
- package/examples/session-plugin-pin-watch.sh +68 -0
- package/examples/session-rate-monitor.sh +176 -0
- package/examples/session-resume-env-fix.sh +0 -0
- package/examples/session-start-quota-status.sh +193 -0
- package/examples/session-start-safety-check.sh +55 -3
- package/examples/session-state-saver.sh +0 -0
- package/examples/session-summary-stop.sh +1 -1
- package/examples/session-summary.sh +0 -0
- package/examples/session-token-counter.sh +1 -1
- package/examples/settings-hooks-key-restorer.sh +99 -0
- package/examples/settings-json-health-check.sh +57 -0
- package/examples/settings-json-model-guard.sh +0 -0
- package/examples/settings-regression-tester.sh +188 -0
- package/examples/shell-config-truncation-guard.sh +12 -0
- package/examples/shell-wrapper-guard.sh +12 -0
- package/examples/skill-cumulative-size-detector.sh +104 -0
- package/examples/skill-description-drop-detector.sh +148 -0
- package/examples/skill-gate.sh +0 -0
- package/examples/skill-truncation-detector.sh +154 -0
- package/examples/skills-context-recorder.sh +167 -0
- package/examples/skills-load-verifier.sh +96 -0
- package/examples/skills-settings-validator.sh +139 -0
- package/examples/sonnet-45-deprecation-helper.sh +85 -0
- package/examples/spec-file-scope-guard.sh +12 -0
- package/examples/spring-profile-guard.sh +1 -0
- package/examples/spurious-malformed-notice-detector.sh +247 -0
- package/examples/sql-bulk-delete-warn.sh +88 -0
- package/examples/sql-injection-detect.sh +0 -0
- package/examples/ssh-key-protect.sh +12 -0
- package/examples/staged-secret-scan.sh +22 -1
- package/examples/stale-temp-settings-detector.sh +86 -0
- package/examples/standing-rule-session-surfacer.sh +137 -0
- package/examples/stop-hook-sigterm-wrapper.sh +182 -0
- package/examples/stop-transcript-write-health.sh +64 -0
- package/examples/strict-allowlist.sh +57 -15
- package/examples/strip-coauthored-by.sh +50 -10
- package/examples/subagent-blast-radius-guard.sh +184 -0
- package/examples/subagent-boundary-precheck.sh +126 -0
- package/examples/subagent-budget-guard.sh +12 -0
- package/examples/subagent-claudemd-inject.sh +0 -0
- package/examples/subagent-closure-verify-gate.sh +164 -0
- package/examples/subagent-destructive-git-guard.sh +120 -0
- package/examples/subagent-error-detector.sh +0 -0
- package/examples/subagent-forged-system-reminder-guard.sh +156 -0
- package/examples/subagent-identity-leak-guard.sh +102 -0
- package/examples/subagent-identity-reassertion.sh +51 -0
- package/examples/subagent-inheritance-tester.sh +179 -0
- package/examples/subagent-permission-mode-guard.sh +110 -0
- package/examples/subagent-scope-guard.sh +12 -0
- package/examples/subagent-spawn-verification-enforcer.sh +102 -0
- package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
- package/examples/subagent-tool-call-limiter.sh +87 -15
- package/examples/subcommand-chain-guard.sh +12 -0
- package/examples/subscription-api-billing-warner.sh +160 -0
- package/examples/subscription-bypass-detector.sh +152 -0
- package/examples/svelte-lint-on-edit.sh +1 -0
- package/examples/swift-build-on-edit.sh +1 -1
- package/examples/symlink-guard.sh +27 -2
- package/examples/symlink-protect.sh +1 -0
- package/examples/system-dir-protection-guard.sh +73 -8
- package/examples/system-message-workaround.sh +38 -13
- package/examples/system-package-guard.sh +12 -0
- package/examples/systemd-service-guard.sh +12 -0
- package/examples/task-integrity-guard.sh +12 -0
- package/examples/temp-file-cleanup.sh +1 -1
- package/examples/temporal-suggestion-detector.sh +135 -0
- package/examples/terraform-guard.sh +27 -6
- package/examples/test-after-edit.sh +1 -1
- package/examples/test-before-push.sh +12 -0
- package/examples/test-coverage-reminder.sh +24 -1
- package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
- package/examples/timezone-guard.sh +0 -0
- package/examples/tmp-output-size-guard.sh +0 -0
- package/examples/todo-check.sh +1 -1
- package/examples/token-budget-guard.sh +12 -0
- package/examples/token-budget-per-task.sh +12 -0
- package/examples/token-usage-tracker.sh +7 -1
- package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
- package/examples/tokenizer-ratio-alert.sh +104 -0
- package/examples/tool-call-rate-limiter.sh +0 -0
- package/examples/tool-result-correlation-checker.sh +167 -0
- package/examples/tool-result-size-guard.sh +132 -0
- package/examples/tool-retry-budget-guard.sh +12 -0
- package/examples/transcript-contamination-detector.sh +138 -0
- package/examples/trustfall-mcp-injection-guard.sh +103 -0
- package/examples/ultrareview-large-diff-advisor.sh +184 -0
- package/examples/unbounded-output-guard.sh +94 -0
- package/examples/uncommitted-changes-stop.sh +1 -0
- package/examples/uncommitted-discard-guard.sh +23 -5
- package/examples/uncommitted-work-guard.sh +12 -0
- package/examples/usage-warn.sh +0 -0
- package/examples/user-account-guard.sh +12 -0
- package/examples/userprompt-submit-receipt.sh +123 -0
- package/examples/variable-expansion-guard.sh +12 -0
- package/examples/verify-after-publish-reminder.sh +93 -0
- package/examples/verify-before-commit.sh +12 -0
- package/examples/version-bump-detector.sh +156 -0
- package/examples/version-regression-warner.sh +144 -0
- package/examples/vue-lint-on-edit.sh +1 -0
- package/examples/warn-cron-cost-trap.sh +173 -0
- package/examples/webfetch-runaway-guard.sh +89 -0
- package/examples/wellness-break-reminder.sh +118 -0
- package/examples/windows-destructive-command-guard.sh +177 -0
- package/examples/windows-path-guard.sh +12 -0
- package/examples/windows-python-stub-detector.sh +63 -0
- package/examples/work-hours-guard.sh +12 -0
- package/examples/working-directory-fence.sh +12 -0
- package/examples/workspace-lease-guard.sh +205 -0
- package/examples/worktree-create-log.sh +1 -0
- package/examples/worktree-delete-guard.sh +12 -0
- package/examples/worktree-edit-boundary-guard.sh +127 -0
- package/examples/worktree-escape-write-guard.sh +114 -0
- package/examples/worktree-hook-linker.sh +0 -0
- package/examples/worktree-hooks-path-fix.sh +111 -0
- package/examples/worktree-parent-write-guard.sh +43 -0
- package/examples/worktree-project-unify.sh +2 -1
- package/examples/worktree-remove-uncommitted-guard.sh +13 -0
- package/examples/worktree-unmerged-guard.sh +7 -1
- package/examples/write-byte-integrity-verifier.sh +190 -0
- package/examples/write-empty-content-guard.sh +67 -0
- package/examples/write-nul-corruption-detector.sh +61 -0
- package/examples/write-overwrite-confirm.sh +160 -14
- package/examples/write-secret-guard.sh +27 -5
- package/examples/write-shrink-guard.sh +12 -0
- package/examples/write-test-ratio.sh +0 -0
- package/examples/wsl-host-disk-space-guard.sh +97 -0
- package/examples/xml-format-leak-detector.sh +266 -0
- package/examples/yaml-syntax-check.sh +12 -0
- package/hooks/hooks.json +6 -6
- package/index.mjs +1718 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-dispatch-watchdog.sh +147 -0
- package/tests/test-completion-claim-without-verification-detector.sh +326 -0
- package/tests/test-compound-bash-permission-resolver.sh +264 -0
- package/tests/test-compound-command-deny-enforcer.sh +67 -0
- package/tests/test-context-length-budget.sh +68 -0
- package/tests/test-context-usage-drift-alert.sh +52 -22
- package/tests/test-cost-incident-self-audit.sh +94 -0
- package/tests/test-cowork-claude-md-load-checker.sh +257 -0
- package/tests/test-cowork-claudemd-helper.sh +141 -0
- package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
- package/tests/test-cowork-hook-absence-warner.sh +230 -0
- package/tests/test-cowork-model-picker-advisor.sh +317 -0
- package/tests/test-credential-exfil-guard.sh +62 -0
- package/tests/test-cron-create-receipt.sh +165 -0
- package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
- package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
- package/tests/test-daily-cost-guard.sh +131 -0
- package/tests/test-deny-rule-integrity-verifier.sh +288 -0
- package/tests/test-deployment-readback-gate.sh +92 -0
- package/tests/test-deployment-readback-gh-adapter.sh +163 -0
- package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
- package/tests/test-dispatch-allowlist-preflight.sh +385 -0
- package/tests/test-dispatch-liveness-watchdog.sh +319 -0
- package/tests/test-dispatch-receipt.sh +314 -0
- package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
- package/tests/test-echo-probe-spam-detector.sh +143 -0
- package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
- package/tests/test-ephemeral-container-detector.sh +251 -0
- package/tests/test-evidence-claim-gate.sh +291 -0
- package/tests/test-extended-thinking-loop-guard.sh +289 -0
- package/tests/test-extended-thinking-resume-warning.sh +240 -0
- package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
- package/tests/test-fabricated-command-detector.sh +296 -0
- package/tests/test-false-disk-full-guard.sh +36 -0
- package/tests/test-feature-deprecation-detector.sh +117 -0
- package/tests/test-forbidden-response-phrase-detector.sh +246 -0
- package/tests/test-git-operations-require-approval.sh +53 -0
- package/tests/test-git-push-blast-radius-guard.sh +115 -0
- package/tests/test-goal-iteration-limit-warner.sh +128 -0
- package/tests/test-growthbook-flag-monitor.sh +428 -0
- package/tests/test-halt-signal-detector.sh +120 -0
- package/tests/test-hook-self-disable-detector.sh +232 -0
- package/tests/test-iteration-quality-degradation-detector.sh +244 -0
- package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
- package/tests/test-marketplace-plugins.sh +193 -0
- package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
- package/tests/test-mcp-orphan-leak-warner.sh +71 -0
- package/tests/test-mcp-permissions-ask-warner.sh +207 -0
- package/tests/test-mcp-routine-approval-detector.sh +229 -0
- package/tests/test-mcp-startup-bloat-detector.sh +141 -0
- package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
- package/tests/test-memory-chain-audit.sh +59 -0
- package/tests/test-memory-orphan-detector.sh +227 -0
- package/tests/test-model-swap-suggester.sh +368 -0
- package/tests/test-model-version-lock.sh +83 -0
- package/tests/test-multi-file-plan-routing-gate.sh +277 -0
- package/tests/test-multi-window-auth-drift-detector.sh +262 -0
- package/tests/test-nested-spawn-inflight-guard.sh +281 -0
- package/tests/test-no-force-flag.sh +49 -0
- package/tests/test-non-english-quality-warner.sh +229 -0
- package/tests/test-oauth-refresh-monitor.sh +311 -0
- package/tests/test-opus-degradation-tracker.sh +274 -0
- package/tests/test-opus48-routine-task-warning.sh +201 -0
- package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
- package/tests/test-output-token-spike-detector.sh +315 -0
- package/tests/test-parallel-batch-size-limiter.sh +228 -0
- package/tests/test-parallel-cascade-detector.sh +191 -0
- package/tests/test-partial-view-claim-arrest.sh +272 -0
- package/tests/test-per-prompt-token-cap.sh +136 -0
- package/tests/test-persisted-1m-model-advisor.sh +71 -0
- package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
- package/tests/test-post-edit-disk-verify.sh +294 -0
- package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
- package/tests/test-pre-execution-claim-detector.sh +366 -0
- package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
- package/tests/test-proxy-capture-suggester.sh +214 -0
- package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
- package/tests/test-quota-anomaly-detector.sh +321 -0
- package/tests/test-quota-reset-audit.sh +81 -0
- package/tests/test-read-loop-detector.sh +137 -0
- package/tests/test-read-once-guard.sh +85 -0
- package/tests/test-receipts-aggregate.sh +143 -0
- package/tests/test-redirect-fragment-warner.sh +130 -0
- package/tests/test-redundant-read-blocker.sh +155 -0
- package/tests/test-refusal-arrest-gate.sh +303 -0
- package/tests/test-remote-control-billing-classifier.sh +125 -0
- package/tests/test-resume-drift-watcher.sh +65 -0
- package/tests/test-rg-replace-flag-detector.sh +175 -0
- package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
- package/tests/test-rm-safety-net.sh +115 -0
- package/tests/test-route-handler-emptiness-gate.sh +300 -0
- package/tests/test-runtime-binary-change-detector.sh +196 -0
- package/tests/test-same-command-repeat-detector.sh +165 -0
- package/tests/test-same-correction-arrest.sh +165 -0
- package/tests/test-scope-expansion-receipt.sh +207 -0
- package/tests/test-server-side-prompt-injection-detector.sh +181 -0
- package/tests/test-session-persistence-verifier.sh +128 -0
- package/tests/test-session-rate-monitor.sh +284 -0
- package/tests/test-session-start-quota-status.sh +210 -0
- package/tests/test-session-start-safety-check.sh +138 -0
- package/tests/test-settings-hooks-key-restorer.sh +257 -0
- package/tests/test-settings-json-health-check.sh +70 -0
- package/tests/test-settings-regression-tester.sh +197 -0
- package/tests/test-skill-cumulative-size-detector.sh +198 -0
- package/tests/test-skill-description-drop-detector.sh +236 -0
- package/tests/test-skill-truncation-detector.sh +263 -0
- package/tests/test-skills-context-recorder.sh +329 -0
- package/tests/test-skills-load-verifier.sh +184 -0
- package/tests/test-skills-settings-validator.sh +242 -0
- package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
- package/tests/test-spurious-malformed-notice-detector.sh +290 -0
- package/tests/test-sql-bulk-delete-warn.sh +123 -0
- package/tests/test-ssh-key-protect.sh +81 -0
- package/tests/test-stale-temp-settings-detector.sh +161 -0
- package/tests/test-standing-rule-session-surfacer.sh +215 -0
- package/tests/test-starter-hooks-manifest.sh +96 -0
- package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
- package/tests/test-strict-allowlist.sh +72 -0
- package/tests/test-subagent-boundary-precheck.sh +137 -0
- package/tests/test-subagent-closure-verify-gate.sh +193 -0
- package/tests/test-subagent-destructive-git-guard.sh +86 -0
- package/tests/test-subagent-identity-leak-guard.sh +62 -0
- package/tests/test-subagent-identity-reassertion.sh +61 -0
- package/tests/test-subagent-inheritance-tester.sh +319 -0
- package/tests/test-subagent-permission-mode-guard.sh +61 -0
- package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
- package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
- package/tests/test-subagent-tool-call-limiter.sh +97 -0
- package/tests/test-subscription-api-billing-warner.sh +138 -0
- package/tests/test-subscription-bypass-detector.sh +255 -0
- package/tests/test-temporal-suggestion-detector.sh +183 -0
- package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
- package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
- package/tests/test-tokenizer-ratio-alert.sh +93 -0
- package/tests/test-tool-result-correlation-checker.sh +264 -0
- package/tests/test-tool-result-size-guard.sh +121 -0
- package/tests/test-transcript-contamination-detector.sh +264 -0
- package/tests/test-trigger-header-parsing.sh +151 -0
- package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
- package/tests/test-userprompt-submit-receipt.sh +181 -0
- package/tests/test-verify-after-publish-reminder.sh +184 -0
- package/tests/test-version-bump-detector.sh +212 -0
- package/tests/test-version-regression-warner.sh +165 -0
- package/tests/test-warn-cron-cost-trap.sh +82 -0
- package/tests/test-webfetch-runaway-guard.sh +77 -0
- package/tests/test-wellness-break-reminder.sh +138 -0
- package/tests/test-windows-destructive-command-guard.sh +169 -0
- package/tests/test-windows-python-stub-detector.sh +146 -0
- package/tests/test-worktree-edit-boundary-guard.sh +219 -0
- package/tests/test-write-byte-integrity-verifier.sh +192 -0
- package/tests/test-xml-format-leak-detector.sh +299 -0
- package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
- package/tests/workspace-lease-guard.test.sh +144 -0
- package/tests/worktree-escape-write-guard.test.sh +68 -0
- package/tests/worktree-hooks-path-fix.test.sh +181 -0
- package/tests/worktree-parent-write-guard.test.sh +51 -0
- package/tests/write-empty-content-guard.test.sh +39 -0
- package/tests/write-nul-corruption-detector.test.sh +29 -0
- package/tests/write-overwrite-unread-content.test.sh +178 -0
- package/tests/wsl-host-disk-space-guard.test.sh +55 -0
|
@@ -2,15 +2,16 @@
|
|
|
2
2
|
# block-database-wipe.sh — Block destructive database commands
|
|
3
3
|
#
|
|
4
4
|
# Prevents accidental database destruction from commands like:
|
|
5
|
-
# - Laravel: migrate:fresh, migrate:reset, db:wipe
|
|
6
|
-
# - Django: flush, sqlflush
|
|
7
|
-
# - Rails: db:drop, db:reset
|
|
5
|
+
# - Laravel: migrate:fresh, migrate:refresh, migrate:reset, db:wipe
|
|
6
|
+
# - Django: flush, sqlflush, migrate <app> zero
|
|
7
|
+
# - Rails: db:drop, db:reset, db:schema:load
|
|
8
8
|
# - Raw SQL: DROP DATABASE, TRUNCATE
|
|
9
9
|
# - Symfony/Doctrine: fixtures:load (without --append), schema:drop, database:drop
|
|
10
10
|
# - Prisma: migrate reset, db push --force-reset
|
|
11
|
+
# - TypeORM/Sequelize: schema:drop, db:drop
|
|
11
12
|
# - PostgreSQL: dropdb
|
|
12
13
|
#
|
|
13
|
-
# Born from GitHub Issues #37405, #37439, #34729, #37574
|
|
14
|
+
# Born from GitHub Issues #37405, #37439, #34729, #37574, #69059
|
|
14
15
|
#
|
|
15
16
|
# Usage: Add to settings.json as a PreToolUse hook
|
|
16
17
|
#
|
|
@@ -25,13 +26,25 @@
|
|
|
25
26
|
#
|
|
26
27
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
27
28
|
|
|
29
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
30
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
31
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
32
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
33
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
34
|
+
_nojq_warned="/tmp/cc-nojq-warned-block-database-wipe-$PPID"
|
|
35
|
+
[ -f "$_nojq_warned" ] || {
|
|
36
|
+
echo "WARNING [block-database-wipe]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
37
|
+
: > "$_nojq_warned"
|
|
38
|
+
}
|
|
39
|
+
fi
|
|
40
|
+
|
|
28
41
|
INPUT=$(cat)
|
|
29
42
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
30
43
|
|
|
31
44
|
[[ -z "$COMMAND" ]] && exit 0
|
|
32
45
|
|
|
33
46
|
# Laravel destructive commands
|
|
34
|
-
if echo "$COMMAND" | grep -qiE 'artisan\s+(migrate:fresh|migrate:reset|db:wipe|db:seed\s+--force)'; then
|
|
47
|
+
if echo "$COMMAND" | grep -qiE 'artisan\s+(migrate:fresh|migrate:refresh|migrate:reset|db:wipe|db:seed\s+--force)'; then
|
|
35
48
|
echo "BLOCKED: Destructive Laravel database command" >&2
|
|
36
49
|
echo "Command: $COMMAND" >&2
|
|
37
50
|
exit 2
|
|
@@ -39,21 +52,26 @@ fi
|
|
|
39
52
|
|
|
40
53
|
# Laravel --env flag without corresponding .env file
|
|
41
54
|
if echo "$COMMAND" | grep -qE 'artisan.*--env='; then
|
|
42
|
-
|
|
55
|
+
# -P は GNU 拡張。BSD grep では ENV_NAME が空になり、下の「.env.<名前> が無い」検査だけが
|
|
56
|
+
# 静かに消える(この入力では別の exit 2 が先に止めるので結果は変わらないが、検査は消えている)。
|
|
57
|
+
# 後読み (?<=…) の代わりに、-- 以降を切り出して前置きを落とす。
|
|
58
|
+
ENV_NAME=$(echo "$COMMAND" | grep -oE '\-\-env=[A-Za-z0-9_]+' | sed -E 's/^--env=//')
|
|
43
59
|
if [ -n "$ENV_NAME" ] && [ ! -f ".env.$ENV_NAME" ]; then
|
|
44
60
|
echo "BLOCKED: .env.$ENV_NAME does not exist. Command would fall back to .env (possibly production)" >&2
|
|
45
61
|
exit 2
|
|
46
62
|
fi
|
|
47
63
|
fi
|
|
48
64
|
|
|
49
|
-
# Django destructive commands
|
|
50
|
-
|
|
65
|
+
# Django destructive commands (flush wipes data; "migrate <app> zero" unapplies all
|
|
66
|
+
# migrations for an app, dropping its tables)
|
|
67
|
+
if echo "$COMMAND" | grep -qiE 'manage\.py\s+(flush|sqlflush)' \
|
|
68
|
+
|| echo "$COMMAND" | grep -qiE 'manage\.py\s+migrate\s+\w+\s+zero'; then
|
|
51
69
|
echo "BLOCKED: Destructive Django database command" >&2
|
|
52
70
|
exit 2
|
|
53
71
|
fi
|
|
54
72
|
|
|
55
|
-
# Rails destructive commands
|
|
56
|
-
if echo "$COMMAND" | grep -qiE 'rake\s+db:(drop|reset
|
|
73
|
+
# Rails destructive commands (db:schema:load drops and recreates every table from schema.rb)
|
|
74
|
+
if echo "$COMMAND" | grep -qiE '(rake|rails)\s+db:(drop|reset|schema:load)'; then
|
|
57
75
|
echo "BLOCKED: Destructive Rails database command" >&2
|
|
58
76
|
exit 2
|
|
59
77
|
fi
|
|
@@ -76,6 +94,13 @@ if echo "$COMMAND" | grep -qiE 'prisma\s+migrate\s+reset|prisma\s+db\s+push\s+--
|
|
|
76
94
|
exit 2
|
|
77
95
|
fi
|
|
78
96
|
|
|
97
|
+
# TypeORM / Sequelize destructive commands
|
|
98
|
+
# typeorm "schema:drop" drops the whole schema; sequelize(-cli) "db:drop" drops the database
|
|
99
|
+
if echo "$COMMAND" | grep -qiE 'typeorm\s+schema:drop|sequelize(-cli)?\s+db:drop'; then
|
|
100
|
+
echo "BLOCKED: Destructive TypeORM/Sequelize database command" >&2
|
|
101
|
+
exit 2
|
|
102
|
+
fi
|
|
103
|
+
|
|
79
104
|
# PostgreSQL CLI
|
|
80
105
|
if echo "$COMMAND" | grep -qE '^\s*dropdb\s'; then
|
|
81
106
|
echo "BLOCKED: dropdb command" >&2
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# }
|
|
16
16
|
# }
|
|
17
17
|
#
|
|
18
|
-
# TRIGGER:
|
|
18
|
+
# TRIGGER: PostToolUse MATCHER: "Bash"
|
|
19
19
|
|
|
20
20
|
INPUT=$(cat)
|
|
21
21
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
@@ -28,11 +28,16 @@ if ! echo "$COMMAND" | grep -qE 'git\s+(checkout\s+-b|branch|switch\s+-c)\s'; th
|
|
|
28
28
|
fi
|
|
29
29
|
|
|
30
30
|
# Extract branch name
|
|
31
|
-
|
|
31
|
+
# -P は GNU 拡張で、BSD grep では BRANCH が空になり、下の「空なら exit 0」で
|
|
32
|
+
# 検査そのものが消える。\K に POSIX の等価物は無いので、コマンド語から一致させて
|
|
33
|
+
# 前置きを sed で落とす。
|
|
34
|
+
BRANCH=$(echo "$COMMAND" \
|
|
35
|
+
| grep -oE '(checkout[[:space:]]+-b|branch|switch[[:space:]]+-c)[[:space:]]+[^[:space:]]+' \
|
|
36
|
+
| sed -E 's/^(checkout[[:space:]]+-b|branch|switch[[:space:]]+-c)[[:space:]]+//')
|
|
32
37
|
[[ -z "$BRANCH" ]] && exit 0
|
|
33
38
|
|
|
34
39
|
# Check for spaces or special characters
|
|
35
|
-
if echo "$BRANCH" | grep -
|
|
40
|
+
if echo "$BRANCH" | grep -qE '[^a-zA-Z0-9/_.-]'; then
|
|
36
41
|
echo "" >&2
|
|
37
42
|
echo "WARNING: Branch name contains special characters: $BRANCH" >&2
|
|
38
43
|
echo "Use only: a-z, 0-9, /, -, ., _" >&2
|
|
File without changes
|
|
@@ -29,6 +29,18 @@
|
|
|
29
29
|
#
|
|
30
30
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
31
31
|
|
|
32
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
33
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
34
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
35
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
36
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
37
|
+
_nojq_warned="/tmp/cc-nojq-warned-broad-find-guard-$PPID"
|
|
38
|
+
[ -f "$_nojq_warned" ] || {
|
|
39
|
+
echo "WARNING [broad-find-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
40
|
+
: > "$_nojq_warned"
|
|
41
|
+
}
|
|
42
|
+
fi
|
|
43
|
+
|
|
32
44
|
INPUT=$(cat)
|
|
33
45
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
34
46
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# broad-prefix-session-trap-warner.sh — Cluster 6 Axis 8
|
|
4
|
+
# Warn before a broad static `ask` rule is session-approved
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# Cluster 6 Axis 8 (surfaced 2026-05-26 via #62437).
|
|
8
|
+
#
|
|
9
|
+
# When a static ask rule like `Bash(docker --host:*)` exists in
|
|
10
|
+
# settings.json and the operator selects "Approve always for
|
|
11
|
+
# this session" on the first matching command, the matching
|
|
12
|
+
# engine caches the approval. Subsequent commands that match the
|
|
13
|
+
# SAME pattern then bypass the PreToolUse hook chain entirely —
|
|
14
|
+
# the hook's `permissionDecision: deny` output is never reached.
|
|
15
|
+
#
|
|
16
|
+
# The trap is broad-prefix session approval. A single approval
|
|
17
|
+
# of `docker --host=unix:///var/run/docker.sock ps` silently
|
|
18
|
+
# whitelists `docker --host=unix:///var/run/docker.sock rm -f *`
|
|
19
|
+
# for the rest of the session, even though a PreToolUse hook is
|
|
20
|
+
# actively trying to deny destructive `docker rm` commands.
|
|
21
|
+
#
|
|
22
|
+
# This hook fires on every PreToolUse for matching commands so
|
|
23
|
+
# that the first session-level approval is at least visible:
|
|
24
|
+
# the operator sees the trap articulated before they click
|
|
25
|
+
# "Always" and inadvertently shadow their own deny logic.
|
|
26
|
+
#
|
|
27
|
+
# DETECTION:
|
|
28
|
+
# PreToolUse on Bash. For each Bash command, check if it matches
|
|
29
|
+
# any configured broad-prefix pattern. A broad prefix is one
|
|
30
|
+
# where the same root command can introduce both safe and
|
|
31
|
+
# destructive subcommands (docker, gcloud, aws, kubectl, helm,
|
|
32
|
+
# terraform, rm -rf, dd, mkfs). If matched, advise the operator
|
|
33
|
+
# to use "Approve once" rather than "Approve always for this
|
|
34
|
+
# session".
|
|
35
|
+
#
|
|
36
|
+
# OUTPUT:
|
|
37
|
+
# stderr advisory naming the matched prefix and the deny-bypass
|
|
38
|
+
# trap, plus a JSON additionalContext block summarising the same
|
|
39
|
+
# for the model. Exit 0 always (advisory, not blocking) so the
|
|
40
|
+
# permission gate still owns the actual decision.
|
|
41
|
+
#
|
|
42
|
+
# CONFIGURATION:
|
|
43
|
+
# CC_BROAD_PREFIX_PATTERNS — colon-separated grep -E patterns
|
|
44
|
+
# matched against the Bash command.
|
|
45
|
+
# Default covers common broad-prefix
|
|
46
|
+
# admin tools.
|
|
47
|
+
# CC_BROAD_PREFIX_DISABLE — set to 1 to suppress entirely
|
|
48
|
+
# (operator already aware of trap).
|
|
49
|
+
# CC_BROAD_PREFIX_SILENT — set to 1 to skip JSON output but
|
|
50
|
+
# still emit stderr advisory.
|
|
51
|
+
#
|
|
52
|
+
# RELATED ISSUES:
|
|
53
|
+
# https://github.com/anthropics/claude-code/issues/62437
|
|
54
|
+
# https://github.com/anthropics/claude-code/issues/30519 (meta)
|
|
55
|
+
# https://github.com/anthropics/claude-code/issues/39523 (meta)
|
|
56
|
+
#
|
|
57
|
+
# TRIGGER: PreToolUse
|
|
58
|
+
# MATCHER: "Bash"
|
|
59
|
+
# ================================================================
|
|
60
|
+
|
|
61
|
+
set -u
|
|
62
|
+
|
|
63
|
+
INPUT=$(cat 2>/dev/null || echo "{}")
|
|
64
|
+
|
|
65
|
+
[ "${CC_BROAD_PREFIX_DISABLE:-0}" = "1" ] && exit 0
|
|
66
|
+
|
|
67
|
+
# Default broad prefixes. The principle: the same root command can
|
|
68
|
+
# introduce a safe read-only invocation OR a destructive one, so
|
|
69
|
+
# session-wide approval of the prefix is the trap.
|
|
70
|
+
DEFAULT_PATTERNS='docker( |$):gcloud( |$):aws( |$):kubectl( |$):helm( |$):terraform( |$):rm +-[rRf]:dd( |$):mkfs'
|
|
71
|
+
PATTERNS="${CC_BROAD_PREFIX_PATTERNS:-$DEFAULT_PATTERNS}"
|
|
72
|
+
|
|
73
|
+
COMMAND=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
74
|
+
[ -z "$COMMAND" ] && exit 0
|
|
75
|
+
|
|
76
|
+
MATCHED_PATTERN=""
|
|
77
|
+
IFS=':' read -ra PATTERN_ARR <<< "$PATTERNS"
|
|
78
|
+
for pat in "${PATTERN_ARR[@]}"; do
|
|
79
|
+
[ -z "$pat" ] && continue
|
|
80
|
+
if printf '%s' "$COMMAND" | grep -qE "$pat"; then
|
|
81
|
+
MATCHED_PATTERN="$pat"
|
|
82
|
+
break
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
86
|
+
[ -z "$MATCHED_PATTERN" ] && exit 0
|
|
87
|
+
|
|
88
|
+
MSG="broad-prefix command detected: '$MATCHED_PATTERN' matches this command. Cluster 6 Axis 8 trap (#62437): if you select 'Approve always for this session' on the upcoming prompt, the matching engine caches the approval for the prefix — and subsequent commands matching the same prefix will bypass the PreToolUse hook chain entirely (your hook's permissionDecision: deny will never fire).
|
|
89
|
+
|
|
90
|
+
Recommendation: select 'Approve once' for this invocation. Reserve 'Always' for narrow, fully-qualified commands (not broad prefixes like '$MATCHED_PATTERN').
|
|
91
|
+
|
|
92
|
+
Trap mechanics: a session approval of 'docker ps' silently whitelists 'docker rm -f *' for the rest of the session even if a PreToolUse hook is actively denying destructive docker subcommands. Related: meta-issue #30519, bypass-mode meta #39523."
|
|
93
|
+
|
|
94
|
+
echo "[broad-prefix-session-trap-warner] $MSG" >&2
|
|
95
|
+
|
|
96
|
+
if [ "${CC_BROAD_PREFIX_SILENT:-0}" != "1" ]; then
|
|
97
|
+
jq -n --arg msg "$MSG" '
|
|
98
|
+
{
|
|
99
|
+
"hookSpecificOutput": {
|
|
100
|
+
"hookEventName": "PreToolUse",
|
|
101
|
+
"additionalContext": $msg
|
|
102
|
+
}
|
|
103
|
+
}' 2>/dev/null || true
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
exit 0
|
|
@@ -17,6 +17,18 @@
|
|
|
17
17
|
#
|
|
18
18
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
19
19
|
|
|
20
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
21
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
22
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
23
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
24
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
25
|
+
_nojq_warned="/tmp/cc-nojq-warned-bulk-file-delete-guard-$PPID"
|
|
26
|
+
[ -f "$_nojq_warned" ] || {
|
|
27
|
+
echo "WARNING [bulk-file-delete-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
28
|
+
: > "$_nojq_warned"
|
|
29
|
+
}
|
|
30
|
+
fi
|
|
31
|
+
|
|
20
32
|
INPUT=$(cat)
|
|
21
33
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
22
34
|
[[ -z "$COMMAND" ]] && exit 0
|
|
@@ -27,22 +39,55 @@ THRESHOLD=10
|
|
|
27
39
|
IS_BULK=0
|
|
28
40
|
TARGET=""
|
|
29
41
|
|
|
42
|
+
# Normalise a target so it can actually be counted.
|
|
43
|
+
# Measured 2026-09-18: the same 25-file directory was let through when the path
|
|
44
|
+
# was quoted, reached via `cd`, or written as a glob - only a bare absolute path
|
|
45
|
+
# was blocked. Every one of those is an ordinary way to write the command, so the
|
|
46
|
+
# guard was warning instead of blocking on the shapes people use most.
|
|
47
|
+
resolve_target() {
|
|
48
|
+
local t="$1"
|
|
49
|
+
# Strip surrounding quotes - the counting test below is a literal -d check
|
|
50
|
+
t="${t%\"}"; t="${t#\"}"
|
|
51
|
+
t="${t%\'}"; t="${t#\'}"
|
|
52
|
+
# `cd <dir> && rm -rf <name>`: count relative to the directory we cd into
|
|
53
|
+
if [[ "$t" != /* ]]; then
|
|
54
|
+
local cd_dir
|
|
55
|
+
cd_dir=$(echo "$COMMAND" | grep -oE '^[[:space:]]*cd[[:space:]]+[^&;|]+' | sed 's/^[[:space:]]*cd[[:space:]]\+//')
|
|
56
|
+
# Trim trailing whitespace BEFORE unquoting - `cd "dir" && rm -rf x`
|
|
57
|
+
# leaves a space after the closing quote, and stripping quotes first
|
|
58
|
+
# then silently does nothing (measured 2026-09-18).
|
|
59
|
+
cd_dir="${cd_dir%"${cd_dir##*[![:space:]]}"}"
|
|
60
|
+
cd_dir="${cd_dir%\"}"; cd_dir="${cd_dir#\"}"
|
|
61
|
+
cd_dir="${cd_dir%\'}"; cd_dir="${cd_dir#\'}"
|
|
62
|
+
[[ -n "$cd_dir" ]] && t="${cd_dir%/}/$t"
|
|
63
|
+
fi
|
|
64
|
+
# A trailing glob still names a real parent - count that instead
|
|
65
|
+
if [[ "$t" == *[\*\?]* ]]; then
|
|
66
|
+
local parent="${t%/*}"
|
|
67
|
+
[[ "$parent" != "$t" ]] && t="$parent"
|
|
68
|
+
fi
|
|
69
|
+
printf '%s' "${t%/}"
|
|
70
|
+
}
|
|
71
|
+
|
|
30
72
|
# rm -rf / rm -r with wildcards or broad directory paths
|
|
31
73
|
if echo "$COMMAND" | grep -qE 'rm\s+(-[a-zA-Z]*r[a-zA-Z]*f?|(-[a-zA-Z]*f[a-zA-Z]*r))\s'; then
|
|
32
74
|
# Extract the target path
|
|
33
75
|
TARGET=$(echo "$COMMAND" | grep -oE 'rm\s+-[a-zA-Z]+\s+(.+)' | sed 's/rm\s\+-[a-zA-Z]\+\s\+//')
|
|
76
|
+
TARGET=$(resolve_target "$TARGET")
|
|
34
77
|
IS_BULK=1
|
|
35
78
|
fi
|
|
36
79
|
|
|
37
80
|
# find ... -delete
|
|
38
81
|
if echo "$COMMAND" | grep -qE 'find\s+.*-delete'; then
|
|
39
82
|
TARGET=$(echo "$COMMAND" | grep -oE 'find\s+(\S+)' | sed 's/find\s\+//')
|
|
83
|
+
TARGET=$(resolve_target "$TARGET")
|
|
40
84
|
IS_BULK=1
|
|
41
85
|
fi
|
|
42
86
|
|
|
43
87
|
# find ... -exec rm
|
|
44
88
|
if echo "$COMMAND" | grep -qE 'find\s+.*-exec\s+rm'; then
|
|
45
89
|
TARGET=$(echo "$COMMAND" | grep -oE 'find\s+(\S+)' | sed 's/find\s\+//')
|
|
90
|
+
TARGET=$(resolve_target "$TARGET")
|
|
46
91
|
IS_BULK=1
|
|
47
92
|
fi
|
|
48
93
|
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# bypass-mode-effective-verifier.sh — Warn when bypass mode is actually in effect
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# This hook reports at session start via hookSpecificOutput /
|
|
7
|
+
# additionalContext. Without the TRIGGER header below, the
|
|
8
|
+
# installer registered it under the default PreToolUse/Bash,
|
|
9
|
+
# so it fired on every Bash call and never ran at session start.
|
|
10
|
+
#
|
|
11
|
+
# TRIGGER: SessionStart
|
|
12
|
+
# MATCHER: ""
|
|
13
|
+
# ================================================================
|
|
14
|
+
|
|
15
|
+
# ================================================================
|
|
16
|
+
# bypass-mode-effective-verifier.sh — Warn about partial bypass-mode
|
|
17
|
+
# coverage when --dangerously-skip-permissions is active
|
|
18
|
+
# ================================================================
|
|
19
|
+
# PURPOSE:
|
|
20
|
+
# Cluster 6 Axis 7. The --dangerously-skip-permissions flag
|
|
21
|
+
# (a.k.a. "bypass mode") does NOT bypass every permission gate
|
|
22
|
+
# the way operators expect. Documented exceptions and known bugs:
|
|
23
|
+
# - Edit tool prompts still fire (#36192)
|
|
24
|
+
# - Cowork scheduled tasks ignore "Always allow" rules and
|
|
25
|
+
# re-prompt every run (#47180)
|
|
26
|
+
# - Mobile Remote Control shows permission prompts despite the
|
|
27
|
+
# flag being set (#29214, 71 reactions)
|
|
28
|
+
# - The flag itself stopped working entirely after v2.1.77
|
|
29
|
+
# (#36168, 63 reactions, regression open as of v2.1.150)
|
|
30
|
+
# Meta-issue #39523 tracks the regression with 12+ duplicates
|
|
31
|
+
# over 9 months.
|
|
32
|
+
#
|
|
33
|
+
# The reverse case, added 2026-08-11 from a first-hand test on
|
|
34
|
+
# 2.1.226: crossSessionInbound. The changelog says inbound peer
|
|
35
|
+
# messages are held for approval when permissions are bypassed.
|
|
36
|
+
# Measured here, with the setting unset they were delivered and
|
|
37
|
+
# acted on with no dialog; setting it to "refuse" blocked them.
|
|
38
|
+
# So this is a gate operators believe the default gives them and
|
|
39
|
+
# it did not. The hook flags it when bypass is active and the
|
|
40
|
+
# setting is absent. See SETTINGS_REFERENCE.md for the four-row
|
|
41
|
+
# measurement table.
|
|
42
|
+
#
|
|
43
|
+
# Operators run with --dangerously-skip-permissions expecting
|
|
44
|
+
# "no prompts at all" and only discover the partial coverage
|
|
45
|
+
# when something they assumed was bypassed surfaces a prompt
|
|
46
|
+
# anyway, mid-task. The hook makes the partial coverage legible
|
|
47
|
+
# at session start so the operator can plan accordingly.
|
|
48
|
+
#
|
|
49
|
+
# DETECTION:
|
|
50
|
+
# At SessionStart, detect bypass mode via three signals:
|
|
51
|
+
# 1. env var CLAUDE_PERMISSION_MODE = "bypassPermissions"
|
|
52
|
+
# 2. env var CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS = "1"/"true"
|
|
53
|
+
# 3. permission_mode field in the hook input JSON
|
|
54
|
+
# If any signal indicates bypass mode is active, emit the warning.
|
|
55
|
+
#
|
|
56
|
+
# OUTPUT:
|
|
57
|
+
# hookSpecificOutput.additionalContext naming the four known
|
|
58
|
+
# tool surfaces that the bypass does NOT cover, with issue links
|
|
59
|
+
# so the operator can verify the current upstream state. Kept
|
|
60
|
+
# short to minimize cache_creation tokens at session start
|
|
61
|
+
# (Cluster 4 — Pro Max quota anomaly — interaction).
|
|
62
|
+
#
|
|
63
|
+
# CONFIGURATION:
|
|
64
|
+
# CC_BYPASS_VERIFIER_DISABLE — set to 1 to suppress the warning
|
|
65
|
+
# entirely (operator already aware).
|
|
66
|
+
# CC_BYPASS_VERIFIER_SILENT — set to 1 to skip JSON output but
|
|
67
|
+
# still emit stderr advisory.
|
|
68
|
+
#
|
|
69
|
+
# RELATED ISSUES:
|
|
70
|
+
# https://github.com/anthropics/claude-code/issues/29214
|
|
71
|
+
# https://github.com/anthropics/claude-code/issues/36168
|
|
72
|
+
# https://github.com/anthropics/claude-code/issues/36192
|
|
73
|
+
# https://github.com/anthropics/claude-code/issues/39523
|
|
74
|
+
# https://github.com/anthropics/claude-code/issues/47180
|
|
75
|
+
# ================================================================
|
|
76
|
+
|
|
77
|
+
set -u
|
|
78
|
+
|
|
79
|
+
INPUT=$(cat 2>/dev/null || echo "{}")
|
|
80
|
+
|
|
81
|
+
# Allow operator to disable without removing the hook.
|
|
82
|
+
[ "${CC_BYPASS_VERIFIER_DISABLE:-0}" = "1" ] && exit 0
|
|
83
|
+
|
|
84
|
+
# Detect bypass mode via three independent signals.
|
|
85
|
+
BYPASS_ACTIVE=0
|
|
86
|
+
BYPASS_SIGNAL=""
|
|
87
|
+
|
|
88
|
+
# Signal 1: env var CLAUDE_PERMISSION_MODE
|
|
89
|
+
if [ "${CLAUDE_PERMISSION_MODE:-}" = "bypassPermissions" ]; then
|
|
90
|
+
BYPASS_ACTIVE=1
|
|
91
|
+
BYPASS_SIGNAL="CLAUDE_PERMISSION_MODE=bypassPermissions"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Signal 2: env var CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS
|
|
95
|
+
case "${CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS:-}" in
|
|
96
|
+
1|true|TRUE|True|yes|YES)
|
|
97
|
+
BYPASS_ACTIVE=1
|
|
98
|
+
BYPASS_SIGNAL="CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS=${CLAUDE_DANGEROUSLY_SKIP_PERMISSIONS}"
|
|
99
|
+
;;
|
|
100
|
+
esac
|
|
101
|
+
|
|
102
|
+
# Signal 3: permission_mode field in the hook input JSON
|
|
103
|
+
INPUT_MODE=$(printf '%s' "$INPUT" | jq -r '.permission_mode // .permissionMode // empty' 2>/dev/null)
|
|
104
|
+
if [ "$INPUT_MODE" = "bypassPermissions" ]; then
|
|
105
|
+
BYPASS_ACTIVE=1
|
|
106
|
+
BYPASS_SIGNAL="hook input permission_mode=bypassPermissions"
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
# Signal 4: settings.json. Env vars and hook input miss the case where bypass is
|
|
110
|
+
# set as the *saved default* (#65848): accepting the warning prompt silently writes
|
|
111
|
+
# `defaultMode: bypassPermissions` and `skipDangerousModePermissionPrompt: true` to
|
|
112
|
+
# settings.json permanently, and the upstream prompt never reappears — so the operator
|
|
113
|
+
# loses the per-session awareness that they are in dangerous mode at all. Read the
|
|
114
|
+
# settings file directly so a silently-persisted default is still surfaced each session.
|
|
115
|
+
# CC_BYPASS_VERIFIER_SETTINGS overrides the path (used by tests).
|
|
116
|
+
SETTINGS_FILE="${CC_BYPASS_VERIFIER_SETTINGS:-$HOME/.claude/settings.json}"
|
|
117
|
+
SKIP_PROMPT_PERSISTED=0
|
|
118
|
+
if [ -f "$SETTINGS_FILE" ]; then
|
|
119
|
+
SETTINGS_MODE=$(jq -r '.permissions.defaultMode // empty' "$SETTINGS_FILE" 2>/dev/null)
|
|
120
|
+
if [ "$SETTINGS_MODE" = "bypassPermissions" ]; then
|
|
121
|
+
BYPASS_ACTIVE=1
|
|
122
|
+
[ -z "$BYPASS_SIGNAL" ] && BYPASS_SIGNAL="settings.json permissions.defaultMode=bypassPermissions"
|
|
123
|
+
fi
|
|
124
|
+
SKIP_PROMPT=$(jq -r '.skipDangerousModePermissionPrompt // empty' "$SETTINGS_FILE" 2>/dev/null)
|
|
125
|
+
case "$SKIP_PROMPT" in 1|true|TRUE|True|yes|YES) SKIP_PROMPT_PERSISTED=1 ;; esac
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
# Cross-session inbound messages (2.1.224+). This is the reverse of the cases above: not a
|
|
129
|
+
# gate that survives bypass unexpectedly, but a gate operators believe they have and do not.
|
|
130
|
+
#
|
|
131
|
+
# Measured 2026-08-11 on 2.1.226 (Linux/WSL2), receiver under --dangerously-skip-permissions
|
|
132
|
+
# with `crossSessionInbound` absent from every settings file: SendMessage from another session
|
|
133
|
+
# was DELIVERED with no approval dialog and no hold — from a bypass-class sender and from a
|
|
134
|
+
# prompting-class sender alike — and the receiver acted on the content unattended. Setting
|
|
135
|
+
# `crossSessionInbound: "refuse"` on the receiver blocked delivery under the identical
|
|
136
|
+
# procedure, so the gate itself works; the default is what does not gate. The changelog
|
|
137
|
+
# wording ("held for your approval" when permissions are bypassed) did not reproduce here.
|
|
138
|
+
#
|
|
139
|
+
# An explicit value is resolved before any mode-based default, so setting it always wins.
|
|
140
|
+
# Only the user settings file is inspected: a value in settings.local.json or a project file
|
|
141
|
+
# would also count, so this is a prompt to check, not a verdict.
|
|
142
|
+
CSI_UNSET=0
|
|
143
|
+
if [ "$BYPASS_ACTIVE" = "1" ]; then
|
|
144
|
+
CSI_VALUE=""
|
|
145
|
+
if [ -f "$SETTINGS_FILE" ]; then
|
|
146
|
+
CSI_VALUE=$(jq -r '.crossSessionInbound // empty' "$SETTINGS_FILE" 2>/dev/null)
|
|
147
|
+
fi
|
|
148
|
+
[ -z "$CSI_VALUE" ] && CSI_UNSET=1
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Nothing to warn about if bypass isn't active AND the dangerous-mode prompt
|
|
152
|
+
# has not been silently suppressed.
|
|
153
|
+
[ "$BYPASS_ACTIVE" = "0" ] && [ "$SKIP_PROMPT_PERSISTED" = "0" ] && exit 0
|
|
154
|
+
|
|
155
|
+
# The standing note about the silently-persisted dangerous-mode prompt (#65848).
|
|
156
|
+
# Accepting the bypass warning writes `skipDangerousModePermissionPrompt: true` to
|
|
157
|
+
# settings.json permanently with no disclosure, so Claude Code never re-warns. The
|
|
158
|
+
# hook re-surfaces that suppressed awareness each session.
|
|
159
|
+
SKIP_NOTE=""
|
|
160
|
+
if [ "$SKIP_PROMPT_PERSISTED" = "1" ]; then
|
|
161
|
+
SKIP_NOTE="
|
|
162
|
+
- skipDangerousModePermissionPrompt=true is set in settings.json: the upstream dangerous-mode warning is silently suppressed on this machine (#65848). Claude Code will not re-warn you when entering bypass mode. Remove that key to restore the prompt, or keep this hook as the standing warning."
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Cross-session inbound is unset while bypass is active: peer messages arrive ungated.
|
|
166
|
+
CSI_NOTE=""
|
|
167
|
+
if [ "$CSI_UNSET" = "1" ]; then
|
|
168
|
+
CSI_NOTE="
|
|
169
|
+
- crossSessionInbound is not set in settings.json. Measured on 2.1.226: under bypass, SendMessage from your other sessions was delivered with no approval dialog and acted on, and \"refuse\" blocked it under the identical test. If nobody is watching this session, set \"refuse\" (opt out) or \"hold\" (park for review; note held messages expire on overflow and at shutdown). Check settings.local.json and project settings too — a value there also counts."
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
# Build the warning message. Kept compact to minimize cache_creation
|
|
173
|
+
# token growth at session start.
|
|
174
|
+
if [ "$BYPASS_ACTIVE" = "1" ]; then
|
|
175
|
+
MSG="bypass mode ACTIVE ($BYPASS_SIGNAL). --dangerously-skip-permissions does NOT cover every permission gate. Known exceptions in cc-safe-setup Cluster 6 Axis 7 tracking:
|
|
176
|
+
|
|
177
|
+
- Edit tool still prompts (#36192)
|
|
178
|
+
- Cowork scheduled tasks re-prompt every run (#47180)
|
|
179
|
+
- Mobile Remote Control shows prompts (#29214)
|
|
180
|
+
- Bypass flag itself broken after v2.1.77 (#36168, regression open)${SKIP_NOTE}${CSI_NOTE}
|
|
181
|
+
|
|
182
|
+
If you depend on bypass for unattended runs (cron, watchdog, automation), test the specific tool surfaces you use BEFORE the run, not during. Tracking meta-issue: #39523 (12+ duplicates over 9 months)."
|
|
183
|
+
else
|
|
184
|
+
# Bypass is not currently the active mode, but the dangerous-mode warning has been
|
|
185
|
+
# permanently suppressed — surface that disabled guardrail on its own (#65848).
|
|
186
|
+
MSG="dangerous-mode warning SUPPRESSED.${SKIP_NOTE}"
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
# Always echo to stderr for operator visibility.
|
|
190
|
+
echo "[bypass-mode-effective-verifier] $MSG" >&2
|
|
191
|
+
|
|
192
|
+
# Emit JSON additionalContext unless silent mode is requested.
|
|
193
|
+
if [ "${CC_BYPASS_VERIFIER_SILENT:-0}" != "1" ]; then
|
|
194
|
+
jq -n --arg msg "$MSG" '
|
|
195
|
+
{
|
|
196
|
+
"hookSpecificOutput": {
|
|
197
|
+
"hookEventName": "SessionStart",
|
|
198
|
+
"additionalContext": $msg
|
|
199
|
+
}
|
|
200
|
+
}' 2>/dev/null || true
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
exit 0
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# cache-creation-drift-detector.sh — alert when per-request cache_creation drifts above baseline
|
|
3
|
+
#
|
|
4
|
+
# Why: Issue #46917 documents that Claude Code v2.1.100+ inflates
|
|
5
|
+
# cache_creation_input_tokens by ~20K vs v2.1.98 on the SAME payload, server-side.
|
|
6
|
+
# This is the load-bearing reproduction in a ~2,200-reaction Pro Max quota
|
|
7
|
+
# anomaly cluster (#16157 / #38335 / #46917 / #45756 / #29579 / #41788 / #13585
|
|
8
|
+
# / #23706 / #16856 / #19673). Four issues name a runtime version or date
|
|
9
|
+
# boundary (2026-03-23 / v2.1.89 / v2.1.100 / 2.1.1), so the inflation is
|
|
10
|
+
# version-correlated and operator-side measurable.
|
|
11
|
+
#
|
|
12
|
+
# The existing cache-tier-logger.sh logs every event but never computes
|
|
13
|
+
# drift — operators have to write awk pipelines to spot the regression.
|
|
14
|
+
# This hook does the drift computation inline and surfaces a one-line
|
|
15
|
+
# stderr warning when the current request's cache_creation exceeds the
|
|
16
|
+
# trailing-window mean by a configurable multiplier.
|
|
17
|
+
#
|
|
18
|
+
# Event: PostToolUse MATCHER: "" (all tools)
|
|
19
|
+
# Action: Read cache_creation_input_tokens from the PostToolUse payload (or the
|
|
20
|
+
# last assistant turn in the transcript as fallback). Append to a rolling
|
|
21
|
+
# JSONL log. Compute the mean of the last N nonzero samples. If the
|
|
22
|
+
# current value exceeds threshold * mean, emit a warning to stderr.
|
|
23
|
+
# Advisory only (exit 0); does not block.
|
|
24
|
+
#
|
|
25
|
+
# Configuration (all optional):
|
|
26
|
+
# CC_CACHE_DRIFT_LOG Log path (default: ~/.cache/cc-safe-setup/cache-creation-drift.jsonl)
|
|
27
|
+
# CC_CACHE_DRIFT_THRESHOLD Multiplier for alert (default: 1.25 = 25% above mean)
|
|
28
|
+
# CC_CACHE_DRIFT_MIN_HISTORY Minimum samples before alerting (default: 20)
|
|
29
|
+
# CC_CACHE_DRIFT_WINDOW Trailing window size for mean (default: 200 samples)
|
|
30
|
+
# CC_CACHE_DRIFT_SILENT Set to "1" to suppress stderr (still logs)
|
|
31
|
+
#
|
|
32
|
+
# Inspect the log:
|
|
33
|
+
# tail -50 ~/.cache/cc-safe-setup/cache-creation-drift.jsonl
|
|
34
|
+
# jq -s 'map(.cc_tokens) | add / length' ~/.cache/cc-safe-setup/cache-creation-drift.jsonl
|
|
35
|
+
#
|
|
36
|
+
# The registration was missing from this header. The installer reads TRIGGER
|
|
37
|
+
# and MATCHER from here and falls back to PreToolUse / Bash when both are
|
|
38
|
+
# absent, so this hook was being registered at a moment where the field it
|
|
39
|
+
# reads is always empty: it installed, it appeared in the settings, and it
|
|
40
|
+
# did nothing. Measured 2026-08-04 across examples/: 14 files were like this.
|
|
41
|
+
# TRIGGER: PostToolUse
|
|
42
|
+
# MATCHER: ""
|
|
43
|
+
|
|
44
|
+
set -u
|
|
45
|
+
|
|
46
|
+
LOG="${CC_CACHE_DRIFT_LOG:-${HOME}/.cache/cc-safe-setup/cache-creation-drift.jsonl}"
|
|
47
|
+
THRESHOLD="${CC_CACHE_DRIFT_THRESHOLD:-1.25}"
|
|
48
|
+
MIN_HISTORY="${CC_CACHE_DRIFT_MIN_HISTORY:-20}"
|
|
49
|
+
WINDOW="${CC_CACHE_DRIFT_WINDOW:-200}"
|
|
50
|
+
SILENT="${CC_CACHE_DRIFT_SILENT:-0}"
|
|
51
|
+
|
|
52
|
+
mkdir -p "$(dirname "$LOG")" 2>/dev/null
|
|
53
|
+
|
|
54
|
+
INPUT=$(cat)
|
|
55
|
+
|
|
56
|
+
# Extract cache_creation from the PostToolUse payload (path varies by tool).
|
|
57
|
+
CC_TOKENS=$(printf '%s' "$INPUT" | jq -r '.tool_response.usage.cache_creation_input_tokens // empty' 2>/dev/null)
|
|
58
|
+
|
|
59
|
+
# Fallback: read the last assistant turn's usage from the transcript.
|
|
60
|
+
if [ -z "$CC_TOKENS" ]; then
|
|
61
|
+
TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
62
|
+
if [ -n "$TRANSCRIPT" ] && [ -r "$TRANSCRIPT" ]; then
|
|
63
|
+
LAST_USAGE=$(tac "$TRANSCRIPT" 2>/dev/null | grep -m1 '"usage"' || true)
|
|
64
|
+
if [ -n "$LAST_USAGE" ]; then
|
|
65
|
+
CC_TOKENS=$(printf '%s' "$LAST_USAGE" | \
|
|
66
|
+
jq -r '.message.usage.cache_creation_input_tokens // .usage.cache_creation_input_tokens // empty' 2>/dev/null)
|
|
67
|
+
fi
|
|
68
|
+
fi
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# No usable measurement — exit quietly (this is the common case for many tools).
|
|
72
|
+
if [ -z "$CC_TOKENS" ] || [ "$CC_TOKENS" = "0" ] || [ "$CC_TOKENS" = "null" ]; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Validate the value is a positive integer.
|
|
77
|
+
case "$CC_TOKENS" in
|
|
78
|
+
''|*[!0-9]*) exit 0 ;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
|
|
82
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
83
|
+
|
|
84
|
+
# Append this sample to the rolling log as a JSONL line.
|
|
85
|
+
printf '{"ts":"%s","session":"%s","cc_tokens":%s}\n' "$TS" "$SESSION_ID" "$CC_TOKENS" >> "$LOG"
|
|
86
|
+
|
|
87
|
+
# How many historical samples do we have so far? (Includes the line we just appended.)
|
|
88
|
+
SAMPLE_COUNT=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ')
|
|
89
|
+
SAMPLE_COUNT="${SAMPLE_COUNT:-0}"
|
|
90
|
+
|
|
91
|
+
# Need at least MIN_HISTORY samples before we trust the baseline.
|
|
92
|
+
if [ "$SAMPLE_COUNT" -lt "$MIN_HISTORY" ]; then
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Compute the mean of the trailing window (excluding the just-written sample).
|
|
97
|
+
# We exclude the current sample so the alert compares "this" against "the past".
|
|
98
|
+
TAIL_LINES=$((WINDOW + 1))
|
|
99
|
+
MEAN=$(tail -n "$TAIL_LINES" "$LOG" 2>/dev/null | head -n -1 | \
|
|
100
|
+
jq -s 'if length > 0 then (map(.cc_tokens) | add / length) else 0 end' 2>/dev/null)
|
|
101
|
+
|
|
102
|
+
# If the baseline mean is invalid or zero, skip (defensive).
|
|
103
|
+
if [ -z "$MEAN" ] || [ "$MEAN" = "0" ] || [ "$MEAN" = "null" ]; then
|
|
104
|
+
exit 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Compute ratio = CC_TOKENS / MEAN. Use awk because bash lacks float arithmetic.
|
|
108
|
+
RATIO=$(awk -v c="$CC_TOKENS" -v m="$MEAN" 'BEGIN { if (m > 0) printf "%.3f", c/m; else print "0" }')
|
|
109
|
+
EXCEEDS=$(awk -v r="$RATIO" -v t="$THRESHOLD" 'BEGIN { print (r > t) ? 1 : 0 }')
|
|
110
|
+
|
|
111
|
+
if [ "$EXCEEDS" = "1" ] && [ "$SILENT" != "1" ]; then
|
|
112
|
+
# Format the baseline mean as an integer for the human-readable output.
|
|
113
|
+
MEAN_INT=$(awk -v m="$MEAN" 'BEGIN { printf "%d", m }')
|
|
114
|
+
PCT=$(awk -v r="$RATIO" 'BEGIN { printf "%d", (r - 1) * 100 }')
|
|
115
|
+
echo "NOTICE: cache_creation_input_tokens=${CC_TOKENS} is ${PCT}% above your trailing-${WINDOW}-sample baseline (~${MEAN_INT})." >&2
|
|
116
|
+
echo " Possible version-correlated server-side inflation (see anthropics/claude-code #46917)." >&2
|
|
117
|
+
echo " Inspect ${LOG} or run: jq -s 'map(.cc_tokens) | add/length' ${LOG}" >&2
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
exit 0
|