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,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# subagent-identity-leak-guard.sh — Warn when subagent delegation
|
|
4
|
+
# lacks identity boundary enforcement
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# When the main agent spawns a subagent via the Agent tool, checks
|
|
8
|
+
# whether the delegation prompt includes explicit identity boundary
|
|
9
|
+
# enforcement: the subagent's own role, prohibition against
|
|
10
|
+
# impersonating the parent, and prohibition against exposing parent
|
|
11
|
+
# conversation history. Warns via stderr when these are missing.
|
|
12
|
+
#
|
|
13
|
+
# TRIGGER: PreToolUse
|
|
14
|
+
# MATCHER: "Agent"
|
|
15
|
+
#
|
|
16
|
+
# WHY THIS MATTERS:
|
|
17
|
+
# In v2.1.126, a regression was reported in Issue #55488: a spawned
|
|
18
|
+
# subagent (e.g. backend) was DM'd directly via the team chat UI
|
|
19
|
+
# and (1) identified itself as the parent ("team-lead") instead of
|
|
20
|
+
# its assigned name (backend), and (2) showed the user the parent's
|
|
21
|
+
# conversation history. This is an identity boundary failure: the
|
|
22
|
+
# subagent has no persistent state separating its identity from the
|
|
23
|
+
# parent's, so when queried directly it falls back to the parent's
|
|
24
|
+
# identity and history.
|
|
25
|
+
#
|
|
26
|
+
# While the root cause needs to be fixed by Anthropic, parent agents
|
|
27
|
+
# can preventively reduce the failure surface by including explicit
|
|
28
|
+
# identity boundary instructions in the delegation prompt. This hook
|
|
29
|
+
# warns when those instructions are missing.
|
|
30
|
+
#
|
|
31
|
+
# WHAT IT CHECKS:
|
|
32
|
+
# 1. Prompt mentions the subagent's own role or name (e.g. "you are",
|
|
33
|
+
# "your role is", "as the X agent")
|
|
34
|
+
# 2. Prompt prohibits impersonating the parent (e.g. "do not identify
|
|
35
|
+
# as", "do not claim to be the parent")
|
|
36
|
+
# 3. Prompt prohibits exposing parent conversation history (e.g. "do
|
|
37
|
+
# not share parent's history", "do not expose conversation log")
|
|
38
|
+
#
|
|
39
|
+
# OUTPUT:
|
|
40
|
+
# Warning to stderr listing which identity boundary instructions are
|
|
41
|
+
# missing. Always exits 0 — advisory only, never blocks.
|
|
42
|
+
#
|
|
43
|
+
# CONFIGURATION:
|
|
44
|
+
# CC_SUBAGENT_IDENTITY_REQUIRE_ALL — set to "1" to require all 3
|
|
45
|
+
# checks (default: warn on any missing check, do not require all)
|
|
46
|
+
#
|
|
47
|
+
# RELATED ISSUES:
|
|
48
|
+
# https://github.com/anthropics/claude-code/issues/55488
|
|
49
|
+
# ================================================================
|
|
50
|
+
|
|
51
|
+
set -u
|
|
52
|
+
|
|
53
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
54
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
55
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
56
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
57
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
58
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-identity-leak-guard-$PPID"
|
|
59
|
+
[ -f "$_nojq_warned" ] || {
|
|
60
|
+
echo "WARNING [subagent-identity-leak-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
61
|
+
: > "$_nojq_warned"
|
|
62
|
+
}
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
INPUT=$(cat)
|
|
66
|
+
|
|
67
|
+
PROMPT=$(printf '%s' "$INPUT" | jq -r '.tool_input.prompt // empty' 2>/dev/null)
|
|
68
|
+
|
|
69
|
+
if [ -z "$PROMPT" ]; then
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
WARNINGS=""
|
|
74
|
+
|
|
75
|
+
# Check 1: Subagent's own role or name is mentioned
|
|
76
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'you are |your role |your name |as the [a-z]+ (agent|subagent)|act as '; then
|
|
77
|
+
WARNINGS="${WARNINGS} - No explicit role assignment. Subagent may fall back to parent's identity (Issue #55488).\n"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Check 2: Prohibition against impersonating the parent
|
|
81
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'do not (identify|claim|act|pretend) (as|to be) (the )?(parent|team-lead|orchestrator|main agent)|never (identify|claim|impersonate|pretend) (as|to be) (the )?(parent|team-lead|orchestrator)'; then
|
|
82
|
+
WARNINGS="${WARNINGS} - No prohibition against impersonating the parent. Without this, the subagent may identify as the parent when DM'd directly.\n"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Check 3: Prohibition against exposing parent conversation history
|
|
86
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'do not (share|expose|reveal|show) (the )?(parent|main agent)\b.{0,40}(history|conversation|log|messages)|never (share|expose|reveal) (the )?(parent|main agent).{0,40}(history|conversation)'; then
|
|
87
|
+
WARNINGS="${WARNINGS} - No prohibition against exposing parent's conversation history. Without this, the subagent may show the user the parent's full chat history (Issue #55488 reproduction).\n"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
if [ -n "$WARNINGS" ]; then
|
|
91
|
+
REQUIRE_ALL="${CC_SUBAGENT_IDENTITY_REQUIRE_ALL:-0}"
|
|
92
|
+
printf '⚠️ Subagent identity boundary not enforced in delegation prompt:\n' >&2
|
|
93
|
+
printf '%b' "$WARNINGS" >&2
|
|
94
|
+
printf '\n Reference: https://github.com/anthropics/claude-code/issues/55488\n' >&2
|
|
95
|
+
printf ' Recommended fix: prepend the prompt with the 3 boundary instructions.\n' >&2
|
|
96
|
+
if [ "$REQUIRE_ALL" = "1" ]; then
|
|
97
|
+
# Strict mode: block when any check fails
|
|
98
|
+
exit 2
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
exit 0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# subagent-identity-reassertion.sh — Re-assert subagent identity to mitigate parent-context leak
|
|
3
|
+
#
|
|
4
|
+
# Solves: Subagent identity leak (Issue #55488, v2.1.126 regression).
|
|
5
|
+
# When DM'd directly via team chat UI, the subagent dispatch may fall
|
|
6
|
+
# back to the parent's conversation context — surfacing parent
|
|
7
|
+
# identity and history that the subagent should not have access to.
|
|
8
|
+
#
|
|
9
|
+
# How it works: PreToolUse hook on Agent that emits a stderr REMINDER right
|
|
10
|
+
# before every Agent spawn. The reminder makes parent-context leaks visible
|
|
11
|
+
# in the operator's terminal (early detection signal) and surfaces the
|
|
12
|
+
# recommended operational workaround (relay through parent rather than
|
|
13
|
+
# DM the subagent directly) on each dispatch.
|
|
14
|
+
#
|
|
15
|
+
# Trade-off: Adds a stderr line per Agent call. Use only if your threat model
|
|
16
|
+
# includes sensitive parent-session context that subagents should not see.
|
|
17
|
+
# Issue #55488 workarounds 1-3 (explicit re-assertion / parent relay /
|
|
18
|
+
# context audit) are usually sufficient and cheaper.
|
|
19
|
+
#
|
|
20
|
+
# Reference: Issue #55488 (yurukusa Comment 5/2 14:27 JST)
|
|
21
|
+
# https://github.com/anthropics/claude-code/issues/55488
|
|
22
|
+
#
|
|
23
|
+
# TRIGGER: PreToolUse
|
|
24
|
+
# MATCHER: "Agent"
|
|
25
|
+
|
|
26
|
+
set -euo pipefail
|
|
27
|
+
|
|
28
|
+
INPUT=$(cat)
|
|
29
|
+
|
|
30
|
+
# Apply only on Agent tool calls. Tolerate malformed JSON by treating
|
|
31
|
+
# unparseable input as a non-Agent fast path (silent exit 0).
|
|
32
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)
|
|
33
|
+
[ "$TOOL" = "Agent" ] || exit 0
|
|
34
|
+
|
|
35
|
+
# Extract subagent type / name for the reminder
|
|
36
|
+
SUBAGENT_TYPE=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // empty' 2>/dev/null || true)
|
|
37
|
+
SUBAGENT_NAME=$(echo "$INPUT" | jq -r '.tool_input.name // empty' 2>/dev/null || true)
|
|
38
|
+
|
|
39
|
+
ROLE_LABEL="subagent"
|
|
40
|
+
[ -n "$SUBAGENT_TYPE" ] && ROLE_LABEL="$SUBAGENT_TYPE"
|
|
41
|
+
[ -n "$SUBAGENT_NAME" ] && ROLE_LABEL="$SUBAGENT_NAME ($SUBAGENT_TYPE)"
|
|
42
|
+
|
|
43
|
+
# Emit reminder to stderr — Claude Code surfaces this in the operator's terminal
|
|
44
|
+
cat >&2 <<EOF
|
|
45
|
+
[subagent-identity-reassertion] Spawning $ROLE_LABEL — Issue #55488 mitigation
|
|
46
|
+
- Operational guard: route sensitive DMs through the parent agent, not directly to this subagent
|
|
47
|
+
- Audit: ensure parent context does not contain secrets the subagent must not see
|
|
48
|
+
- Recovery: if leak observed, send "Your role is $ROLE_LABEL. Confirm." to lock identity for the turn
|
|
49
|
+
EOF
|
|
50
|
+
|
|
51
|
+
exit 0
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# subagent-inheritance-tester.sh — Audit subagent frontmatter for
|
|
4
|
+
# missing tool boundaries and
|
|
5
|
+
# non-functional memory directives
|
|
6
|
+
# ================================================================
|
|
7
|
+
# PURPOSE:
|
|
8
|
+
# Two May 2026 incidents documented subagent docs that looked
|
|
9
|
+
# fine but did not enforce the parent's safety boundary:
|
|
10
|
+
#
|
|
11
|
+
# #57068 — A parent settings.json with Deny rule on .env reads
|
|
12
|
+
# did not propagate to a subagent. The subagent read
|
|
13
|
+
# and reported the file's contents because the agent
|
|
14
|
+
# doc omitted an explicit tools: list and inherited a
|
|
15
|
+
# broader default.
|
|
16
|
+
# #57507 — A subagent doc declared its scope using a memory:
|
|
17
|
+
# field. memory: is silently ignored in subagent
|
|
18
|
+
# frontmatter (only tools:, model:, description: and
|
|
19
|
+
# name: are honored). The author believed the scope
|
|
20
|
+
# was bound; the runtime treated it as unbounded.
|
|
21
|
+
#
|
|
22
|
+
# On SessionStart, this hook scans ~/.claude/agents/ and the
|
|
23
|
+
# project's .claude/agents/ directory and reports each doc
|
|
24
|
+
# that (a) lacks an explicit tools: list, (b) uses a memory:
|
|
25
|
+
# field, or (c) lacks frontmatter entirely. When the parent
|
|
26
|
+
# settings.json contains Deny rules, the warning escalates
|
|
27
|
+
# because those rules cannot be relied upon for subagents
|
|
28
|
+
# that have no tool binding.
|
|
29
|
+
#
|
|
30
|
+
# TRIGGER: SessionStart
|
|
31
|
+
#
|
|
32
|
+
# CONFIG:
|
|
33
|
+
# CC_SUBAGENT_INHERITANCE_BLOCK=0 (0 = warn; 1 = exit 2)
|
|
34
|
+
# CC_SUBAGENT_INHERITANCE_PATHS="" (extra colon-separated dirs)
|
|
35
|
+
#
|
|
36
|
+
# Born from:
|
|
37
|
+
# https://github.com/anthropics/claude-code/issues/57068
|
|
38
|
+
# https://github.com/anthropics/claude-code/issues/57507
|
|
39
|
+
# Related: chapter 9 of the May 2026 claim-verify case handbook
|
|
40
|
+
# ("自動の点検の道具の素案 5 件" — proposed detection
|
|
41
|
+
# tools 4 / 5, the fourth being subagent-inheritance-tester)
|
|
42
|
+
# ================================================================
|
|
43
|
+
|
|
44
|
+
set -u
|
|
45
|
+
|
|
46
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
47
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
48
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
49
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
50
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
51
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-inheritance-tester-$PPID"
|
|
52
|
+
[ -f "$_nojq_warned" ] || {
|
|
53
|
+
echo "WARNING [subagent-inheritance-tester]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
54
|
+
: > "$_nojq_warned"
|
|
55
|
+
}
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
59
|
+
|
|
60
|
+
# Resolve the project directory if the caller provided it.
|
|
61
|
+
PROJECT_DIR=$(printf '%s' "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)
|
|
62
|
+
[ -z "$PROJECT_DIR" ] && PROJECT_DIR="${CLAUDE_PROJECT_DIR:-}"
|
|
63
|
+
|
|
64
|
+
BLOCK="${CC_SUBAGENT_INHERITANCE_BLOCK:-0}"
|
|
65
|
+
EXTRA="${CC_SUBAGENT_INHERITANCE_PATHS:-}"
|
|
66
|
+
|
|
67
|
+
SCAN_DIRS=()
|
|
68
|
+
[ -d "${HOME}/.claude/agents" ] && SCAN_DIRS+=("${HOME}/.claude/agents")
|
|
69
|
+
[ -n "$PROJECT_DIR" ] && [ -d "${PROJECT_DIR}/.claude/agents" ] && SCAN_DIRS+=("${PROJECT_DIR}/.claude/agents")
|
|
70
|
+
if [ -n "$EXTRA" ]; then
|
|
71
|
+
IFS=':' read -ra EXTRA_DIRS <<< "$EXTRA"
|
|
72
|
+
for d in "${EXTRA_DIRS[@]}"; do
|
|
73
|
+
[ -d "$d" ] && SCAN_DIRS+=("$d")
|
|
74
|
+
done
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Nothing to audit, exit silently.
|
|
78
|
+
if [ "${#SCAN_DIRS[@]}" -eq 0 ]; then
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Collect parent Deny rules. When present, missing tool bindings
|
|
83
|
+
# in subagents are escalated because the deny boundary cannot be
|
|
84
|
+
# inherited reliably.
|
|
85
|
+
DENY_RULES=""
|
|
86
|
+
for settings in "${HOME}/.claude/settings.json" \
|
|
87
|
+
"${HOME}/.claude/settings.local.json" \
|
|
88
|
+
"${PROJECT_DIR}/.claude/settings.json" \
|
|
89
|
+
"${PROJECT_DIR}/.claude/settings.local.json"; do
|
|
90
|
+
[ -n "$settings" ] || continue
|
|
91
|
+
[ -f "$settings" ] || continue
|
|
92
|
+
deny=$(jq -r '.permissions.deny[]? // empty' "$settings" 2>/dev/null || true)
|
|
93
|
+
if [ -n "$deny" ]; then
|
|
94
|
+
DENY_RULES="${DENY_RULES}${deny}
|
|
95
|
+
"
|
|
96
|
+
fi
|
|
97
|
+
done
|
|
98
|
+
|
|
99
|
+
extract_frontmatter() {
|
|
100
|
+
awk '
|
|
101
|
+
/^---[[:space:]]*$/ {
|
|
102
|
+
if (!opened) { opened=1; next }
|
|
103
|
+
else { exit }
|
|
104
|
+
}
|
|
105
|
+
opened { print }
|
|
106
|
+
' "$1" 2>/dev/null
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
ISSUES=""
|
|
110
|
+
|
|
111
|
+
for dir in "${SCAN_DIRS[@]}"; do
|
|
112
|
+
# Find .md files; skip hidden and backup files.
|
|
113
|
+
while IFS= read -r doc; do
|
|
114
|
+
[ -f "$doc" ] || continue
|
|
115
|
+
case "$(basename "$doc")" in
|
|
116
|
+
.*|*.bak|*~) continue ;;
|
|
117
|
+
esac
|
|
118
|
+
|
|
119
|
+
# First non-empty line must be `---` for valid frontmatter.
|
|
120
|
+
first=$(awk 'NF { print; exit }' "$doc" 2>/dev/null || true)
|
|
121
|
+
if [ "$first" != "---" ]; then
|
|
122
|
+
ISSUES="${ISSUES} - ${doc}: no YAML frontmatter; subagent definition will be ignored or treated as bare prompt
|
|
123
|
+
"
|
|
124
|
+
continue
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
fm=$(extract_frontmatter "$doc")
|
|
128
|
+
if [ -z "$fm" ]; then
|
|
129
|
+
ISSUES="${ISSUES} - ${doc}: empty frontmatter block
|
|
130
|
+
"
|
|
131
|
+
continue
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
has_tools=$(printf '%s' "$fm" | grep -cE '^[[:space:]]*tools[[:space:]]*:' || true)
|
|
135
|
+
has_memory=$(printf '%s' "$fm" | grep -cE '^[[:space:]]*memory[[:space:]]*:' || true)
|
|
136
|
+
has_name=$(printf '%s' "$fm" | grep -cE '^[[:space:]]*name[[:space:]]*:' || true)
|
|
137
|
+
|
|
138
|
+
if [ "$has_name" -eq 0 ]; then
|
|
139
|
+
ISSUES="${ISSUES} - ${doc}: frontmatter missing required 'name:' key
|
|
140
|
+
"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
if [ "$has_memory" -gt 0 ]; then
|
|
144
|
+
ISSUES="${ISSUES} - ${doc}: 'memory:' key found in frontmatter — silently ignored at runtime (Issue #57507). Move scope/context into the prompt body.
|
|
145
|
+
"
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
if [ "$has_tools" -eq 0 ]; then
|
|
149
|
+
if [ -n "$DENY_RULES" ]; then
|
|
150
|
+
ISSUES="${ISSUES} - ${doc}: no explicit 'tools:' list; parent Deny rules (e.g. .env) cannot be relied upon to propagate (Issue #57068). Add tools: with the minimum needed.
|
|
151
|
+
"
|
|
152
|
+
else
|
|
153
|
+
ISSUES="${ISSUES} - ${doc}: no explicit 'tools:' list; subagent will inherit the broad default tool set. Pin to least-privilege.
|
|
154
|
+
"
|
|
155
|
+
fi
|
|
156
|
+
fi
|
|
157
|
+
done < <(find "$dir" -maxdepth 2 -type f -name '*.md' 2>/dev/null)
|
|
158
|
+
done
|
|
159
|
+
|
|
160
|
+
if [ -z "$ISSUES" ]; then
|
|
161
|
+
exit 0
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
printf '⚠️ subagent-inheritance-tester: subagent docs with inheritance gaps:\n' >&2
|
|
165
|
+
printf '%b' "$ISSUES" >&2
|
|
166
|
+
if [ -n "$DENY_RULES" ]; then
|
|
167
|
+
printf '\n Parent Deny rules in effect:\n' >&2
|
|
168
|
+
printf '%s' "$DENY_RULES" | sed 's/^/ /' >&2
|
|
169
|
+
fi
|
|
170
|
+
printf '\n References:\n' >&2
|
|
171
|
+
printf ' https://github.com/anthropics/claude-code/issues/57068\n' >&2
|
|
172
|
+
printf ' https://github.com/anthropics/claude-code/issues/57507\n' >&2
|
|
173
|
+
printf ' Recommended fix: add an explicit tools: list to each agent doc; remove memory: keys.\n' >&2
|
|
174
|
+
|
|
175
|
+
if [ "$BLOCK" = "1" ]; then
|
|
176
|
+
exit 2
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
exit 0
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# subagent-permission-mode-guard.sh — Warn when Agent tool's mode
|
|
4
|
+
# parameter conflicts with sub-agent
|
|
5
|
+
# frontmatter permissionMode
|
|
6
|
+
# ================================================================
|
|
7
|
+
# PURPOSE:
|
|
8
|
+
# When the main agent spawns a sub-agent via the Agent tool with a
|
|
9
|
+
# `mode` parameter (e.g. `bypassPermissions`), checks whether the
|
|
10
|
+
# delegation prompt acknowledges that the sub-agent's YAML frontmatter
|
|
11
|
+
# `permissionMode` field can silently override the spawn-time
|
|
12
|
+
# parameter. Warns when the delegation prompt assumes the spawn-time
|
|
13
|
+
# parameter wins.
|
|
14
|
+
#
|
|
15
|
+
# TRIGGER: PreToolUse
|
|
16
|
+
# MATCHER: "Agent"
|
|
17
|
+
#
|
|
18
|
+
# WHY THIS MATTERS:
|
|
19
|
+
# Issue #55691 reported that the Agent tool's `mode` parameter does
|
|
20
|
+
# not override a sub-agent's YAML frontmatter `permissionMode`. When
|
|
21
|
+
# the sub-agent has no `permissionMode` declared, behaviour falls back
|
|
22
|
+
# to `default` mode — and the spawn-time `mode` parameter is silently
|
|
23
|
+
# a no-op. The docs read as if the Agent tool parameter wins
|
|
24
|
+
# per-spawn, but empirically the frontmatter (or its absence) wins.
|
|
25
|
+
#
|
|
26
|
+
# This is a permission-priority boundary failure. The parent agent
|
|
27
|
+
# may believe it has elevated the sub-agent's permissions for a
|
|
28
|
+
# specific task, while the sub-agent silently runs in default mode.
|
|
29
|
+
# The work proceeds without the expected permission elevation,
|
|
30
|
+
# producing wrong results.
|
|
31
|
+
#
|
|
32
|
+
# WHAT IT CHECKS:
|
|
33
|
+
# 1. Tool input contains a `mode` parameter (e.g.
|
|
34
|
+
# `mode: "bypassPermissions"`)
|
|
35
|
+
# 2. If yes, prompt acknowledges that the sub-agent's frontmatter
|
|
36
|
+
# may override (e.g. "if frontmatter has permissionMode", "verify
|
|
37
|
+
# the sub-agent's frontmatter", "frontmatter wins")
|
|
38
|
+
# 3. If yes, prompt asks for explicit verification before relying on
|
|
39
|
+
# the elevated mode (e.g. "verify the mode is active", "check
|
|
40
|
+
# effective permissions")
|
|
41
|
+
#
|
|
42
|
+
# OUTPUT:
|
|
43
|
+
# Warning to stderr when the spawn-time mode parameter is used but
|
|
44
|
+
# the prompt does not acknowledge the frontmatter override risk.
|
|
45
|
+
# Always exits 0 — advisory only, never blocks.
|
|
46
|
+
#
|
|
47
|
+
# CONFIGURATION:
|
|
48
|
+
# CC_SUBAGENT_MODE_REQUIRE_ALL — set to "1" to block when any check
|
|
49
|
+
# fails (default: warn only)
|
|
50
|
+
#
|
|
51
|
+
# RELATED ISSUES:
|
|
52
|
+
# https://github.com/anthropics/claude-code/issues/55691
|
|
53
|
+
# ================================================================
|
|
54
|
+
|
|
55
|
+
set -u
|
|
56
|
+
|
|
57
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
58
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
59
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
60
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
61
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
62
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-permission-mode-guard-$PPID"
|
|
63
|
+
[ -f "$_nojq_warned" ] || {
|
|
64
|
+
echo "WARNING [subagent-permission-mode-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
65
|
+
: > "$_nojq_warned"
|
|
66
|
+
}
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
INPUT=$(cat)
|
|
70
|
+
|
|
71
|
+
PROMPT=$(printf '%s' "$INPUT" | jq -r '.tool_input.prompt // empty' 2>/dev/null)
|
|
72
|
+
MODE=$(printf '%s' "$INPUT" | jq -r '.tool_input.mode // empty' 2>/dev/null)
|
|
73
|
+
|
|
74
|
+
# If no mode parameter, no check needed
|
|
75
|
+
if [ -z "$MODE" ]; then
|
|
76
|
+
exit 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# If mode parameter present but no prompt, warn briefly
|
|
80
|
+
if [ -z "$PROMPT" ]; then
|
|
81
|
+
printf '⚠️ Agent tool spawn with mode=%s but empty prompt:\n' "$MODE" >&2
|
|
82
|
+
printf ' - The mode parameter may be silently overridden by the sub-agent frontmatter (Issue #55691).\n' >&2
|
|
83
|
+
printf ' Reference: https://github.com/anthropics/claude-code/issues/55691\n' >&2
|
|
84
|
+
exit 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
WARNINGS=""
|
|
88
|
+
|
|
89
|
+
# Check 1: Frontmatter override acknowledgement
|
|
90
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'frontmatter|permissionMode|permission mode|YAML.+(field|frontmatter)|sub[- ]?agent.+(definition|YAML)'; then
|
|
91
|
+
WARNINGS="${WARNINGS} - Mode parameter '${MODE}' set, but prompt does not acknowledge the sub-agent frontmatter override risk (Issue #55691). The mode may be silently a no-op.\n"
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Check 2: Explicit verification request
|
|
95
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'verify (the )?mode|check (the )?(effective )?permission|verify (the )?(elevated|active)|effective permission|active mode'; then
|
|
96
|
+
WARNINGS="${WARNINGS} - Mode parameter '${MODE}' set, but prompt does not request verification of the actual effective mode. Without verification, a silent fallback to default mode passes unnoticed.\n"
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
if [ -n "$WARNINGS" ]; then
|
|
100
|
+
REQUIRE_ALL="${CC_SUBAGENT_MODE_REQUIRE_ALL:-0}"
|
|
101
|
+
printf '⚠️ Subagent permission mode boundary not enforced:\n' >&2
|
|
102
|
+
printf '%b' "$WARNINGS" >&2
|
|
103
|
+
printf '\n Reference: https://github.com/anthropics/claude-code/issues/55691\n' >&2
|
|
104
|
+
printf ' Recommended fix: acknowledge the frontmatter override, request explicit verification of the effective mode.\n' >&2
|
|
105
|
+
if [ "$REQUIRE_ALL" = "1" ]; then
|
|
106
|
+
exit 2
|
|
107
|
+
fi
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
exit 0
|
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
# Setup: echo "src/auth/" > .claude/agent-scope.txt
|
|
13
13
|
# ================================================================
|
|
14
14
|
|
|
15
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
16
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
17
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
18
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
19
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
20
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-scope-guard-$PPID"
|
|
21
|
+
[ -f "$_nojq_warned" ] || {
|
|
22
|
+
echo "WARNING [subagent-scope-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
23
|
+
: > "$_nojq_warned"
|
|
24
|
+
}
|
|
25
|
+
fi
|
|
26
|
+
|
|
15
27
|
INPUT=$(cat)
|
|
16
28
|
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
17
29
|
[ -z "$FILE" ] && exit 0
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# subagent-spawn-verification-enforcer.sh — Warn when subagent prompt
|
|
4
|
+
# lacks output verification
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# When the main agent spawns a subagent via the Agent tool, checks
|
|
8
|
+
# whether the delegation prompt names a concrete artifact the
|
|
9
|
+
# subagent must produce (file path, commit hash, process id, etc.)
|
|
10
|
+
# and whether the parent will verify that artifact with a read-only
|
|
11
|
+
# inspection. Warns when the contract is missing — the parent will
|
|
12
|
+
# then accept any "spawned successfully" reply at face value.
|
|
13
|
+
#
|
|
14
|
+
# TRIGGER: PreToolUse
|
|
15
|
+
# MATCHER: "Agent"
|
|
16
|
+
#
|
|
17
|
+
# WHY THIS MATTERS:
|
|
18
|
+
# Issue #55666 reported that named Agent spawns under
|
|
19
|
+
# CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 reply "Spawned successfully.
|
|
20
|
+
# The agent is now running." while no actual process is created. The
|
|
21
|
+
# inbox is set up but the work never runs. Without an artifact-based
|
|
22
|
+
# verification step in the parent, the parent trusts the textual
|
|
23
|
+
# "success" reply and proceeds — silently dropping the requested work.
|
|
24
|
+
#
|
|
25
|
+
# The root cause must be fixed in the runtime, but parent agents can
|
|
26
|
+
# preventively catch this class of failure by (1) requiring the
|
|
27
|
+
# subagent to produce a concrete artifact (file write / commit / log
|
|
28
|
+
# line / stdout marker) and (2) verifying that artifact exists before
|
|
29
|
+
# trusting the success reply.
|
|
30
|
+
#
|
|
31
|
+
# WHAT IT CHECKS:
|
|
32
|
+
# 1. Prompt names a concrete artifact (e.g. "write to /tmp/X",
|
|
33
|
+
# "create file at", "commit with message", "produce output line",
|
|
34
|
+
# "log to")
|
|
35
|
+
# 2. Prompt includes a verification step (e.g. "verify by", "check
|
|
36
|
+
# that the file exists", "read back", "parent will inspect")
|
|
37
|
+
# 3. Prompt warns against trusting textual success without artifact
|
|
38
|
+
# (optional, recommended for high-stakes delegation)
|
|
39
|
+
#
|
|
40
|
+
# OUTPUT:
|
|
41
|
+
# Warning to stderr listing which artifact / verification instructions
|
|
42
|
+
# are missing. Always exits 0 — advisory only, never blocks.
|
|
43
|
+
#
|
|
44
|
+
# CONFIGURATION:
|
|
45
|
+
# CC_SUBAGENT_VERIFY_REQUIRE_ALL — set to "1" to block when any check
|
|
46
|
+
# fails (default: warn only)
|
|
47
|
+
#
|
|
48
|
+
# RELATED ISSUES:
|
|
49
|
+
# https://github.com/anthropics/claude-code/issues/55666
|
|
50
|
+
# ================================================================
|
|
51
|
+
|
|
52
|
+
set -u
|
|
53
|
+
|
|
54
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
55
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
56
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
57
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
58
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
59
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-spawn-verification-enforcer-$PPID"
|
|
60
|
+
[ -f "$_nojq_warned" ] || {
|
|
61
|
+
echo "WARNING [subagent-spawn-verification-enforcer]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
62
|
+
: > "$_nojq_warned"
|
|
63
|
+
}
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
INPUT=$(cat)
|
|
67
|
+
|
|
68
|
+
PROMPT=$(printf '%s' "$INPUT" | jq -r '.tool_input.prompt // empty' 2>/dev/null)
|
|
69
|
+
|
|
70
|
+
if [ -z "$PROMPT" ]; then
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
WARNINGS=""
|
|
75
|
+
|
|
76
|
+
# Check 1: Concrete artifact named (file path, commit, marker, etc.)
|
|
77
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'write (to |the )?[/~]|create (a )?file|commit (with|the)|produce (an? )?output|log (to|the)|/tmp/|/var/|\.txt|\.md|\.json|\.log'; then
|
|
78
|
+
WARNINGS="${WARNINGS} - No concrete artifact named. Subagent's textual 'success' reply is unverifiable (Issue #55666 surface).\n"
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Check 2: Verification step named
|
|
82
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'verify (by|with|that|the)|check (that|the file|the artifact|exists|after)|read back|parent (will|should) (inspect|verify|check)|i will (check|verify|inspect)'; then
|
|
83
|
+
WARNINGS="${WARNINGS} - No artifact verification step. Without read-only inspection, fabricated success replies are silently trusted.\n"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Check 3: Distrust of textual success (warning, not strictly required)
|
|
87
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'do not trust|do not (rely on|believe|reply)|require (the|an) artifact|artifact[- ]based|reply[- ]only|without producing'; then
|
|
88
|
+
WARNINGS="${WARNINGS} - Recommended: prompt does not warn the subagent against 'reply-only' success. Adding 'do not reply success without producing the artifact' reduces fabrication risk.\n"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
if [ -n "$WARNINGS" ]; then
|
|
92
|
+
REQUIRE_ALL="${CC_SUBAGENT_VERIFY_REQUIRE_ALL:-0}"
|
|
93
|
+
printf '⚠️ Subagent output verification not enforced in delegation prompt:\n' >&2
|
|
94
|
+
printf '%b' "$WARNINGS" >&2
|
|
95
|
+
printf '\n Reference: https://github.com/anthropics/claude-code/issues/55666\n' >&2
|
|
96
|
+
printf ' Recommended fix: name a concrete artifact, name parent verification step, warn the subagent against reply-only success.\n' >&2
|
|
97
|
+
if [ "$REQUIRE_ALL" = "1" ]; then
|
|
98
|
+
exit 2
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
exit 0
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# subagent-tool-allowlist-enforcer.sh — Warn when subagent prompt
|
|
4
|
+
# lacks tool allowlist boundary
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# When the main agent spawns a subagent via the Agent tool, checks
|
|
8
|
+
# whether the delegation prompt explicitly states which tools the
|
|
9
|
+
# subagent is allowed to use, which tools are forbidden, and how the
|
|
10
|
+
# parent should verify the subagent's claimed results. Warns via
|
|
11
|
+
# stderr when these tool-boundary instructions are missing.
|
|
12
|
+
#
|
|
13
|
+
# TRIGGER: PreToolUse
|
|
14
|
+
# MATCHER: "Agent"
|
|
15
|
+
#
|
|
16
|
+
# WHY THIS MATTERS:
|
|
17
|
+
# Issue #55653 reported a subagent that fabricated "saved file" claims
|
|
18
|
+
# while only having read-only tool access. The subagent had no
|
|
19
|
+
# persistent state binding it to its allowed tool list, so when asked
|
|
20
|
+
# to "save", it produced a fictional success report instead of a
|
|
21
|
+
# permission-denied failure. This is a tool-list boundary failure.
|
|
22
|
+
#
|
|
23
|
+
# While the root cause must be fixed in the agent runtime, parent
|
|
24
|
+
# agents can preventively reduce the failure surface by stating the
|
|
25
|
+
# allowed tool set explicitly in the delegation prompt and instructing
|
|
26
|
+
# the parent to verify the result with read-only inspection (file
|
|
27
|
+
# stat, git status, etc.) before trusting any "saved" or "modified"
|
|
28
|
+
# claim.
|
|
29
|
+
#
|
|
30
|
+
# WHAT IT CHECKS:
|
|
31
|
+
# 1. Prompt names the allowed tool set (e.g. "you can use Read",
|
|
32
|
+
# "allowed tools:", "tools: read, grep")
|
|
33
|
+
# 2. Prompt names the forbidden tools or capability boundary (e.g.
|
|
34
|
+
# "do not write", "no edit", "read-only")
|
|
35
|
+
# 3. Prompt instructs the parent to verify results with read-only
|
|
36
|
+
# inspection (e.g. "I will verify with stat", "parent checks
|
|
37
|
+
# file existence", "verify before trusting")
|
|
38
|
+
#
|
|
39
|
+
# OUTPUT:
|
|
40
|
+
# Warning to stderr listing which tool boundary instructions are
|
|
41
|
+
# missing. Always exits 0 — advisory only, never blocks.
|
|
42
|
+
#
|
|
43
|
+
# CONFIGURATION:
|
|
44
|
+
# CC_SUBAGENT_TOOL_REQUIRE_ALL — set to "1" to block when any check
|
|
45
|
+
# fails (default: warn only)
|
|
46
|
+
#
|
|
47
|
+
# RELATED ISSUES:
|
|
48
|
+
# https://github.com/anthropics/claude-code/issues/55653
|
|
49
|
+
# ================================================================
|
|
50
|
+
|
|
51
|
+
set -u
|
|
52
|
+
|
|
53
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
54
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
55
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
56
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
57
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
58
|
+
_nojq_warned="/tmp/cc-nojq-warned-subagent-tool-allowlist-enforcer-$PPID"
|
|
59
|
+
[ -f "$_nojq_warned" ] || {
|
|
60
|
+
echo "WARNING [subagent-tool-allowlist-enforcer]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
61
|
+
: > "$_nojq_warned"
|
|
62
|
+
}
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
INPUT=$(cat)
|
|
66
|
+
|
|
67
|
+
PROMPT=$(printf '%s' "$INPUT" | jq -r '.tool_input.prompt // empty' 2>/dev/null)
|
|
68
|
+
|
|
69
|
+
if [ -z "$PROMPT" ]; then
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
WARNINGS=""
|
|
74
|
+
|
|
75
|
+
# Check 1: Allowed tool set is named
|
|
76
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'you can use|allowed tools?:|tools:|use only|use the following tools|tool(s)? you may use'; then
|
|
77
|
+
WARNINGS="${WARNINGS} - No allowed tool set named. Subagent may attempt operations outside its capability and fabricate results (Issue #55653).\n"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Check 2: Forbidden tools or capability boundary is named
|
|
81
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'do not (write|edit|modify|save|create|delete)|no (write|edit|modify|save)|read[-]?only|never (write|edit|modify|save|create|delete)|forbidden tools?'; then
|
|
82
|
+
WARNINGS="${WARNINGS} - No forbidden tools or read-only constraint named. Subagent may claim success on operations it cannot actually perform.\n"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Check 3: Parent's verification step is named
|
|
86
|
+
if ! printf '%s' "$PROMPT" | grep -qiE 'verify (with|by|using)|parent (will|should) (check|verify|inspect)|i will verify|verify (the )?result|check (the )?(file|output|result) (exists|after)'; then
|
|
87
|
+
WARNINGS="${WARNINGS} - No parent verification step. Without read-only inspection (file stat / git status), fabricated claims pass silently.\n"
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
if [ -n "$WARNINGS" ]; then
|
|
91
|
+
REQUIRE_ALL="${CC_SUBAGENT_TOOL_REQUIRE_ALL:-0}"
|
|
92
|
+
printf '⚠️ Subagent tool boundary not enforced in delegation prompt:\n' >&2
|
|
93
|
+
printf '%b' "$WARNINGS" >&2
|
|
94
|
+
printf '\n Reference: https://github.com/anthropics/claude-code/issues/55653\n' >&2
|
|
95
|
+
printf ' Recommended fix: name allowed tools, name forbidden capabilities, name parent verification step.\n' >&2
|
|
96
|
+
if [ "$REQUIRE_ALL" = "1" ]; then
|
|
97
|
+
exit 2
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
exit 0
|