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,247 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# spurious-malformed-notice-detector.sh — Warn when "malformed
|
|
4
|
+
# and could not be parsed" notices co-occur with successful
|
|
5
|
+
# tool executions in the trailing transcript window, signalling
|
|
6
|
+
# sub-pattern 12C (the harness-layer spurious notice).
|
|
7
|
+
# ================================================================
|
|
8
|
+
# PURPOSE:
|
|
9
|
+
# Issue #62700 documents a case where, after most tool calls
|
|
10
|
+
# (Bash / Edit / Write), the assistant turn is immediately
|
|
11
|
+
# followed by a system message "Your tool call was malformed
|
|
12
|
+
# and could not be parsed. Please retry." — yet the tool
|
|
13
|
+
# actually executed correctly (git commit/push/cherry-pick,
|
|
14
|
+
# gh queries, file writes all produced normal output and took
|
|
15
|
+
# effect). Sometimes the spurious notice is accompanied by
|
|
16
|
+
# "[Request interrupted by user]" and the conversation appears
|
|
17
|
+
# to hang, requiring repeated manual "continue".
|
|
18
|
+
#
|
|
19
|
+
# The other Cluster 12 sub-pattern detectors key off the same
|
|
20
|
+
# surface marker but recommend different recoveries:
|
|
21
|
+
# - 12A (#62344) → /clear to drop poisoned history
|
|
22
|
+
# - 12B (#62467) → switch model / disable extended thinking
|
|
23
|
+
# 12C is at the harness/streaming layer — the tool succeeded
|
|
24
|
+
# and the notice is the bug. The recovery is the opposite of
|
|
25
|
+
# 12A/12B: do NOT /clear (it would discard accumulated context
|
|
26
|
+
# for no benefit) and do NOT switch model (the inference is
|
|
27
|
+
# working correctly). Verify the tool output is correct (it
|
|
28
|
+
# likely is) and proceed.
|
|
29
|
+
#
|
|
30
|
+
# This hook fires only when the surface marker AND successful
|
|
31
|
+
# tool_result blocks co-occur in the same window, so it does
|
|
32
|
+
# not fire on the 12A "retry also failed" terminal state.
|
|
33
|
+
#
|
|
34
|
+
# TRIGGER: PostToolUse MATCHER: ""
|
|
35
|
+
# CLUSTER: 12 (Tool Call Parsing failures in Opus 4.7)
|
|
36
|
+
# SUB-PATTERN: 12C (spurious malformed notice; harness-layer)
|
|
37
|
+
#
|
|
38
|
+
# BEHAVIOR:
|
|
39
|
+
# - Read transcript_path from PostToolUse hook input.
|
|
40
|
+
# - Scan the trailing LOOKBACK lines.
|
|
41
|
+
# - Count marker occurrences ("malformed and could not be
|
|
42
|
+
# parsed", the literal phrase Anthropic's runtime emits).
|
|
43
|
+
# - Count successful tool_result blocks in the same window
|
|
44
|
+
# (.type == "tool_result" and .is_error is not true).
|
|
45
|
+
# - If markers >= MARKER_THRESHOLD AND successes >= markers,
|
|
46
|
+
# emit a one-screen stderr advisory naming sub-pattern 12C
|
|
47
|
+
# and the "verify output, ignore notice" recovery path.
|
|
48
|
+
# - Rate-limit advisory emission per session via a counter
|
|
49
|
+
# file so the warning does not repeat on every PostToolUse
|
|
50
|
+
# after the first detection.
|
|
51
|
+
# - Always exits 0 (advisory only; never blocks tool execution).
|
|
52
|
+
#
|
|
53
|
+
# WHY THE CO-OCCURRENCE CHECK:
|
|
54
|
+
# The 12A detector fires on the marker alone because the
|
|
55
|
+
# recovery (/clear) is appropriate for any cause of the marker
|
|
56
|
+
# if retries are failing. 12C is the opposite case — the
|
|
57
|
+
# marker is firing while retries are succeeding, so /clear is
|
|
58
|
+
# the wrong recovery. The co-occurrence of marker + successful
|
|
59
|
+
# tool_result is the structural signal that distinguishes the
|
|
60
|
+
# harness-layer false-positive from the model-layer failure.
|
|
61
|
+
#
|
|
62
|
+
# In practice 12A and 12C may both fire on the same session
|
|
63
|
+
# (the marker is present and tools are succeeding, but the
|
|
64
|
+
# operator should be aware of both possibilities). That is
|
|
65
|
+
# intended: 12A advises checkpoint + /clear in case retries
|
|
66
|
+
# start failing, 12C confirms the current state and points at
|
|
67
|
+
# the harness layer rather than the session layer.
|
|
68
|
+
#
|
|
69
|
+
# CONFIGURATION (env vars):
|
|
70
|
+
# CC_SPURIOUS_MALFORMED_DISABLE Set to "1" to silence.
|
|
71
|
+
# CC_SPURIOUS_MALFORMED_LOOKBACK How many recent transcript
|
|
72
|
+
# lines to scan. Default 200.
|
|
73
|
+
# CC_SPURIOUS_MALFORMED_THRESHOLD Minimum marker occurrences
|
|
74
|
+
# in LOOKBACK to fire.
|
|
75
|
+
# Default 1.
|
|
76
|
+
# CC_SPURIOUS_MALFORMED_COOLDOWN Minimum tool calls between
|
|
77
|
+
# repeat advisories per
|
|
78
|
+
# session. Default 30.
|
|
79
|
+
# CC_SPURIOUS_MALFORMED_TRANSCRIPT Override transcript path
|
|
80
|
+
# (used by tests).
|
|
81
|
+
# CC_SPURIOUS_MALFORMED_STATE_DIR Override state directory
|
|
82
|
+
# (used by tests). Default
|
|
83
|
+
# /tmp/cc-spurious-malformed.
|
|
84
|
+
#
|
|
85
|
+
# UPSTREAM REFERENCES:
|
|
86
|
+
# #62700 (central case: spurious notice, tools execute
|
|
87
|
+
# correctly, accompanied by "[Request interrupted by
|
|
88
|
+
# user]" and apparent session hangs)
|
|
89
|
+
# #62123 (broader "retry also failed" central case, 21 reactions)
|
|
90
|
+
# #62344 (sub-pattern 12A, in-context few-shot poisoning)
|
|
91
|
+
# #62467 (sub-pattern 12B, extended-thinking serialization)
|
|
92
|
+
#
|
|
93
|
+
# RECOVERY ON A HIT:
|
|
94
|
+
# The advisory points operators at the verification path:
|
|
95
|
+
# - Verify the tool output (the most recent tool_result
|
|
96
|
+
# block) is what you expected. If yes, the notice is
|
|
97
|
+
# spurious — ignore it and proceed.
|
|
98
|
+
# - Do NOT /clear (would discard context for no benefit).
|
|
99
|
+
# - Do NOT switch model (inference is working correctly).
|
|
100
|
+
# - If session appears to hang, type "continue" to advance
|
|
101
|
+
# (per the #62700 reporter's workaround).
|
|
102
|
+
# The defect is at the streaming/parsing layer in the harness;
|
|
103
|
+
# operator-side hooks cannot recover it, only flag it so the
|
|
104
|
+
# operator stops applying the wrong recoveries.
|
|
105
|
+
# ================================================================
|
|
106
|
+
|
|
107
|
+
set -u
|
|
108
|
+
|
|
109
|
+
if [ "${CC_SPURIOUS_MALFORMED_DISABLE:-0}" = "1" ]; then
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
LOOKBACK="${CC_SPURIOUS_MALFORMED_LOOKBACK:-200}"
|
|
114
|
+
THRESHOLD="${CC_SPURIOUS_MALFORMED_THRESHOLD:-1}"
|
|
115
|
+
COOLDOWN="${CC_SPURIOUS_MALFORMED_COOLDOWN:-30}"
|
|
116
|
+
STATE_DIR="${CC_SPURIOUS_MALFORMED_STATE_DIR:-/tmp/cc-spurious-malformed}"
|
|
117
|
+
|
|
118
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
119
|
+
|
|
120
|
+
TRANSCRIPT_PATH="${CC_SPURIOUS_MALFORMED_TRANSCRIPT:-}"
|
|
121
|
+
if [ -z "$TRANSCRIPT_PATH" ]; then
|
|
122
|
+
TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
123
|
+
fi
|
|
124
|
+
|
|
125
|
+
if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
126
|
+
exit 0
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "default"' 2>/dev/null)
|
|
130
|
+
[ -z "$SESSION_ID" ] && SESSION_ID="default"
|
|
131
|
+
|
|
132
|
+
SAFE_SESSION=$(printf '%s' "$SESSION_ID" | tr -c 'A-Za-z0-9._-' '_' | head -c 80)
|
|
133
|
+
[ -z "$SAFE_SESSION" ] && SAFE_SESSION="default"
|
|
134
|
+
|
|
135
|
+
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
136
|
+
|
|
137
|
+
COUNTER_FILE="$STATE_DIR/${SAFE_SESSION}.count"
|
|
138
|
+
LASTFIRED_FILE="$STATE_DIR/${SAFE_SESSION}.lastfired"
|
|
139
|
+
|
|
140
|
+
COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
|
|
141
|
+
COUNT=$((COUNT + 1))
|
|
142
|
+
echo "$COUNT" > "$COUNTER_FILE"
|
|
143
|
+
|
|
144
|
+
TAIL_WINDOW=$(tail -n "$LOOKBACK" "$TRANSCRIPT_PATH" 2>/dev/null || true)
|
|
145
|
+
|
|
146
|
+
# Count marker occurrences in the trailing window.
|
|
147
|
+
MARKERS=$(printf '%s\n' "$TAIL_WINDOW" | grep -c 'malformed and could not be parsed' || true)
|
|
148
|
+
MARKERS="${MARKERS:-0}"
|
|
149
|
+
|
|
150
|
+
if [ "$MARKERS" -lt "$THRESHOLD" ]; then
|
|
151
|
+
exit 0
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Count successful tool_result blocks in the same window.
|
|
155
|
+
# A tool_result is "successful" when .is_error is absent or not true.
|
|
156
|
+
# Each transcript line is parsed independently; non-JSON lines are
|
|
157
|
+
# silently skipped. Both top-level and .message.content shapes are
|
|
158
|
+
# checked to handle the common Claude Code transcript variants.
|
|
159
|
+
SUCCESSES=$(printf '%s\n' "$TAIL_WINDOW" | jq -R -r '
|
|
160
|
+
try (fromjson) catch null | select(. != null) | . as $obj |
|
|
161
|
+
(($obj.content // $obj.message.content // [])) as $blocks |
|
|
162
|
+
if ($blocks | type) == "array" then
|
|
163
|
+
($blocks
|
|
164
|
+
| map(select(.type == "tool_result" and ((.is_error // false) != true)))
|
|
165
|
+
| length)
|
|
166
|
+
else
|
|
167
|
+
0
|
|
168
|
+
end
|
|
169
|
+
' 2>/dev/null | awk 'BEGIN{s=0} {s+=$0} END{print s+0}')
|
|
170
|
+
|
|
171
|
+
SUCCESSES="${SUCCESSES:-0}"
|
|
172
|
+
|
|
173
|
+
# 12C signature: marker fires alongside at least as many successful
|
|
174
|
+
# tool_result blocks. If successes < markers, the cluster is more
|
|
175
|
+
# likely 12A (retries actually failing) and the 12C advisory would
|
|
176
|
+
# be misleading — stay silent and let the 12A hook surface the case.
|
|
177
|
+
if [ "$SUCCESSES" -lt "$MARKERS" ]; then
|
|
178
|
+
exit 0
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
LASTFIRED=$(cat "$LASTFIRED_FILE" 2>/dev/null || echo 0)
|
|
182
|
+
SINCE=$((COUNT - LASTFIRED))
|
|
183
|
+
|
|
184
|
+
if [ "$LASTFIRED" -gt 0 ] && [ "$SINCE" -lt "$COOLDOWN" ]; then
|
|
185
|
+
exit 0
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
echo "$COUNT" > "$LASTFIRED_FILE"
|
|
189
|
+
|
|
190
|
+
cat >&2 <<EOF
|
|
191
|
+
|
|
192
|
+
⚠️ Detected ${MARKERS} "malformed and could not be parsed" notice(s)
|
|
193
|
+
alongside ${SUCCESSES} successful tool_result block(s) in the
|
|
194
|
+
trailing ${LOOKBACK} transcript lines.
|
|
195
|
+
|
|
196
|
+
This is the signature for sub-pattern 12C (spurious malformed notice
|
|
197
|
+
at the harness/streaming layer), the case filed in #62700. After
|
|
198
|
+
most tool calls (Bash / Edit / Write), the assistant turn is
|
|
199
|
+
immediately followed by the malformed-parse notice, yet the tool
|
|
200
|
+
actually executed correctly — git commit/push, gh queries, file
|
|
201
|
+
writes all produced normal output and took effect. Sometimes the
|
|
202
|
+
spurious notice is accompanied by "[Request interrupted by user]"
|
|
203
|
+
and the conversation appears to hang, requiring repeated manual
|
|
204
|
+
"continue".
|
|
205
|
+
|
|
206
|
+
Sub-pattern 12C is distinct from:
|
|
207
|
+
- 12A (#62344, in-context few-shot poisoning) → /clear to recover.
|
|
208
|
+
12A fires when retries genuinely fail and the broken format is
|
|
209
|
+
reproduced. The current window shows successful tool_results,
|
|
210
|
+
so /clear would discard accumulated context for no benefit.
|
|
211
|
+
- 12B (#62467, extended-thinking serialization defect) → switch
|
|
212
|
+
model / disable extended thinking. 12B fires when the assistant
|
|
213
|
+
turn carries stop_reason="tool_use" with no parseable tool_use
|
|
214
|
+
block. The current window has successful tool_results, so the
|
|
215
|
+
model-layer workaround is not the right recovery.
|
|
216
|
+
|
|
217
|
+
Recommended verification path for 12C:
|
|
218
|
+
1. Verify the most recent tool_result block(s) in your session.
|
|
219
|
+
If the output is what you expected, the notice is spurious —
|
|
220
|
+
the tool succeeded and the harness misclassified it.
|
|
221
|
+
2. Proceed with your work. Do NOT /clear and do NOT switch model;
|
|
222
|
+
both would burn context for a defect that is not in your
|
|
223
|
+
session or your model.
|
|
224
|
+
3. If the session appears to hang, type "continue" to advance
|
|
225
|
+
(per the #62700 reporter's workaround).
|
|
226
|
+
4. Consider filing on #62700 to add your environment details
|
|
227
|
+
(plugins, hooks, MCP servers); the streaming-layer hypothesis
|
|
228
|
+
is open and your data may help isolate it.
|
|
229
|
+
|
|
230
|
+
If retries ARE failing for you in addition to the notice, the
|
|
231
|
+
session is more likely 12A — checkpoint your active work to disk
|
|
232
|
+
and \`/clear\`. The 12A advisory (long-session-malformed-tool-call-
|
|
233
|
+
detector.sh, PR #406) covers that case.
|
|
234
|
+
|
|
235
|
+
References: #62700 (the spurious-notice central case), #62123 (the
|
|
236
|
+
broader "retry also failed" central case), Cluster 12 in the
|
|
237
|
+
cc-safe-setup tracker:
|
|
238
|
+
https://yurukusa.github.io/cc-safe-setup/cluster-tracker.html#cluster-tool-call-parsing
|
|
239
|
+
|
|
240
|
+
Silence: set CC_SPURIOUS_MALFORMED_DISABLE=1.
|
|
241
|
+
Tune sensitivity: CC_SPURIOUS_MALFORMED_THRESHOLD (default 1),
|
|
242
|
+
CC_SPURIOUS_MALFORMED_LOOKBACK (default 200 lines),
|
|
243
|
+
CC_SPURIOUS_MALFORMED_COOLDOWN (default 30 tool calls).
|
|
244
|
+
|
|
245
|
+
EOF
|
|
246
|
+
|
|
247
|
+
exit 0
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# TRIGGER: PreToolUse MATCHER: "Bash|PowerShell"
|
|
3
|
+
#
|
|
4
|
+
# sql-bulk-delete-warn: warn when a SQL DELETE/UPDATE statement is about to
|
|
5
|
+
# run via psql / mysql / sqlite3 / sqlcmd without a row-count safeguard.
|
|
6
|
+
#
|
|
7
|
+
# Motivated by Issue #56738 (claude-code, 2026-05-06): a regex with capture
|
|
8
|
+
# groups in regexp_match returned NULL for nearly every row, and the
|
|
9
|
+
# subsequent `DELETE FROM table WHERE _clean_title IS NULL` wiped 24,472 of
|
|
10
|
+
# 24,475 rows. autovacuum cleaned dead tuples within ~5 minutes, blocking
|
|
11
|
+
# pg_dirtyread recovery. 3 days of scraping work permanently lost.
|
|
12
|
+
#
|
|
13
|
+
# Detected high-risk patterns:
|
|
14
|
+
# 1. DELETE / UPDATE with no WHERE clause (full-table touch)
|
|
15
|
+
# 2. DELETE WHERE col IS NULL (Issue #56738 pattern: NULL arises from a
|
|
16
|
+
# computed column populated by a prior UPDATE that may have failed)
|
|
17
|
+
# 3. DELETE / UPDATE without a LIMIT in MySQL contexts
|
|
18
|
+
#
|
|
19
|
+
# Strict mode: set CC_SQL_BULK_DELETE_BLOCK=1 to exit 2 instead of warning.
|
|
20
|
+
|
|
21
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
22
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
23
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
24
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
25
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
26
|
+
_nojq_warned="/tmp/cc-nojq-warned-sql-bulk-delete-warn-$PPID"
|
|
27
|
+
[ -f "$_nojq_warned" ] || {
|
|
28
|
+
echo "WARNING [sql-bulk-delete-warn]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
29
|
+
: > "$_nojq_warned"
|
|
30
|
+
}
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
34
|
+
[ -z "$COMMAND" ] && exit 0
|
|
35
|
+
|
|
36
|
+
# Skip non-SQL invocations
|
|
37
|
+
if ! echo "$COMMAND" | grep -qiE '(^|[ \t/])(psql|mysql|sqlite3?|sqlcmd|cockroach\s+sql|duckdb)\b'; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Skip pure SELECT / EXPLAIN / DESCRIBE invocations
|
|
42
|
+
if ! echo "$COMMAND" | grep -qiE '\b(DELETE|UPDATE|TRUNCATE|DROP)\b'; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
WARN=""
|
|
47
|
+
|
|
48
|
+
# Pattern 1: DELETE / UPDATE without WHERE
|
|
49
|
+
if echo "$COMMAND" | grep -qiE '\b(DELETE\s+FROM|UPDATE)\s+[a-zA-Z_][a-zA-Z0-9_."]*\s*(;|$)'; then
|
|
50
|
+
WARN="${WARN}WARNING: DELETE/UPDATE without a WHERE clause detected (full-table touch).
|
|
51
|
+
"
|
|
52
|
+
fi
|
|
53
|
+
if echo "$COMMAND" | grep -qiE '\b(DELETE\s+FROM|UPDATE)\s+[a-zA-Z_][a-zA-Z0-9_."]*\s+(SET\s+[^;]*\s*;|;|$)' && \
|
|
54
|
+
! echo "$COMMAND" | grep -qiE '\bWHERE\b'; then
|
|
55
|
+
WARN="${WARN}WARNING: DELETE/UPDATE without WHERE detected (full-table touch).
|
|
56
|
+
"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Pattern 2: DELETE WHERE column IS NULL (Issue #56738 pattern)
|
|
60
|
+
if echo "$COMMAND" | grep -qiE 'DELETE\s+FROM\s+[a-zA-Z_][a-zA-Z0-9_."]*\s+WHERE\s+[a-zA-Z_][a-zA-Z0-9_.]*\s+IS\s+NULL'; then
|
|
61
|
+
WARN="${WARN}WARNING: 'DELETE WHERE col IS NULL' pattern detected. If the column was just populated by a regex/UPDATE, a silent NULL on most rows wipes nearly the whole table (Issue #56738: 24,472 of 24,475 rows lost).
|
|
62
|
+
SUGGESTION: run 'SELECT COUNT(*) FROM <table> WHERE <col> IS NULL' first; if the count is unexpectedly high, the populating step failed.
|
|
63
|
+
"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Pattern 3: TRUNCATE / DROP without explicit guard
|
|
67
|
+
if echo "$COMMAND" | grep -qiE '\bTRUNCATE\s+TABLE\b'; then
|
|
68
|
+
WARN="${WARN}WARNING: TRUNCATE TABLE detected. This bypasses transaction logs in some engines and is non-recoverable.
|
|
69
|
+
"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Pattern 4: psql -c '...' inline with DELETE/UPDATE (no transaction wrapping)
|
|
73
|
+
if echo "$COMMAND" | grep -qiE 'psql\s+.*-c\s+["\047][^"\047]*\b(DELETE|UPDATE|TRUNCATE)\b' && \
|
|
74
|
+
! echo "$COMMAND" | grep -qiE '\b(BEGIN|START\s+TRANSACTION)\b'; then
|
|
75
|
+
WARN="${WARN}WARNING: psql -c with DELETE/UPDATE/TRUNCATE has no explicit transaction. autocommit may persist the change before you can verify.
|
|
76
|
+
SUGGESTION: wrap in BEGIN; ... ROLLBACK; first to check row counts before COMMIT.
|
|
77
|
+
"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if [ -n "$WARN" ]; then
|
|
81
|
+
printf '%s' "$WARN" >&2
|
|
82
|
+
if [ "${CC_SQL_BULK_DELETE_BLOCK:-0}" = "1" ]; then
|
|
83
|
+
echo "BLOCKED by sql-bulk-delete-warn (strict mode). Unset CC_SQL_BULK_DELETE_BLOCK to convert to advisory." >&2
|
|
84
|
+
exit 2
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
exit 0
|
|
File without changes
|
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
11
11
|
# ================================================================
|
|
12
12
|
|
|
13
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
14
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
15
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
16
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
17
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
18
|
+
_nojq_warned="/tmp/cc-nojq-warned-ssh-key-protect-$PPID"
|
|
19
|
+
[ -f "$_nojq_warned" ] || {
|
|
20
|
+
echo "WARNING [ssh-key-protect]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
21
|
+
: > "$_nojq_warned"
|
|
22
|
+
}
|
|
23
|
+
fi
|
|
24
|
+
|
|
13
25
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
14
26
|
[ -z "$COMMAND" ] && exit 0
|
|
15
27
|
|
|
@@ -18,6 +18,18 @@
|
|
|
18
18
|
#
|
|
19
19
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
20
20
|
|
|
21
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
22
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
23
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
24
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
25
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
26
|
+
_nojq_warned="/tmp/cc-nojq-warned-staged-secret-scan-$PPID"
|
|
27
|
+
[ -f "$_nojq_warned" ] || {
|
|
28
|
+
echo "WARNING [staged-secret-scan]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
29
|
+
: > "$_nojq_warned"
|
|
30
|
+
}
|
|
31
|
+
fi
|
|
32
|
+
|
|
21
33
|
INPUT=$(cat)
|
|
22
34
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
23
35
|
[[ -z "$COMMAND" ]] && exit 0
|
|
@@ -52,7 +64,16 @@ if echo "$DIFF" | grep -qE '^\+.*AKIA[0-9A-Z]{16}'; then
|
|
|
52
64
|
fi
|
|
53
65
|
|
|
54
66
|
# Common API key prefixes
|
|
55
|
-
if echo "$DIFF" | grep -qE '^\+.*(
|
|
67
|
+
if echo "$DIFF" | grep -qE '^\+.*(pk_[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36}|gho_[a-zA-Z0-9]{36}|glpat-[a-zA-Z0-9]{20}|xoxb-[0-9]{10,})'; then
|
|
68
|
+
echo "BLOCKED: API key/token detected in staged changes" >&2
|
|
69
|
+
FOUND=1
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# OpenAI keys. 2026-08: いまの鍵は `sk-proj-` で始まり区切りの `-` `_` を含むので、
|
|
73
|
+
# 文字集合に `-` `_` を入れる。ただし入れた途端に `disk-usage-…` `task-management-…`
|
|
74
|
+
# の中の `sk-` へ当たるようになるため、左の境界を必ず一組で持たせる。
|
|
75
|
+
# 差分の行は `^\+` を先に食うので、直後に来る場合と途中に来る場合を分けて書く。
|
|
76
|
+
if echo "$DIFF" | grep -qE '^\+(sk-[A-Za-z0-9_-]{20,}|.*[^A-Za-z0-9]sk-[A-Za-z0-9_-]{20,})'; then
|
|
56
77
|
echo "BLOCKED: API key/token detected in staged changes" >&2
|
|
57
78
|
FOUND=1
|
|
58
79
|
fi
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# stale-temp-settings-detector.sh — Warn when /tmp holds a stale
|
|
4
|
+
# claude-settings file owned by a different local user.
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# Claude Desktop launches Claude Code with `--settings '{}'` and
|
|
8
|
+
# writes the inline payload to /tmp/claude-settings-<hash>.json.
|
|
9
|
+
# The hash is deterministic across users on the same host, so a
|
|
10
|
+
# stale file owned by user A blocks a fresh start by user B with
|
|
11
|
+
# EACCES, and the only message the user sees is "Claude Code
|
|
12
|
+
# process exited with code 1".
|
|
13
|
+
#
|
|
14
|
+
# TRIGGER: SessionStart
|
|
15
|
+
# MATCHER: (none)
|
|
16
|
+
#
|
|
17
|
+
# WHY THIS MATTERS:
|
|
18
|
+
# Issue #57224 (filed 2026-05-08, area:security) describes a
|
|
19
|
+
# shared-host crash where a stale /tmp/claude-settings-44136fa
|
|
20
|
+
# 355b3678a.json owned by another local user blocked startup.
|
|
21
|
+
# The error surfacing was masked into "process exited with code 1".
|
|
22
|
+
#
|
|
23
|
+
# This detector scans /tmp at session start, lists any
|
|
24
|
+
# claude-settings-*.json owned by other users, and surfaces the
|
|
25
|
+
# actual owner names so the user can act before retrying.
|
|
26
|
+
#
|
|
27
|
+
# CONFIGURATION:
|
|
28
|
+
# STALE_TEMP_SETTINGS_DISABLE set to 1 to silence this hook
|
|
29
|
+
#
|
|
30
|
+
# RELATED ISSUES:
|
|
31
|
+
# https://github.com/anthropics/claude-code/issues/57224
|
|
32
|
+
# ================================================================
|
|
33
|
+
|
|
34
|
+
set -u
|
|
35
|
+
|
|
36
|
+
[ "${STALE_TEMP_SETTINGS_DISABLE:-0}" = "1" ] && exit 0
|
|
37
|
+
|
|
38
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
39
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
40
|
+
|
|
41
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
42
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
43
|
+
[ -z "$SESSION_ID" ] && SESSION_ID="unknown-$(date +%s)"
|
|
44
|
+
|
|
45
|
+
# One warning per session
|
|
46
|
+
WARN_LOG="$LOG_DIR/stale-temp-settings-warned-$SESSION_ID"
|
|
47
|
+
[ -f "$WARN_LOG" ] && exit 0
|
|
48
|
+
|
|
49
|
+
CURRENT_UID=$(id -u 2>/dev/null || echo "")
|
|
50
|
+
[ -z "$CURRENT_UID" ] && exit 0
|
|
51
|
+
|
|
52
|
+
# Find files matching the pattern. -maxdepth 1 keeps the scan scoped.
|
|
53
|
+
# Suppress errors so a missing /tmp or restricted access exits cleanly.
|
|
54
|
+
MATCHES=$(find /tmp -maxdepth 1 -name 'claude-settings-*.json' -type f 2>/dev/null)
|
|
55
|
+
[ -z "$MATCHES" ] && exit 0
|
|
56
|
+
|
|
57
|
+
FOREIGN=""
|
|
58
|
+
while IFS= read -r path; do
|
|
59
|
+
[ -z "$path" ] && continue
|
|
60
|
+
# Skip if we cannot stat the file
|
|
61
|
+
OWNER_UID=$(stat -c '%u' "$path" 2>/dev/null) || continue
|
|
62
|
+
if [ "$OWNER_UID" != "$CURRENT_UID" ]; then
|
|
63
|
+
OWNER_NAME=$(stat -c '%U' "$path" 2>/dev/null)
|
|
64
|
+
FOREIGN="${FOREIGN} $path (owner: ${OWNER_NAME:-uid=$OWNER_UID})"$'\n'
|
|
65
|
+
fi
|
|
66
|
+
done <<< "$MATCHES"
|
|
67
|
+
|
|
68
|
+
if [ -n "$FOREIGN" ]; then
|
|
69
|
+
cat >&2 <<MSG
|
|
70
|
+
stale-temp-settings-detector: /tmp holds claude-settings file(s)
|
|
71
|
+
owned by a different user. Claude Desktop's inline-settings
|
|
72
|
+
launch path uses a deterministic name and will fail with EACCES
|
|
73
|
+
on collision, surfacing only "process exited with code 1".
|
|
74
|
+
|
|
75
|
+
Foreign files:
|
|
76
|
+
${FOREIGN}
|
|
77
|
+
If you have permission, remove them and retry. Otherwise, ask the
|
|
78
|
+
host administrator to clean /tmp/claude-settings-*.json or wait
|
|
79
|
+
for the other user's session to finish.
|
|
80
|
+
|
|
81
|
+
Background: Issue #57224 (filed 2026-05-08, area:security).
|
|
82
|
+
MSG
|
|
83
|
+
touch "$WARN_LOG"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
exit 0
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# standing-rule-session-surfacer.sh — Surface standing rules from
|
|
4
|
+
# user's auto-memory files on every SessionStart so the model
|
|
5
|
+
# cannot "load but forget" them across a long session
|
|
6
|
+
# ================================================================
|
|
7
|
+
# PURPOSE:
|
|
8
|
+
# Issue #59944 documents an entire 5-hour Claude Code session
|
|
9
|
+
# in which a user-stored "STANDING RULE" (marked "third strike"
|
|
10
|
+
# in the operator's own memory file, indexed in MEMORY.md as
|
|
11
|
+
# always-loaded) was read at session start, then violated across
|
|
12
|
+
# 8 backend commits, with the model only acknowledging the rule
|
|
13
|
+
# existed after the operator asked a direct point-blank question
|
|
14
|
+
# about it.
|
|
15
|
+
#
|
|
16
|
+
# The structural failure: auto-memory loads files, but does not
|
|
17
|
+
# bind behavior. The rule sits in the system prompt as text,
|
|
18
|
+
# indistinguishable from any other text. Without a visible,
|
|
19
|
+
# load-bearing surfacing at session start, "STANDING RULE" lines
|
|
20
|
+
# carry no more weight than a comment.
|
|
21
|
+
#
|
|
22
|
+
# This hook surfaces matching lines (STANDING RULE / strict /
|
|
23
|
+
# third strike / MUST / NEVER / ALWAYS) from the user's memory
|
|
24
|
+
# files into a SessionStart system-reminder block. Re-stating
|
|
25
|
+
# the rule, in load-bearing position, on every new session is
|
|
26
|
+
# the cheapest possible defense.
|
|
27
|
+
#
|
|
28
|
+
# TRIGGER: SessionStart
|
|
29
|
+
# MATCHER: (none)
|
|
30
|
+
#
|
|
31
|
+
# WHY THIS MATTERS:
|
|
32
|
+
# - #59944 reporter's exact framing: "Claude Code read this file
|
|
33
|
+
# at session start. Then it spent the entire session doing
|
|
34
|
+
# backend-only curl probes on tasks the simulation doc
|
|
35
|
+
# explicitly described as UI surfaces."
|
|
36
|
+
# - #59938 (v2.1.128) is the same structural failure on a
|
|
37
|
+
# different surface (CLAUDE.md instead of memory file), with
|
|
38
|
+
# the model directly confessing after the fact: "The rule is
|
|
39
|
+
# already in both CLAUDE.md and my memory file — I just failed
|
|
40
|
+
# to apply it."
|
|
41
|
+
# - Two independent reporters, two different versions, two
|
|
42
|
+
# surfaces (auto-memory and CLAUDE.md), one structural shape.
|
|
43
|
+
#
|
|
44
|
+
# CONFIGURATION:
|
|
45
|
+
# CC_STANDING_RULE_MAX_LINES — max lines surfaced per file
|
|
46
|
+
# (default: 8). Long memory files
|
|
47
|
+
# must be allowed to grow without
|
|
48
|
+
# flooding the system prompt.
|
|
49
|
+
# CC_STANDING_RULE_PATTERN — regex of rule markers to surface
|
|
50
|
+
# (default: documented below).
|
|
51
|
+
# CC_STANDING_RULE_MEMORY_DIR — alternate memory directory to
|
|
52
|
+
# scan. Default scans every
|
|
53
|
+
# .claude/projects/*/memory/ under
|
|
54
|
+
# $HOME.
|
|
55
|
+
#
|
|
56
|
+
# OUTPUT:
|
|
57
|
+
# A JSON object on stdout with `hookSpecificOutput.additionalContext`
|
|
58
|
+
# containing the surfaced rules. Claude Code injects this as a
|
|
59
|
+
# system-reminder for the new session.
|
|
60
|
+
#
|
|
61
|
+
# RELATED ISSUES:
|
|
62
|
+
# https://github.com/anthropics/claude-code/issues/59944
|
|
63
|
+
# https://github.com/anthropics/claude-code/issues/59938
|
|
64
|
+
# ================================================================
|
|
65
|
+
|
|
66
|
+
set -u
|
|
67
|
+
|
|
68
|
+
MAX_LINES="${CC_STANDING_RULE_MAX_LINES:-8}"
|
|
69
|
+
PATTERN="${CC_STANDING_RULE_PATTERN:-STANDING RULE|third strike|strict rule|MUST NOT|MUST ALWAYS|NEVER do|ALWAYS do|絶対|必ず|してはいけない|やるな}"
|
|
70
|
+
|
|
71
|
+
# Find every memory directory. Default: $HOME/.claude/projects/*/memory/
|
|
72
|
+
# (the auto-memory layout Claude Code uses today). Operators can override
|
|
73
|
+
# via CC_STANDING_RULE_MEMORY_DIR for a single explicit directory.
|
|
74
|
+
if [ -n "${CC_STANDING_RULE_MEMORY_DIR:-}" ]; then
|
|
75
|
+
MEMORY_DIRS=("$CC_STANDING_RULE_MEMORY_DIR")
|
|
76
|
+
else
|
|
77
|
+
mapfile -t MEMORY_DIRS < <(find "$HOME/.claude/projects" -maxdepth 2 -type d -name memory 2>/dev/null)
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
[ ${#MEMORY_DIRS[@]} -eq 0 ] && exit 0
|
|
81
|
+
|
|
82
|
+
# Collect matching lines from every .md file in every memory dir.
|
|
83
|
+
# Limit to MAX_LINES per file to prevent flooding.
|
|
84
|
+
COLLECTED=""
|
|
85
|
+
SCANNED=0
|
|
86
|
+
|
|
87
|
+
for dir in "${MEMORY_DIRS[@]}"; do
|
|
88
|
+
[ -d "$dir" ] || continue
|
|
89
|
+
for f in "$dir"/*.md; do
|
|
90
|
+
[ -f "$f" ] || continue
|
|
91
|
+
SCANNED=$((SCANNED + 1))
|
|
92
|
+
# Grab matching lines, limit, prefix with the filename.
|
|
93
|
+
matches=$(grep -nE "$PATTERN" "$f" 2>/dev/null | head -n "$MAX_LINES" || true)
|
|
94
|
+
if [ -n "$matches" ]; then
|
|
95
|
+
relname=$(basename "$f")
|
|
96
|
+
COLLECTED="${COLLECTED}
|
|
97
|
+
[${relname}]
|
|
98
|
+
${matches}
|
|
99
|
+
"
|
|
100
|
+
fi
|
|
101
|
+
done
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
# Nothing matched. Exit cleanly. The user has no standing rules
|
|
105
|
+
# in their memory layer; this hook produces no output.
|
|
106
|
+
if [ -z "$COLLECTED" ]; then
|
|
107
|
+
exit 0
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
# Build the additionalContext payload. The leading message frames
|
|
111
|
+
# the rules as load-bearing, not advisory. This phrasing is
|
|
112
|
+
# deliberate: it tells the model that these rules apply to the
|
|
113
|
+
# session it is about to start, not just to past conversations.
|
|
114
|
+
CONTEXT="===== STANDING RULES FROM AUTO-MEMORY =====
|
|
115
|
+
The following rules were marked as STANDING / MUST / NEVER / ALWAYS / 必ず /
|
|
116
|
+
絶対 etc. in your memory files, scanned at session start. They apply to this
|
|
117
|
+
session immediately. Read them. Apply them. If you find yourself about to
|
|
118
|
+
take an action that conflicts with one, stop and verify the conflict before
|
|
119
|
+
proceeding.
|
|
120
|
+
|
|
121
|
+
Scanned ${SCANNED} memory file(s) across ${#MEMORY_DIRS[@]} memory director(y/ies).
|
|
122
|
+
${COLLECTED}
|
|
123
|
+
===== END STANDING RULES ====="
|
|
124
|
+
|
|
125
|
+
# Emit as JSON for Claude Code to consume. The hookSpecificOutput
|
|
126
|
+
# schema is the documented surface for SessionStart hooks to inject
|
|
127
|
+
# additional context.
|
|
128
|
+
jq -n \
|
|
129
|
+
--arg ctx "$CONTEXT" \
|
|
130
|
+
'{
|
|
131
|
+
hookSpecificOutput: {
|
|
132
|
+
hookEventName: "SessionStart",
|
|
133
|
+
additionalContext: $ctx
|
|
134
|
+
}
|
|
135
|
+
}'
|
|
136
|
+
|
|
137
|
+
exit 0
|