cc-safe-setup 29.7.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.
- 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 +419 -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-circuit-breaker.sh +72 -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 +89 -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/thinking-stall-detector.sh +61 -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 +1699 -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-circuit-breaker.sh +134 -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-exploration-budget-guard.sh +164 -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-thinking-stall-detector.sh +151 -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
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# claudemd-tool-prohibition.sh — Block tool calls that the operator's CLAUDE.md
|
|
3
|
+
# explicitly prohibits.
|
|
4
|
+
#
|
|
5
|
+
# Solves: harness-side recognition-without-arrest at the system-prompt layer
|
|
6
|
+
# (issue #60323). The harness injects a `<system-reminder>` suggesting
|
|
7
|
+
# TaskCreate even when the operator's CLAUDE.md says "Do NOT use TaskCreate".
|
|
8
|
+
# The model then has to choose between (a) violating the operator's rule or
|
|
9
|
+
# (b) spending output tokens on a meta-acknowledgment of the conflict.
|
|
10
|
+
#
|
|
11
|
+
# This hook resolves the conflict deterministically at the runtime layer:
|
|
12
|
+
# it reads the operator's CLAUDE.md, extracts tools the operator has
|
|
13
|
+
# prohibited, and blocks any PreToolUse call to a prohibited tool with
|
|
14
|
+
# a clear message about which rule it violated. The model's articulation
|
|
15
|
+
# of the rule is no longer load-bearing because the hook enforces the
|
|
16
|
+
# rule directly.
|
|
17
|
+
#
|
|
18
|
+
# How prohibitions are declared in CLAUDE.md
|
|
19
|
+
# The hook accepts three common operator-natural formats. Tool names must be
|
|
20
|
+
# inside backticks for unambiguous extraction.
|
|
21
|
+
#
|
|
22
|
+
# Format 1 — inline prose:
|
|
23
|
+
# Do NOT use `TaskCreate` for session-local work.
|
|
24
|
+
# do not call `TaskList` in this project.
|
|
25
|
+
# never use `TaskUpdate`.
|
|
26
|
+
#
|
|
27
|
+
# Format 2 — Japanese prose:
|
|
28
|
+
# `TaskCreate` を使うな
|
|
29
|
+
# `TaskList` の使用は禁止
|
|
30
|
+
#
|
|
31
|
+
# Format 3 — list under a "Forbidden Tools" / 禁止 header (within 20 lines):
|
|
32
|
+
# ## Forbidden Tools
|
|
33
|
+
# - `TaskCreate`
|
|
34
|
+
# - `TaskList`
|
|
35
|
+
#
|
|
36
|
+
# TRIGGER: PreToolUse
|
|
37
|
+
# MATCHER: ""
|
|
38
|
+
#
|
|
39
|
+
# Configuration:
|
|
40
|
+
# CC_TOOL_PROHIBITION_DISABLE=1 Disable the hook entirely.
|
|
41
|
+
# CC_TOOL_PROHIBITION_WARN=1 Advisory mode: warn to stderr but exit 0
|
|
42
|
+
# instead of blocking. Default: block (exit 2).
|
|
43
|
+
# CC_CLAUDEMD_PATH=/path/to/file Override CLAUDE.md search path.
|
|
44
|
+
|
|
45
|
+
set -u
|
|
46
|
+
|
|
47
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
48
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
49
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
50
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
51
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
52
|
+
_nojq_warned="/tmp/cc-nojq-warned-claudemd-tool-prohibition-$PPID"
|
|
53
|
+
[ -f "$_nojq_warned" ] || {
|
|
54
|
+
echo "WARNING [claudemd-tool-prohibition]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
55
|
+
: > "$_nojq_warned"
|
|
56
|
+
}
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
[ "${CC_TOOL_PROHIBITION_DISABLE:-0}" = "1" ] && exit 0
|
|
60
|
+
|
|
61
|
+
INPUT=$(cat)
|
|
62
|
+
|
|
63
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
64
|
+
[ -z "$TOOL_NAME" ] && exit 0
|
|
65
|
+
|
|
66
|
+
# Find CLAUDE.md. Search order: explicit override, project CLAUDE.md, parent
|
|
67
|
+
# directory, user-global ~/.claude/CLAUDE.md.
|
|
68
|
+
CLAUDEMD=""
|
|
69
|
+
if [ -n "${CC_CLAUDEMD_PATH:-}" ] && [ -r "$CC_CLAUDEMD_PATH" ]; then
|
|
70
|
+
CLAUDEMD="$CC_CLAUDEMD_PATH"
|
|
71
|
+
else
|
|
72
|
+
for candidate in "CLAUDE.md" ".claude/CLAUDE.md" "../CLAUDE.md" "$HOME/.claude/CLAUDE.md"; do
|
|
73
|
+
if [ -r "$candidate" ]; then
|
|
74
|
+
CLAUDEMD="$candidate"
|
|
75
|
+
break
|
|
76
|
+
fi
|
|
77
|
+
done
|
|
78
|
+
fi
|
|
79
|
+
[ -z "$CLAUDEMD" ] && exit 0
|
|
80
|
+
|
|
81
|
+
# Extract prohibited tool names from CLAUDE.md.
|
|
82
|
+
# We collect tool names in two passes:
|
|
83
|
+
# Pass 1 — prose patterns matching "do not use `X`" / "禁止" / etc.
|
|
84
|
+
# Pass 2 — list items under headers that mention forbidden / prohibited / 禁止.
|
|
85
|
+
FORBIDDEN_LIST=""
|
|
86
|
+
|
|
87
|
+
# Pass 1: prose prohibitions
|
|
88
|
+
PROSE=$(grep -iE '(do[ -]not (use|call)|never (use|call)|禁止|を使うな|使用は禁止)' "$CLAUDEMD" 2>/dev/null || true)
|
|
89
|
+
if [ -n "$PROSE" ]; then
|
|
90
|
+
# Extract backtick-quoted tokens from these lines
|
|
91
|
+
EXTRACTED=$(printf '%s\n' "$PROSE" | grep -oE '`[A-Za-z][A-Za-z0-9_-]+`' 2>/dev/null | sed 's/`//g' | sort -u || true)
|
|
92
|
+
if [ -n "$EXTRACTED" ]; then
|
|
93
|
+
FORBIDDEN_LIST="$EXTRACTED"
|
|
94
|
+
fi
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Pass 2: list items under "Forbidden Tools" / "Prohibited Tools" / "禁止" headers
|
|
98
|
+
# (only the 20 lines following the header are scanned)
|
|
99
|
+
HEADER_LINES=$(grep -inE '^#+ +(forbidden tools|prohibited tools|禁止する道具|使用禁止)' "$CLAUDEMD" 2>/dev/null | cut -d: -f1 || true)
|
|
100
|
+
if [ -n "$HEADER_LINES" ]; then
|
|
101
|
+
for ln in $HEADER_LINES; do
|
|
102
|
+
SECTION=$(sed -n "${ln},$((ln+20))p" "$CLAUDEMD" 2>/dev/null || true)
|
|
103
|
+
ITEMS=$(printf '%s\n' "$SECTION" | grep -E '^[ ]*[-*] +`[A-Za-z][A-Za-z0-9_-]+`' 2>/dev/null | grep -oE '`[A-Za-z][A-Za-z0-9_-]+`' | sed 's/`//g' || true)
|
|
104
|
+
if [ -n "$ITEMS" ]; then
|
|
105
|
+
FORBIDDEN_LIST="${FORBIDDEN_LIST}${FORBIDDEN_LIST:+$'\n'}${ITEMS}"
|
|
106
|
+
fi
|
|
107
|
+
done
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
[ -z "$FORBIDDEN_LIST" ] && exit 0
|
|
111
|
+
|
|
112
|
+
# Normalise and check whether the active tool is in the forbidden set.
|
|
113
|
+
FORBIDDEN_LIST=$(printf '%s\n' "$FORBIDDEN_LIST" | sort -u)
|
|
114
|
+
|
|
115
|
+
if printf '%s\n' "$FORBIDDEN_LIST" | grep -qFx -- "$TOOL_NAME"; then
|
|
116
|
+
if [ "${CC_TOOL_PROHIBITION_WARN:-0}" = "1" ]; then
|
|
117
|
+
echo "⚠ claudemd-tool-prohibition: tool '$TOOL_NAME' is prohibited by $CLAUDEMD" >&2
|
|
118
|
+
echo " Continuing (advisory mode). Set CC_TOOL_PROHIBITION_WARN=0 to block." >&2
|
|
119
|
+
exit 0
|
|
120
|
+
fi
|
|
121
|
+
echo "BLOCKED: tool '$TOOL_NAME' is prohibited by your CLAUDE.md ($CLAUDEMD)." >&2
|
|
122
|
+
echo " The harness injected a suggestion or workflow that conflicts with your operator-scope rule." >&2
|
|
123
|
+
echo " See issue #60323 for the failure shape (system-reminder vs CLAUDE.md prohibition)." >&2
|
|
124
|
+
echo " To allow this call temporarily, run with CC_TOOL_PROHIBITION_WARN=1 (advisory) or CC_TOOL_PROHIBITION_DISABLE=1." >&2
|
|
125
|
+
exit 2
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
exit 0
|
|
@@ -1,21 +1,38 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# clear-command-confirm-guard.sh —
|
|
2
|
+
# clear-command-confirm-guard.sh — DOES NOT FIRE. Kept as a record, not as a guard.
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# This hook was written to block an accidental /clear (prefix matching means
|
|
5
|
+
# /c + Enter can hit /clear instead of /commit or /compact, #40931). It cannot
|
|
6
|
+
# work, and this file is kept so that nobody rebuilds it from the same idea.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
8
|
+
# WHY IT CANNOT WORK
|
|
9
|
+
# Slash commands never reach UserPromptSubmit. Measured 2026-09-19 on Claude
|
|
10
|
+
# Code 2.1.270 (Linux/WSL2), with every other hook removed via
|
|
11
|
+
# --setting-sources '' and a single recording hook passed inline through
|
|
12
|
+
# --settings, driven through a pty:
|
|
10
13
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
# typed UserPromptSubmit SessionEnd
|
|
15
|
+
# ordinary text fires, prompt holds it --
|
|
16
|
+
# /clear never fires fires, reason="clear"
|
|
17
|
+
# /exit never fires fires, reason="prompt_input_exit"
|
|
18
|
+
#
|
|
19
|
+
# The matcher below is therefore never evaluated. Feeding this script
|
|
20
|
+
# {"prompt":"/clear"} by hand does make it exit 2 -- that proves the script's
|
|
21
|
+
# own logic and nothing else, which is exactly the trap this file now warns
|
|
22
|
+
# about.
|
|
23
|
+
#
|
|
24
|
+
# TWO MORE DEFECTS, recorded so the pattern is not copied:
|
|
25
|
+
# * grep -qE '^/clear$' matches per line, not against the whole input, so a
|
|
26
|
+
# prompt that merely contains /clear on its own line would have been refused.
|
|
27
|
+
# * The refusal text said "permanently destroys all context". Saved history is
|
|
28
|
+
# still reachable with /resume; only the current context goes.
|
|
29
|
+
#
|
|
30
|
+
# WHAT TO USE INSTEAD
|
|
31
|
+
# You cannot block /clear with a hook. You can run one last thing against the
|
|
32
|
+
# conversation before it goes: SessionEnd fires with reason="clear" while
|
|
33
|
+
# transcript_path still points at a readable file. See handoff-on-clear.sh.
|
|
34
|
+
#
|
|
35
|
+
# TRIGGER: none
|
|
16
36
|
|
|
17
|
-
|
|
18
|
-
echo "BLOCKED: /clear permanently destroys all context. Use /compact instead to reduce context safely." >&2
|
|
19
|
-
exit 2
|
|
20
|
-
fi
|
|
37
|
+
echo "clear-command-confirm-guard.sh does not fire on Claude Code 2.1.270: slash commands never reach UserPromptSubmit. See handoff-on-clear.sh for what works." >&2
|
|
21
38
|
exit 0
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# cli-config-pinning-detector.sh — Detect Anthropic CLI config that silently pins
|
|
3
|
+
# organization_id and overrides Claude Code auth routing
|
|
4
|
+
# (Cluster 19 candidate, axis 19H — local-side credential override)
|
|
5
|
+
#
|
|
6
|
+
# Background:
|
|
7
|
+
# Cluster 19 axis 19H documents a class of authentication failures where the
|
|
8
|
+
# operator appears to be logged in with the correct email, but Claude Code is
|
|
9
|
+
# routed to the wrong organization (and therefore the wrong billing path).
|
|
10
|
+
#
|
|
11
|
+
# The mechanism: Claude Code and the standalone Anthropic CLI share the
|
|
12
|
+
# ~/.config/anthropic directory. If the CLI has written a config file at
|
|
13
|
+
# ~/.config/anthropic/configs/default.json with a hardcoded organization_id
|
|
14
|
+
# (e.g., from an "Individual Org" used briefly during testing), Claude Code
|
|
15
|
+
# honors that pinned organization_id. `claude auth login` / `claude auth
|
|
16
|
+
# logout` do not always clear or update this pin — so the operator ends up
|
|
17
|
+
# "logged in" but routed to the wrong organization, and the failure surfaces
|
|
18
|
+
# downstream as billing-path or quota-state confusion.
|
|
19
|
+
#
|
|
20
|
+
# Anchor case: #60742 — "[BUG] Anthropic CLI Overwrites and Pins Claude Code
|
|
21
|
+
# Credentials".
|
|
22
|
+
#
|
|
23
|
+
# This hook is a SessionStart advisory that fires when:
|
|
24
|
+
# - the file ~/.config/anthropic/configs/default.json (or override path) exists,
|
|
25
|
+
# AND it contains a non-empty organization_id field, AND
|
|
26
|
+
# - the operator has not already seen the advisory in this session
|
|
27
|
+
#
|
|
28
|
+
# The advisory describes the pinning behavior, points at the file and the
|
|
29
|
+
# pinned organization_id value, and recommends an explicit verification step.
|
|
30
|
+
# The hook does not auto-delete or auto-edit the config file — that decision
|
|
31
|
+
# belongs to the operator (the pinned org may be intentional).
|
|
32
|
+
#
|
|
33
|
+
# Reference:
|
|
34
|
+
# https://gist.github.com/yurukusa/58cb17bfda4d5ab31bd804809809d22f (auth cluster field guide)
|
|
35
|
+
#
|
|
36
|
+
# Why a hook helps:
|
|
37
|
+
# Without the advisory, the operator discovers the wrong-organization routing
|
|
38
|
+
# only at billing-cycle review, or when a teammate flags that their work is
|
|
39
|
+
# showing up under an unexpected org. With the advisory, the pinning is
|
|
40
|
+
# surfaced at SessionStart so the operator can verify org routing before
|
|
41
|
+
# substantive work attaches to the wrong billing path.
|
|
42
|
+
#
|
|
43
|
+
# When this hook does NOT emit anything:
|
|
44
|
+
# - CC_AUTH_PIN_DISABLE=1
|
|
45
|
+
# - CC_AUTH_PIN_QUIET=1
|
|
46
|
+
# - the CLI config file does not exist
|
|
47
|
+
# - the CLI config file exists but has no organization_id field
|
|
48
|
+
# - the advisory has already fired in this session
|
|
49
|
+
#
|
|
50
|
+
# Hook config (settings.json):
|
|
51
|
+
# {
|
|
52
|
+
# "hooks": {
|
|
53
|
+
# "SessionStart": [{
|
|
54
|
+
# "matcher": "",
|
|
55
|
+
# "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/cli-config-pinning-detector.sh" }]
|
|
56
|
+
# }]
|
|
57
|
+
# }
|
|
58
|
+
# }
|
|
59
|
+
#
|
|
60
|
+
# Env vars:
|
|
61
|
+
# CC_AUTH_PIN_DISABLE=1 — never emit
|
|
62
|
+
# CC_AUTH_PIN_QUIET=1 — silent (process but never write to stderr)
|
|
63
|
+
# CC_AUTH_PIN_CONFIG=<path> — config file path override (tests)
|
|
64
|
+
# CC_AUTH_PIN_STATE_DIR=<path> — one-shot state dir override (default ~/.claude/state)
|
|
65
|
+
# CC_AUTH_PIN_SESSION_ID=<id> — session id override (tests)
|
|
66
|
+
#
|
|
67
|
+
# Design notes:
|
|
68
|
+
# - Opt-out. The pinning behavior is silent by design (no upstream signal),
|
|
69
|
+
# so a one-shot stderr advisory at SessionStart is the only place this
|
|
70
|
+
# surfaces before the operator commits substantive work to the wrong org.
|
|
71
|
+
# - One-shot per session. The advisory fires once. The operator either
|
|
72
|
+
# verifies and dismisses, or unsets the pin in the file deliberately.
|
|
73
|
+
# - Never blocks. Exit always 0. The pin may be intentional (multi-org
|
|
74
|
+
# setups); auto-deleting it would break those workflows.
|
|
75
|
+
# - Does not require jq. The organization_id field is parsed with a portable
|
|
76
|
+
# grep/sed pipeline so the hook works on bare shells.
|
|
77
|
+
|
|
78
|
+
set -u
|
|
79
|
+
|
|
80
|
+
if [[ "${CC_AUTH_PIN_DISABLE:-0}" = "1" ]]; then
|
|
81
|
+
exit 0
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
CONFIG_FILE="${CC_AUTH_PIN_CONFIG:-$HOME/.config/anthropic/configs/default.json}"
|
|
85
|
+
|
|
86
|
+
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
87
|
+
exit 0
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
STATE_DIR="${CC_AUTH_PIN_STATE_DIR:-$HOME/.claude/state}"
|
|
91
|
+
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
92
|
+
|
|
93
|
+
SESSION_ID="${CC_AUTH_PIN_SESSION_ID:-${CLAUDE_SESSION_ID:-default}}"
|
|
94
|
+
GUARD_FILE="$STATE_DIR/auth-pin-${SESSION_ID}.fired"
|
|
95
|
+
|
|
96
|
+
if [[ -f "$GUARD_FILE" ]]; then
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Extract organization_id without requiring jq. The portable approach:
|
|
101
|
+
# 1) grep for the key (allowing leading whitespace and the optional underscore)
|
|
102
|
+
# 2) sed-strip the key, separator, quotes, and trailing comma
|
|
103
|
+
ORG_LINE=$(grep -E '"organization_id"[[:space:]]*:' "$CONFIG_FILE" 2>/dev/null | head -1)
|
|
104
|
+
if [[ -z "$ORG_LINE" ]]; then
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
ORG_ID=$(echo "$ORG_LINE" \
|
|
109
|
+
| sed -E 's/.*"organization_id"[[:space:]]*:[[:space:]]*"?([^",}[:space:]]+)"?.*/\1/' \
|
|
110
|
+
| tr -d '[:space:]')
|
|
111
|
+
|
|
112
|
+
if [[ -z "$ORG_ID" ]] || [[ "$ORG_ID" == "null" ]] || [[ "$ORG_ID" == "$ORG_LINE" ]]; then
|
|
113
|
+
exit 0
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
# Mark one-shot guard.
|
|
117
|
+
touch "$GUARD_FILE" 2>/dev/null
|
|
118
|
+
|
|
119
|
+
if [[ "${CC_AUTH_PIN_QUIET:-0}" = "1" ]]; then
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
cat >&2 <<EOF
|
|
124
|
+
|
|
125
|
+
────────────────────────────────────────────────────────────────────
|
|
126
|
+
Auth advisory — Cluster 19 axis 19H (CLI config pinning)
|
|
127
|
+
────────────────────────────────────────────────────────────────────
|
|
128
|
+
Anthropic CLI config detected with pinned organization_id:
|
|
129
|
+
${CONFIG_FILE}
|
|
130
|
+
organization_id: ${ORG_ID}
|
|
131
|
+
|
|
132
|
+
The Cluster 19 axis 19H pattern: Claude Code shares the
|
|
133
|
+
~/.config/anthropic directory with the standalone Anthropic CLI.
|
|
134
|
+
When the CLI has written a config file with a hardcoded
|
|
135
|
+
organization_id, Claude Code honors that pin — even if
|
|
136
|
+
\`claude auth login\` / \`claude auth logout\` were run afterwards.
|
|
137
|
+
The visible state is "logged in with the correct email," but tool
|
|
138
|
+
calls are routed to the pinned org's billing path.
|
|
139
|
+
|
|
140
|
+
Anchor case: #60742.
|
|
141
|
+
|
|
142
|
+
Recommended verification before substantive work:
|
|
143
|
+
|
|
144
|
+
/account
|
|
145
|
+
|
|
146
|
+
Confirm the "Organization" field matches your intended billing org.
|
|
147
|
+
If it does not match, the pin in the file above is overriding
|
|
148
|
+
your interactive auth. Two recovery paths:
|
|
149
|
+
|
|
150
|
+
1) Edit ${CONFIG_FILE} and remove the
|
|
151
|
+
"organization_id" line, then run /login to re-pick the org.
|
|
152
|
+
2) Delete the file entirely if the standalone CLI is not used.
|
|
153
|
+
|
|
154
|
+
Field guide: https://gist.github.com/yurukusa/58cb17bfda4d5ab31bd804809809d22f
|
|
155
|
+
|
|
156
|
+
(This advisory fires once per session. To disable:
|
|
157
|
+
export CC_AUTH_PIN_DISABLE=1)
|
|
158
|
+
────────────────────────────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
EOF
|
|
161
|
+
|
|
162
|
+
exit 0
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# cliff-countdown-advisor.sh
|
|
3
|
+
#
|
|
4
|
+
# SessionStart hook that articulates the days remaining until the 2026-06-15
|
|
5
|
+
# Anthropic billing-split cliff, plus operator-side guidance to minimize Pool 2
|
|
6
|
+
# usage signals during the preparation window.
|
|
7
|
+
#
|
|
8
|
+
# Designed to surface the cliff timing once per session without becoming noise:
|
|
9
|
+
# - Quiet beyond 30 days before cliff (no output)
|
|
10
|
+
# - Caution between 15-30 days before cliff (single-line note)
|
|
11
|
+
# - Elevated between 1-14 days before cliff (multi-line advisory)
|
|
12
|
+
# - Acute on cliff day (2026-06-15, dedicated message)
|
|
13
|
+
# - Post-cliff window (1-30 days after) surfaces the diff-capture procedure
|
|
14
|
+
# - Silent beyond 30 days after cliff
|
|
15
|
+
#
|
|
16
|
+
# Environment variables (all optional):
|
|
17
|
+
# - CC_CLIFF_DATE: override the cliff date (YYYY-MM-DD format, default 2026-06-15)
|
|
18
|
+
# - CC_CLIFF_QUIET: if set to "1", suppress all output (opt-out)
|
|
19
|
+
# - CC_CLIFF_DISABLE: if set to "1", disable the hook entirely (alias for QUIET)
|
|
20
|
+
#
|
|
21
|
+
# Exit codes:
|
|
22
|
+
# - Always exits 0 (advisory hook, never blocks)
|
|
23
|
+
#
|
|
24
|
+
# Reference: docs/june-15-cliff-14-day-plan.md (the 14-day preparation plan)
|
|
25
|
+
|
|
26
|
+
set -uo pipefail
|
|
27
|
+
|
|
28
|
+
# Opt-out check
|
|
29
|
+
if [[ "${CC_CLIFF_QUIET:-0}" == "1" ]] || [[ "${CC_CLIFF_DISABLE:-0}" == "1" ]]; then
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
CLIFF_DATE="${CC_CLIFF_DATE:-2026-06-15}"
|
|
34
|
+
|
|
35
|
+
# Convert dates to seconds since epoch for comparison
|
|
36
|
+
if ! cliff_epoch=$(date -d "${CLIFF_DATE}" +%s 2>/dev/null); then
|
|
37
|
+
# Date parsing failed (e.g. on macOS without GNU date) — silently exit
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
now_epoch=$(date +%s)
|
|
42
|
+
diff_seconds=$((cliff_epoch - now_epoch))
|
|
43
|
+
diff_days=$((diff_seconds / 86400))
|
|
44
|
+
|
|
45
|
+
# Today is 2026-06-15 (cliff day, +/- 12 hours)
|
|
46
|
+
if [[ ${diff_days} -ge -1 ]] && [[ ${diff_days} -le 0 ]]; then
|
|
47
|
+
cat <<'EOF'
|
|
48
|
+
[cliff-countdown] ★ 2026-06-15 cliff day. Anthropic billing split is active now.
|
|
49
|
+
|
|
50
|
+
Today's measurement priority:
|
|
51
|
+
1. Capture Anthropic Console Usage snapshot before any heavy work
|
|
52
|
+
2. Watch for the first Pool 2 charges to surface (typically within 12-24h)
|
|
53
|
+
3. Save the snapshot to ~/ops/measurements/2026-06-15-cliff-day.json
|
|
54
|
+
|
|
55
|
+
Reference (free, MIT):
|
|
56
|
+
- 14-day plan: docs/june-15-cliff-14-day-plan.md (post-cliff diff section)
|
|
57
|
+
|
|
58
|
+
Set CC_CLIFF_QUIET=1 to suppress this advisory.
|
|
59
|
+
EOF
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# 1-14 days before cliff (elevated advisory)
|
|
64
|
+
if [[ ${diff_days} -ge 1 ]] && [[ ${diff_days} -le 14 ]]; then
|
|
65
|
+
cat <<EOF
|
|
66
|
+
[cliff-countdown] ⚠ ${diff_days} days until the 2026-06-15 cliff.
|
|
67
|
+
|
|
68
|
+
Operator-side actions to consider:
|
|
69
|
+
- Capture Anthropic Console Usage baseline (Pool 1 vs Pool 2 ratio)
|
|
70
|
+
- Reduce \`claude -p\` and Agent SDK calls running on cron / background paths
|
|
71
|
+
- Stop parallel \`claude -p\` invocations (run sequentially during the window)
|
|
72
|
+
- Set or verify the monthly Spend Limit in Anthropic Console
|
|
73
|
+
|
|
74
|
+
Reference (free, MIT):
|
|
75
|
+
- 14-day plan: docs/june-15-cliff-14-day-plan.md
|
|
76
|
+
|
|
77
|
+
Set CC_CLIFF_QUIET=1 to suppress this advisory.
|
|
78
|
+
EOF
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# 15-30 days before cliff (caution)
|
|
83
|
+
if [[ ${diff_days} -ge 15 ]] && [[ ${diff_days} -le 30 ]]; then
|
|
84
|
+
echo "[cliff-countdown] ${diff_days} days until the 2026-06-15 billing cliff. Start the baseline capture this week. Reference: docs/june-15-cliff-14-day-plan.md"
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# 1-30 days after cliff (post-cliff diff capture)
|
|
89
|
+
if [[ ${diff_days} -le -2 ]] && [[ ${diff_days} -ge -30 ]]; then
|
|
90
|
+
days_after=$((-diff_days))
|
|
91
|
+
echo "[cliff-countdown] Day ${days_after} after the 2026-06-15 cliff. Capture diff vs pre-cliff baseline if not already done. Reference: docs/june-15-cliff-14-day-plan.md (6/16 onward section)."
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Otherwise quiet
|
|
96
|
+
exit 0
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
# MATCHER: "Bash"
|
|
13
13
|
# CATEGORY: security
|
|
14
14
|
|
|
15
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
16
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
17
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
18
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
19
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
20
|
+
_nojq_warned="/tmp/cc-nojq-warned-clipboard-secret-guard-$PPID"
|
|
21
|
+
[ -f "$_nojq_warned" ] || {
|
|
22
|
+
echo "WARNING [clipboard-secret-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
23
|
+
: > "$_nojq_warned"
|
|
24
|
+
}
|
|
25
|
+
fi
|
|
26
|
+
|
|
15
27
|
INPUT=$(cat)
|
|
16
28
|
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
17
29
|
[ -z "$CMD" ] && exit 0
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# closure-word-verify-gate.sh — Stop the turn if a closure word ("done",
|
|
3
|
+
# "shipped", "complete", "production ready", "bitti", "finished") was used
|
|
4
|
+
# without a corresponding verification tool call in the same turn.
|
|
5
|
+
#
|
|
6
|
+
# Solves: #60506 — "Self-report: six days of architectural drift on a customer
|
|
7
|
+
# project despite full hook + memory + skill enforcement."
|
|
8
|
+
#
|
|
9
|
+
# In that case, claude-opus-4-7 reported in its own first-person Issue body:
|
|
10
|
+
#
|
|
11
|
+
# "'Done' is cheap for me. I said 'bitti / shipped / production ready'
|
|
12
|
+
# without performing a browser CRUD round-trip, even after the customer
|
|
13
|
+
# wrote an explicit rule: 'no claim bitti without browser test.' Two
|
|
14
|
+
# hours after the rule I said 'bitti' again, without opening the browser.
|
|
15
|
+
# The customer caught me because he opened the screen."
|
|
16
|
+
#
|
|
17
|
+
# The customer's own engineering recommendation #4 in #60506:
|
|
18
|
+
#
|
|
19
|
+
# "Quality-scorecard gate before closure words. When I emit 'shipped',
|
|
20
|
+
# 'complete', 'production ready', 'done', 'bitti', require — by hook
|
|
21
|
+
# or by tool — that a quality-scorecard tool was called in the same
|
|
22
|
+
# turn. Otherwise replace the closure word with 'pending verification.'"
|
|
23
|
+
#
|
|
24
|
+
# This hook is the harness-level form of that requirement. It runs on Stop,
|
|
25
|
+
# scans the assistant's most recent transcript turn for closure words, and
|
|
26
|
+
# refuses the Stop (returning exit 2 with stderr feedback Claude sees) if
|
|
27
|
+
# no verification command appeared in the same turn.
|
|
28
|
+
#
|
|
29
|
+
# This is distinct from existing verify-before-commit.sh and
|
|
30
|
+
# verify-before-done.sh, both of which fire on `git commit` time only.
|
|
31
|
+
# closure-word-verify-gate.sh fires on *any* assistant turn that asserts
|
|
32
|
+
# completion, regardless of whether a commit is being made.
|
|
33
|
+
#
|
|
34
|
+
# Related Issues:
|
|
35
|
+
# #60506 (@zean89, 2026-05-19) — first-person self-report of the failure
|
|
36
|
+
# #60226 (@suwayama, 2026-05-18) — recognition-without-arrest framework
|
|
37
|
+
# #37818 — Claude declares fixes done without
|
|
38
|
+
# verification
|
|
39
|
+
#
|
|
40
|
+
# TRIGGER: Stop
|
|
41
|
+
# MATCHER: ""
|
|
42
|
+
#
|
|
43
|
+
# CONFIGURATION (environment variables):
|
|
44
|
+
# CC_CLOSURE_WORDS default built-in — pipe-separated regex of
|
|
45
|
+
# closure phrases
|
|
46
|
+
# CC_VERIFICATION_COMMANDS default built-in — regex of verification tools
|
|
47
|
+
# (test runners, browsers)
|
|
48
|
+
# CC_CLOSURE_GATE_DISABLE set to "1" to disable the gate entirely
|
|
49
|
+
#
|
|
50
|
+
# USAGE (settings.json):
|
|
51
|
+
# {
|
|
52
|
+
# "hooks": {
|
|
53
|
+
# "Stop": [{
|
|
54
|
+
# "matcher": "",
|
|
55
|
+
# "hooks": [{
|
|
56
|
+
# "type": "command",
|
|
57
|
+
# "command": "~/.claude/hooks/closure-word-verify-gate.sh"
|
|
58
|
+
# }]
|
|
59
|
+
# }]
|
|
60
|
+
# }
|
|
61
|
+
# }
|
|
62
|
+
|
|
63
|
+
set -uo pipefail
|
|
64
|
+
|
|
65
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
66
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
67
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
68
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
69
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
70
|
+
_nojq_warned="/tmp/cc-nojq-warned-closure-word-verify-gate-$PPID"
|
|
71
|
+
[ -f "$_nojq_warned" ] || {
|
|
72
|
+
echo "WARNING [closure-word-verify-gate]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
73
|
+
: > "$_nojq_warned"
|
|
74
|
+
}
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
[ "${CC_CLOSURE_GATE_DISABLE:-0}" = "1" ] && exit 0
|
|
78
|
+
|
|
79
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
80
|
+
[ -z "$INPUT" ] && exit 0
|
|
81
|
+
|
|
82
|
+
DEFAULT_CLOSURES='\b(done|shipped|complete|completed|production[[:space:]]+ready|ready[[:space:]]+to[[:space:]]+merge|ready[[:space:]]+to[[:space:]]+ship|bitti|finished|all[[:space:]]+set|works[[:space:]]+now|fixed[[:space:]]+it)\b'
|
|
83
|
+
DEFAULT_VERIFICATION='(npm[[:space:]]+(run[[:space:]]+)?test|pytest|playwright|cypress|jest[[:space:]]|vitest|bun[[:space:]]+test|cargo[[:space:]]+test|go[[:space:]]+test|mocha|phpunit|rspec|curl[[:space:]].*localhost|gh[[:space:]]+pr[[:space:]]+checks|deno[[:space:]]+test|tox|make[[:space:]]+test)'
|
|
84
|
+
|
|
85
|
+
CLOSURES="${CC_CLOSURE_WORDS:-$DEFAULT_CLOSURES}"
|
|
86
|
+
VERIFICATION="${CC_VERIFICATION_COMMANDS:-$DEFAULT_VERIFICATION}"
|
|
87
|
+
|
|
88
|
+
# Stop-hook input shape varies across Claude Code versions; try several keys.
|
|
89
|
+
# The fields we care about are the assistant's most recent message text and
|
|
90
|
+
# the list of Bash commands that ran in the same turn.
|
|
91
|
+
ASSISTANT_TEXT=$(printf '%s' "$INPUT" | jq -r '
|
|
92
|
+
.transcript[-1].content //
|
|
93
|
+
.last_assistant_message //
|
|
94
|
+
.stop_input.assistant_text //
|
|
95
|
+
.assistant_message //
|
|
96
|
+
empty
|
|
97
|
+
' 2>/dev/null)
|
|
98
|
+
|
|
99
|
+
# Commands that ran in this turn (multiple possible keys depending on
|
|
100
|
+
# harness version)
|
|
101
|
+
TURN_COMMANDS=$(printf '%s' "$INPUT" | jq -r '
|
|
102
|
+
[ .turn_tool_calls[]?.command,
|
|
103
|
+
.recent_commands[]?,
|
|
104
|
+
.transcript[-1].tool_calls[]?.input.command,
|
|
105
|
+
.last_turn_commands[]?
|
|
106
|
+
] | map(select(. != null)) | .[]
|
|
107
|
+
' 2>/dev/null || true)
|
|
108
|
+
|
|
109
|
+
# If we cannot find the assistant text, the harness shape differs and we
|
|
110
|
+
# refuse to false-positive — exit silently.
|
|
111
|
+
[ -z "$ASSISTANT_TEXT" ] && exit 0
|
|
112
|
+
|
|
113
|
+
# No closure word in the turn → nothing to gate.
|
|
114
|
+
if ! printf '%s' "$ASSISTANT_TEXT" | grep -Eiq "$CLOSURES"; then
|
|
115
|
+
exit 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Closure word present. Did a verification command run in the same turn?
|
|
119
|
+
if [ -n "$TURN_COMMANDS" ] && printf '%s' "$TURN_COMMANDS" | grep -Eiq "$VERIFICATION"; then
|
|
120
|
+
# Verification artifact present — closure is grounded.
|
|
121
|
+
exit 0
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Closure word without verification → block the Stop and surface feedback.
|
|
125
|
+
MATCHED_WORD=$(printf '%s' "$ASSISTANT_TEXT" | grep -Eio "$CLOSURES" | head -1)
|
|
126
|
+
|
|
127
|
+
cat >&2 <<EOF
|
|
128
|
+
<system-reminder>
|
|
129
|
+
CLOSURE WITHOUT VERIFICATION — the word "$MATCHED_WORD" was used in this turn
|
|
130
|
+
but no verification command (test runner, Playwright, curl-against-local,
|
|
131
|
+
gh pr checks) ran in the same turn.
|
|
132
|
+
|
|
133
|
+
This is the failure mode documented in #60506 and #37818: closure words are
|
|
134
|
+
emitted before the actual state has been verified. The cost of an unverified
|
|
135
|
+
"$MATCHED_WORD" lands on the operator, not on the model.
|
|
136
|
+
|
|
137
|
+
Before ending this turn, either:
|
|
138
|
+
|
|
139
|
+
1. Run a verification command (npm test, pytest, playwright, curl, etc.)
|
|
140
|
+
that exercises the claim being made, and re-state closure only after
|
|
141
|
+
that verification passes, OR
|
|
142
|
+
2. Replace "$MATCHED_WORD" with "pending verification — needs <specific
|
|
143
|
+
verification step>" so the operator knows the claim is not yet grounded.
|
|
144
|
+
|
|
145
|
+
To disable this gate intentionally (for non-code turns, retrospectives,
|
|
146
|
+
documentation work), set CC_CLOSURE_GATE_DISABLE=1 in your environment.
|
|
147
|
+
</system-reminder>
|
|
148
|
+
EOF
|
|
149
|
+
|
|
150
|
+
exit 2
|
|
@@ -10,19 +10,39 @@
|
|
|
10
10
|
# Detects:
|
|
11
11
|
# gcloud compute instances delete
|
|
12
12
|
# gcloud sql instances delete
|
|
13
|
-
# gcloud storage rm
|
|
13
|
+
# gcloud storage rm / gcloud storage rb (objects / buckets — #70024)
|
|
14
|
+
# gsutil rm / gsutil rb (legacy GCS removal, incl. gsutil -m rm)
|
|
14
15
|
# gcloud projects delete
|
|
15
16
|
# az vm delete
|
|
16
17
|
# az storage account delete
|
|
17
18
|
# az sql db delete
|
|
18
19
|
# az group delete
|
|
20
|
+
# az ad group delete (the irreversible deletion in #69397)
|
|
19
21
|
#
|
|
20
22
|
# Does NOT block:
|
|
21
23
|
# gcloud compute instances list/describe
|
|
22
24
|
# az vm list/show
|
|
23
25
|
# gcloud/az read-only operations
|
|
24
26
|
#
|
|
25
|
-
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
27
|
+
# TRIGGER: PreToolUse MATCHER: "Bash|PowerShell"
|
|
28
|
+
# On Windows, az/gcloud commonly run through the PowerShell tool,
|
|
29
|
+
# which is separate from Bash in Claude Code. A Bash-only matcher
|
|
30
|
+
# never fires on the PowerShell tool, so the irreversible
|
|
31
|
+
# `az ad group delete` in #69397 ran with no permission prompt.
|
|
32
|
+
# Register with matcher "Bash|PowerShell"; both tools populate
|
|
33
|
+
# tool_input.command.
|
|
34
|
+
|
|
35
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
36
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
37
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
38
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
39
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
40
|
+
_nojq_warned="/tmp/cc-nojq-warned-cloud-cli-guard-$PPID"
|
|
41
|
+
[ -f "$_nojq_warned" ] || {
|
|
42
|
+
echo "WARNING [cloud-cli-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
43
|
+
: > "$_nojq_warned"
|
|
44
|
+
}
|
|
45
|
+
fi
|
|
26
46
|
|
|
27
47
|
INPUT=$(cat)
|
|
28
48
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
@@ -37,6 +57,23 @@ if echo "$COMMAND" | grep -qE '\bgcloud\s+.*(delete|destroy|remove|reset)\b'; th
|
|
|
37
57
|
exit 2
|
|
38
58
|
fi
|
|
39
59
|
|
|
60
|
+
# Block cloud-storage object/bucket removal via the `rm`/`rb` subcommands.
|
|
61
|
+
# The gcloud check above keys on delete|destroy|remove|reset, but Google Cloud
|
|
62
|
+
# Storage removal uses the literal subcommand `rm` (objects) and `rb` (buckets) —
|
|
63
|
+
# `gcloud storage rm` / `gsutil rm` — none of which contain "remove". Without this
|
|
64
|
+
# branch those slip past the guard entirely (and rm-safety-net only fires on a
|
|
65
|
+
# command that *starts* with `rm`, not on `gcloud storage rm`). #70024: an agent
|
|
66
|
+
# ran `gcloud storage rm -r` after a failed `mv` and destroyed the source objects.
|
|
67
|
+
if echo "$COMMAND" | grep -qE '\bgcloud\s+storage\s+(rm|rb)\b' \
|
|
68
|
+
|| echo "$COMMAND" | grep -qE '\bgsutil\s+(-[a-zA-Z]+\s+)*(rm|rb)\b'; then
|
|
69
|
+
echo "BLOCKED: Destructive Google Cloud Storage removal detected." >&2
|
|
70
|
+
echo " Command: $COMMAND" >&2
|
|
71
|
+
echo " This deletes cloud objects/buckets irreversibly. Confirm the copy/move" >&2
|
|
72
|
+
echo " succeeded first ('gcloud storage ls' / 'cp'); never delete after an" >&2
|
|
73
|
+
echo " unverified transfer (#70024)." >&2
|
|
74
|
+
exit 2
|
|
75
|
+
fi
|
|
76
|
+
|
|
40
77
|
# Block destructive az (Azure) operations
|
|
41
78
|
if echo "$COMMAND" | grep -qE '\baz\s+.*(delete|destroy|remove)\b'; then
|
|
42
79
|
echo "BLOCKED: Destructive Azure operation detected." >&2
|