cc-safe-setup 29.8.0 → 30.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +421 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-dispatch-watchdog.sh +149 -0
- package/examples/completion-claim-without-verification-detector.sh +207 -0
- package/examples/composer-guard.sh +12 -0
- package/examples/compound-bash-permission-resolver.sh +156 -0
- package/examples/compound-command-allow.sh +1 -1
- package/examples/compound-command-deny-enforcer.sh +183 -0
- package/examples/compound-inject-guard.sh +12 -0
- package/examples/concurrent-edit-lock.sh +12 -0
- package/examples/conflict-marker-guard.sh +12 -0
- package/examples/consecutive-error-breaker.sh +0 -0
- package/examples/console-log-count.sh +1 -0
- package/examples/context-compact-advisor.sh +29 -2
- package/examples/context-length-budget.sh +69 -0
- package/examples/context-threshold-alert.sh +12 -0
- package/examples/context-usage-drift-alert.sh +41 -13
- package/examples/conversation-history-guard.sh +12 -0
- package/examples/core-file-protect-guard.sh +12 -0
- package/examples/cors-star-warn.sh +0 -0
- package/examples/cost-incident-self-audit.sh +162 -0
- package/examples/cowork-claude-md-load-checker.sh +100 -0
- package/examples/cowork-fuse-staleness-watcher.sh +140 -0
- package/examples/cowork-hook-absence-warner.sh +167 -0
- package/examples/cowork-model-picker-advisor.sh +115 -0
- package/examples/credential-exfil-guard.sh +65 -4
- package/examples/credential-file-cat-guard.sh +17 -1
- package/examples/cron-create-receipt.sh +112 -0
- package/examples/cron-modification-guard.sh +12 -0
- package/examples/cross-product-mcp-spawn-detector.sh +178 -0
- package/examples/cwd-project-boundary-guard.sh +0 -0
- package/examples/daemon-zombie-worker-surfacer.sh +118 -0
- package/examples/daily-cost-guard.sh +164 -0
- package/examples/daily-usage-tracker.sh +0 -0
- package/examples/dangerous-pip-flag-guard.sh +12 -0
- package/examples/db-connect-guard.sh +13 -1
- package/examples/denied-action-retry-guard.sh +12 -0
- package/examples/deny-bypass-detector.sh +12 -0
- package/examples/deny-rule-integrity-verifier.sh +181 -0
- package/examples/dependency-install-guard.sh +12 -0
- package/examples/deploy-guard.sh +14 -2
- package/examples/deploy-path-verify-guard.sh +12 -0
- package/examples/deployment-readback-gate.sh +135 -0
- package/examples/deployment-readback-gh-adapter.sh +247 -0
- package/examples/deployment-verify-guard.sh +25 -2
- package/examples/destructive-db-script-write-guard.sh +166 -0
- package/examples/destructive-migration-write-guard.sh +163 -0
- package/examples/diff-size-guard.sh +12 -0
- package/examples/disabled-feature-toggle-advisor.sh +88 -0
- package/examples/disk-partition-guard.sh +12 -0
- package/examples/dispatch-allowlist-preflight.sh +301 -0
- package/examples/dispatch-liveness-watchdog.sh +216 -0
- package/examples/dispatch-receipt.sh +174 -0
- package/examples/django-migrate-guard.sh +12 -0
- package/examples/dns-config-guard.sh +12 -0
- package/examples/docker-dangerous-guard.sh +12 -0
- package/examples/docker-volume-guard.sh +0 -0
- package/examples/dockerfile-latest-guard.sh +1 -0
- package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
- package/examples/dotenv-commit-guard.sh +12 -0
- package/examples/dotenv-read-guard.sh +12 -0
- package/examples/dotfile-protection-guard.sh +12 -0
- package/examples/dotnet-build-on-edit.sh +1 -1
- package/examples/drizzle-migrate-guard.sh +27 -2
- package/examples/echo-probe-spam-detector.sh +176 -0
- package/examples/edit-counter-test-gate.sh +12 -0
- package/examples/edit-error-counter.sh +1 -1
- package/examples/edit-guard.sh +12 -0
- package/examples/edit-old-string-validator.sh +12 -0
- package/examples/edit-quote-ambiguity-guard.sh +97 -0
- package/examples/edit-retry-loop-guard.sh +0 -0
- package/examples/edit-verify.sh +0 -0
- package/examples/env-inline-secret-guard.sh +14 -2
- package/examples/env-naming-convention.sh +0 -0
- package/examples/env-prod-guard.sh +0 -0
- package/examples/env-required-check.sh +0 -0
- package/examples/env-source-guard.sh +12 -0
- package/examples/env-var-check.sh +24 -1
- package/examples/ephemeral-container-detector.sh +147 -0
- package/examples/error-memory-guard.sh +12 -0
- package/examples/evidence-claim-gate.sh +187 -0
- package/examples/exploration-budget-guard.sh +12 -0
- package/examples/expo-eject-guard.sh +13 -0
- package/examples/extended-thinking-loop-guard.sh +139 -0
- package/examples/extended-thinking-resume-warning.sh +119 -0
- package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
- package/examples/fabricated-command-detector.sh +145 -0
- package/examples/false-disk-full-guard.sh +63 -0
- package/examples/feature-deprecation-detector.sh +109 -0
- package/examples/file-change-tracker.sh +1 -1
- package/examples/file-change-undo-tracker.sh +0 -0
- package/examples/file-edit-backup.sh +63 -14
- package/examples/file-reference-check.sh +0 -0
- package/examples/file-size-limit.sh +12 -0
- package/examples/financial-operation-guard.sh +12 -0
- package/examples/firewall-guard.sh +12 -0
- package/examples/fish-shell-wrapper.sh +125 -7
- package/examples/five-hundred-milestone.sh +1 -0
- package/examples/flask-static-route-guard.sh +89 -0
- package/examples/forbidden-response-phrase-detector.sh +161 -0
- package/examples/gem-push-guard.sh +13 -0
- package/examples/gh-cli-destructive-guard.sh +13 -1
- package/examples/git-checkout-safety-guard.sh +12 -0
- package/examples/git-checkout-uncommitted-guard.sh +12 -0
- package/examples/git-config-guard.sh +12 -0
- package/examples/git-crypt-worktree-guard.sh +12 -0
- package/examples/git-filter-repo-guard.sh +56 -0
- package/examples/git-history-rewrite-guard.sh +12 -0
- package/examples/git-hook-bypass-guard.sh +0 -0
- package/examples/git-maintenance-guard.sh +83 -0
- package/examples/git-merge-conflict-prevent.sh +0 -0
- package/examples/git-message-length-check.sh +0 -0
- package/examples/git-message-length.sh +0 -0
- package/examples/git-operations-require-approval.sh +68 -14
- package/examples/git-pack-temp-cleanup-guard.sh +102 -0
- package/examples/git-push-blast-radius-guard.sh +218 -0
- package/examples/git-remote-guard.sh +24 -3
- package/examples/git-rm-orphan-wipe-guard.sh +85 -0
- package/examples/git-stash-before-checkout.sh +12 -0
- package/examples/git-stash-before-danger.sh +0 -0
- package/examples/git-submodule-guard.sh +69 -2
- package/examples/git-tag-guard.sh +12 -0
- package/examples/github-actions-secret-guard.sh +0 -0
- package/examples/gitignore-check.sh +0 -0
- package/examples/gitops-drift-guard.sh +12 -0
- package/examples/go-mod-tidy-warn.sh +1 -0
- package/examples/go-vet-after-edit.sh +12 -0
- package/examples/goal-iteration-limit-warner.sh +152 -0
- package/examples/grep-nul-false-negative-guard.sh +30 -0
- package/examples/growthbook-flag-monitor.sh +257 -0
- package/examples/hallucination-url-check.sh +1 -1
- package/examples/halt-signal-detector.sh +135 -0
- package/examples/handoff-on-clear.sh +65 -0
- package/examples/hardcoded-ip-guard.sh +1 -0
- package/examples/headless-empty-result-guard.sh +0 -0
- package/examples/headless-stop-guard.sh +0 -0
- package/examples/helm-install-guard.sh +2 -1
- package/examples/home-critical-bash-guard.sh +17 -1
- package/examples/hook-debug-wrapper.sh +6 -2
- package/examples/hook-permission-fixer.sh +0 -0
- package/examples/hook-self-disable-detector.sh +99 -0
- package/examples/hook-stdout-sanitizer.sh +6 -2
- package/examples/hook-tamper-guard.sh +12 -0
- package/examples/idle-session-cost-alert.sh +0 -0
- package/examples/image-dimension-guard.sh +109 -0
- package/examples/image-file-validator.sh +0 -0
- package/examples/iteration-quality-degradation-detector.sh +170 -0
- package/examples/java-compile-on-edit.sh +1 -1
- package/examples/json-syntax-check.sh +0 -0
- package/examples/k8s-production-guard.sh +13 -1
- package/examples/kill-process-guard.sh +12 -0
- package/examples/kubernetes-guard.sh +13 -1
- package/examples/laravel-artisan-guard.sh +13 -0
- package/examples/large-file-guard.sh +1 -1
- package/examples/log-level-guard.sh +0 -0
- package/examples/log-truncation-guard.sh +12 -0
- package/examples/long-session-malformed-tool-call-detector.sh +183 -0
- package/examples/loop-detector.sh +12 -0
- package/examples/magic-number-warn.sh +1 -0
- package/examples/main-branch-warn.sh +12 -0
- package/examples/markdown-link-check.sh +0 -0
- package/examples/max-concurrent-agents.sh +12 -0
- package/examples/max-edit-size-guard.sh +13 -0
- package/examples/max-file-count-guard.sh +0 -0
- package/examples/max-file-delete-count.sh +0 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +0 -0
- package/examples/max-subagent-count.sh +0 -0
- package/examples/mcp-config-freeze.sh +12 -0
- package/examples/mcp-config-poisoning-audit.sh +150 -0
- package/examples/mcp-data-boundary.sh +1 -1
- package/examples/mcp-misdiagnosis-arrest.sh +209 -0
- package/examples/mcp-orphan-leak-warner.sh +49 -0
- package/examples/mcp-permissions-ask-warner.sh +151 -0
- package/examples/mcp-routine-approval-detector.sh +154 -0
- package/examples/mcp-server-allowlist.sh +12 -0
- package/examples/mcp-server-guard.sh +12 -0
- package/examples/mcp-startup-bloat-detector.sh +87 -0
- package/examples/mcp-stdio-compatibility-test.sh +153 -0
- package/examples/mcp-tool-audit-log.sh +0 -0
- package/examples/mcp-tool-guard.sh +101 -1
- package/examples/mcp-warmup-wait.sh +0 -0
- package/examples/memory-chain-audit.sh +56 -0
- package/examples/memory-orphan-detector.sh +188 -0
- package/examples/memory-write-guard.sh +99 -17
- package/examples/migration-verify-guard.sh +12 -0
- package/examples/model-swap-suggester.sh +177 -0
- package/examples/model-version-alert.sh +5 -1
- package/examples/model-version-lock.sh +63 -0
- package/examples/move-delete-sequence-guard.sh +33 -2
- package/examples/multi-file-plan-routing-gate.sh +192 -0
- package/examples/multi-vendor-concurrent-warner.sh +108 -0
- package/examples/multi-window-auth-drift-detector.sh +183 -0
- package/examples/multiline-command-approver.sh +161 -23
- package/examples/nested-background-agent-guard.sh +109 -0
- package/examples/nested-spawn-inflight-guard.sh +178 -0
- package/examples/network-exfil-guard.sh +12 -0
- package/examples/network-guard.sh +12 -0
- package/examples/network-interface-guard.sh +12 -0
- package/examples/nextjs-env-guard.sh +1 -1
- package/examples/no-absolute-import.sh +0 -0
- package/examples/no-alert-confirm-prompt.sh +0 -0
- package/examples/no-anonymous-default-export.sh +0 -0
- package/examples/no-any-type.sh +0 -0
- package/examples/no-any-typescript.sh +1 -0
- package/examples/no-ask-human.sh +12 -0
- package/examples/no-assignment-in-condition.sh +0 -0
- package/examples/no-base64-exfil.sh +12 -0
- package/examples/no-callback-hell.sh +0 -0
- package/examples/no-circular-dependency.sh +0 -0
- package/examples/no-cleartext-storage.sh +0 -0
- package/examples/no-commented-code.sh +0 -0
- package/examples/no-commit-fixup.sh +0 -0
- package/examples/no-console-assert.sh +0 -0
- package/examples/no-console-error-swallow.sh +0 -0
- package/examples/no-console-in-prod.sh +0 -0
- package/examples/no-console-log-commit.sh +12 -0
- package/examples/no-console-log.sh +0 -0
- package/examples/no-console-time.sh +0 -0
- package/examples/no-cors-wildcard.sh +4 -1
- package/examples/no-curl-upload.sh +0 -0
- package/examples/no-dangerouslySetInnerHTML.sh +0 -0
- package/examples/no-dangling-await.sh +1 -0
- package/examples/no-debug-commit.sh +12 -0
- package/examples/no-debug-in-commit.sh +0 -0
- package/examples/no-deep-nesting.sh +0 -0
- package/examples/no-deep-relative-import.sh +1 -0
- package/examples/no-default-credentials.sh +0 -0
- package/examples/no-deploy-friday.sh +13 -1
- package/examples/no-disabled-test.sh +0 -0
- package/examples/no-document-write.sh +0 -0
- package/examples/no-empty-function.sh +0 -0
- package/examples/no-eval-in-template.sh +0 -0
- package/examples/no-eval-template.sh +3 -1
- package/examples/no-eval.sh +0 -0
- package/examples/no-exec-user-input.sh +0 -0
- package/examples/no-fixme-ship.sh +12 -0
- package/examples/no-floating-promises.sh +0 -0
- package/examples/no-force-flag.sh +22 -5
- package/examples/no-force-install.sh +0 -0
- package/examples/no-git-amend.sh +12 -0
- package/examples/no-git-rebase-public.sh +0 -0
- package/examples/no-global-install.sh +12 -0
- package/examples/no-global-state.sh +0 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +0 -0
- package/examples/no-helmet-missing.sh +0 -0
- package/examples/no-http-url.sh +1 -0
- package/examples/no-http-without-https.sh +0 -0
- package/examples/no-inline-style.sh +0 -0
- package/examples/no-inline-styles.sh +1 -0
- package/examples/no-innerhtml.sh +0 -0
- package/examples/no-install-global.sh +12 -0
- package/examples/no-jwt-in-url.sh +0 -0
- package/examples/no-large-commit.sh +0 -0
- package/examples/no-localhost-expose.sh +0 -0
- package/examples/no-magic-number.sh +0 -0
- package/examples/no-md5-sha1.sh +0 -0
- package/examples/no-mixed-line-endings.sh +8 -1
- package/examples/no-mutation-in-reducer.sh +0 -0
- package/examples/no-nested-ternary.sh +0 -0
- package/examples/no-network-exfil.sh +0 -0
- package/examples/no-open-redirect.sh +0 -0
- package/examples/no-output-truncation.sh +12 -0
- package/examples/no-package-downgrade.sh +0 -0
- package/examples/no-package-lock-edit.sh +12 -0
- package/examples/no-path-join-user-input.sh +0 -0
- package/examples/no-port-bind.sh +0 -0
- package/examples/no-process-exit.sh +0 -0
- package/examples/no-prototype-pollution.sh +0 -0
- package/examples/no-push-without-ci.sh +0 -0
- package/examples/no-push-without-tests.sh +12 -0
- package/examples/no-raw-password-in-url.sh +0 -0
- package/examples/no-root-user-docker.sh +1 -0
- package/examples/no-root-write.sh +12 -0
- package/examples/no-secrets-in-args.sh +4 -1
- package/examples/no-secrets-in-logs.sh +0 -0
- package/examples/no-sensitive-log.sh +0 -0
- package/examples/no-sleep-in-hooks.sh +0 -0
- package/examples/no-star-import-python.sh +1 -0
- package/examples/no-string-concat-sql.sh +0 -0
- package/examples/no-sudo-guard.sh +12 -0
- package/examples/no-sync-fs.sh +0 -0
- package/examples/no-todo-in-merge.sh +0 -0
- package/examples/no-todo-in-production.sh +1 -0
- package/examples/no-todo-without-issue.sh +0 -0
- package/examples/no-unused-import.sh +0 -0
- package/examples/no-var-keyword.sh +0 -0
- package/examples/no-verify-blocker.sh +12 -0
- package/examples/no-wget-piped-bash.sh +12 -0
- package/examples/no-wildcard-cors.sh +0 -0
- package/examples/no-wildcard-delete.sh +0 -0
- package/examples/no-wildcard-import.sh +0 -0
- package/examples/no-with-statement.sh +0 -0
- package/examples/no-write-outside-src.sh +0 -0
- package/examples/no-xml-external-entity.sh +0 -0
- package/examples/non-english-quality-warner.sh +156 -0
- package/examples/notify-waiting.sh +1 -1
- package/examples/npm-audit-warn.sh +0 -0
- package/examples/npm-global-install-guard.sh +12 -0
- package/examples/npm-publish-guard.sh +12 -0
- package/examples/npm-script-injection.sh +0 -0
- package/examples/npm-supply-chain-guard.sh +0 -0
- package/examples/nuxt-config-guard.sh +1 -0
- package/examples/oauth-refresh-monitor.sh +210 -0
- package/examples/opus-degradation-tracker.sh +187 -0
- package/examples/opus48-routine-task-warning.sh +196 -0
- package/examples/opus48-thinking-wedge-advisor.sh +143 -0
- package/examples/output-credential-scan.sh +1 -1
- package/examples/output-secret-mask.sh +31 -9
- package/examples/output-token-spike-detector.sh +145 -0
- package/examples/package-json-guard.sh +12 -0
- package/examples/package-lock-frozen.sh +12 -0
- package/examples/parallel-batch-size-limiter.sh +121 -0
- package/examples/parallel-cascade-detector.sh +116 -0
- package/examples/partial-view-claim-arrest.sh +174 -0
- package/examples/path-deny-bash-guard.sh +12 -0
- package/examples/path-traversal-guard.sh +12 -0
- package/examples/per-prompt-token-cap.sh +124 -0
- package/examples/permission-audit-log.sh +1 -1
- package/examples/permission-denial-enforcer.sh +12 -0
- package/examples/permission-entry-validator.sh +0 -0
- package/examples/persisted-1m-model-advisor.sh +88 -0
- package/examples/php-lint-on-edit.sh +1 -1
- package/examples/pii-upload-guard.sh +12 -0
- package/examples/pip-publish-guard.sh +13 -0
- package/examples/pip-requirements-guard.sh +12 -0
- package/examples/pip-venv-required.sh +12 -0
- package/examples/plan-mode-edit-guard.sh +12 -0
- package/examples/plan-mode-enforcer.sh +12 -0
- package/examples/plan-mode-strict-guard.sh +12 -0
- package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
- package/examples/plugin-process-cleanup.sh +0 -0
- package/examples/polyglot-rm-guard.sh +12 -0
- package/examples/post-compact-safety.sh +12 -0
- package/examples/post-edit-disk-verify.sh +152 -0
- package/examples/powershell-remove-item-guard.sh +85 -0
- package/examples/pr-description-check.sh +0 -0
- package/examples/pr-duplicate-guard.sh +13 -0
- package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
- package/examples/pre-compact-knowledge-save.sh +0 -0
- package/examples/pre-compact-transcript-backup.sh +0 -0
- package/examples/pre-execution-claim-detector.sh +179 -0
- package/examples/prefer-builtin-tools.sh +10 -1
- package/examples/prefer-const.sh +0 -0
- package/examples/prefer-dedicated-tools.sh +12 -0
- package/examples/prefer-optional-chaining.sh +0 -0
- package/examples/prisma-migrate-guard.sh +24 -7
- package/examples/production-port-kill-guard.sh +12 -0
- package/examples/prompt-injection-guard.sh +2 -1
- package/examples/prompt-usage-logger.sh +0 -0
- package/examples/protect-claudemd.sh +12 -0
- package/examples/protect-dotfiles.sh +12 -0
- package/examples/proxy-capture-suggester.sh +159 -0
- package/examples/public-artefact-socratic-narrowing.sh +232 -0
- package/examples/public-repo-push-guard.sh +12 -0
- package/examples/push-requires-test-pass-record.sh +0 -0
- package/examples/push-requires-test-pass.sh +12 -0
- package/examples/quota-anomaly-detector.sh +173 -0
- package/examples/quota-reset-audit.sh +58 -0
- package/examples/quoted-flag-approver.sh +99 -10
- package/examples/rails-migration-guard.sh +12 -0
- package/examples/rate-limit-guard.sh +0 -0
- package/examples/read-all-files-enforcer.sh +0 -0
- package/examples/read-budget-guard.sh +12 -0
- package/examples/read-loop-detector.sh +59 -0
- package/examples/read-once-guard.sh +96 -0
- package/examples/read-only-mode.sh +12 -0
- package/examples/readme-exists-check.sh +0 -0
- package/examples/record-read-coverage.sh +73 -0
- package/examples/redirect-fragment-warner.sh +149 -0
- package/examples/redis-flushall-guard.sh +13 -0
- package/examples/redundant-read-blocker.sh +132 -0
- package/examples/refusal-arrest-gate.sh +248 -0
- package/examples/registry-publish-guard.sh +13 -1
- package/examples/remote-control-billing-classifier.sh +135 -0
- package/examples/replace-all-guard.sh +12 -0
- package/examples/repo-visibility-guard.sh +12 -0
- package/examples/reroute-after-block-guard.sh +150 -0
- package/examples/response-budget-guard.sh +0 -0
- package/examples/resume-drift-watcher.sh +57 -0
- package/examples/rg-replace-flag-detector.sh +125 -0
- package/examples/rhetorical-verification-prompt-detector.sh +102 -0
- package/examples/ripgrep-permission-fix.sh +0 -0
- package/examples/rm-safety-net.sh +151 -8
- package/examples/role-tool-guard.sh +12 -0
- package/examples/route-handler-emptiness-gate.sh +324 -0
- package/examples/ruby-lint-on-edit.sh +1 -1
- package/examples/runtime-binary-change-detector.sh +102 -0
- package/examples/same-command-repeat-detector.sh +196 -0
- package/examples/same-correction-arrest.sh +169 -0
- package/examples/sandbox-denywrite-enforcer.sh +78 -0
- package/examples/sandbox-relative-path-audit.sh +83 -25
- package/examples/sandbox-write-verify.sh +12 -0
- package/examples/schema-migration-guard.sh +0 -0
- package/examples/scope-expansion-receipt.sh +178 -0
- package/examples/scope-guard.sh +88 -9
- package/examples/secret-file-read-guard.sh +12 -0
- package/examples/secret-file-write-guard.sh +150 -0
- package/examples/self-modify-bypass-guard.sh +0 -0
- package/examples/sensitive-file-read-guard.sh +23 -3
- package/examples/sensitive-log-guard.sh +1 -0
- package/examples/server-side-prompt-injection-detector.sh +69 -0
- package/examples/session-agent-cost-limiter.sh +12 -0
- package/examples/session-backup-on-start.sh +1 -1
- package/examples/session-cost-alert.sh +12 -0
- package/examples/session-drift-guard.sh +12 -0
- package/examples/session-duration-guard.sh +25 -2
- package/examples/session-end-logger.sh +0 -0
- package/examples/session-health-monitor.sh +0 -0
- package/examples/session-index-repair.sh +1 -1
- package/examples/session-memory-watchdog.sh +1 -0
- package/examples/session-permission-reset-guard.sh +12 -0
- package/examples/session-persistence-verifier.sh +93 -0
- package/examples/session-plugin-pin-watch.sh +68 -0
- package/examples/session-rate-monitor.sh +176 -0
- package/examples/session-resume-env-fix.sh +0 -0
- package/examples/session-start-quota-status.sh +193 -0
- package/examples/session-start-safety-check.sh +55 -3
- package/examples/session-state-saver.sh +0 -0
- package/examples/session-summary-stop.sh +1 -1
- package/examples/session-summary.sh +0 -0
- package/examples/session-token-counter.sh +1 -1
- package/examples/settings-hooks-key-restorer.sh +99 -0
- package/examples/settings-json-health-check.sh +57 -0
- package/examples/settings-json-model-guard.sh +0 -0
- package/examples/settings-regression-tester.sh +188 -0
- package/examples/shell-config-truncation-guard.sh +12 -0
- package/examples/shell-wrapper-guard.sh +12 -0
- package/examples/skill-cumulative-size-detector.sh +104 -0
- package/examples/skill-description-drop-detector.sh +148 -0
- package/examples/skill-gate.sh +0 -0
- package/examples/skill-truncation-detector.sh +154 -0
- package/examples/skills-context-recorder.sh +167 -0
- package/examples/skills-load-verifier.sh +96 -0
- package/examples/skills-settings-validator.sh +139 -0
- package/examples/sonnet-45-deprecation-helper.sh +85 -0
- package/examples/spec-file-scope-guard.sh +12 -0
- package/examples/spring-profile-guard.sh +1 -0
- package/examples/spurious-malformed-notice-detector.sh +247 -0
- package/examples/sql-bulk-delete-warn.sh +88 -0
- package/examples/sql-injection-detect.sh +0 -0
- package/examples/ssh-key-protect.sh +12 -0
- package/examples/staged-secret-scan.sh +22 -1
- package/examples/stale-temp-settings-detector.sh +86 -0
- package/examples/standing-rule-session-surfacer.sh +137 -0
- package/examples/stop-hook-sigterm-wrapper.sh +182 -0
- package/examples/stop-transcript-write-health.sh +64 -0
- package/examples/strict-allowlist.sh +57 -15
- package/examples/strip-coauthored-by.sh +50 -10
- package/examples/subagent-blast-radius-guard.sh +184 -0
- package/examples/subagent-boundary-precheck.sh +126 -0
- package/examples/subagent-budget-guard.sh +12 -0
- package/examples/subagent-claudemd-inject.sh +0 -0
- package/examples/subagent-closure-verify-gate.sh +164 -0
- package/examples/subagent-destructive-git-guard.sh +120 -0
- package/examples/subagent-error-detector.sh +0 -0
- package/examples/subagent-forged-system-reminder-guard.sh +156 -0
- package/examples/subagent-identity-leak-guard.sh +102 -0
- package/examples/subagent-identity-reassertion.sh +51 -0
- package/examples/subagent-inheritance-tester.sh +179 -0
- package/examples/subagent-permission-mode-guard.sh +110 -0
- package/examples/subagent-scope-guard.sh +12 -0
- package/examples/subagent-spawn-verification-enforcer.sh +102 -0
- package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
- package/examples/subagent-tool-call-limiter.sh +87 -15
- package/examples/subcommand-chain-guard.sh +12 -0
- package/examples/subscription-api-billing-warner.sh +160 -0
- package/examples/subscription-bypass-detector.sh +152 -0
- package/examples/svelte-lint-on-edit.sh +1 -0
- package/examples/swift-build-on-edit.sh +1 -1
- package/examples/symlink-guard.sh +27 -2
- package/examples/symlink-protect.sh +1 -0
- package/examples/system-dir-protection-guard.sh +73 -8
- package/examples/system-message-workaround.sh +38 -13
- package/examples/system-package-guard.sh +12 -0
- package/examples/systemd-service-guard.sh +12 -0
- package/examples/task-integrity-guard.sh +12 -0
- package/examples/temp-file-cleanup.sh +1 -1
- package/examples/temporal-suggestion-detector.sh +135 -0
- package/examples/terraform-guard.sh +27 -6
- package/examples/test-after-edit.sh +1 -1
- package/examples/test-before-push.sh +12 -0
- package/examples/test-coverage-reminder.sh +24 -1
- package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
- package/examples/timezone-guard.sh +0 -0
- package/examples/tmp-output-size-guard.sh +0 -0
- package/examples/todo-check.sh +1 -1
- package/examples/token-budget-guard.sh +12 -0
- package/examples/token-budget-per-task.sh +12 -0
- package/examples/token-usage-tracker.sh +7 -1
- package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
- package/examples/tokenizer-ratio-alert.sh +104 -0
- package/examples/tool-call-rate-limiter.sh +0 -0
- package/examples/tool-result-correlation-checker.sh +167 -0
- package/examples/tool-result-size-guard.sh +132 -0
- package/examples/tool-retry-budget-guard.sh +12 -0
- package/examples/transcript-contamination-detector.sh +138 -0
- package/examples/trustfall-mcp-injection-guard.sh +103 -0
- package/examples/ultrareview-large-diff-advisor.sh +184 -0
- package/examples/unbounded-output-guard.sh +94 -0
- package/examples/uncommitted-changes-stop.sh +1 -0
- package/examples/uncommitted-discard-guard.sh +23 -5
- package/examples/uncommitted-work-guard.sh +12 -0
- package/examples/usage-warn.sh +0 -0
- package/examples/user-account-guard.sh +12 -0
- package/examples/userprompt-submit-receipt.sh +123 -0
- package/examples/variable-expansion-guard.sh +12 -0
- package/examples/verify-after-publish-reminder.sh +93 -0
- package/examples/verify-before-commit.sh +12 -0
- package/examples/version-bump-detector.sh +156 -0
- package/examples/version-regression-warner.sh +144 -0
- package/examples/vue-lint-on-edit.sh +1 -0
- package/examples/warn-cron-cost-trap.sh +173 -0
- package/examples/webfetch-runaway-guard.sh +89 -0
- package/examples/wellness-break-reminder.sh +118 -0
- package/examples/windows-destructive-command-guard.sh +177 -0
- package/examples/windows-path-guard.sh +12 -0
- package/examples/windows-python-stub-detector.sh +63 -0
- package/examples/work-hours-guard.sh +12 -0
- package/examples/working-directory-fence.sh +12 -0
- package/examples/workspace-lease-guard.sh +205 -0
- package/examples/worktree-create-log.sh +1 -0
- package/examples/worktree-delete-guard.sh +12 -0
- package/examples/worktree-edit-boundary-guard.sh +127 -0
- package/examples/worktree-escape-write-guard.sh +114 -0
- package/examples/worktree-hook-linker.sh +0 -0
- package/examples/worktree-hooks-path-fix.sh +111 -0
- package/examples/worktree-parent-write-guard.sh +43 -0
- package/examples/worktree-project-unify.sh +2 -1
- package/examples/worktree-remove-uncommitted-guard.sh +13 -0
- package/examples/worktree-unmerged-guard.sh +7 -1
- package/examples/write-byte-integrity-verifier.sh +190 -0
- package/examples/write-empty-content-guard.sh +67 -0
- package/examples/write-nul-corruption-detector.sh +61 -0
- package/examples/write-overwrite-confirm.sh +160 -14
- package/examples/write-secret-guard.sh +27 -5
- package/examples/write-shrink-guard.sh +12 -0
- package/examples/write-test-ratio.sh +0 -0
- package/examples/wsl-host-disk-space-guard.sh +97 -0
- package/examples/xml-format-leak-detector.sh +266 -0
- package/examples/yaml-syntax-check.sh +12 -0
- package/hooks/hooks.json +6 -6
- package/index.mjs +1718 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-dispatch-watchdog.sh +147 -0
- package/tests/test-completion-claim-without-verification-detector.sh +326 -0
- package/tests/test-compound-bash-permission-resolver.sh +264 -0
- package/tests/test-compound-command-deny-enforcer.sh +67 -0
- package/tests/test-context-length-budget.sh +68 -0
- package/tests/test-context-usage-drift-alert.sh +52 -22
- package/tests/test-cost-incident-self-audit.sh +94 -0
- package/tests/test-cowork-claude-md-load-checker.sh +257 -0
- package/tests/test-cowork-claudemd-helper.sh +141 -0
- package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
- package/tests/test-cowork-hook-absence-warner.sh +230 -0
- package/tests/test-cowork-model-picker-advisor.sh +317 -0
- package/tests/test-credential-exfil-guard.sh +62 -0
- package/tests/test-cron-create-receipt.sh +165 -0
- package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
- package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
- package/tests/test-daily-cost-guard.sh +131 -0
- package/tests/test-deny-rule-integrity-verifier.sh +288 -0
- package/tests/test-deployment-readback-gate.sh +92 -0
- package/tests/test-deployment-readback-gh-adapter.sh +163 -0
- package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
- package/tests/test-dispatch-allowlist-preflight.sh +385 -0
- package/tests/test-dispatch-liveness-watchdog.sh +319 -0
- package/tests/test-dispatch-receipt.sh +314 -0
- package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
- package/tests/test-echo-probe-spam-detector.sh +143 -0
- package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
- package/tests/test-ephemeral-container-detector.sh +251 -0
- package/tests/test-evidence-claim-gate.sh +291 -0
- package/tests/test-extended-thinking-loop-guard.sh +289 -0
- package/tests/test-extended-thinking-resume-warning.sh +240 -0
- package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
- package/tests/test-fabricated-command-detector.sh +296 -0
- package/tests/test-false-disk-full-guard.sh +36 -0
- package/tests/test-feature-deprecation-detector.sh +117 -0
- package/tests/test-forbidden-response-phrase-detector.sh +246 -0
- package/tests/test-git-operations-require-approval.sh +53 -0
- package/tests/test-git-push-blast-radius-guard.sh +115 -0
- package/tests/test-goal-iteration-limit-warner.sh +128 -0
- package/tests/test-growthbook-flag-monitor.sh +428 -0
- package/tests/test-halt-signal-detector.sh +120 -0
- package/tests/test-hook-self-disable-detector.sh +232 -0
- package/tests/test-iteration-quality-degradation-detector.sh +244 -0
- package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
- package/tests/test-marketplace-plugins.sh +193 -0
- package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
- package/tests/test-mcp-orphan-leak-warner.sh +71 -0
- package/tests/test-mcp-permissions-ask-warner.sh +207 -0
- package/tests/test-mcp-routine-approval-detector.sh +229 -0
- package/tests/test-mcp-startup-bloat-detector.sh +141 -0
- package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
- package/tests/test-memory-chain-audit.sh +59 -0
- package/tests/test-memory-orphan-detector.sh +227 -0
- package/tests/test-model-swap-suggester.sh +368 -0
- package/tests/test-model-version-lock.sh +83 -0
- package/tests/test-multi-file-plan-routing-gate.sh +277 -0
- package/tests/test-multi-window-auth-drift-detector.sh +262 -0
- package/tests/test-nested-spawn-inflight-guard.sh +281 -0
- package/tests/test-no-force-flag.sh +49 -0
- package/tests/test-non-english-quality-warner.sh +229 -0
- package/tests/test-oauth-refresh-monitor.sh +311 -0
- package/tests/test-opus-degradation-tracker.sh +274 -0
- package/tests/test-opus48-routine-task-warning.sh +201 -0
- package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
- package/tests/test-output-token-spike-detector.sh +315 -0
- package/tests/test-parallel-batch-size-limiter.sh +228 -0
- package/tests/test-parallel-cascade-detector.sh +191 -0
- package/tests/test-partial-view-claim-arrest.sh +272 -0
- package/tests/test-per-prompt-token-cap.sh +136 -0
- package/tests/test-persisted-1m-model-advisor.sh +71 -0
- package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
- package/tests/test-post-edit-disk-verify.sh +294 -0
- package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
- package/tests/test-pre-execution-claim-detector.sh +366 -0
- package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
- package/tests/test-proxy-capture-suggester.sh +214 -0
- package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
- package/tests/test-quota-anomaly-detector.sh +321 -0
- package/tests/test-quota-reset-audit.sh +81 -0
- package/tests/test-read-loop-detector.sh +137 -0
- package/tests/test-read-once-guard.sh +85 -0
- package/tests/test-receipts-aggregate.sh +143 -0
- package/tests/test-redirect-fragment-warner.sh +130 -0
- package/tests/test-redundant-read-blocker.sh +155 -0
- package/tests/test-refusal-arrest-gate.sh +303 -0
- package/tests/test-remote-control-billing-classifier.sh +125 -0
- package/tests/test-resume-drift-watcher.sh +65 -0
- package/tests/test-rg-replace-flag-detector.sh +175 -0
- package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
- package/tests/test-rm-safety-net.sh +115 -0
- package/tests/test-route-handler-emptiness-gate.sh +300 -0
- package/tests/test-runtime-binary-change-detector.sh +196 -0
- package/tests/test-same-command-repeat-detector.sh +165 -0
- package/tests/test-same-correction-arrest.sh +165 -0
- package/tests/test-scope-expansion-receipt.sh +207 -0
- package/tests/test-server-side-prompt-injection-detector.sh +181 -0
- package/tests/test-session-persistence-verifier.sh +128 -0
- package/tests/test-session-rate-monitor.sh +284 -0
- package/tests/test-session-start-quota-status.sh +210 -0
- package/tests/test-session-start-safety-check.sh +138 -0
- package/tests/test-settings-hooks-key-restorer.sh +257 -0
- package/tests/test-settings-json-health-check.sh +70 -0
- package/tests/test-settings-regression-tester.sh +197 -0
- package/tests/test-skill-cumulative-size-detector.sh +198 -0
- package/tests/test-skill-description-drop-detector.sh +236 -0
- package/tests/test-skill-truncation-detector.sh +263 -0
- package/tests/test-skills-context-recorder.sh +329 -0
- package/tests/test-skills-load-verifier.sh +184 -0
- package/tests/test-skills-settings-validator.sh +242 -0
- package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
- package/tests/test-spurious-malformed-notice-detector.sh +290 -0
- package/tests/test-sql-bulk-delete-warn.sh +123 -0
- package/tests/test-ssh-key-protect.sh +81 -0
- package/tests/test-stale-temp-settings-detector.sh +161 -0
- package/tests/test-standing-rule-session-surfacer.sh +215 -0
- package/tests/test-starter-hooks-manifest.sh +96 -0
- package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
- package/tests/test-strict-allowlist.sh +72 -0
- package/tests/test-subagent-boundary-precheck.sh +137 -0
- package/tests/test-subagent-closure-verify-gate.sh +193 -0
- package/tests/test-subagent-destructive-git-guard.sh +86 -0
- package/tests/test-subagent-identity-leak-guard.sh +62 -0
- package/tests/test-subagent-identity-reassertion.sh +61 -0
- package/tests/test-subagent-inheritance-tester.sh +319 -0
- package/tests/test-subagent-permission-mode-guard.sh +61 -0
- package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
- package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
- package/tests/test-subagent-tool-call-limiter.sh +97 -0
- package/tests/test-subscription-api-billing-warner.sh +138 -0
- package/tests/test-subscription-bypass-detector.sh +255 -0
- package/tests/test-temporal-suggestion-detector.sh +183 -0
- package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
- package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
- package/tests/test-tokenizer-ratio-alert.sh +93 -0
- package/tests/test-tool-result-correlation-checker.sh +264 -0
- package/tests/test-tool-result-size-guard.sh +121 -0
- package/tests/test-transcript-contamination-detector.sh +264 -0
- package/tests/test-trigger-header-parsing.sh +151 -0
- package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
- package/tests/test-userprompt-submit-receipt.sh +181 -0
- package/tests/test-verify-after-publish-reminder.sh +184 -0
- package/tests/test-version-bump-detector.sh +212 -0
- package/tests/test-version-regression-warner.sh +165 -0
- package/tests/test-warn-cron-cost-trap.sh +82 -0
- package/tests/test-webfetch-runaway-guard.sh +77 -0
- package/tests/test-wellness-break-reminder.sh +138 -0
- package/tests/test-windows-destructive-command-guard.sh +169 -0
- package/tests/test-windows-python-stub-detector.sh +146 -0
- package/tests/test-worktree-edit-boundary-guard.sh +219 -0
- package/tests/test-write-byte-integrity-verifier.sh +192 -0
- package/tests/test-xml-format-leak-detector.sh +299 -0
- package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
- package/tests/workspace-lease-guard.test.sh +144 -0
- package/tests/worktree-escape-write-guard.test.sh +68 -0
- package/tests/worktree-hooks-path-fix.test.sh +181 -0
- package/tests/worktree-parent-write-guard.test.sh +51 -0
- package/tests/write-empty-content-guard.test.sh +39 -0
- package/tests/write-nul-corruption-detector.test.sh +29 -0
- package/tests/write-overwrite-unread-content.test.sh +178 -0
- package/tests/wsl-host-disk-space-guard.test.sh +55 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# write-empty-content-guard.sh — Block clearing an existing non-empty file with empty content
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# A Write that sends empty or whitespace-only content to a path that
|
|
7
|
+
# already holds a non-empty file silently clears that file. Reported in
|
|
8
|
+
# anthropics/claude-code#72666 (a tool wrote null/empty content and wiped
|
|
9
|
+
# the file with no safety confirmation). Almost every real edit has real
|
|
10
|
+
# content, so an empty write over a non-empty file is nearly always an
|
|
11
|
+
# accident — this blocks exactly that case and nothing else.
|
|
12
|
+
#
|
|
13
|
+
# HOW IT WORKS:
|
|
14
|
+
# PreToolUse on Write. If the target file exists and is non-empty, and the
|
|
15
|
+
# incoming `content` is empty or only whitespace, exit 2 (block) with a
|
|
16
|
+
# message. New files, and writes that carry real content, pass through.
|
|
17
|
+
# This is narrower than a generic overwrite warning: it does not fire on
|
|
18
|
+
# normal edits, only on the truncate-to-empty case.
|
|
19
|
+
#
|
|
20
|
+
# TRIGGER: PreToolUse
|
|
21
|
+
# MATCHER: "Write"
|
|
22
|
+
#
|
|
23
|
+
# CONFIGURATION:
|
|
24
|
+
# none
|
|
25
|
+
# ================================================================
|
|
26
|
+
set -uo pipefail
|
|
27
|
+
|
|
28
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
29
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
30
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
31
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
32
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
33
|
+
_nojq_warned="/tmp/cc-nojq-warned-write-empty-content-guard-$PPID"
|
|
34
|
+
[ -f "$_nojq_warned" ] || {
|
|
35
|
+
echo "WARNING [write-empty-content-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
36
|
+
: > "$_nojq_warned"
|
|
37
|
+
}
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
INPUT=$(cat)
|
|
41
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
42
|
+
|
|
43
|
+
# No path -> not our case.
|
|
44
|
+
[ -z "$FILE" ] && exit 0
|
|
45
|
+
# Target does not exist -> creating a (possibly empty) new file is fine.
|
|
46
|
+
[ -f "$FILE" ] || exit 0
|
|
47
|
+
# Target is already empty -> nothing to lose.
|
|
48
|
+
[ -s "$FILE" ] || exit 0
|
|
49
|
+
|
|
50
|
+
# `content` is absent for a Write only in odd cases; treat absent as empty.
|
|
51
|
+
CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // ""' 2>/dev/null)
|
|
52
|
+
|
|
53
|
+
# Is the incoming content empty or whitespace-only?
|
|
54
|
+
if printf '%s' "$CONTENT" | grep -q '[^[:space:]]'; then
|
|
55
|
+
# Has at least one non-whitespace character -> real content, allow.
|
|
56
|
+
exit 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
exist_lines=$(wc -l < "$FILE" 2>/dev/null | tr -d ' ')
|
|
60
|
+
cat >&2 <<EOF
|
|
61
|
+
BLOCKED: Write would clear an existing non-empty file with empty content.
|
|
62
|
+
file: $FILE (currently ~${exist_lines} lines)
|
|
63
|
+
incoming content is empty or whitespace-only — this silently wipes the file (#72666).
|
|
64
|
+
If you really mean to empty it, do it explicitly (e.g. ': > "$FILE"') or write the
|
|
65
|
+
intended content. If this was an accidental empty/null write, re-issue with real content.
|
|
66
|
+
EOF
|
|
67
|
+
exit 2
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# write-nul-corruption-detector.sh — Detect NUL-byte corruption after Write/Edit
|
|
3
|
+
#
|
|
4
|
+
# Solves: On some setups (notably the Windows Cowork workspace mount) Claude
|
|
5
|
+
# Code's Write/Edit tools return success while the file written to the
|
|
6
|
+
# host disk is silently corrupted — the tail is replaced with NUL bytes
|
|
7
|
+
# (\x00). Because the byte count can be unchanged, `wc -c` and a glance
|
|
8
|
+
# at `tail` look fine, so the corruption passes review and only surfaces
|
|
9
|
+
# later when the file fails to parse or build. (GitHub Issue #70414)
|
|
10
|
+
#
|
|
11
|
+
# How it works:
|
|
12
|
+
# After Write or Edit, if the target is a text-ish file (not a known binary
|
|
13
|
+
# extension) and contains NUL bytes, raise exit 2 so Claude is told the write
|
|
14
|
+
# landed corrupted and should re-verify, instead of trusting the reported
|
|
15
|
+
# success. NUL padding survives a byte-count check; this catches it. Pure
|
|
16
|
+
# truncation without NUL bytes needs a separate size comparison and is out of
|
|
17
|
+
# scope for this hook.
|
|
18
|
+
#
|
|
19
|
+
# Why exit 2 (not a silent warning): a corrupted write is a data-integrity event
|
|
20
|
+
# — the model just recorded "done" against a file that is broken on disk. exit 2
|
|
21
|
+
# feeds the message back so the model stops trusting the success and re-checks.
|
|
22
|
+
#
|
|
23
|
+
# TRIGGER: PostToolUse MATCHER: "Write|Edit"
|
|
24
|
+
|
|
25
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
26
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
27
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
28
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
29
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
30
|
+
_nojq_warned="/tmp/cc-nojq-warned-write-nul-corruption-detector-$PPID"
|
|
31
|
+
[ -f "$_nojq_warned" ] || {
|
|
32
|
+
echo "WARNING [write-nul-corruption-detector]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
33
|
+
: > "$_nojq_warned"
|
|
34
|
+
}
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
INPUT=$(cat)
|
|
38
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.file // empty' 2>/dev/null)
|
|
39
|
+
|
|
40
|
+
[ -z "$FILE" ] || [ ! -f "$FILE" ] && exit 0
|
|
41
|
+
|
|
42
|
+
# Skip known binary formats — NUL bytes are legitimate there, not corruption.
|
|
43
|
+
case "$FILE" in
|
|
44
|
+
*.png|*.jpg|*.jpeg|*.gif|*.webp|*.ico|*.bmp|*.tiff|*.pdf|*.zip|*.gz|*.tgz|*.bz2|*.xz|*.7z|*.rar|*.tar|*.jar|*.war|*.class|*.so|*.o|*.a|*.dylib|*.dll|*.exe|*.bin|*.wasm|*.woff|*.woff2|*.ttf|*.otf|*.eot|*.mp3|*.mp4|*.wav|*.avi|*.mov|*.mkv|*.flac|*.ogg|*.webm|*.pyc|*.pdb|*.db|*.sqlite|*.sqlite3|*.parquet|*.dat)
|
|
45
|
+
exit 0 ;;
|
|
46
|
+
esac
|
|
47
|
+
|
|
48
|
+
# Detect NUL bytes by counting them out. The previous check used `grep -aPq`,
|
|
49
|
+
# but -P is GNU-only: on BSD grep (macOS) it failed, the failure was swallowed
|
|
50
|
+
# by 2>/dev/null, and the corrupted write was reported as clean. Comparing the
|
|
51
|
+
# byte count with and without NULs is exact and works on every platform.
|
|
52
|
+
if [ "$(wc -c < "$FILE" 2>/dev/null || echo 0)" -ne "$(tr -d '\000' < "$FILE" 2>/dev/null | wc -c)" ]; then
|
|
53
|
+
echo "⚠ NUL bytes found in $FILE right after Write/Edit — the write may have landed corrupted (e.g. Cowork/Windows silent NUL-padding, #70414)." >&2
|
|
54
|
+
echo " The tool reported success, but a text file should not contain NUL. The byte count can be unchanged, so 'wc -c' and 'tail' will not reveal this." >&2
|
|
55
|
+
echo " Verify: tr -d '\\000' < \"$FILE\" | wc -c (compare with wc -c on the file itself)" >&2
|
|
56
|
+
echo " Inspect: cat -v \"$FILE\" | tail (NUL shows as ^@)" >&2
|
|
57
|
+
echo " Recover: git checkout -- \"$FILE\" (if tracked), or re-write and re-verify before trusting 'done'." >&2
|
|
58
|
+
exit 2
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
exit 0
|
|
@@ -1,40 +1,186 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# write-overwrite-confirm.sh — Warn when Write
|
|
2
|
+
# write-overwrite-confirm.sh — Warn when Write destroys content nobody looked at
|
|
3
3
|
#
|
|
4
|
-
# Solves: Write tool silently replacing large files with new content
|
|
5
|
-
# A 500-line file can be overwritten with 10 lines
|
|
4
|
+
# Solves (original): Write tool silently replacing large files with new content
|
|
5
|
+
# (#34597). A 500-line file can be overwritten with 10 lines.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# Solves (2026-08 addition): #78273 — the agent read FIVE lines of a hand-built
|
|
8
|
+
# file, confirmed it had content, then overwrote the whole file with its
|
|
9
|
+
# own analysis. The original was not in git and was unrecoverable.
|
|
10
|
+
# The size check below could not see this: the replacement was not
|
|
11
|
+
# smaller, so nothing fired.
|
|
12
|
+
#
|
|
13
|
+
# A user on that thread named the general shape of the gap:
|
|
14
|
+
# "most guards key off the shape of a tool call rather than whether a
|
|
15
|
+
# write is about to destroy pre-existing, un-backed-up content
|
|
16
|
+
# (…) diffing intent against existing content before an overwrite is
|
|
17
|
+
# basically missing across the board right now."
|
|
18
|
+
#
|
|
19
|
+
# WHAT THIS ADDS: before an overwrite, ask two questions instead of one.
|
|
20
|
+
# 1. Is the replacement much smaller? (original check)
|
|
21
|
+
# 2. Was the part being destroyed ever read? (new check)
|
|
22
|
+
#
|
|
23
|
+
# Question 2 needs a record of what was read, which is why this hook is
|
|
24
|
+
# paired with examples/record-read-coverage.sh (PostToolUse on Read).
|
|
25
|
+
# Without that recorder, no read coverage is known and this check stays
|
|
26
|
+
# silent rather than warning on everything — a guard that always fires is
|
|
27
|
+
# the same as no guard.
|
|
10
28
|
#
|
|
11
29
|
# TRIGGER: PreToolUse
|
|
12
30
|
# MATCHER: "Write"
|
|
31
|
+
#
|
|
32
|
+
# TUNING (env):
|
|
33
|
+
# CC_WRITE_OVERWRITE_MIN_LINES default 20 — check 2 only: ignore smaller files
|
|
34
|
+
# CC_WRITE_OVERWRITE_MAX_DESTROY default 10 — check 2 only: unseen lines before warning
|
|
35
|
+
# CC_WRITE_OVERWRITE_BLOCK=1 — refuse the write (exit 2) instead of warning.
|
|
36
|
+
# Applies to BOTH checks below.
|
|
37
|
+
# CC_READ_LOG default /tmp/cc-read-files — check 2 only
|
|
38
|
+
#
|
|
39
|
+
# WHAT BLOCK=1 DID NOT COVER BEFORE 2026-09-19: check 1 (the shrink check) always
|
|
40
|
+
# exited 0, no matter how this was set, and check 2 exits early when the paired
|
|
41
|
+
# recorder has never run. So someone who set BLOCK=1 without installing
|
|
42
|
+
# examples/record-read-coverage.sh got exit 0 on every write while believing
|
|
43
|
+
# overwrites were refused — measured with controls on 2026-09-19. That is the
|
|
44
|
+
# failure this file names two screens down: a guard whose blocking mode does not
|
|
45
|
+
# block teaches you to ignore the word.
|
|
13
46
|
|
|
14
|
-
set -
|
|
47
|
+
set -uo pipefail
|
|
48
|
+
|
|
49
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
50
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
51
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
52
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
53
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
54
|
+
_nojq_warned="/tmp/cc-nojq-warned-write-overwrite-confirm-$PPID"
|
|
55
|
+
[ -f "$_nojq_warned" ] || {
|
|
56
|
+
echo "WARNING [write-overwrite-confirm]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
57
|
+
: > "$_nojq_warned"
|
|
58
|
+
}
|
|
59
|
+
fi
|
|
15
60
|
|
|
16
61
|
INPUT=$(cat)
|
|
17
|
-
FILE=$(
|
|
62
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
|
|
18
63
|
[ -z "$FILE" ] && exit 0
|
|
19
64
|
|
|
20
65
|
# Skip if file doesn't exist (new file creation)
|
|
21
66
|
[ ! -f "$FILE" ] && exit 0
|
|
22
67
|
|
|
23
|
-
# Get current file size (lines)
|
|
24
68
|
CURRENT_LINES=$(wc -l < "$FILE" 2>/dev/null || echo 0)
|
|
69
|
+
case "$CURRENT_LINES" in ''|*[!0-9]*) CURRENT_LINES=0 ;; esac
|
|
70
|
+
|
|
71
|
+
NEW_CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // empty' 2>/dev/null || true)
|
|
72
|
+
# printf '%s\n' and not '%s': the original used echo, which appends a newline, so
|
|
73
|
+
# single-line content counted as 1. Dropping that newline made wc -l return 0 and
|
|
74
|
+
# silently disabled the shrink check below.
|
|
75
|
+
NEW_LINES=$(printf '%s\n' "$NEW_CONTENT" | wc -l 2>/dev/null || echo 0)
|
|
76
|
+
case "$NEW_LINES" in ''|*[!0-9]*) NEW_LINES=0 ;; esac
|
|
25
77
|
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
78
|
+
# The label has to match what this run actually does. A hook that prints
|
|
79
|
+
# "BLOCKED" and then exits 0 teaches the reader to ignore the word. Decided
|
|
80
|
+
# once, up here, because BOTH checks below print it and both have to agree.
|
|
81
|
+
if [ "${CC_WRITE_OVERWRITE_BLOCK:-0}" = "1" ]; then
|
|
82
|
+
LABEL="BLOCKED"
|
|
83
|
+
else
|
|
84
|
+
LABEL="WARNING"
|
|
85
|
+
fi
|
|
29
86
|
|
|
30
|
-
#
|
|
87
|
+
# ---------------------------------------------------------------
|
|
88
|
+
# Check 1 (original): the replacement is much smaller than the file
|
|
89
|
+
# ---------------------------------------------------------------
|
|
31
90
|
if [ "$CURRENT_LINES" -gt 50 ] && [ "$NEW_LINES" -gt 0 ]; then
|
|
32
91
|
RATIO=$((NEW_LINES * 100 / CURRENT_LINES))
|
|
33
92
|
if [ "$RATIO" -lt 50 ]; then
|
|
34
|
-
echo "
|
|
93
|
+
echo "$LABEL: File shrinking from $CURRENT_LINES to ~$NEW_LINES lines ($RATIO%)." >&2
|
|
35
94
|
echo "File: $FILE" >&2
|
|
36
95
|
echo "Consider using Edit tool for targeted changes instead of full rewrite." >&2
|
|
96
|
+
# Before 2026-09-19 this fell straight through to exit 0, so the mode
|
|
97
|
+
# documented as "refuse the write" refused nothing here - and check 2,
|
|
98
|
+
# the only one that honoured it, exits early when the paired recorder
|
|
99
|
+
# has never run. Measured: 60 lines -> 1 line with BLOCK=1 returned 0.
|
|
100
|
+
[ "$LABEL" = "BLOCKED" ] && exit 2
|
|
37
101
|
fi
|
|
38
102
|
fi
|
|
39
103
|
|
|
104
|
+
# ---------------------------------------------------------------
|
|
105
|
+
# Check 2 (2026-08): the overwrite destroys lines nobody has read
|
|
106
|
+
# ---------------------------------------------------------------
|
|
107
|
+
MIN_LINES="${CC_WRITE_OVERWRITE_MIN_LINES:-20}"
|
|
108
|
+
MAX_DESTROY="${CC_WRITE_OVERWRITE_MAX_DESTROY:-10}"
|
|
109
|
+
READ_LOG="${CC_READ_LOG:-/tmp/cc-read-files}"
|
|
110
|
+
|
|
111
|
+
case "$MIN_LINES" in ''|*[!0-9]*) MIN_LINES=20 ;; esac
|
|
112
|
+
case "$MAX_DESTROY" in ''|*[!0-9]*) MAX_DESTROY=10 ;; esac
|
|
113
|
+
|
|
114
|
+
[ "$CURRENT_LINES" -lt "$MIN_LINES" ] && exit 0
|
|
115
|
+
|
|
116
|
+
# No recorder installed means no coverage information at all. Staying silent is
|
|
117
|
+
# deliberate: warning on every overwrite would make this hook noise, which is
|
|
118
|
+
# exactly the failure mode read-before-edit.sh had while its recorder was missing.
|
|
119
|
+
[ -f "$READ_LOG" ] || exit 0
|
|
120
|
+
|
|
121
|
+
# Did the reads so far cover the whole file? Intervals are merged because a file
|
|
122
|
+
# is often read in pages (offset 1 limit 100, then offset 101 limit 100, ...).
|
|
123
|
+
# offset/limit of 0 means the Read carried no such argument, i.e. it started at
|
|
124
|
+
# the top and ran to the tool's own cap, so treat it as covering what existed then.
|
|
125
|
+
COVERED=$(awk -F'\t' -v f="$FILE" -v total="$CURRENT_LINES" '
|
|
126
|
+
# n must start as a number. An uninitialised awk variable is the empty string,
|
|
127
|
+
# and s[n] then writes to the subscript "" instead of 0, so every interval
|
|
128
|
+
# lands in one invisible slot and the file always looks unread.
|
|
129
|
+
BEGIN { n = 0 }
|
|
130
|
+
$1 == f {
|
|
131
|
+
off = ($2 + 0 < 1) ? 1 : $2 + 0
|
|
132
|
+
lim = $3 + 0
|
|
133
|
+
end = (lim > 0) ? off + lim - 1 : ($4 + 0 > 0 ? $4 + 0 : total)
|
|
134
|
+
if (end > total) end = total
|
|
135
|
+
if (end >= off) { s[n] = off; e[n] = end; n++ }
|
|
136
|
+
}
|
|
137
|
+
END {
|
|
138
|
+
if (n == 0) { print 0; exit }
|
|
139
|
+
for (i = 0; i < n; i++)
|
|
140
|
+
for (j = i + 1; j < n; j++)
|
|
141
|
+
if (s[j] < s[i]) { t=s[i];s[i]=s[j];s[j]=t; t=e[i];e[i]=e[j];e[j]=t }
|
|
142
|
+
reach = 0
|
|
143
|
+
for (i = 0; i < n; i++) {
|
|
144
|
+
if (s[i] > reach + 1) break
|
|
145
|
+
if (e[i] > reach) reach = e[i]
|
|
146
|
+
}
|
|
147
|
+
print (reach >= total) ? 1 : 0
|
|
148
|
+
}' "$READ_LOG" 2>/dev/null || echo 0)
|
|
149
|
+
case "$COVERED" in ''|*[!0-9]*) COVERED=0 ;; esac
|
|
150
|
+
|
|
151
|
+
[ "$COVERED" = "1" ] && exit 0
|
|
152
|
+
|
|
153
|
+
# Count existing lines that do not appear anywhere in the replacement. This is a
|
|
154
|
+
# deliberately crude diff: it asks "is this content going away", not "did the
|
|
155
|
+
# line move". Moved lines are not destroyed, so undercounting them is correct.
|
|
156
|
+
TMP_NEW=$(mktemp 2>/dev/null) || exit 0
|
|
157
|
+
printf '%s\n' "$NEW_CONTENT" > "$TMP_NEW" 2>/dev/null || { rm -f "$TMP_NEW"; exit 0; }
|
|
158
|
+
|
|
159
|
+
if [ ! -s "$TMP_NEW" ]; then
|
|
160
|
+
# Replacing a real file with nothing destroys all of it.
|
|
161
|
+
DESTROYED="$CURRENT_LINES"
|
|
162
|
+
else
|
|
163
|
+
DESTROYED=$(grep -F -x -v -f "$TMP_NEW" -- "$FILE" 2>/dev/null | grep -c '[^[:space:]]' || echo 0)
|
|
164
|
+
fi
|
|
165
|
+
rm -f "$TMP_NEW"
|
|
166
|
+
case "$DESTROYED" in ''|*[!0-9]*) DESTROYED=0 ;; esac
|
|
167
|
+
|
|
168
|
+
[ "$DESTROYED" -lt "$MAX_DESTROY" ] && exit 0
|
|
169
|
+
|
|
170
|
+
echo "" >&2
|
|
171
|
+
echo "$LABEL: overwriting content that was never read." >&2
|
|
172
|
+
echo " File: $FILE ($CURRENT_LINES lines)" >&2
|
|
173
|
+
echo " Lines destroyed: $DESTROYED (present now, absent from the replacement)" >&2
|
|
174
|
+
echo " Read coverage: the whole file was never read in this session" >&2
|
|
175
|
+
echo "" >&2
|
|
176
|
+
echo " This is the shape of issue #78273: a few lines were read, the file was" >&2
|
|
177
|
+
echo " confirmed to have content, and then all of it was replaced." >&2
|
|
178
|
+
echo "" >&2
|
|
179
|
+
echo " Read the whole file first, or use Edit for a targeted change." >&2
|
|
180
|
+
echo " To allow this once: CC_WRITE_OVERWRITE_MAX_DESTROY=$((DESTROYED + 1))" >&2
|
|
181
|
+
if [ "$LABEL" = "WARNING" ]; then
|
|
182
|
+
echo " To refuse writes like this instead of warning: CC_WRITE_OVERWRITE_BLOCK=1" >&2
|
|
183
|
+
fi
|
|
184
|
+
|
|
185
|
+
[ "$LABEL" = "BLOCKED" ] && exit 2
|
|
40
186
|
exit 0
|
|
@@ -27,6 +27,18 @@
|
|
|
27
27
|
#
|
|
28
28
|
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
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-write-secret-guard-$PPID"
|
|
36
|
+
[ -f "$_nojq_warned" ] || {
|
|
37
|
+
echo "WARNING [write-secret-guard]: 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
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
32
44
|
|
|
@@ -75,13 +87,23 @@ if echo "$CONTENT" | grep -qE '(ghp_|gho_|ghs_|ghr_|github_pat_)[A-Za-z0-9_]{20,
|
|
|
75
87
|
fi
|
|
76
88
|
|
|
77
89
|
# OpenAI API key (sk-... or sk-proj-...)
|
|
78
|
-
|
|
90
|
+
# The prefix has to START a token. Without the left boundary this pattern also
|
|
91
|
+
# fired on ordinary English words that end in "sk" before a separator — task-,
|
|
92
|
+
# ask-, risk-, disk-, desk- — so writing a file named
|
|
93
|
+
# task-management-system-config.json was refused as a leaked OpenAI key.
|
|
94
|
+
# (Found 2026-08-13 the hard way: this hook blocked a write here over the
|
|
95
|
+
# filename ask-under-permissive-modes-firsthand-2026-08-13.json.)
|
|
96
|
+
# A guard that refuses ordinary work is a guard people switch off, so the
|
|
97
|
+
# false positive costs more than it looks. A real key never has a word
|
|
98
|
+
# character immediately before its prefix, so the boundary loses no detection.
|
|
99
|
+
if echo "$CONTENT" | grep -qE '(^|[^A-Za-z0-9_-])sk-[A-Za-z0-9_-]{20,}' \
|
|
100
|
+
&& ! echo "$CONTENT" | grep -qE '(^|[^A-Za-z0-9_-])sk-ant-'; then
|
|
79
101
|
# Exclude Anthropic keys (handled separately)
|
|
80
102
|
BLOCKED="OpenAI API key (sk-...)"
|
|
81
103
|
fi
|
|
82
104
|
|
|
83
|
-
# Anthropic API key
|
|
84
|
-
if echo "$CONTENT" | grep -qE 'sk-ant-[A-Za-z0-9-]{20,}'; then
|
|
105
|
+
# Anthropic API key — same boundary, same reason as above
|
|
106
|
+
if echo "$CONTENT" | grep -qE '(^|[^A-Za-z0-9_-])sk-ant-[A-Za-z0-9-]{20,}'; then
|
|
85
107
|
BLOCKED="Anthropic API key (sk-ant-...)"
|
|
86
108
|
fi
|
|
87
109
|
|
|
@@ -90,8 +112,8 @@ if echo "$CONTENT" | grep -qE '(xoxb-|xoxp-|xoxs-|xoxa-)[0-9A-Za-z-]{20,}'; then
|
|
|
90
112
|
BLOCKED="Slack token"
|
|
91
113
|
fi
|
|
92
114
|
|
|
93
|
-
# Stripe keys
|
|
94
|
-
if echo "$CONTENT" | grep -qE '(sk_live_|pk_live_|rk_live_)[A-Za-z0-9]{20,}'; then
|
|
115
|
+
# Stripe keys — same boundary: task_live_/risk_live_ end in the same two letters
|
|
116
|
+
if echo "$CONTENT" | grep -qE '(^|[^A-Za-z0-9_-])(sk_live_|pk_live_|rk_live_)[A-Za-z0-9]{20,}'; then
|
|
95
117
|
BLOCKED="Stripe API key"
|
|
96
118
|
fi
|
|
97
119
|
|
|
@@ -16,6 +16,18 @@
|
|
|
16
16
|
# DECISION: exit 2 = block, exit 0 = allow
|
|
17
17
|
# ================================================================
|
|
18
18
|
|
|
19
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
20
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
21
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
22
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
23
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
24
|
+
_nojq_warned="/tmp/cc-nojq-warned-write-shrink-guard-$PPID"
|
|
25
|
+
[ -f "$_nojq_warned" ] || {
|
|
26
|
+
echo "WARNING [write-shrink-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
27
|
+
: > "$_nojq_warned"
|
|
28
|
+
}
|
|
29
|
+
fi
|
|
30
|
+
|
|
19
31
|
INPUT=$(cat)
|
|
20
32
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
21
33
|
[ "$TOOL" != "Write" ] && exit 0
|
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# wsl-host-disk-space-guard.sh — Watch the WSL host (Windows C:) too
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# The bundled disk-space-guard.sh only inspects the working
|
|
7
|
+
# directory's filesystem (`df .`). On WSL2 that misses the actual
|
|
8
|
+
# choke point: the Windows host drive that backs ext4.vhdx.
|
|
9
|
+
#
|
|
10
|
+
# Past incident (2026-05-04): WSL `/dev/sdd` had 162 GiB free, but
|
|
11
|
+
# Windows `C:` was at 96% (38 GiB free out of 931 GiB). Claude Code
|
|
12
|
+
# and Codex CLI both crashed with "getpwnam failed" / I/O errors
|
|
13
|
+
# because the host could no longer extend ext4.vhdx.
|
|
14
|
+
#
|
|
15
|
+
# This hook checks `/`, `/home`, and `/mnt/c`, blocks Bash/Write
|
|
16
|
+
# when the host is critical, and warns earlier than that.
|
|
17
|
+
#
|
|
18
|
+
# TRIGGER: PreToolUse MATCHER: "Write|Bash"
|
|
19
|
+
#
|
|
20
|
+
# CONFIG:
|
|
21
|
+
# CC_HOST_DISK_WARN_PCT=90 /mnt/c warn at this percent used
|
|
22
|
+
# CC_HOST_DISK_BLOCK_PCT=95 /mnt/c block at this percent used
|
|
23
|
+
# CC_LINUX_DISK_WARN_PCT=85 /, /home warn at this percent used
|
|
24
|
+
# CC_LINUX_DISK_BLOCK_PCT=95 /, /home block at this percent used
|
|
25
|
+
# CC_HOST_DISK_DISABLE=1 disable this hook entirely
|
|
26
|
+
# ================================================================
|
|
27
|
+
|
|
28
|
+
[ "${CC_HOST_DISK_DISABLE:-0}" = "1" ] && exit 0
|
|
29
|
+
|
|
30
|
+
HOST_WARN="${CC_HOST_DISK_WARN_PCT:-90}"
|
|
31
|
+
HOST_BLOCK="${CC_HOST_DISK_BLOCK_PCT:-95}"
|
|
32
|
+
LINUX_WARN="${CC_LINUX_DISK_WARN_PCT:-85}"
|
|
33
|
+
LINUX_BLOCK="${CC_LINUX_DISK_BLOCK_PCT:-95}"
|
|
34
|
+
|
|
35
|
+
# Read percent used for a mount point, or empty if it does not exist.
|
|
36
|
+
# We check existence so this hook works on non-WSL hosts too.
|
|
37
|
+
pct_for() {
|
|
38
|
+
local mount="$1"
|
|
39
|
+
[ -d "$mount" ] || return 0
|
|
40
|
+
df --output=pcent "$mount" 2>/dev/null | tail -1 | tr -d ' %'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
avail_for() {
|
|
44
|
+
local mount="$1"
|
|
45
|
+
[ -d "$mount" ] || return 0
|
|
46
|
+
df -h --output=avail "$mount" 2>/dev/null | tail -1 | tr -d ' '
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
block=0
|
|
50
|
+
warn_lines=""
|
|
51
|
+
|
|
52
|
+
check_linux() {
|
|
53
|
+
local mount="$1"
|
|
54
|
+
local pct
|
|
55
|
+
pct=$(pct_for "$mount")
|
|
56
|
+
[ -z "$pct" ] && return 0
|
|
57
|
+
if [ "$pct" -ge "$LINUX_BLOCK" ]; then
|
|
58
|
+
echo "BLOCKED: $mount is ${pct}% full ($(avail_for "$mount") free) — above ${LINUX_BLOCK}%." >&2
|
|
59
|
+
echo " Free space inside WSL before more writes:" >&2
|
|
60
|
+
echo " du -sh ~/.cache ~/.npm ~/.claude/debug ~/.local/share/Trash 2>/dev/null" >&2
|
|
61
|
+
block=1
|
|
62
|
+
elif [ "$pct" -ge "$LINUX_WARN" ]; then
|
|
63
|
+
warn_lines="${warn_lines}WARNING: $mount is ${pct}% full ($(avail_for "$mount") free) — above ${LINUX_WARN}%."$'\n'
|
|
64
|
+
fi
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
check_host() {
|
|
68
|
+
local mount="$1"
|
|
69
|
+
local pct
|
|
70
|
+
pct=$(pct_for "$mount")
|
|
71
|
+
[ -z "$pct" ] && return 0
|
|
72
|
+
if [ "$pct" -ge "$HOST_BLOCK" ]; then
|
|
73
|
+
echo "BLOCKED: Windows host $mount is ${pct}% full ($(avail_for "$mount") free) — above ${HOST_BLOCK}%." >&2
|
|
74
|
+
echo " WSL can no longer safely extend ext4.vhdx. Past incident crashed CC and Codex." >&2
|
|
75
|
+
echo " Recovery on Windows (admin PowerShell):" >&2
|
|
76
|
+
echo " wsl --shutdown" >&2
|
|
77
|
+
echo " Optimize-VHD -Path <ext4.vhdx> -Mode Full" >&2
|
|
78
|
+
block=1
|
|
79
|
+
elif [ "$pct" -ge "$HOST_WARN" ]; then
|
|
80
|
+
warn_lines="${warn_lines}WARNING: Windows host $mount is ${pct}% full ($(avail_for "$mount") free) — above ${HOST_WARN}%."$'\n'
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# /home is on the same vhdx as / on most WSL setups, but check both in
|
|
85
|
+
# case the user mounted /home separately.
|
|
86
|
+
check_linux /
|
|
87
|
+
[ "$(stat -c '%d' /home 2>/dev/null)" != "$(stat -c '%d' / 2>/dev/null)" ] && check_linux /home
|
|
88
|
+
|
|
89
|
+
# /mnt/c only exists on WSL.
|
|
90
|
+
check_host /mnt/c
|
|
91
|
+
|
|
92
|
+
if [ -n "$warn_lines" ]; then
|
|
93
|
+
printf '%s' "$warn_lines" >&2
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
[ "$block" -eq 1 ] && exit 2
|
|
97
|
+
exit 0
|