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,159 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# proxy-capture-suggester.sh — Surface HTTPS proxy capture path for compliance-bound operators
|
|
3
|
+
#
|
|
4
|
+
# Background:
|
|
5
|
+
# v2.1.150+ injects server-side strings into the system prompt via two cached channels:
|
|
6
|
+
# the bootstrap API `client_data` field and the GrowthBook `tengu_heron_brook` flag.
|
|
7
|
+
# The opt-out env vars (CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1, DISABLE_GROWTHBOOK=1)
|
|
8
|
+
# close the injection channel going forward, and cache-residue-detector.sh prompts
|
|
9
|
+
# removal of pre-opt-out cached values. Neither produces a reconstructible audit trail
|
|
10
|
+
# of what the agent was instructed at the time of any logged action.
|
|
11
|
+
#
|
|
12
|
+
# For operators in regulated industries (financial services, healthcare, government,
|
|
13
|
+
# defense) the audit trail gap is the structural concern. The opt-outs answer
|
|
14
|
+
# "stop trusting Anthropic with the prompt", but compliance frameworks (SOX, HIPAA,
|
|
15
|
+
# FedRAMP, PCI-DSS, EU AI Act Article 12) also require "produce the exact prompt that
|
|
16
|
+
# was sent for any logged tool execution within the retention window".
|
|
17
|
+
#
|
|
18
|
+
# The only operator-side path to that audit trail is HTTPS proxy capture: an MITM
|
|
19
|
+
# proxy between the Claude Code client and api.anthropic.com that records the full
|
|
20
|
+
# request body of every API call. Anthropic does not provide a first-party audit
|
|
21
|
+
# export; the proxy capture path is the workaround.
|
|
22
|
+
#
|
|
23
|
+
# Reference: https://github.com/anthropics/claude-code/issues/62061 (46+ reactions)
|
|
24
|
+
# https://gist.github.com/yurukusa/03839b3c3f88e1cce38fb0f2c127544d (v2.1.150 audit paths)
|
|
25
|
+
#
|
|
26
|
+
# What this hook does:
|
|
27
|
+
# On SessionStart, when CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 is set, inspect the
|
|
28
|
+
# environment for an active HTTPS proxy configuration. If none is present, emit a
|
|
29
|
+
# one-time advisory naming three audit-grade proxy tools with concrete invocation,
|
|
30
|
+
# the CA-trust step required for TLS termination, and the env-var bridge that wires
|
|
31
|
+
# Claude Code's API client into the proxy.
|
|
32
|
+
#
|
|
33
|
+
# The hook is opt-in. Most operators do not need an audit trail and would not
|
|
34
|
+
# benefit from running an MITM proxy locally; it adds attack surface, latency, and
|
|
35
|
+
# maintenance overhead. The advisory only fires when an operator has explicitly
|
|
36
|
+
# declared compliance intent via the opt-in env var.
|
|
37
|
+
#
|
|
38
|
+
# When this hook does NOT fire:
|
|
39
|
+
# - CC_PROXY_CAPTURE_SUGGESTER_ENABLE is unset or set to 0 (the default)
|
|
40
|
+
# - CC_PROXY_CAPTURE_SUGGESTER_QUIET=1 (silenced after acknowledgement)
|
|
41
|
+
# - An HTTPS proxy is already active (HTTPS_PROXY / https_proxy / ALL_PROXY contains a value)
|
|
42
|
+
#
|
|
43
|
+
# When this hook DOES fire (default behavior with ENABLE=1):
|
|
44
|
+
# - SessionStart and no HTTPS_PROXY-family env var is set → emit the four-tool advisory
|
|
45
|
+
# - SessionStart and a proxy IS set but ANTHROPIC_LOG_DIR is unset → emit a shorter
|
|
46
|
+
# advisory pointing out that proxy capture is active but no local log sink is configured
|
|
47
|
+
#
|
|
48
|
+
# Hook config (settings.json):
|
|
49
|
+
# {
|
|
50
|
+
# "hooks": {
|
|
51
|
+
# "SessionStart": [{
|
|
52
|
+
# "matcher": "",
|
|
53
|
+
# "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/proxy-capture-suggester.sh" }]
|
|
54
|
+
# }]
|
|
55
|
+
# }
|
|
56
|
+
# }
|
|
57
|
+
#
|
|
58
|
+
# Env vars:
|
|
59
|
+
# CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1 — opt in to the advisory (default off)
|
|
60
|
+
# CC_PROXY_CAPTURE_SUGGESTER_QUIET=1 — silence permanently after acknowledgement
|
|
61
|
+
#
|
|
62
|
+
# Privacy: the hook reads only the names of standard proxy env vars (HTTPS_PROXY,
|
|
63
|
+
# https_proxy, ALL_PROXY, NO_PROXY, ANTHROPIC_LOG_DIR). It never reads, transmits, or
|
|
64
|
+
# logs the values themselves.
|
|
65
|
+
|
|
66
|
+
set -u
|
|
67
|
+
|
|
68
|
+
# Silenced permanently after acknowledgement
|
|
69
|
+
if [ "${CC_PROXY_CAPTURE_SUGGESTER_QUIET:-0}" = "1" ]; then
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Opt-in: silent unless the operator explicitly declared compliance intent
|
|
74
|
+
if [ "${CC_PROXY_CAPTURE_SUGGESTER_ENABLE:-0}" != "1" ]; then
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Check for an active HTTPS proxy (uppercase or lowercase, plus ALL_PROXY)
|
|
79
|
+
PROXY_ACTIVE=0
|
|
80
|
+
for var in HTTPS_PROXY https_proxy ALL_PROXY all_proxy; do
|
|
81
|
+
# shellcheck disable=SC1083
|
|
82
|
+
eval val="\${$var:-}"
|
|
83
|
+
if [ -n "${val:-}" ]; then
|
|
84
|
+
PROXY_ACTIVE=1
|
|
85
|
+
break
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
if [ "$PROXY_ACTIVE" = "1" ]; then
|
|
90
|
+
# Proxy is active. Check whether an audit log sink is configured.
|
|
91
|
+
if [ -z "${ANTHROPIC_LOG_DIR:-}" ]; then
|
|
92
|
+
cat >&2 <<'EOF'
|
|
93
|
+
[proxy-capture-suggester] HTTPS proxy is active but ANTHROPIC_LOG_DIR is unset.
|
|
94
|
+
Compliance-grade audit trails require a stable on-disk sink for the captured
|
|
95
|
+
request bodies. Configure one before relying on the proxy capture for evidence:
|
|
96
|
+
|
|
97
|
+
export ANTHROPIC_LOG_DIR="$HOME/.claude/api-audit-log"
|
|
98
|
+
mkdir -p "$ANTHROPIC_LOG_DIR"
|
|
99
|
+
|
|
100
|
+
mitmproxy: --save-stream-file "$ANTHROPIC_LOG_DIR/$(date -u +%Y%m%dT%H%M%SZ).flow"
|
|
101
|
+
Burp Suite: Project options -> HTTP -> Logging -> Requests -> file in $ANTHROPIC_LOG_DIR
|
|
102
|
+
Charles: Tools -> Auto Save -> directory in $ANTHROPIC_LOG_DIR, format .chlsj
|
|
103
|
+
|
|
104
|
+
Silence this advisory once configured:
|
|
105
|
+
export CC_PROXY_CAPTURE_SUGGESTER_QUIET=1
|
|
106
|
+
EOF
|
|
107
|
+
fi
|
|
108
|
+
exit 0
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# No proxy active — emit the full four-tool advisory.
|
|
112
|
+
cat >&2 <<'EOF'
|
|
113
|
+
[proxy-capture-suggester] Compliance audit intent declared (CC_PROXY_CAPTURE_SUGGESTER_ENABLE=1)
|
|
114
|
+
but no HTTPS proxy is configured. Without one, you cannot reconstruct the system prompt that
|
|
115
|
+
was sent at the time of any logged tool execution. The v2.1.150 server-side injection channel
|
|
116
|
+
(GrowthBook tengu_heron_brook + bootstrap client_data) is acknowledged-intentional by Anthropic;
|
|
117
|
+
opt-out env vars close the channel going forward but produce no audit trail.
|
|
118
|
+
|
|
119
|
+
Four operator-side proxy options that terminate TLS and record the full request body:
|
|
120
|
+
|
|
121
|
+
1. mitmproxy (free, scriptable, recommended for compliance pipelines)
|
|
122
|
+
brew install mitmproxy # macOS
|
|
123
|
+
pipx install mitmproxy # Linux
|
|
124
|
+
Start:
|
|
125
|
+
mitmproxy --mode regular --listen-port 8080 \
|
|
126
|
+
--save-stream-file "$HOME/.claude/api-audit-log/$(date -u +%Y%m%dT%H%M%SZ).flow"
|
|
127
|
+
Bridge:
|
|
128
|
+
export HTTPS_PROXY=http://127.0.0.1:8080
|
|
129
|
+
export SSL_CERT_FILE="$HOME/.mitmproxy/mitmproxy-ca-cert.pem"
|
|
130
|
+
Verify: a single Claude Code prompt should produce a .flow file with the request body.
|
|
131
|
+
|
|
132
|
+
2. Burp Suite Community (free, GUI, common in enterprise pen-test contexts)
|
|
133
|
+
Proxy listener: 127.0.0.1:8080. Configure HTTPS_PROXY as above. Export the Burp CA cert
|
|
134
|
+
and set SSL_CERT_FILE to its path. Project options -> HTTP -> Logging -> Requests for
|
|
135
|
+
persistent capture.
|
|
136
|
+
|
|
137
|
+
3. Charles Proxy (commercial, $50, GUI, common on macOS dev workstations)
|
|
138
|
+
Default listener 127.0.0.1:8888. Tools -> Auto Save for persistent capture. Trust the
|
|
139
|
+
Charles root certificate via Charles -> Help -> SSL Proxying.
|
|
140
|
+
|
|
141
|
+
4. Anthropic SDK direct logging (free, lightweight, no proxy)
|
|
142
|
+
Set ANTHROPIC_LOG=debug to dump every request to stderr; redirect stderr to a file
|
|
143
|
+
and rotate. This captures less metadata than a proper proxy (no response timing, no
|
|
144
|
+
TLS handshake detail) but produces a request-body audit trail with no MITM overhead.
|
|
145
|
+
|
|
146
|
+
The four paths above produce an audit trail that pairs with cache-residue-detector.sh
|
|
147
|
+
(closes the cache gap) and server-side-prompt-injection-detector.sh (warns on missing
|
|
148
|
+
opt-outs). Together these three hooks cover the v2.1.150 audit surface for operators in
|
|
149
|
+
regulated industries.
|
|
150
|
+
|
|
151
|
+
Silence this advisory after configuring a proxy:
|
|
152
|
+
export CC_PROXY_CAPTURE_SUGGESTER_QUIET=1
|
|
153
|
+
|
|
154
|
+
References:
|
|
155
|
+
https://github.com/anthropics/claude-code/issues/62061 (v2.1.150 injection report, 46+ reactions)
|
|
156
|
+
https://gist.github.com/yurukusa/03839b3c3f88e1cce38fb0f2c127544d (four audit paths writeup)
|
|
157
|
+
EOF
|
|
158
|
+
|
|
159
|
+
exit 0
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# public-artefact-socratic-narrowing.sh — Inject a Socratic-narrowing prompt
|
|
3
|
+
# at the public-artefact emission boundary, asking the agent to re-engage the
|
|
4
|
+
# gradient on decisions in the artefact before it ships.
|
|
5
|
+
#
|
|
6
|
+
# Solves: #60226 (the structural-parent frame) — recognition-without-arrest at
|
|
7
|
+
# the public-artefact emission boundary, as operationalized in @beq00000's
|
|
8
|
+
# clean-state worked example (#60226, 2026-05-19 comment).
|
|
9
|
+
#
|
|
10
|
+
# In that comment, seven instances of recognition-without-arrest surfaced in a
|
|
11
|
+
# single non-drifted session. Three of the seven were caught at the public-
|
|
12
|
+
# artefact emission boundary by the operator's Socratic-narrowing intervention:
|
|
13
|
+
#
|
|
14
|
+
# "The form: not 'is this wrong' (binary question, eliciting binary defence),
|
|
15
|
+
# but 'is this verifiable / already-documented / what-would-actually-need-
|
|
16
|
+
# attention look like' (gradient question, forcing the model to re-engage
|
|
17
|
+
# the rank ordering the original output had flattened). The first form gets
|
|
18
|
+
# defended; the second gets re-decided."
|
|
19
|
+
#
|
|
20
|
+
# The operator-language form is implementable as session discipline today, but
|
|
21
|
+
# the gate fires only when the operator is present and noticing. This hook is
|
|
22
|
+
# the tooling-side form: PreToolUse on the public-artefact emission tools
|
|
23
|
+
# injects a Socratic-narrowing reminder at the boundary so the agent re-engages
|
|
24
|
+
# the gradient regardless of whether the operator is watching this turn.
|
|
25
|
+
#
|
|
26
|
+
# The hook deliberately does not check what the artefact says. Recognition-
|
|
27
|
+
# without-arrest cannot be solved by content classification (that is the
|
|
28
|
+
# failure mode being addressed). The gate's only job is to force one more
|
|
29
|
+
# pass over the artefact with the gradient framing applied. The agent's
|
|
30
|
+
# re-emission is what does the work.
|
|
31
|
+
#
|
|
32
|
+
# Related Issues / Reports:
|
|
33
|
+
# #60226 (@suwayama, 2026-05-18) — recognition-without-arrest framework
|
|
34
|
+
# comment thread → @beq00000 2026-05-19 clean-state worked
|
|
35
|
+
# example with seven instances and the Socratic-narrowing
|
|
36
|
+
# mitigation
|
|
37
|
+
# #60188 (@suwayama) — binary-collapse subhypothesis; the
|
|
38
|
+
# Socratic form re-introduces the gradient
|
|
39
|
+
# #60506 (@zean89, 2026-05-19) — six-day drift across PR-body emissions
|
|
40
|
+
# that survived multiple operator passes
|
|
41
|
+
#
|
|
42
|
+
# TRIGGER: PreToolUse
|
|
43
|
+
# MATCHER: Bash|Write|Edit
|
|
44
|
+
#
|
|
45
|
+
# HOW IT WORKS:
|
|
46
|
+
# 1. Reads PreToolUse input via stdin.
|
|
47
|
+
# 2. For Bash, matches the command against public-artefact emission patterns
|
|
48
|
+
# (gh pr create/edit, gh issue create/comment, gh release create,
|
|
49
|
+
# git commit -m '<long>', git tag -a, etc.).
|
|
50
|
+
# 3. For Write/Edit, matches the target path against public-artefact paths
|
|
51
|
+
# (.github/, CHANGELOG.md, README*.md, docs/, sales-page*.md, etc.).
|
|
52
|
+
# 4. If the artefact body / file content is below a length threshold
|
|
53
|
+
# (default 200 chars), allows it through silently — short artefacts are
|
|
54
|
+
# not where the binary-collapse failure surfaces.
|
|
55
|
+
# 5. Computes a content hash of the artefact body. If the same hash was
|
|
56
|
+
# seen within the cache window (default 600s), allows through — the
|
|
57
|
+
# agent has already re-engaged the gradient on this content.
|
|
58
|
+
# 6. Otherwise emits a Socratic-narrowing system-reminder via stderr and
|
|
59
|
+
# exits 2, blocking the emission until the agent re-emits.
|
|
60
|
+
#
|
|
61
|
+
# The hash-based cache is what makes the gate non-infinite. After the agent
|
|
62
|
+
# re-emits with the gradient applied (different content → new hash → re-fired
|
|
63
|
+
# once), or after deliberately re-emitting the same content (operator-
|
|
64
|
+
# approved → hash matches → passes through), the artefact ships.
|
|
65
|
+
#
|
|
66
|
+
# CONFIGURATION (environment variables):
|
|
67
|
+
# CC_SOCRATIC_DISABLE set to "1" to disable the gate entirely
|
|
68
|
+
# CC_SOCRATIC_STATE_DIR default /tmp/cc-socratic-cache
|
|
69
|
+
# CC_SOCRATIC_BODY_MIN_CHARS default 200 — artefacts shorter than this
|
|
70
|
+
# are not gated
|
|
71
|
+
# CC_SOCRATIC_CACHE_TTL_SECONDS default 600 — how long a hash counts as
|
|
72
|
+
# "already re-engaged"
|
|
73
|
+
# CC_SOCRATIC_BASH_PATTERNS default built-in — regex of Bash commands
|
|
74
|
+
# CC_SOCRATIC_FILE_PATTERNS default built-in — regex of file paths
|
|
75
|
+
#
|
|
76
|
+
# USAGE (settings.json):
|
|
77
|
+
# {
|
|
78
|
+
# "hooks": {
|
|
79
|
+
# "PreToolUse": [{
|
|
80
|
+
# "matcher": "Bash|Write|Edit",
|
|
81
|
+
# "hooks": [{
|
|
82
|
+
# "type": "command",
|
|
83
|
+
# "command": "~/.claude/hooks/public-artefact-socratic-narrowing.sh"
|
|
84
|
+
# }]
|
|
85
|
+
# }]
|
|
86
|
+
# }
|
|
87
|
+
# }
|
|
88
|
+
|
|
89
|
+
set -uo pipefail
|
|
90
|
+
|
|
91
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
92
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
93
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
94
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
95
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
96
|
+
_nojq_warned="/tmp/cc-nojq-warned-public-artefact-socratic-narrowing-$PPID"
|
|
97
|
+
[ -f "$_nojq_warned" ] || {
|
|
98
|
+
echo "WARNING [public-artefact-socratic-narrowing]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
99
|
+
: > "$_nojq_warned"
|
|
100
|
+
}
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
[ "${CC_SOCRATIC_DISABLE:-0}" = "1" ] && exit 0
|
|
104
|
+
|
|
105
|
+
# OPT-IN: this gate blocks every public-artefact emission (commits, PRs, docs
|
|
106
|
+
# edits) on first pass, which is high friction as a default. It is therefore
|
|
107
|
+
# off unless explicitly enabled. Set CC_SOCRATIC_ENABLE=1 to turn it on.
|
|
108
|
+
[ "${CC_SOCRATIC_ENABLE:-0}" = "1" ] || exit 0
|
|
109
|
+
|
|
110
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
111
|
+
[ -z "$INPUT" ] && exit 0
|
|
112
|
+
|
|
113
|
+
STATE_DIR="${CC_SOCRATIC_STATE_DIR:-/tmp/cc-socratic-cache}"
|
|
114
|
+
BODY_MIN_CHARS="${CC_SOCRATIC_BODY_MIN_CHARS:-200}"
|
|
115
|
+
CACHE_TTL="${CC_SOCRATIC_CACHE_TTL_SECONDS:-600}"
|
|
116
|
+
|
|
117
|
+
DEFAULT_BASH_PATTERNS='gh[[:space:]]+pr[[:space:]]+(create|edit)|gh[[:space:]]+issue[[:space:]]+(create|comment)|gh[[:space:]]+release[[:space:]]+create|gh[[:space:]]+gist[[:space:]]+create|git[[:space:]]+commit[[:space:]]+.*-m|git[[:space:]]+tag[[:space:]]+-a|git[[:space:]]+notes[[:space:]]+add'
|
|
118
|
+
DEFAULT_FILE_PATTERNS='(^|/)\.github/|(^|/)CHANGELOG(\.[a-z]+)?|(^|/)README[^/]*$|(^|/)docs?/|(^|/)sales-page|(^|/)launch-|(^|/)RELEASE|(^|/)NOTICE|(^|/)CITATION'
|
|
119
|
+
|
|
120
|
+
BASH_PATTERNS="${CC_SOCRATIC_BASH_PATTERNS:-$DEFAULT_BASH_PATTERNS}"
|
|
121
|
+
FILE_PATTERNS="${CC_SOCRATIC_FILE_PATTERNS:-$DEFAULT_FILE_PATTERNS}"
|
|
122
|
+
|
|
123
|
+
mkdir -p "$STATE_DIR" 2>/dev/null || true
|
|
124
|
+
|
|
125
|
+
# Extract tool name and input from the PreToolUse payload
|
|
126
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // .tool // empty' 2>/dev/null)
|
|
127
|
+
[ -z "$TOOL_NAME" ] && exit 0
|
|
128
|
+
|
|
129
|
+
ARTEFACT_BODY=""
|
|
130
|
+
ARTEFACT_KIND=""
|
|
131
|
+
|
|
132
|
+
case "$TOOL_NAME" in
|
|
133
|
+
Bash)
|
|
134
|
+
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
135
|
+
[ -z "$CMD" ] && exit 0
|
|
136
|
+
# Does the command match a public-artefact emission pattern?
|
|
137
|
+
printf '%s' "$CMD" | grep -Eiq "$BASH_PATTERNS" || exit 0
|
|
138
|
+
ARTEFACT_BODY="$CMD"
|
|
139
|
+
ARTEFACT_KIND="bash-command"
|
|
140
|
+
;;
|
|
141
|
+
Write)
|
|
142
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
143
|
+
[ -z "$FILE_PATH" ] && exit 0
|
|
144
|
+
printf '%s' "$FILE_PATH" | grep -Eiq "$FILE_PATTERNS" || exit 0
|
|
145
|
+
ARTEFACT_BODY=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // empty' 2>/dev/null)
|
|
146
|
+
ARTEFACT_KIND="file-write:$FILE_PATH"
|
|
147
|
+
;;
|
|
148
|
+
Edit)
|
|
149
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
150
|
+
[ -z "$FILE_PATH" ] && exit 0
|
|
151
|
+
printf '%s' "$FILE_PATH" | grep -Eiq "$FILE_PATTERNS" || exit 0
|
|
152
|
+
ARTEFACT_BODY=$(printf '%s' "$INPUT" | jq -r '.tool_input.new_string // empty' 2>/dev/null)
|
|
153
|
+
ARTEFACT_KIND="file-edit:$FILE_PATH"
|
|
154
|
+
;;
|
|
155
|
+
*)
|
|
156
|
+
exit 0
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
|
|
160
|
+
# Below threshold → not where the failure surfaces
|
|
161
|
+
BODY_LEN=${#ARTEFACT_BODY}
|
|
162
|
+
if [ "$BODY_LEN" -lt "$BODY_MIN_CHARS" ]; then
|
|
163
|
+
exit 0
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Hash the artefact body. If we have seen this hash recently, the agent has
|
|
167
|
+
# already had one Socratic-narrowing pass on it — allow through.
|
|
168
|
+
HASH=$(printf '%s' "$ARTEFACT_BODY" | sha256sum 2>/dev/null | awk '{print $1}')
|
|
169
|
+
[ -z "$HASH" ] && exit 0
|
|
170
|
+
|
|
171
|
+
CACHE_FILE="$STATE_DIR/$HASH"
|
|
172
|
+
NOW=$(date +%s)
|
|
173
|
+
|
|
174
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
175
|
+
CACHED_AT=$(cat "$CACHE_FILE" 2>/dev/null || echo 0)
|
|
176
|
+
AGE=$((NOW - CACHED_AT))
|
|
177
|
+
if [ "$AGE" -lt "$CACHE_TTL" ]; then
|
|
178
|
+
# Same content within window → agent has re-engaged → ship it
|
|
179
|
+
exit 0
|
|
180
|
+
fi
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Record the hash so the re-emission passes through
|
|
184
|
+
echo "$NOW" > "$CACHE_FILE"
|
|
185
|
+
|
|
186
|
+
# Best-effort cache eviction: drop entries older than 24h
|
|
187
|
+
find "$STATE_DIR" -type f -mmin +1440 -delete 2>/dev/null || true
|
|
188
|
+
|
|
189
|
+
# Emit the Socratic-narrowing reminder and block the emission once
|
|
190
|
+
cat >&2 <<EOF
|
|
191
|
+
<system-reminder>
|
|
192
|
+
PUBLIC-ARTEFACT EMISSION BOUNDARY — about to emit $ARTEFACT_KIND
|
|
193
|
+
($BODY_LEN chars). This is the boundary at which three of seven instances of
|
|
194
|
+
recognition-without-arrest surfaced in @beq00000's clean-state worked example
|
|
195
|
+
on #60226 (2026-05-19).
|
|
196
|
+
|
|
197
|
+
Before this artefact ships, re-engage the gradient on each decision in it.
|
|
198
|
+
The Socratic-narrowing form (per @beq00000) is the one that works:
|
|
199
|
+
|
|
200
|
+
Not "is any of this wrong?" — that question elicits binary defence and
|
|
201
|
+
the model defends the artefact as emitted.
|
|
202
|
+
|
|
203
|
+
Instead, ask of each list / each claim / each register choice in the
|
|
204
|
+
artefact:
|
|
205
|
+
(a) What is the gradient this decision sits on?
|
|
206
|
+
e.g. item-substantiveness, public-appropriateness, verifiable-vs-
|
|
207
|
+
speculative, novel-vs-already-documented, gradient-flag-quality.
|
|
208
|
+
(b) Which items in the artefact collapse into the substantive end of
|
|
209
|
+
the gradient on second-pass review? Which collapse into the trivial
|
|
210
|
+
end?
|
|
211
|
+
(c) Reproduce the artefact with the gradient applied — keep what
|
|
212
|
+
survives, drop or rephrase what does not.
|
|
213
|
+
|
|
214
|
+
Then re-emit. If the re-emitted artefact is structurally different from this
|
|
215
|
+
one, that is the gate working. If the re-emitted artefact is byte-identical
|
|
216
|
+
to this one and you have considered the gradient and stand by every decision,
|
|
217
|
+
re-running the same command within ${CACHE_TTL}s will ship it (the hash
|
|
218
|
+
matches and the gate passes through).
|
|
219
|
+
|
|
220
|
+
To disable this gate intentionally (for low-stakes commits, automated tooling,
|
|
221
|
+
non-public artefacts mis-classified as public), set CC_SOCRATIC_DISABLE=1 in
|
|
222
|
+
your environment, or refine CC_SOCRATIC_BASH_PATTERNS / CC_SOCRATIC_FILE_PATTERNS
|
|
223
|
+
to exclude the false-positive class.
|
|
224
|
+
|
|
225
|
+
Underlying mechanism (per @suwayama #60188): binary-collapse of decisions
|
|
226
|
+
that should sit on a gradient. The reminder above is the operator-language
|
|
227
|
+
intervention promoted to a tooling-side gate; the gradient framing is what
|
|
228
|
+
makes it work, not the blocking.
|
|
229
|
+
</system-reminder>
|
|
230
|
+
EOF
|
|
231
|
+
|
|
232
|
+
exit 2
|
|
@@ -17,6 +17,18 @@
|
|
|
17
17
|
|
|
18
18
|
set -uo pipefail
|
|
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-public-repo-push-guard-$PPID"
|
|
26
|
+
[ -f "$_nojq_warned" ] || {
|
|
27
|
+
echo "WARNING [public-repo-push-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
|
|
File without changes
|
|
@@ -27,6 +27,18 @@
|
|
|
27
27
|
#
|
|
28
28
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
29
29
|
|
|
30
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
31
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
32
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
33
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
34
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
35
|
+
_nojq_warned="/tmp/cc-nojq-warned-push-requires-test-pass-$PPID"
|
|
36
|
+
[ -f "$_nojq_warned" ] || {
|
|
37
|
+
echo "WARNING [push-requires-test-pass]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
38
|
+
: > "$_nojq_warned"
|
|
39
|
+
}
|
|
40
|
+
fi
|
|
41
|
+
|
|
30
42
|
INPUT=$(cat)
|
|
31
43
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
32
44
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# quota-anomaly-detector.sh — alert when token consumption rate diverges from your personal baseline
|
|
3
|
+
#
|
|
4
|
+
# Why: The Pro Max quota anomaly cluster (#16157 / #38335 / #45756 / #41788 / #29579
|
|
5
|
+
# / #19673 / cumulative ~1,600 reactions) reports the same operator-side symptom:
|
|
6
|
+
# the quota empties materially faster than the same workflow used to consume it,
|
|
7
|
+
# sometimes within minutes of the session starting. Four issues name a runtime
|
|
8
|
+
# version or date boundary (2026-03-23 / v2.1.89 / v2.1.100 / 2.1.1) so the
|
|
9
|
+
# shift is version-correlated.
|
|
10
|
+
#
|
|
11
|
+
# cache-creation-drift-detector.sh catches the *per-request* server-side
|
|
12
|
+
# inflation documented in #46917, but it cannot see the cross-request picture:
|
|
13
|
+
# a session that fires 40 small requests in 10 minutes burns the same quota as
|
|
14
|
+
# one large request, and only the rolling rate exposes it. This hook fills that
|
|
15
|
+
# gap by tracking total tokens-per-minute against a personal trailing baseline.
|
|
16
|
+
#
|
|
17
|
+
# Composes with cache-creation-drift-detector (per-request) and the existing
|
|
18
|
+
# session-quota-tracker.sh (raw tool-call count, no token weight).
|
|
19
|
+
#
|
|
20
|
+
# Event: PostToolUse MATCHER: "" (all tools)
|
|
21
|
+
# Action: Sum input_tokens + output_tokens + cache_read_input_tokens +
|
|
22
|
+
# cache_creation_input_tokens from the PostToolUse payload (or last
|
|
23
|
+
# assistant turn in the transcript as fallback). Append a timestamped
|
|
24
|
+
# sample to a rolling JSONL log. Compute the operator's tokens-per-minute
|
|
25
|
+
# over the trailing window. If the current window's rate exceeds the
|
|
26
|
+
# trailing baseline by a configurable multiplier, emit a one-line stderr
|
|
27
|
+
# warning. Advisory only (exit 0); does not block.
|
|
28
|
+
#
|
|
29
|
+
# Configuration (all optional):
|
|
30
|
+
# CC_QUOTA_ANOMALY_LOG Log path (default: ~/.cache/cc-safe-setup/quota-anomaly.jsonl)
|
|
31
|
+
# CC_QUOTA_ANOMALY_THRESHOLD Multiplier for alert (default: 1.5 = 50% above baseline rate)
|
|
32
|
+
# CC_QUOTA_ANOMALY_MIN_HISTORY Minimum samples before alerting (default: 30)
|
|
33
|
+
# CC_QUOTA_ANOMALY_WINDOW_MIN Current-rate window in minutes (default: 10)
|
|
34
|
+
# CC_QUOTA_ANOMALY_BASELINE_MIN Baseline window in minutes (default: 1440 = 24h)
|
|
35
|
+
# CC_QUOTA_ANOMALY_SILENT Set to "1" to suppress stderr (still logs)
|
|
36
|
+
#
|
|
37
|
+
# Inspect the log:
|
|
38
|
+
# tail -50 ~/.cache/cc-safe-setup/quota-anomaly.jsonl
|
|
39
|
+
# jq -s 'map(.total) | add' ~/.cache/cc-safe-setup/quota-anomaly.jsonl
|
|
40
|
+
#
|
|
41
|
+
# The registration was missing from this header. The installer reads TRIGGER
|
|
42
|
+
# and MATCHER from here and falls back to PreToolUse / Bash when both are
|
|
43
|
+
# absent, so this hook was being registered at a moment where the field it
|
|
44
|
+
# reads is always empty: it installed, it appeared in the settings, and it
|
|
45
|
+
# did nothing. Measured 2026-08-04 across examples/: 14 files were like this.
|
|
46
|
+
# TRIGGER: PostToolUse
|
|
47
|
+
# MATCHER: ""
|
|
48
|
+
|
|
49
|
+
set -u
|
|
50
|
+
|
|
51
|
+
LOG="${CC_QUOTA_ANOMALY_LOG:-${HOME}/.cache/cc-safe-setup/quota-anomaly.jsonl}"
|
|
52
|
+
THRESHOLD="${CC_QUOTA_ANOMALY_THRESHOLD:-1.5}"
|
|
53
|
+
MIN_HISTORY="${CC_QUOTA_ANOMALY_MIN_HISTORY:-30}"
|
|
54
|
+
WINDOW_MIN="${CC_QUOTA_ANOMALY_WINDOW_MIN:-10}"
|
|
55
|
+
BASELINE_MIN="${CC_QUOTA_ANOMALY_BASELINE_MIN:-1440}"
|
|
56
|
+
SILENT="${CC_QUOTA_ANOMALY_SILENT:-0}"
|
|
57
|
+
|
|
58
|
+
mkdir -p "$(dirname "$LOG")" 2>/dev/null
|
|
59
|
+
|
|
60
|
+
INPUT=$(cat)
|
|
61
|
+
|
|
62
|
+
extract_total() {
|
|
63
|
+
# $1 = jq path prefix to usage object
|
|
64
|
+
local prefix="$1"
|
|
65
|
+
printf '%s' "$INPUT" | jq -r --arg p "$prefix" '
|
|
66
|
+
def num(x): if (x | type) == "number" then x else 0 end;
|
|
67
|
+
($p | split(".") | map(select(length > 0))) as $path |
|
|
68
|
+
(getpath($path)) as $u |
|
|
69
|
+
if $u == null then empty
|
|
70
|
+
else
|
|
71
|
+
(num($u.input_tokens) + num($u.output_tokens) +
|
|
72
|
+
num($u.cache_read_input_tokens) + num($u.cache_creation_input_tokens))
|
|
73
|
+
end
|
|
74
|
+
' 2>/dev/null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Try PostToolUse payload first.
|
|
78
|
+
TOTAL=$(extract_total ".tool_response.usage")
|
|
79
|
+
|
|
80
|
+
# Fallback: read the last assistant turn's usage from the transcript.
|
|
81
|
+
if [ -z "$TOTAL" ] || [ "$TOTAL" = "0" ]; then
|
|
82
|
+
TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
83
|
+
if [ -n "$TRANSCRIPT" ] && [ -r "$TRANSCRIPT" ]; then
|
|
84
|
+
LAST_USAGE_LINE=$(tac "$TRANSCRIPT" 2>/dev/null | grep -m1 '"usage"' || true)
|
|
85
|
+
if [ -n "$LAST_USAGE_LINE" ]; then
|
|
86
|
+
TOTAL=$(printf '%s' "$LAST_USAGE_LINE" | jq -r '
|
|
87
|
+
def num(x): if (x | type) == "number" then x else 0 end;
|
|
88
|
+
(.message.usage // .usage // null) as $u |
|
|
89
|
+
if $u == null then empty
|
|
90
|
+
else
|
|
91
|
+
(num($u.input_tokens) + num($u.output_tokens) +
|
|
92
|
+
num($u.cache_read_input_tokens) + num($u.cache_creation_input_tokens))
|
|
93
|
+
end
|
|
94
|
+
' 2>/dev/null)
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
# No usable measurement.
|
|
100
|
+
if [ -z "$TOTAL" ] || [ "$TOTAL" = "0" ] || [ "$TOTAL" = "null" ]; then
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Validate positive integer.
|
|
105
|
+
case "$TOTAL" in
|
|
106
|
+
''|*[!0-9]*) exit 0 ;;
|
|
107
|
+
esac
|
|
108
|
+
|
|
109
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
|
|
110
|
+
NOW_EPOCH=$(date -u +%s)
|
|
111
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
112
|
+
|
|
113
|
+
# Append sample.
|
|
114
|
+
printf '{"ts":"%s","epoch":%s,"session":"%s","total":%s}\n' \
|
|
115
|
+
"$TS" "$NOW_EPOCH" "$SESSION_ID" "$TOTAL" >> "$LOG"
|
|
116
|
+
|
|
117
|
+
# Need MIN_HISTORY samples before trusting the baseline.
|
|
118
|
+
SAMPLE_COUNT=$(wc -l < "$LOG" 2>/dev/null | tr -d ' ')
|
|
119
|
+
SAMPLE_COUNT="${SAMPLE_COUNT:-0}"
|
|
120
|
+
if [ "$SAMPLE_COUNT" -lt "$MIN_HISTORY" ]; then
|
|
121
|
+
exit 0
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Compute current window sum and baseline window sum.
|
|
125
|
+
WINDOW_CUTOFF=$((NOW_EPOCH - WINDOW_MIN * 60))
|
|
126
|
+
BASELINE_CUTOFF=$((NOW_EPOCH - BASELINE_MIN * 60))
|
|
127
|
+
|
|
128
|
+
# Read once, compute both sums and counts.
|
|
129
|
+
SUMS=$(awk -v wc="$WINDOW_CUTOFF" -v bc="$BASELINE_CUTOFF" '
|
|
130
|
+
/"epoch":/ {
|
|
131
|
+
# Extract epoch and total via simple field parse (matches our writer format).
|
|
132
|
+
match($0, /"epoch":[0-9]+/)
|
|
133
|
+
e = substr($0, RSTART+8, RLENGTH-8) + 0
|
|
134
|
+
match($0, /"total":[0-9]+/)
|
|
135
|
+
t = substr($0, RSTART+8, RLENGTH-8) + 0
|
|
136
|
+
if (e >= bc) {
|
|
137
|
+
bs += t; bn++
|
|
138
|
+
if (e >= wc) { ws += t; wn++ }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
END { printf "%d %d %d %d", ws, wn, bs, bn }
|
|
142
|
+
' "$LOG" 2>/dev/null)
|
|
143
|
+
|
|
144
|
+
WINDOW_SUM=$(echo "$SUMS" | awk '{print $1}')
|
|
145
|
+
WINDOW_N=$(echo "$SUMS" | awk '{print $2}')
|
|
146
|
+
BASELINE_SUM=$(echo "$SUMS" | awk '{print $3}')
|
|
147
|
+
BASELINE_N=$(echo "$SUMS" | awk '{print $4}')
|
|
148
|
+
|
|
149
|
+
# Need enough activity in both windows.
|
|
150
|
+
if [ "${WINDOW_N:-0}" -lt 2 ] || [ "${BASELINE_N:-0}" -lt "$MIN_HISTORY" ]; then
|
|
151
|
+
exit 0
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Compute rates: tokens per minute in each window.
|
|
155
|
+
RATIO=$(awk -v ws="$WINDOW_SUM" -v wm="$WINDOW_MIN" \
|
|
156
|
+
-v bs="$BASELINE_SUM" -v bm="$BASELINE_MIN" '
|
|
157
|
+
BEGIN {
|
|
158
|
+
wr = ws / wm
|
|
159
|
+
br = bs / bm
|
|
160
|
+
if (br > 0) printf "%.3f", wr / br; else print "0"
|
|
161
|
+
}')
|
|
162
|
+
EXCEEDS=$(awk -v r="$RATIO" -v t="$THRESHOLD" 'BEGIN { print (r > t) ? 1 : 0 }')
|
|
163
|
+
|
|
164
|
+
if [ "$EXCEEDS" = "1" ] && [ "$SILENT" != "1" ]; then
|
|
165
|
+
WIN_RATE=$(awk -v ws="$WINDOW_SUM" -v wm="$WINDOW_MIN" 'BEGIN { printf "%d", ws/wm }')
|
|
166
|
+
BASE_RATE=$(awk -v bs="$BASELINE_SUM" -v bm="$BASELINE_MIN" 'BEGIN { printf "%d", bs/bm }')
|
|
167
|
+
PCT=$(awk -v r="$RATIO" 'BEGIN { printf "%d", (r - 1) * 100 }')
|
|
168
|
+
echo "NOTICE: token consumption rate ~${WIN_RATE} tok/min over last ${WINDOW_MIN}min is ${PCT}% above your ${BASELINE_MIN}min baseline (~${BASE_RATE} tok/min)." >&2
|
|
169
|
+
echo " Pro Max quota anomaly cluster: anthropics/claude-code #16157 / #38335 / #45756." >&2
|
|
170
|
+
echo " Inspect ${LOG} or set CC_QUOTA_ANOMALY_SILENT=1 to suppress." >&2
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
exit 0
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# quota-reset-audit.sh — weekly quota reset cluster logger (Incident 9)
|
|
3
|
+
# Why: On 2026-04-23 users reported /usage showing quota available while
|
|
4
|
+
# sessions were being rate-limited. Client-side vs server-side
|
|
5
|
+
# timezone handling of the weekly reset diverged. The dashboard's
|
|
6
|
+
# resets_at value is the only ground truth available to users, and
|
|
7
|
+
# a log of resets_at at each session start is the only way to prove
|
|
8
|
+
# "the dashboard said X, the actual reset happened Y."
|
|
9
|
+
# Event: SessionStart
|
|
10
|
+
# Action: Capture /usage --json at session start. Log the timestamp,
|
|
11
|
+
# resets_at, and percent-used to ~/.claude/logs/usage-audit.log.
|
|
12
|
+
# If /usage is unavailable (pre-v2.1.118) log a placeholder so the
|
|
13
|
+
# session never fails because of the hook.
|
|
14
|
+
|
|
15
|
+
set -u
|
|
16
|
+
|
|
17
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
18
|
+
LOG_FILE="${LOG_DIR}/usage-audit.log"
|
|
19
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
20
|
+
|
|
21
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
22
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
|
|
23
|
+
|
|
24
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
25
|
+
|
|
26
|
+
fetch_usage() {
|
|
27
|
+
# Prefer the claude CLI subcommand when available (v2.1.118+ shipped
|
|
28
|
+
# /usage with --json output). Fall back to `claude usage --json` which
|
|
29
|
+
# some earlier builds exposed. If neither works, return empty.
|
|
30
|
+
local out=""
|
|
31
|
+
if command -v claude >/dev/null 2>&1; then
|
|
32
|
+
out=$(timeout 5 claude /usage --json 2>/dev/null || true)
|
|
33
|
+
if [ -z "$out" ] || ! printf '%s' "$out" | jq -e . >/dev/null 2>&1; then
|
|
34
|
+
out=$(timeout 5 claude usage --json 2>/dev/null || true)
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
printf '%s' "$out"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
USAGE_JSON=$(fetch_usage)
|
|
41
|
+
|
|
42
|
+
if [ -z "$USAGE_JSON" ] || ! printf '%s' "$USAGE_JSON" | jq -e . >/dev/null 2>&1; then
|
|
43
|
+
printf '%s\t%s\t%s\t%s\t%s\n' \
|
|
44
|
+
"$TS" "$SESSION_ID" "unavailable" "unavailable" "unavailable" \
|
|
45
|
+
>> "$LOG_FILE"
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Expected /usage fields vary by CC version. Pull common ones defensively.
|
|
50
|
+
RESETS_AT=$(printf '%s' "$USAGE_JSON" | jq -r '.weekly.resets_at // .resets_at // .weeklyResetsAt // "unknown"' 2>/dev/null)
|
|
51
|
+
PCT_USED=$(printf '%s' "$USAGE_JSON" | jq -r '.weekly.percent_used // .percent_used // .weeklyPercentUsed // "unknown"' 2>/dev/null)
|
|
52
|
+
TIER=$(printf '%s' "$USAGE_JSON" | jq -r '.tier // .plan // "unknown"' 2>/dev/null)
|
|
53
|
+
|
|
54
|
+
printf '%s\t%s\t%s\t%s\t%s\n' \
|
|
55
|
+
"$TS" "$SESSION_ID" "$TIER" "$RESETS_AT" "$PCT_USED" \
|
|
56
|
+
>> "$LOG_FILE"
|
|
57
|
+
|
|
58
|
+
exit 0
|