cc-safe-setup 29.7.0 → 30.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +419 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-circuit-breaker.sh +72 -0
- package/examples/compact-dispatch-watchdog.sh +149 -0
- package/examples/completion-claim-without-verification-detector.sh +207 -0
- package/examples/composer-guard.sh +12 -0
- package/examples/compound-bash-permission-resolver.sh +156 -0
- package/examples/compound-command-allow.sh +1 -1
- package/examples/compound-command-deny-enforcer.sh +183 -0
- package/examples/compound-inject-guard.sh +12 -0
- package/examples/concurrent-edit-lock.sh +12 -0
- package/examples/conflict-marker-guard.sh +12 -0
- package/examples/consecutive-error-breaker.sh +0 -0
- package/examples/console-log-count.sh +1 -0
- package/examples/context-compact-advisor.sh +29 -2
- package/examples/context-length-budget.sh +69 -0
- package/examples/context-threshold-alert.sh +12 -0
- package/examples/context-usage-drift-alert.sh +41 -13
- package/examples/conversation-history-guard.sh +12 -0
- package/examples/core-file-protect-guard.sh +12 -0
- package/examples/cors-star-warn.sh +0 -0
- package/examples/cost-incident-self-audit.sh +162 -0
- package/examples/cowork-claude-md-load-checker.sh +100 -0
- package/examples/cowork-fuse-staleness-watcher.sh +140 -0
- package/examples/cowork-hook-absence-warner.sh +167 -0
- package/examples/cowork-model-picker-advisor.sh +115 -0
- package/examples/credential-exfil-guard.sh +65 -4
- package/examples/credential-file-cat-guard.sh +17 -1
- package/examples/cron-create-receipt.sh +112 -0
- package/examples/cron-modification-guard.sh +12 -0
- package/examples/cross-product-mcp-spawn-detector.sh +178 -0
- package/examples/cwd-project-boundary-guard.sh +0 -0
- package/examples/daemon-zombie-worker-surfacer.sh +118 -0
- package/examples/daily-cost-guard.sh +164 -0
- package/examples/daily-usage-tracker.sh +0 -0
- package/examples/dangerous-pip-flag-guard.sh +12 -0
- package/examples/db-connect-guard.sh +13 -1
- package/examples/denied-action-retry-guard.sh +12 -0
- package/examples/deny-bypass-detector.sh +12 -0
- package/examples/deny-rule-integrity-verifier.sh +181 -0
- package/examples/dependency-install-guard.sh +12 -0
- package/examples/deploy-guard.sh +14 -2
- package/examples/deploy-path-verify-guard.sh +12 -0
- package/examples/deployment-readback-gate.sh +135 -0
- package/examples/deployment-readback-gh-adapter.sh +247 -0
- package/examples/deployment-verify-guard.sh +25 -2
- package/examples/destructive-db-script-write-guard.sh +166 -0
- package/examples/destructive-migration-write-guard.sh +163 -0
- package/examples/diff-size-guard.sh +12 -0
- package/examples/disabled-feature-toggle-advisor.sh +88 -0
- package/examples/disk-partition-guard.sh +12 -0
- package/examples/dispatch-allowlist-preflight.sh +301 -0
- package/examples/dispatch-liveness-watchdog.sh +216 -0
- package/examples/dispatch-receipt.sh +174 -0
- package/examples/django-migrate-guard.sh +12 -0
- package/examples/dns-config-guard.sh +12 -0
- package/examples/docker-dangerous-guard.sh +12 -0
- package/examples/docker-volume-guard.sh +0 -0
- package/examples/dockerfile-latest-guard.sh +1 -0
- package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
- package/examples/dotenv-commit-guard.sh +12 -0
- package/examples/dotenv-read-guard.sh +12 -0
- package/examples/dotfile-protection-guard.sh +12 -0
- package/examples/dotnet-build-on-edit.sh +1 -1
- package/examples/drizzle-migrate-guard.sh +27 -2
- package/examples/echo-probe-spam-detector.sh +176 -0
- package/examples/edit-counter-test-gate.sh +12 -0
- package/examples/edit-error-counter.sh +1 -1
- package/examples/edit-guard.sh +12 -0
- package/examples/edit-old-string-validator.sh +12 -0
- package/examples/edit-quote-ambiguity-guard.sh +97 -0
- package/examples/edit-retry-loop-guard.sh +0 -0
- package/examples/edit-verify.sh +0 -0
- package/examples/env-inline-secret-guard.sh +14 -2
- package/examples/env-naming-convention.sh +0 -0
- package/examples/env-prod-guard.sh +0 -0
- package/examples/env-required-check.sh +0 -0
- package/examples/env-source-guard.sh +12 -0
- package/examples/env-var-check.sh +24 -1
- package/examples/ephemeral-container-detector.sh +147 -0
- package/examples/error-memory-guard.sh +12 -0
- package/examples/evidence-claim-gate.sh +187 -0
- package/examples/exploration-budget-guard.sh +89 -0
- package/examples/expo-eject-guard.sh +13 -0
- package/examples/extended-thinking-loop-guard.sh +139 -0
- package/examples/extended-thinking-resume-warning.sh +119 -0
- package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
- package/examples/fabricated-command-detector.sh +145 -0
- package/examples/false-disk-full-guard.sh +63 -0
- package/examples/feature-deprecation-detector.sh +109 -0
- package/examples/file-change-tracker.sh +1 -1
- package/examples/file-change-undo-tracker.sh +0 -0
- package/examples/file-edit-backup.sh +63 -14
- package/examples/file-reference-check.sh +0 -0
- package/examples/file-size-limit.sh +12 -0
- package/examples/financial-operation-guard.sh +12 -0
- package/examples/firewall-guard.sh +12 -0
- package/examples/fish-shell-wrapper.sh +125 -7
- package/examples/five-hundred-milestone.sh +1 -0
- package/examples/flask-static-route-guard.sh +89 -0
- package/examples/forbidden-response-phrase-detector.sh +161 -0
- package/examples/gem-push-guard.sh +13 -0
- package/examples/gh-cli-destructive-guard.sh +13 -1
- package/examples/git-checkout-safety-guard.sh +12 -0
- package/examples/git-checkout-uncommitted-guard.sh +12 -0
- package/examples/git-config-guard.sh +12 -0
- package/examples/git-crypt-worktree-guard.sh +12 -0
- package/examples/git-filter-repo-guard.sh +56 -0
- package/examples/git-history-rewrite-guard.sh +12 -0
- package/examples/git-hook-bypass-guard.sh +0 -0
- package/examples/git-maintenance-guard.sh +83 -0
- package/examples/git-merge-conflict-prevent.sh +0 -0
- package/examples/git-message-length-check.sh +0 -0
- package/examples/git-message-length.sh +0 -0
- package/examples/git-operations-require-approval.sh +68 -14
- package/examples/git-pack-temp-cleanup-guard.sh +102 -0
- package/examples/git-push-blast-radius-guard.sh +218 -0
- package/examples/git-remote-guard.sh +24 -3
- package/examples/git-rm-orphan-wipe-guard.sh +85 -0
- package/examples/git-stash-before-checkout.sh +12 -0
- package/examples/git-stash-before-danger.sh +0 -0
- package/examples/git-submodule-guard.sh +69 -2
- package/examples/git-tag-guard.sh +12 -0
- package/examples/github-actions-secret-guard.sh +0 -0
- package/examples/gitignore-check.sh +0 -0
- package/examples/gitops-drift-guard.sh +12 -0
- package/examples/go-mod-tidy-warn.sh +1 -0
- package/examples/go-vet-after-edit.sh +12 -0
- package/examples/goal-iteration-limit-warner.sh +152 -0
- package/examples/grep-nul-false-negative-guard.sh +30 -0
- package/examples/growthbook-flag-monitor.sh +257 -0
- package/examples/hallucination-url-check.sh +1 -1
- package/examples/halt-signal-detector.sh +135 -0
- package/examples/handoff-on-clear.sh +65 -0
- package/examples/hardcoded-ip-guard.sh +1 -0
- package/examples/headless-empty-result-guard.sh +0 -0
- package/examples/headless-stop-guard.sh +0 -0
- package/examples/helm-install-guard.sh +2 -1
- package/examples/home-critical-bash-guard.sh +17 -1
- package/examples/hook-debug-wrapper.sh +6 -2
- package/examples/hook-permission-fixer.sh +0 -0
- package/examples/hook-self-disable-detector.sh +99 -0
- package/examples/hook-stdout-sanitizer.sh +6 -2
- package/examples/hook-tamper-guard.sh +12 -0
- package/examples/idle-session-cost-alert.sh +0 -0
- package/examples/image-dimension-guard.sh +109 -0
- package/examples/image-file-validator.sh +0 -0
- package/examples/iteration-quality-degradation-detector.sh +170 -0
- package/examples/java-compile-on-edit.sh +1 -1
- package/examples/json-syntax-check.sh +0 -0
- package/examples/k8s-production-guard.sh +13 -1
- package/examples/kill-process-guard.sh +12 -0
- package/examples/kubernetes-guard.sh +13 -1
- package/examples/laravel-artisan-guard.sh +13 -0
- package/examples/large-file-guard.sh +1 -1
- package/examples/log-level-guard.sh +0 -0
- package/examples/log-truncation-guard.sh +12 -0
- package/examples/long-session-malformed-tool-call-detector.sh +183 -0
- package/examples/loop-detector.sh +12 -0
- package/examples/magic-number-warn.sh +1 -0
- package/examples/main-branch-warn.sh +12 -0
- package/examples/markdown-link-check.sh +0 -0
- package/examples/max-concurrent-agents.sh +12 -0
- package/examples/max-edit-size-guard.sh +13 -0
- package/examples/max-file-count-guard.sh +0 -0
- package/examples/max-file-delete-count.sh +0 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +0 -0
- package/examples/max-subagent-count.sh +0 -0
- package/examples/mcp-config-freeze.sh +12 -0
- package/examples/mcp-config-poisoning-audit.sh +150 -0
- package/examples/mcp-data-boundary.sh +1 -1
- package/examples/mcp-misdiagnosis-arrest.sh +209 -0
- package/examples/mcp-orphan-leak-warner.sh +49 -0
- package/examples/mcp-permissions-ask-warner.sh +151 -0
- package/examples/mcp-routine-approval-detector.sh +154 -0
- package/examples/mcp-server-allowlist.sh +12 -0
- package/examples/mcp-server-guard.sh +12 -0
- package/examples/mcp-startup-bloat-detector.sh +87 -0
- package/examples/mcp-stdio-compatibility-test.sh +153 -0
- package/examples/mcp-tool-audit-log.sh +0 -0
- package/examples/mcp-tool-guard.sh +101 -1
- package/examples/mcp-warmup-wait.sh +0 -0
- package/examples/memory-chain-audit.sh +56 -0
- package/examples/memory-orphan-detector.sh +188 -0
- package/examples/memory-write-guard.sh +99 -17
- package/examples/migration-verify-guard.sh +12 -0
- package/examples/model-swap-suggester.sh +177 -0
- package/examples/model-version-alert.sh +5 -1
- package/examples/model-version-lock.sh +63 -0
- package/examples/move-delete-sequence-guard.sh +33 -2
- package/examples/multi-file-plan-routing-gate.sh +192 -0
- package/examples/multi-vendor-concurrent-warner.sh +108 -0
- package/examples/multi-window-auth-drift-detector.sh +183 -0
- package/examples/multiline-command-approver.sh +161 -23
- package/examples/nested-background-agent-guard.sh +109 -0
- package/examples/nested-spawn-inflight-guard.sh +178 -0
- package/examples/network-exfil-guard.sh +12 -0
- package/examples/network-guard.sh +12 -0
- package/examples/network-interface-guard.sh +12 -0
- package/examples/nextjs-env-guard.sh +1 -1
- package/examples/no-absolute-import.sh +0 -0
- package/examples/no-alert-confirm-prompt.sh +0 -0
- package/examples/no-anonymous-default-export.sh +0 -0
- package/examples/no-any-type.sh +0 -0
- package/examples/no-any-typescript.sh +1 -0
- package/examples/no-ask-human.sh +12 -0
- package/examples/no-assignment-in-condition.sh +0 -0
- package/examples/no-base64-exfil.sh +12 -0
- package/examples/no-callback-hell.sh +0 -0
- package/examples/no-circular-dependency.sh +0 -0
- package/examples/no-cleartext-storage.sh +0 -0
- package/examples/no-commented-code.sh +0 -0
- package/examples/no-commit-fixup.sh +0 -0
- package/examples/no-console-assert.sh +0 -0
- package/examples/no-console-error-swallow.sh +0 -0
- package/examples/no-console-in-prod.sh +0 -0
- package/examples/no-console-log-commit.sh +12 -0
- package/examples/no-console-log.sh +0 -0
- package/examples/no-console-time.sh +0 -0
- package/examples/no-cors-wildcard.sh +4 -1
- package/examples/no-curl-upload.sh +0 -0
- package/examples/no-dangerouslySetInnerHTML.sh +0 -0
- package/examples/no-dangling-await.sh +1 -0
- package/examples/no-debug-commit.sh +12 -0
- package/examples/no-debug-in-commit.sh +0 -0
- package/examples/no-deep-nesting.sh +0 -0
- package/examples/no-deep-relative-import.sh +1 -0
- package/examples/no-default-credentials.sh +0 -0
- package/examples/no-deploy-friday.sh +13 -1
- package/examples/no-disabled-test.sh +0 -0
- package/examples/no-document-write.sh +0 -0
- package/examples/no-empty-function.sh +0 -0
- package/examples/no-eval-in-template.sh +0 -0
- package/examples/no-eval-template.sh +3 -1
- package/examples/no-eval.sh +0 -0
- package/examples/no-exec-user-input.sh +0 -0
- package/examples/no-fixme-ship.sh +12 -0
- package/examples/no-floating-promises.sh +0 -0
- package/examples/no-force-flag.sh +22 -5
- package/examples/no-force-install.sh +0 -0
- package/examples/no-git-amend.sh +12 -0
- package/examples/no-git-rebase-public.sh +0 -0
- package/examples/no-global-install.sh +12 -0
- package/examples/no-global-state.sh +0 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +0 -0
- package/examples/no-helmet-missing.sh +0 -0
- package/examples/no-http-url.sh +1 -0
- package/examples/no-http-without-https.sh +0 -0
- package/examples/no-inline-style.sh +0 -0
- package/examples/no-inline-styles.sh +1 -0
- package/examples/no-innerhtml.sh +0 -0
- package/examples/no-install-global.sh +12 -0
- package/examples/no-jwt-in-url.sh +0 -0
- package/examples/no-large-commit.sh +0 -0
- package/examples/no-localhost-expose.sh +0 -0
- package/examples/no-magic-number.sh +0 -0
- package/examples/no-md5-sha1.sh +0 -0
- package/examples/no-mixed-line-endings.sh +8 -1
- package/examples/no-mutation-in-reducer.sh +0 -0
- package/examples/no-nested-ternary.sh +0 -0
- package/examples/no-network-exfil.sh +0 -0
- package/examples/no-open-redirect.sh +0 -0
- package/examples/no-output-truncation.sh +12 -0
- package/examples/no-package-downgrade.sh +0 -0
- package/examples/no-package-lock-edit.sh +12 -0
- package/examples/no-path-join-user-input.sh +0 -0
- package/examples/no-port-bind.sh +0 -0
- package/examples/no-process-exit.sh +0 -0
- package/examples/no-prototype-pollution.sh +0 -0
- package/examples/no-push-without-ci.sh +0 -0
- package/examples/no-push-without-tests.sh +12 -0
- package/examples/no-raw-password-in-url.sh +0 -0
- package/examples/no-root-user-docker.sh +1 -0
- package/examples/no-root-write.sh +12 -0
- package/examples/no-secrets-in-args.sh +4 -1
- package/examples/no-secrets-in-logs.sh +0 -0
- package/examples/no-sensitive-log.sh +0 -0
- package/examples/no-sleep-in-hooks.sh +0 -0
- package/examples/no-star-import-python.sh +1 -0
- package/examples/no-string-concat-sql.sh +0 -0
- package/examples/no-sudo-guard.sh +12 -0
- package/examples/no-sync-fs.sh +0 -0
- package/examples/no-todo-in-merge.sh +0 -0
- package/examples/no-todo-in-production.sh +1 -0
- package/examples/no-todo-without-issue.sh +0 -0
- package/examples/no-unused-import.sh +0 -0
- package/examples/no-var-keyword.sh +0 -0
- package/examples/no-verify-blocker.sh +12 -0
- package/examples/no-wget-piped-bash.sh +12 -0
- package/examples/no-wildcard-cors.sh +0 -0
- package/examples/no-wildcard-delete.sh +0 -0
- package/examples/no-wildcard-import.sh +0 -0
- package/examples/no-with-statement.sh +0 -0
- package/examples/no-write-outside-src.sh +0 -0
- package/examples/no-xml-external-entity.sh +0 -0
- package/examples/non-english-quality-warner.sh +156 -0
- package/examples/notify-waiting.sh +1 -1
- package/examples/npm-audit-warn.sh +0 -0
- package/examples/npm-global-install-guard.sh +12 -0
- package/examples/npm-publish-guard.sh +12 -0
- package/examples/npm-script-injection.sh +0 -0
- package/examples/npm-supply-chain-guard.sh +0 -0
- package/examples/nuxt-config-guard.sh +1 -0
- package/examples/oauth-refresh-monitor.sh +210 -0
- package/examples/opus-degradation-tracker.sh +187 -0
- package/examples/opus48-routine-task-warning.sh +196 -0
- package/examples/opus48-thinking-wedge-advisor.sh +143 -0
- package/examples/output-credential-scan.sh +1 -1
- package/examples/output-secret-mask.sh +31 -9
- package/examples/output-token-spike-detector.sh +145 -0
- package/examples/package-json-guard.sh +12 -0
- package/examples/package-lock-frozen.sh +12 -0
- package/examples/parallel-batch-size-limiter.sh +121 -0
- package/examples/parallel-cascade-detector.sh +116 -0
- package/examples/partial-view-claim-arrest.sh +174 -0
- package/examples/path-deny-bash-guard.sh +12 -0
- package/examples/path-traversal-guard.sh +12 -0
- package/examples/per-prompt-token-cap.sh +124 -0
- package/examples/permission-audit-log.sh +1 -1
- package/examples/permission-denial-enforcer.sh +12 -0
- package/examples/permission-entry-validator.sh +0 -0
- package/examples/persisted-1m-model-advisor.sh +88 -0
- package/examples/php-lint-on-edit.sh +1 -1
- package/examples/pii-upload-guard.sh +12 -0
- package/examples/pip-publish-guard.sh +13 -0
- package/examples/pip-requirements-guard.sh +12 -0
- package/examples/pip-venv-required.sh +12 -0
- package/examples/plan-mode-edit-guard.sh +12 -0
- package/examples/plan-mode-enforcer.sh +12 -0
- package/examples/plan-mode-strict-guard.sh +12 -0
- package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
- package/examples/plugin-process-cleanup.sh +0 -0
- package/examples/polyglot-rm-guard.sh +12 -0
- package/examples/post-compact-safety.sh +12 -0
- package/examples/post-edit-disk-verify.sh +152 -0
- package/examples/powershell-remove-item-guard.sh +85 -0
- package/examples/pr-description-check.sh +0 -0
- package/examples/pr-duplicate-guard.sh +13 -0
- package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
- package/examples/pre-compact-knowledge-save.sh +0 -0
- package/examples/pre-compact-transcript-backup.sh +0 -0
- package/examples/pre-execution-claim-detector.sh +179 -0
- package/examples/prefer-builtin-tools.sh +10 -1
- package/examples/prefer-const.sh +0 -0
- package/examples/prefer-dedicated-tools.sh +12 -0
- package/examples/prefer-optional-chaining.sh +0 -0
- package/examples/prisma-migrate-guard.sh +24 -7
- package/examples/production-port-kill-guard.sh +12 -0
- package/examples/prompt-injection-guard.sh +2 -1
- package/examples/prompt-usage-logger.sh +0 -0
- package/examples/protect-claudemd.sh +12 -0
- package/examples/protect-dotfiles.sh +12 -0
- package/examples/proxy-capture-suggester.sh +159 -0
- package/examples/public-artefact-socratic-narrowing.sh +232 -0
- package/examples/public-repo-push-guard.sh +12 -0
- package/examples/push-requires-test-pass-record.sh +0 -0
- package/examples/push-requires-test-pass.sh +12 -0
- package/examples/quota-anomaly-detector.sh +173 -0
- package/examples/quota-reset-audit.sh +58 -0
- package/examples/quoted-flag-approver.sh +99 -10
- package/examples/rails-migration-guard.sh +12 -0
- package/examples/rate-limit-guard.sh +0 -0
- package/examples/read-all-files-enforcer.sh +0 -0
- package/examples/read-budget-guard.sh +12 -0
- package/examples/read-loop-detector.sh +59 -0
- package/examples/read-once-guard.sh +96 -0
- package/examples/read-only-mode.sh +12 -0
- package/examples/readme-exists-check.sh +0 -0
- package/examples/record-read-coverage.sh +73 -0
- package/examples/redirect-fragment-warner.sh +149 -0
- package/examples/redis-flushall-guard.sh +13 -0
- package/examples/redundant-read-blocker.sh +132 -0
- package/examples/refusal-arrest-gate.sh +248 -0
- package/examples/registry-publish-guard.sh +13 -1
- package/examples/remote-control-billing-classifier.sh +135 -0
- package/examples/replace-all-guard.sh +12 -0
- package/examples/repo-visibility-guard.sh +12 -0
- package/examples/reroute-after-block-guard.sh +150 -0
- package/examples/response-budget-guard.sh +0 -0
- package/examples/resume-drift-watcher.sh +57 -0
- package/examples/rg-replace-flag-detector.sh +125 -0
- package/examples/rhetorical-verification-prompt-detector.sh +102 -0
- package/examples/ripgrep-permission-fix.sh +0 -0
- package/examples/rm-safety-net.sh +151 -8
- package/examples/role-tool-guard.sh +12 -0
- package/examples/route-handler-emptiness-gate.sh +324 -0
- package/examples/ruby-lint-on-edit.sh +1 -1
- package/examples/runtime-binary-change-detector.sh +102 -0
- package/examples/same-command-repeat-detector.sh +196 -0
- package/examples/same-correction-arrest.sh +169 -0
- package/examples/sandbox-denywrite-enforcer.sh +78 -0
- package/examples/sandbox-relative-path-audit.sh +83 -25
- package/examples/sandbox-write-verify.sh +12 -0
- package/examples/schema-migration-guard.sh +0 -0
- package/examples/scope-expansion-receipt.sh +178 -0
- package/examples/scope-guard.sh +88 -9
- package/examples/secret-file-read-guard.sh +12 -0
- package/examples/secret-file-write-guard.sh +150 -0
- package/examples/self-modify-bypass-guard.sh +0 -0
- package/examples/sensitive-file-read-guard.sh +23 -3
- package/examples/sensitive-log-guard.sh +1 -0
- package/examples/server-side-prompt-injection-detector.sh +69 -0
- package/examples/session-agent-cost-limiter.sh +12 -0
- package/examples/session-backup-on-start.sh +1 -1
- package/examples/session-cost-alert.sh +12 -0
- package/examples/session-drift-guard.sh +12 -0
- package/examples/session-duration-guard.sh +25 -2
- package/examples/session-end-logger.sh +0 -0
- package/examples/session-health-monitor.sh +0 -0
- package/examples/session-index-repair.sh +1 -1
- package/examples/session-memory-watchdog.sh +1 -0
- package/examples/session-permission-reset-guard.sh +12 -0
- package/examples/session-persistence-verifier.sh +93 -0
- package/examples/session-plugin-pin-watch.sh +68 -0
- package/examples/session-rate-monitor.sh +176 -0
- package/examples/session-resume-env-fix.sh +0 -0
- package/examples/session-start-quota-status.sh +193 -0
- package/examples/session-start-safety-check.sh +55 -3
- package/examples/session-state-saver.sh +0 -0
- package/examples/session-summary-stop.sh +1 -1
- package/examples/session-summary.sh +0 -0
- package/examples/session-token-counter.sh +1 -1
- package/examples/settings-hooks-key-restorer.sh +99 -0
- package/examples/settings-json-health-check.sh +57 -0
- package/examples/settings-json-model-guard.sh +0 -0
- package/examples/settings-regression-tester.sh +188 -0
- package/examples/shell-config-truncation-guard.sh +12 -0
- package/examples/shell-wrapper-guard.sh +12 -0
- package/examples/skill-cumulative-size-detector.sh +104 -0
- package/examples/skill-description-drop-detector.sh +148 -0
- package/examples/skill-gate.sh +0 -0
- package/examples/skill-truncation-detector.sh +154 -0
- package/examples/skills-context-recorder.sh +167 -0
- package/examples/skills-load-verifier.sh +96 -0
- package/examples/skills-settings-validator.sh +139 -0
- package/examples/sonnet-45-deprecation-helper.sh +85 -0
- package/examples/spec-file-scope-guard.sh +12 -0
- package/examples/spring-profile-guard.sh +1 -0
- package/examples/spurious-malformed-notice-detector.sh +247 -0
- package/examples/sql-bulk-delete-warn.sh +88 -0
- package/examples/sql-injection-detect.sh +0 -0
- package/examples/ssh-key-protect.sh +12 -0
- package/examples/staged-secret-scan.sh +22 -1
- package/examples/stale-temp-settings-detector.sh +86 -0
- package/examples/standing-rule-session-surfacer.sh +137 -0
- package/examples/stop-hook-sigterm-wrapper.sh +182 -0
- package/examples/stop-transcript-write-health.sh +64 -0
- package/examples/strict-allowlist.sh +57 -15
- package/examples/strip-coauthored-by.sh +50 -10
- package/examples/subagent-blast-radius-guard.sh +184 -0
- package/examples/subagent-boundary-precheck.sh +126 -0
- package/examples/subagent-budget-guard.sh +12 -0
- package/examples/subagent-claudemd-inject.sh +0 -0
- package/examples/subagent-closure-verify-gate.sh +164 -0
- package/examples/subagent-destructive-git-guard.sh +120 -0
- package/examples/subagent-error-detector.sh +0 -0
- package/examples/subagent-forged-system-reminder-guard.sh +156 -0
- package/examples/subagent-identity-leak-guard.sh +102 -0
- package/examples/subagent-identity-reassertion.sh +51 -0
- package/examples/subagent-inheritance-tester.sh +179 -0
- package/examples/subagent-permission-mode-guard.sh +110 -0
- package/examples/subagent-scope-guard.sh +12 -0
- package/examples/subagent-spawn-verification-enforcer.sh +102 -0
- package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
- package/examples/subagent-tool-call-limiter.sh +87 -15
- package/examples/subcommand-chain-guard.sh +12 -0
- package/examples/subscription-api-billing-warner.sh +160 -0
- package/examples/subscription-bypass-detector.sh +152 -0
- package/examples/svelte-lint-on-edit.sh +1 -0
- package/examples/swift-build-on-edit.sh +1 -1
- package/examples/symlink-guard.sh +27 -2
- package/examples/symlink-protect.sh +1 -0
- package/examples/system-dir-protection-guard.sh +73 -8
- package/examples/system-message-workaround.sh +38 -13
- package/examples/system-package-guard.sh +12 -0
- package/examples/systemd-service-guard.sh +12 -0
- package/examples/task-integrity-guard.sh +12 -0
- package/examples/temp-file-cleanup.sh +1 -1
- package/examples/temporal-suggestion-detector.sh +135 -0
- package/examples/terraform-guard.sh +27 -6
- package/examples/test-after-edit.sh +1 -1
- package/examples/test-before-push.sh +12 -0
- package/examples/test-coverage-reminder.sh +24 -1
- package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
- package/examples/thinking-stall-detector.sh +61 -0
- package/examples/timezone-guard.sh +0 -0
- package/examples/tmp-output-size-guard.sh +0 -0
- package/examples/todo-check.sh +1 -1
- package/examples/token-budget-guard.sh +12 -0
- package/examples/token-budget-per-task.sh +12 -0
- package/examples/token-usage-tracker.sh +7 -1
- package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
- package/examples/tokenizer-ratio-alert.sh +104 -0
- package/examples/tool-call-rate-limiter.sh +0 -0
- package/examples/tool-result-correlation-checker.sh +167 -0
- package/examples/tool-result-size-guard.sh +132 -0
- package/examples/tool-retry-budget-guard.sh +12 -0
- package/examples/transcript-contamination-detector.sh +138 -0
- package/examples/trustfall-mcp-injection-guard.sh +103 -0
- package/examples/ultrareview-large-diff-advisor.sh +184 -0
- package/examples/unbounded-output-guard.sh +94 -0
- package/examples/uncommitted-changes-stop.sh +1 -0
- package/examples/uncommitted-discard-guard.sh +23 -5
- package/examples/uncommitted-work-guard.sh +12 -0
- package/examples/usage-warn.sh +0 -0
- package/examples/user-account-guard.sh +12 -0
- package/examples/userprompt-submit-receipt.sh +123 -0
- package/examples/variable-expansion-guard.sh +12 -0
- package/examples/verify-after-publish-reminder.sh +93 -0
- package/examples/verify-before-commit.sh +12 -0
- package/examples/version-bump-detector.sh +156 -0
- package/examples/version-regression-warner.sh +144 -0
- package/examples/vue-lint-on-edit.sh +1 -0
- package/examples/warn-cron-cost-trap.sh +173 -0
- package/examples/webfetch-runaway-guard.sh +89 -0
- package/examples/wellness-break-reminder.sh +118 -0
- package/examples/windows-destructive-command-guard.sh +177 -0
- package/examples/windows-path-guard.sh +12 -0
- package/examples/windows-python-stub-detector.sh +63 -0
- package/examples/work-hours-guard.sh +12 -0
- package/examples/working-directory-fence.sh +12 -0
- package/examples/workspace-lease-guard.sh +205 -0
- package/examples/worktree-create-log.sh +1 -0
- package/examples/worktree-delete-guard.sh +12 -0
- package/examples/worktree-edit-boundary-guard.sh +127 -0
- package/examples/worktree-escape-write-guard.sh +114 -0
- package/examples/worktree-hook-linker.sh +0 -0
- package/examples/worktree-hooks-path-fix.sh +111 -0
- package/examples/worktree-parent-write-guard.sh +43 -0
- package/examples/worktree-project-unify.sh +2 -1
- package/examples/worktree-remove-uncommitted-guard.sh +13 -0
- package/examples/worktree-unmerged-guard.sh +7 -1
- package/examples/write-byte-integrity-verifier.sh +190 -0
- package/examples/write-empty-content-guard.sh +67 -0
- package/examples/write-nul-corruption-detector.sh +61 -0
- package/examples/write-overwrite-confirm.sh +160 -14
- package/examples/write-secret-guard.sh +27 -5
- package/examples/write-shrink-guard.sh +12 -0
- package/examples/write-test-ratio.sh +0 -0
- package/examples/wsl-host-disk-space-guard.sh +97 -0
- package/examples/xml-format-leak-detector.sh +266 -0
- package/examples/yaml-syntax-check.sh +12 -0
- package/hooks/hooks.json +6 -6
- package/index.mjs +1699 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-circuit-breaker.sh +134 -0
- package/tests/test-compact-dispatch-watchdog.sh +147 -0
- package/tests/test-completion-claim-without-verification-detector.sh +326 -0
- package/tests/test-compound-bash-permission-resolver.sh +264 -0
- package/tests/test-compound-command-deny-enforcer.sh +67 -0
- package/tests/test-context-length-budget.sh +68 -0
- package/tests/test-context-usage-drift-alert.sh +52 -22
- package/tests/test-cost-incident-self-audit.sh +94 -0
- package/tests/test-cowork-claude-md-load-checker.sh +257 -0
- package/tests/test-cowork-claudemd-helper.sh +141 -0
- package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
- package/tests/test-cowork-hook-absence-warner.sh +230 -0
- package/tests/test-cowork-model-picker-advisor.sh +317 -0
- package/tests/test-credential-exfil-guard.sh +62 -0
- package/tests/test-cron-create-receipt.sh +165 -0
- package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
- package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
- package/tests/test-daily-cost-guard.sh +131 -0
- package/tests/test-deny-rule-integrity-verifier.sh +288 -0
- package/tests/test-deployment-readback-gate.sh +92 -0
- package/tests/test-deployment-readback-gh-adapter.sh +163 -0
- package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
- package/tests/test-dispatch-allowlist-preflight.sh +385 -0
- package/tests/test-dispatch-liveness-watchdog.sh +319 -0
- package/tests/test-dispatch-receipt.sh +314 -0
- package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
- package/tests/test-echo-probe-spam-detector.sh +143 -0
- package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
- package/tests/test-ephemeral-container-detector.sh +251 -0
- package/tests/test-evidence-claim-gate.sh +291 -0
- package/tests/test-exploration-budget-guard.sh +164 -0
- package/tests/test-extended-thinking-loop-guard.sh +289 -0
- package/tests/test-extended-thinking-resume-warning.sh +240 -0
- package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
- package/tests/test-fabricated-command-detector.sh +296 -0
- package/tests/test-false-disk-full-guard.sh +36 -0
- package/tests/test-feature-deprecation-detector.sh +117 -0
- package/tests/test-forbidden-response-phrase-detector.sh +246 -0
- package/tests/test-git-operations-require-approval.sh +53 -0
- package/tests/test-git-push-blast-radius-guard.sh +115 -0
- package/tests/test-goal-iteration-limit-warner.sh +128 -0
- package/tests/test-growthbook-flag-monitor.sh +428 -0
- package/tests/test-halt-signal-detector.sh +120 -0
- package/tests/test-hook-self-disable-detector.sh +232 -0
- package/tests/test-iteration-quality-degradation-detector.sh +244 -0
- package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
- package/tests/test-marketplace-plugins.sh +193 -0
- package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
- package/tests/test-mcp-orphan-leak-warner.sh +71 -0
- package/tests/test-mcp-permissions-ask-warner.sh +207 -0
- package/tests/test-mcp-routine-approval-detector.sh +229 -0
- package/tests/test-mcp-startup-bloat-detector.sh +141 -0
- package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
- package/tests/test-memory-chain-audit.sh +59 -0
- package/tests/test-memory-orphan-detector.sh +227 -0
- package/tests/test-model-swap-suggester.sh +368 -0
- package/tests/test-model-version-lock.sh +83 -0
- package/tests/test-multi-file-plan-routing-gate.sh +277 -0
- package/tests/test-multi-window-auth-drift-detector.sh +262 -0
- package/tests/test-nested-spawn-inflight-guard.sh +281 -0
- package/tests/test-no-force-flag.sh +49 -0
- package/tests/test-non-english-quality-warner.sh +229 -0
- package/tests/test-oauth-refresh-monitor.sh +311 -0
- package/tests/test-opus-degradation-tracker.sh +274 -0
- package/tests/test-opus48-routine-task-warning.sh +201 -0
- package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
- package/tests/test-output-token-spike-detector.sh +315 -0
- package/tests/test-parallel-batch-size-limiter.sh +228 -0
- package/tests/test-parallel-cascade-detector.sh +191 -0
- package/tests/test-partial-view-claim-arrest.sh +272 -0
- package/tests/test-per-prompt-token-cap.sh +136 -0
- package/tests/test-persisted-1m-model-advisor.sh +71 -0
- package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
- package/tests/test-post-edit-disk-verify.sh +294 -0
- package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
- package/tests/test-pre-execution-claim-detector.sh +366 -0
- package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
- package/tests/test-proxy-capture-suggester.sh +214 -0
- package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
- package/tests/test-quota-anomaly-detector.sh +321 -0
- package/tests/test-quota-reset-audit.sh +81 -0
- package/tests/test-read-loop-detector.sh +137 -0
- package/tests/test-read-once-guard.sh +85 -0
- package/tests/test-receipts-aggregate.sh +143 -0
- package/tests/test-redirect-fragment-warner.sh +130 -0
- package/tests/test-redundant-read-blocker.sh +155 -0
- package/tests/test-refusal-arrest-gate.sh +303 -0
- package/tests/test-remote-control-billing-classifier.sh +125 -0
- package/tests/test-resume-drift-watcher.sh +65 -0
- package/tests/test-rg-replace-flag-detector.sh +175 -0
- package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
- package/tests/test-rm-safety-net.sh +115 -0
- package/tests/test-route-handler-emptiness-gate.sh +300 -0
- package/tests/test-runtime-binary-change-detector.sh +196 -0
- package/tests/test-same-command-repeat-detector.sh +165 -0
- package/tests/test-same-correction-arrest.sh +165 -0
- package/tests/test-scope-expansion-receipt.sh +207 -0
- package/tests/test-server-side-prompt-injection-detector.sh +181 -0
- package/tests/test-session-persistence-verifier.sh +128 -0
- package/tests/test-session-rate-monitor.sh +284 -0
- package/tests/test-session-start-quota-status.sh +210 -0
- package/tests/test-session-start-safety-check.sh +138 -0
- package/tests/test-settings-hooks-key-restorer.sh +257 -0
- package/tests/test-settings-json-health-check.sh +70 -0
- package/tests/test-settings-regression-tester.sh +197 -0
- package/tests/test-skill-cumulative-size-detector.sh +198 -0
- package/tests/test-skill-description-drop-detector.sh +236 -0
- package/tests/test-skill-truncation-detector.sh +263 -0
- package/tests/test-skills-context-recorder.sh +329 -0
- package/tests/test-skills-load-verifier.sh +184 -0
- package/tests/test-skills-settings-validator.sh +242 -0
- package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
- package/tests/test-spurious-malformed-notice-detector.sh +290 -0
- package/tests/test-sql-bulk-delete-warn.sh +123 -0
- package/tests/test-ssh-key-protect.sh +81 -0
- package/tests/test-stale-temp-settings-detector.sh +161 -0
- package/tests/test-standing-rule-session-surfacer.sh +215 -0
- package/tests/test-starter-hooks-manifest.sh +96 -0
- package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
- package/tests/test-strict-allowlist.sh +72 -0
- package/tests/test-subagent-boundary-precheck.sh +137 -0
- package/tests/test-subagent-closure-verify-gate.sh +193 -0
- package/tests/test-subagent-destructive-git-guard.sh +86 -0
- package/tests/test-subagent-identity-leak-guard.sh +62 -0
- package/tests/test-subagent-identity-reassertion.sh +61 -0
- package/tests/test-subagent-inheritance-tester.sh +319 -0
- package/tests/test-subagent-permission-mode-guard.sh +61 -0
- package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
- package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
- package/tests/test-subagent-tool-call-limiter.sh +97 -0
- package/tests/test-subscription-api-billing-warner.sh +138 -0
- package/tests/test-subscription-bypass-detector.sh +255 -0
- package/tests/test-temporal-suggestion-detector.sh +183 -0
- package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
- package/tests/test-thinking-stall-detector.sh +151 -0
- package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
- package/tests/test-tokenizer-ratio-alert.sh +93 -0
- package/tests/test-tool-result-correlation-checker.sh +264 -0
- package/tests/test-tool-result-size-guard.sh +121 -0
- package/tests/test-transcript-contamination-detector.sh +264 -0
- package/tests/test-trigger-header-parsing.sh +151 -0
- package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
- package/tests/test-userprompt-submit-receipt.sh +181 -0
- package/tests/test-verify-after-publish-reminder.sh +184 -0
- package/tests/test-version-bump-detector.sh +212 -0
- package/tests/test-version-regression-warner.sh +165 -0
- package/tests/test-warn-cron-cost-trap.sh +82 -0
- package/tests/test-webfetch-runaway-guard.sh +77 -0
- package/tests/test-wellness-break-reminder.sh +138 -0
- package/tests/test-windows-destructive-command-guard.sh +169 -0
- package/tests/test-windows-python-stub-detector.sh +146 -0
- package/tests/test-worktree-edit-boundary-guard.sh +219 -0
- package/tests/test-write-byte-integrity-verifier.sh +192 -0
- package/tests/test-xml-format-leak-detector.sh +299 -0
- package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
- package/tests/workspace-lease-guard.test.sh +144 -0
- package/tests/worktree-escape-write-guard.test.sh +68 -0
- package/tests/worktree-hooks-path-fix.test.sh +181 -0
- package/tests/worktree-parent-write-guard.test.sh +51 -0
- package/tests/write-empty-content-guard.test.sh +39 -0
- package/tests/write-nul-corruption-detector.test.sh +29 -0
- package/tests/write-overwrite-unread-content.test.sh +178 -0
- package/tests/wsl-host-disk-space-guard.test.sh +55 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# exploration-budget-guard.sh — Stop excessive exploration from draining tokens
|
|
3
|
+
#
|
|
4
|
+
# Solves: #51054 — Claude wastes 20% of weekly allowance exploring files
|
|
5
|
+
# on a simple task instead of acting. Read/Glob/Grep loops with
|
|
6
|
+
# no Edit/Write progress.
|
|
7
|
+
#
|
|
8
|
+
# Tracks read-only tool calls (Read, Glob, Grep) per session. After 25
|
|
9
|
+
# consecutive reads without a write, warns. After 40, blocks.
|
|
10
|
+
# Resets when an Edit/Write/Bash(write) occurs.
|
|
11
|
+
#
|
|
12
|
+
# TRIGGER: PreToolUse MATCHER: "Read|Glob|Grep|Edit|Write"
|
|
13
|
+
|
|
14
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
15
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
16
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
17
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
18
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
19
|
+
_nojq_warned="/tmp/cc-nojq-warned-exploration-budget-guard-$PPID"
|
|
20
|
+
[ -f "$_nojq_warned" ] || {
|
|
21
|
+
echo "WARNING [exploration-budget-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
22
|
+
: > "$_nojq_warned"
|
|
23
|
+
}
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
INPUT=$(cat)
|
|
27
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
28
|
+
|
|
29
|
+
STATE_DIR="/tmp/.cc-exploration-budget"
|
|
30
|
+
mkdir -p "$STATE_DIR"
|
|
31
|
+
|
|
32
|
+
# Session-scoped state file (keyed by parent PID)
|
|
33
|
+
STATE_FILE="$STATE_DIR/session-$$"
|
|
34
|
+
# Fall back to a shared file if $$ changes between hook calls
|
|
35
|
+
STATE_FILE="$STATE_DIR/exploration-count"
|
|
36
|
+
|
|
37
|
+
NOW=$(date +%s)
|
|
38
|
+
|
|
39
|
+
case "$TOOL" in
|
|
40
|
+
Edit|Write)
|
|
41
|
+
# Write operation = progress. Reset exploration counter.
|
|
42
|
+
echo "0 $NOW" > "$STATE_FILE"
|
|
43
|
+
exit 0
|
|
44
|
+
;;
|
|
45
|
+
Read|Glob|Grep)
|
|
46
|
+
# Read operation = exploration. Increment counter.
|
|
47
|
+
;;
|
|
48
|
+
*)
|
|
49
|
+
exit 0
|
|
50
|
+
;;
|
|
51
|
+
esac
|
|
52
|
+
|
|
53
|
+
# Read current count
|
|
54
|
+
COUNT=0
|
|
55
|
+
LAST_TIME=0
|
|
56
|
+
if [ -f "$STATE_FILE" ]; then
|
|
57
|
+
read -r COUNT LAST_TIME < "$STATE_FILE" 2>/dev/null || true
|
|
58
|
+
# Reset if more than 10 minutes since last call (new task)
|
|
59
|
+
ELAPSED=$(( NOW - LAST_TIME ))
|
|
60
|
+
if [ "$ELAPSED" -gt 600 ]; then
|
|
61
|
+
COUNT=0
|
|
62
|
+
fi
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
COUNT=$(( COUNT + 1 ))
|
|
66
|
+
echo "$COUNT $NOW" > "$STATE_FILE"
|
|
67
|
+
|
|
68
|
+
WARN_THRESHOLD=25
|
|
69
|
+
BLOCK_THRESHOLD=40
|
|
70
|
+
|
|
71
|
+
if [ "$COUNT" -ge "$BLOCK_THRESHOLD" ]; then
|
|
72
|
+
echo "BLOCKED: $COUNT consecutive read operations without writing anything." >&2
|
|
73
|
+
echo " You're stuck in an exploration loop — this wastes tokens." >&2
|
|
74
|
+
echo " Take action NOW:" >&2
|
|
75
|
+
echo " 1. Write your solution based on what you've already read" >&2
|
|
76
|
+
echo " 2. If unsure, make a small change and test it" >&2
|
|
77
|
+
echo " 3. Ask the user for clarification instead of reading more files" >&2
|
|
78
|
+
echo "" >&2
|
|
79
|
+
echo " Exploration budget: $COUNT/$BLOCK_THRESHOLD (EXCEEDED)" >&2
|
|
80
|
+
exit 2
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
if [ "$COUNT" -ge "$WARN_THRESHOLD" ]; then
|
|
84
|
+
echo "WARNING: $COUNT consecutive reads without any write." >&2
|
|
85
|
+
echo " You may be over-exploring. Consider acting on what you know." >&2
|
|
86
|
+
echo " Budget: $COUNT/$BLOCK_THRESHOLD reads before block." >&2
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
exit 0
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
#
|
|
2
3
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
4
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
5
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
6
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
7
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
8
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
9
|
+
_nojq_warned="/tmp/cc-nojq-warned-expo-eject-guard-$PPID"
|
|
10
|
+
[ -f "$_nojq_warned" ] || {
|
|
11
|
+
echo "WARNING [expo-eject-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
12
|
+
: > "$_nojq_warned"
|
|
13
|
+
}
|
|
14
|
+
fi
|
|
15
|
+
|
|
3
16
|
INPUT=$(cat)
|
|
4
17
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
5
18
|
[[ -z "$COMMAND" ]] && exit 0
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# extended-thinking-loop-guard.sh — Hard-block a Cluster 13A resume when the
|
|
3
|
+
# session is running under an autonomous-loop / headless-resume harness.
|
|
4
|
+
#
|
|
5
|
+
# Solves: the LMS927369 amplification reported in #63147 on 2026-05-29. The
|
|
6
|
+
# well-known 13A wedge (transcript persists thinking blocks with
|
|
7
|
+
# `thinking: ""` + retained `signature`, then resume re-sends them and the
|
|
8
|
+
# API returns 400) is normally a one-time failure under interactive use.
|
|
9
|
+
# Under `/loop`-style autonomous resume, the failure is instead an
|
|
10
|
+
# *unrecoverable infinite loop*: the loop queues another continuation,
|
|
11
|
+
# the latest assistant message is unchanged on disk, the next request
|
|
12
|
+
# hits the same 400, and the loop never bails because the wedged turn
|
|
13
|
+
# never gets past the API.
|
|
14
|
+
#
|
|
15
|
+
# Why a second hook (in addition to PR #445's advisory): the existing
|
|
16
|
+
# extended-thinking-resume-warning.sh always exits 0 — it surfaces the
|
|
17
|
+
# precursor to the operator's terminal but does not block the session
|
|
18
|
+
# start. Under `/loop`, nobody is watching stderr in the moment, so a
|
|
19
|
+
# non-blocking advisory does not break the loop. This hook is the
|
|
20
|
+
# opt-in BLOCKING complement: when the operator declares "I am running
|
|
21
|
+
# under an autonomous resume harness" via CC_LOOP_GUARD_ENABLED=1, the
|
|
22
|
+
# hook scans the transcript on the disk and exits 2 with a decision
|
|
23
|
+
# block if the 13A precursor is present. The blocking exit propagates
|
|
24
|
+
# into the loop layer and breaks the retry cycle.
|
|
25
|
+
#
|
|
26
|
+
# Issue addressed: #63147 (central case), amplification reported by
|
|
27
|
+
# LMS927369 (https://github.com/anthropics/claude-code/issues/63147#issuecomment-4571317923).
|
|
28
|
+
# Field guide: https://gist.github.com/yurukusa/8c6be069f602399238356a9c9b719a45
|
|
29
|
+
#
|
|
30
|
+
# Default behavior: SILENT NO-OP. The hook exits 0 immediately unless
|
|
31
|
+
# CC_LOOP_GUARD_ENABLED=1 is explicitly set. This makes it safe to drop
|
|
32
|
+
# into a settings.json template that gets applied broadly — interactive
|
|
33
|
+
# operators who do not set the env var see no change in behavior. Only
|
|
34
|
+
# harnesses that opt in get the blocking semantics.
|
|
35
|
+
#
|
|
36
|
+
# Environment variables:
|
|
37
|
+
# CC_LOOP_GUARD_ENABLED=1 — REQUIRED to arm the guard
|
|
38
|
+
# CC_LOOP_GUARD_DISABLE=1 — kill switch (wins over enable)
|
|
39
|
+
# CC_LOOP_GUARD_TRANSCRIPT=<path> — override transcript path (test)
|
|
40
|
+
# CC_LOOP_GUARD_FORCE=1 — fire regardless of source (test)
|
|
41
|
+
# CC_LOOP_GUARD_THRESHOLD=<N> — minimum precursor blocks to
|
|
42
|
+
# trigger (default 1)
|
|
43
|
+
#
|
|
44
|
+
# TRIGGER: SessionStart
|
|
45
|
+
# MATCHER: "" (filters event internally)
|
|
46
|
+
#
|
|
47
|
+
# Exit codes:
|
|
48
|
+
# 0 — safe to proceed (env disabled, no precursor, or non-resume source)
|
|
49
|
+
# 2 — BLOCK (precursor detected under armed guard); decision JSON on stderr
|
|
50
|
+
|
|
51
|
+
set -uo pipefail
|
|
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-extended-thinking-loop-guard-$PPID"
|
|
59
|
+
[ -f "$_nojq_warned" ] || {
|
|
60
|
+
echo "WARNING [extended-thinking-loop-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
|
+
# Kill switch wins.
|
|
68
|
+
[ "${CC_LOOP_GUARD_DISABLE:-0}" = "1" ] && exit 0
|
|
69
|
+
|
|
70
|
+
# Default behavior: not armed → silent no-op. This is the key safety
|
|
71
|
+
# property: dropping the hook into settings.json without setting the env
|
|
72
|
+
# var must not change behavior for interactive operators.
|
|
73
|
+
[ "${CC_LOOP_GUARD_ENABLED:-0}" = "1" ] || exit 0
|
|
74
|
+
|
|
75
|
+
EVENT=$(printf '%s' "$INPUT" | jq -r '.event // .hook_event_name // empty' 2>/dev/null)
|
|
76
|
+
case "$EVENT" in
|
|
77
|
+
session_start|SessionStart|sessionstart) ;;
|
|
78
|
+
*) exit 0 ;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
# Only fire on resume/continue. A fresh `startup` cannot carry a stale
|
|
82
|
+
# precursor (no transcript yet). Unknown source defaults to scanning so
|
|
83
|
+
# new client versions that introduce new source labels stay covered.
|
|
84
|
+
SOURCE=$(printf '%s' "$INPUT" | jq -r '.source // empty' 2>/dev/null)
|
|
85
|
+
if [ "${CC_LOOP_GUARD_FORCE:-0}" != "1" ]; then
|
|
86
|
+
case "$SOURCE" in
|
|
87
|
+
resume|continue|"") ;;
|
|
88
|
+
startup|fresh|new) exit 0 ;;
|
|
89
|
+
*) ;;
|
|
90
|
+
esac
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Locate the transcript file. Same heuristic as PR #445 — recompute the
|
|
94
|
+
# Claude Code project slug from CC_PROJECT_DIR or PWD; if it doesn't
|
|
95
|
+
# resolve, fail open rather than blocking blindly.
|
|
96
|
+
LATEST="${CC_LOOP_GUARD_TRANSCRIPT:-}"
|
|
97
|
+
if [ -z "$LATEST" ]; then
|
|
98
|
+
PROJ_DIR="${CC_PROJECT_DIR:-$PWD}"
|
|
99
|
+
SLUG=$(printf '%s' "$PROJ_DIR" | sed 's|/|-|g')
|
|
100
|
+
TRANSCRIPT_DIR="${HOME}/.claude/projects/${SLUG}"
|
|
101
|
+
[ -d "$TRANSCRIPT_DIR" ] || exit 0
|
|
102
|
+
LATEST=$(ls -t "$TRANSCRIPT_DIR"/*.jsonl 2>/dev/null | head -1)
|
|
103
|
+
fi
|
|
104
|
+
[ -n "$LATEST" ] || exit 0
|
|
105
|
+
[ -r "$LATEST" ] || exit 0
|
|
106
|
+
|
|
107
|
+
# Scan for empty-thinking + non-empty-signature blocks. Same shape as the
|
|
108
|
+
# PR #445 detector; the difference is what we do with the result.
|
|
109
|
+
SCAN=$(jq -rR 'fromjson? | select(.type == "assistant") | .message.content[]? | select(.type == "thinking" and ((.thinking // "") | length) == 0 and ((.signature // "") | length) > 0) | (.signature | length)' "$LATEST" 2>/dev/null || true)
|
|
110
|
+
|
|
111
|
+
if [ -z "$SCAN" ]; then
|
|
112
|
+
exit 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
COUNT=$(printf '%s\n' "$SCAN" | grep -c .)
|
|
116
|
+
THRESHOLD="${CC_LOOP_GUARD_THRESHOLD:-1}"
|
|
117
|
+
|
|
118
|
+
if [ "$COUNT" -lt "$THRESHOLD" ]; then
|
|
119
|
+
exit 0
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
# Block. Emit decision JSON on stderr and exit 2. The decision payload is
|
|
123
|
+
# what Claude Code surfaces to the operator (and what an enclosing harness
|
|
124
|
+
# can grep for to identify the bail reason).
|
|
125
|
+
REASON="Cluster 13A precursor detected on disk (${COUNT} empty-text-signed thinking block(s) in ${LATEST}). Under autonomous loop, resuming this transcript would re-send the corrupted blocks, hit API 400 (\`thinking\` blocks cannot be modified), and the loop would replay indefinitely. Stopping the resume to break the loop. Recover by: (1) backing up the .jsonl, (2) stripping thinking/redacted_thinking blocks from assistant content arrays in-place (leave uuid/parentUuid chains intact), (3) clearing CC_LOOP_GUARD_ENABLED or setting CC_LOOP_GUARD_DISABLE=1 for the recovery session, then resuming. Reference: https://github.com/anthropics/claude-code/issues/63147 — Field guide: https://gist.github.com/yurukusa/8c6be069f602399238356a9c9b719a45"
|
|
126
|
+
|
|
127
|
+
# JSON-escape the reason field for the decision payload. Use jq for the
|
|
128
|
+
# escape so embedded backticks, quotes, slashes, etc. don't break the JSON.
|
|
129
|
+
DECISION=$(jq -nc --arg r "$REASON" '{decision:"block", reason:$r}' 2>/dev/null)
|
|
130
|
+
|
|
131
|
+
if [ -n "$DECISION" ]; then
|
|
132
|
+
printf '%s\n' "$DECISION" >&2
|
|
133
|
+
else
|
|
134
|
+
# jq unavailable for the escape — fall back to a plain-text reason.
|
|
135
|
+
# Operators get the message; harness grep on "decision" may miss it.
|
|
136
|
+
printf '[extended-thinking-loop-guard] BLOCK: %s\n' "$REASON" >&2
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
exit 2
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# extended-thinking-resume-warning.sh — Warn before resuming a session whose
|
|
3
|
+
# transcript carries the 13A precursor.
|
|
4
|
+
#
|
|
5
|
+
# Solves: Cluster 13 Axis A — the resume serialization corruption that wedges
|
|
6
|
+
# extended-thinking sessions on a permanent API 400. Claude Code
|
|
7
|
+
# persists thinking blocks to the session transcript with the
|
|
8
|
+
# `thinking` field emptied to "" but the `signature` field retained
|
|
9
|
+
# from the original response. When the session is resumed, the client
|
|
10
|
+
# sends `{"thinking": "", "signature": "<original>"}` to the API; the
|
|
11
|
+
# signature was computed over the original non-empty thinking text,
|
|
12
|
+
# so validation fails and the session is permanently wedged.
|
|
13
|
+
#
|
|
14
|
+
# Issue addressed: #63147 (central case, 33 reactions). Field guide:
|
|
15
|
+
# https://gist.github.com/yurukusa/8c6be069f602399238356a9c9b719a45
|
|
16
|
+
#
|
|
17
|
+
# How it works: SessionStart hook. When the session source indicates a resume
|
|
18
|
+
# or continue, finds the transcript directory for the current project
|
|
19
|
+
# (~/.claude/projects/<slug>/) and reads the most recent .jsonl file. Scans
|
|
20
|
+
# the file for assistant thinking blocks where `thinking` is empty but
|
|
21
|
+
# `signature` is non-empty — the on-disk shape that becomes the 13A wedge
|
|
22
|
+
# on the next API request.
|
|
23
|
+
#
|
|
24
|
+
# If the pattern is present, the hook emits a stderr advisory naming
|
|
25
|
+
# sub-pattern 13A, pointing at the field guide, and listing the recommended
|
|
26
|
+
# actions (save state, start fresh). The hook NEVER blocks — exit 0 always.
|
|
27
|
+
#
|
|
28
|
+
# Heuristic notes:
|
|
29
|
+
# - Claude Code's project slug is the absolute project dir with leading
|
|
30
|
+
# slash stripped and remaining `/` replaced with `-` (e.g.
|
|
31
|
+
# `/home/u/proj` → `home-u-proj`). The hook recomputes this from
|
|
32
|
+
# CC_PROJECT_DIR or PWD; if the layout differs in a future client
|
|
33
|
+
# version the hook fails open rather than emitting a stale warning.
|
|
34
|
+
# - Trailing thinking blocks in healthy sessions are *also* frequently
|
|
35
|
+
# stored empty-but-signed (per #63147 evidence), so the hook fires on
|
|
36
|
+
# a SHAPE that is common, not a SHAPE that is uniquely broken. The
|
|
37
|
+
# advisory is calibrated to match: it warns the operator that resume
|
|
38
|
+
# may hit the 400, not that it definitely will.
|
|
39
|
+
#
|
|
40
|
+
# Environment variables:
|
|
41
|
+
# CC_EXTENDED_THINKING_RESUME_DISABLE=1 — disable advisory entirely
|
|
42
|
+
# CC_EXTENDED_THINKING_RESUME_VERBOSE=1 — include per-block sizes
|
|
43
|
+
# CC_EXTENDED_THINKING_RESUME_TRANSCRIPT — override transcript path (test)
|
|
44
|
+
# CC_EXTENDED_THINKING_RESUME_FORCE=1 — fire regardless of source (test)
|
|
45
|
+
#
|
|
46
|
+
# TRIGGER: SessionStart
|
|
47
|
+
# MATCHER: "" (filters event internally)
|
|
48
|
+
|
|
49
|
+
set -uo pipefail
|
|
50
|
+
|
|
51
|
+
INPUT=$(cat)
|
|
52
|
+
[ "${CC_EXTENDED_THINKING_RESUME_DISABLE:-0}" = "1" ] && exit 0
|
|
53
|
+
|
|
54
|
+
EVENT=$(printf '%s' "$INPUT" | jq -r '.event // .hook_event_name // empty' 2>/dev/null)
|
|
55
|
+
case "$EVENT" in
|
|
56
|
+
session_start|SessionStart|sessionstart) ;;
|
|
57
|
+
*) exit 0 ;;
|
|
58
|
+
esac
|
|
59
|
+
|
|
60
|
+
# Only fire on resume/continue. Some clients send `source: "resume"`,
|
|
61
|
+
# others `source: "continue"`, others omit it. Fail-open: when the source
|
|
62
|
+
# field is missing or unknown, default to scanning (the cost is one
|
|
63
|
+
# advisory if the transcript happens to carry the precursor shape).
|
|
64
|
+
SOURCE=$(printf '%s' "$INPUT" | jq -r '.source // empty' 2>/dev/null)
|
|
65
|
+
if [ "${CC_EXTENDED_THINKING_RESUME_FORCE:-0}" != "1" ]; then
|
|
66
|
+
case "$SOURCE" in
|
|
67
|
+
resume|continue|"") ;;
|
|
68
|
+
startup|fresh|new) exit 0 ;;
|
|
69
|
+
*) ;; # unknown source — scan anyway
|
|
70
|
+
esac
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Locate the transcript file.
|
|
74
|
+
LATEST="${CC_EXTENDED_THINKING_RESUME_TRANSCRIPT:-}"
|
|
75
|
+
if [ -z "$LATEST" ]; then
|
|
76
|
+
PROJ_DIR="${CC_PROJECT_DIR:-$PWD}"
|
|
77
|
+
SLUG=$(printf '%s' "$PROJ_DIR" | sed 's|/|-|g')
|
|
78
|
+
TRANSCRIPT_DIR="${HOME}/.claude/projects/${SLUG}"
|
|
79
|
+
[ -d "$TRANSCRIPT_DIR" ] || exit 0
|
|
80
|
+
LATEST=$(ls -t "$TRANSCRIPT_DIR"/*.jsonl 2>/dev/null | head -1)
|
|
81
|
+
fi
|
|
82
|
+
[ -n "$LATEST" ] || exit 0
|
|
83
|
+
[ -r "$LATEST" ] || exit 0
|
|
84
|
+
|
|
85
|
+
# Scan for empty-thinking + non-empty-signature blocks. Read each line as
|
|
86
|
+
# raw text and use fromjson? so malformed lines are silently skipped rather
|
|
87
|
+
# than aborting the scan.
|
|
88
|
+
SCAN=$(jq -rR 'fromjson? | select(.type == "assistant") | .message.content[]? | select(.type == "thinking" and ((.thinking // "") | length) == 0 and ((.signature // "") | length) > 0) | (.signature | length)' "$LATEST" 2>/dev/null || true)
|
|
89
|
+
[ -z "$SCAN" ] && exit 0
|
|
90
|
+
|
|
91
|
+
COUNT=$(printf '%s\n' "$SCAN" | grep -c .)
|
|
92
|
+
SIG_LENGTHS=$(printf '%s' "$SCAN" | tr '\n' ' ')
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
echo "[extended-thinking-resume-warning] Cluster 13A precursor detected."
|
|
96
|
+
echo ""
|
|
97
|
+
echo " Transcript: $LATEST"
|
|
98
|
+
echo " Empty-text signed thinking block(s): ${COUNT}"
|
|
99
|
+
echo ""
|
|
100
|
+
echo "Resuming this session may hit the persistent API 400:"
|
|
101
|
+
echo " \`thinking\` blocks in the latest assistant message cannot be modified."
|
|
102
|
+
echo ""
|
|
103
|
+
echo "Once it fires, the wedge persists for the life of the transcript —"
|
|
104
|
+
echo "every subsequent turn re-sends the same corrupted message and re-fails."
|
|
105
|
+
echo ""
|
|
106
|
+
echo "Recommended actions:"
|
|
107
|
+
echo " - If resume is critical, save state from the running process now."
|
|
108
|
+
echo " - Otherwise start a fresh session; the wedge cannot be cleared in-session."
|
|
109
|
+
echo " - Disable extended thinking via /model if your next task allows."
|
|
110
|
+
echo ""
|
|
111
|
+
echo "Reference: https://github.com/anthropics/claude-code/issues/63147"
|
|
112
|
+
echo "Field guide: https://gist.github.com/yurukusa/8c6be069f602399238356a9c9b719a45"
|
|
113
|
+
if [ "${CC_EXTENDED_THINKING_RESUME_VERBOSE:-0}" = "1" ]; then
|
|
114
|
+
echo ""
|
|
115
|
+
echo "(per-block signature lengths: ${SIG_LENGTHS})"
|
|
116
|
+
fi
|
|
117
|
+
} >&2
|
|
118
|
+
|
|
119
|
+
exit 0
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# extended-thinking-tool-use-mismatch-detector.sh — Warn when the
|
|
4
|
+
# structural 12B pattern is detected in the trailing transcript:
|
|
5
|
+
# assistant turns with stop_reason="tool_use" but no parseable
|
|
6
|
+
# tool_use block in content (only thinking and/or text blocks).
|
|
7
|
+
# ================================================================
|
|
8
|
+
# PURPOSE:
|
|
9
|
+
# Issue #62467 documents that when Opus 4.7's extended thinking
|
|
10
|
+
# is active, the assistant turn can carry stop_reason="tool_use"
|
|
11
|
+
# yet emit only a thinking block — no tool_use block reaches the
|
|
12
|
+
# harness parser. The harness then surfaces a "malformed and
|
|
13
|
+
# could not be parsed" notice and retries; in the reporter's
|
|
14
|
+
# sessions ~20 retry prompts accumulated across 6 sessions with
|
|
15
|
+
# no recovery. Output size and special characters are ruled out;
|
|
16
|
+
# the common factor is Opus 4.7 + extended thinking.
|
|
17
|
+
#
|
|
18
|
+
# The companion sub-pattern 12A
|
|
19
|
+
# (long-session-malformed-tool-call-detector.sh, PR #406) keys
|
|
20
|
+
# off the literal "malformed and could not be parsed" string in
|
|
21
|
+
# the transcript text. That text marker fires for any cause of
|
|
22
|
+
# the same surface symptom. The 12B detector here keys off the
|
|
23
|
+
# structural mismatch directly — stop_reason vs. content-block
|
|
24
|
+
# absence — so the operator gets sub-pattern-specific naming
|
|
25
|
+
# even when 12A's text marker has not appeared yet (the harness
|
|
26
|
+
# may suppress the parser notice in some configurations) or when
|
|
27
|
+
# it fires together with 12A's marker (both advisories then name
|
|
28
|
+
# the cluster, with 12B specifically calling out the
|
|
29
|
+
# extended-thinking factor and pointing to the workaround at the
|
|
30
|
+
# model layer rather than at the session layer).
|
|
31
|
+
#
|
|
32
|
+
# TRIGGER: PostToolUse MATCHER: ""
|
|
33
|
+
# CLUSTER: 12 (Tool Call Parsing failures in Opus 4.7)
|
|
34
|
+
# SUB-PATTERN: 12B (extended-thinking serialization defect)
|
|
35
|
+
#
|
|
36
|
+
# BEHAVIOR:
|
|
37
|
+
# - Read transcript_path from PostToolUse hook input.
|
|
38
|
+
# - Scan the trailing LOOKBACK lines for assistant turns.
|
|
39
|
+
# - For each assistant turn, check if .stop_reason == "tool_use"
|
|
40
|
+
# and the .content array contains no element with
|
|
41
|
+
# .type == "tool_use". Count each such mismatch.
|
|
42
|
+
# - If at or above the threshold, emit a one-screen stderr
|
|
43
|
+
# advisory naming sub-pattern 12B and pointing to the
|
|
44
|
+
# model-layer workaround (switch to a variant without
|
|
45
|
+
# extended thinking).
|
|
46
|
+
# - Rate-limit advisory emission per session via a counter
|
|
47
|
+
# file so the warning does not repeat on every PostToolUse
|
|
48
|
+
# after the first detection.
|
|
49
|
+
# - Always exits 0 (advisory only; never blocks tool execution).
|
|
50
|
+
#
|
|
51
|
+
# CONFIGURATION (env vars):
|
|
52
|
+
# CC_THINKING_MISMATCH_DISABLE Set to "1" to silence.
|
|
53
|
+
# CC_THINKING_MISMATCH_LOOKBACK How many recent transcript
|
|
54
|
+
# lines to scan. Default 150.
|
|
55
|
+
# CC_THINKING_MISMATCH_THRESHOLD Minimum mismatches in
|
|
56
|
+
# LOOKBACK to fire. Default 2.
|
|
57
|
+
# (Single mismatches are rare
|
|
58
|
+
# but can occur from unrelated
|
|
59
|
+
# serialization edge cases;
|
|
60
|
+
# requiring 2 keys off the
|
|
61
|
+
# repeated-failure shape
|
|
62
|
+
# #62467 actually documents.)
|
|
63
|
+
# CC_THINKING_MISMATCH_COOLDOWN Minimum tool calls between
|
|
64
|
+
# repeat advisories per
|
|
65
|
+
# session. Default 30.
|
|
66
|
+
# CC_THINKING_MISMATCH_TRANSCRIPT Override transcript path
|
|
67
|
+
# (used by tests).
|
|
68
|
+
# CC_THINKING_MISMATCH_STATE_DIR Override state directory
|
|
69
|
+
# (used by tests). Default
|
|
70
|
+
# /tmp/cc-thinking-mismatch.
|
|
71
|
+
#
|
|
72
|
+
# UPSTREAM REFERENCES:
|
|
73
|
+
# #62467 (central case: stop_reason="tool_use" with only a
|
|
74
|
+
# thinking block, ~20 retry prompts across 6 sessions,
|
|
75
|
+
# Opus 4.7 + extended thinking)
|
|
76
|
+
# #62123 (broader "retry also failed" central case, 21 reactions)
|
|
77
|
+
# #62344 (in-context few-shot poisoning, sub-pattern 12A)
|
|
78
|
+
# #62700 (spurious malformed notice, sub-pattern 12C)
|
|
79
|
+
#
|
|
80
|
+
# RECOVERY ON A HIT:
|
|
81
|
+
# The advisory does not recover the session. The known
|
|
82
|
+
# workaround for sub-pattern 12B is at the model layer:
|
|
83
|
+
# - Switch to a Claude Sonnet variant for the task at hand.
|
|
84
|
+
# - Disable extended thinking via the /model command when
|
|
85
|
+
# Opus's standard mode is sufficient.
|
|
86
|
+
# /clear (the 12A recovery) does not fix 12B because the
|
|
87
|
+
# serialization defect re-fires on the next extended-thinking
|
|
88
|
+
# turn even in a fresh session. The advisory's value is in
|
|
89
|
+
# pointing the operator at the correct workaround layer.
|
|
90
|
+
# ================================================================
|
|
91
|
+
|
|
92
|
+
set -u
|
|
93
|
+
|
|
94
|
+
if [ "${CC_THINKING_MISMATCH_DISABLE:-0}" = "1" ]; then
|
|
95
|
+
exit 0
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
LOOKBACK="${CC_THINKING_MISMATCH_LOOKBACK:-150}"
|
|
99
|
+
THRESHOLD="${CC_THINKING_MISMATCH_THRESHOLD:-2}"
|
|
100
|
+
COOLDOWN="${CC_THINKING_MISMATCH_COOLDOWN:-30}"
|
|
101
|
+
STATE_DIR="${CC_THINKING_MISMATCH_STATE_DIR:-/tmp/cc-thinking-mismatch}"
|
|
102
|
+
|
|
103
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
104
|
+
|
|
105
|
+
TRANSCRIPT_PATH="${CC_THINKING_MISMATCH_TRANSCRIPT:-}"
|
|
106
|
+
if [ -z "$TRANSCRIPT_PATH" ]; then
|
|
107
|
+
TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
111
|
+
exit 0
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "default"' 2>/dev/null)
|
|
115
|
+
[ -z "$SESSION_ID" ] && SESSION_ID="default"
|
|
116
|
+
|
|
117
|
+
SAFE_SESSION=$(printf '%s' "$SESSION_ID" | tr -c 'A-Za-z0-9._-' '_' | head -c 80)
|
|
118
|
+
[ -z "$SAFE_SESSION" ] && SAFE_SESSION="default"
|
|
119
|
+
|
|
120
|
+
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
121
|
+
|
|
122
|
+
COUNTER_FILE="$STATE_DIR/${SAFE_SESSION}.count"
|
|
123
|
+
LASTFIRED_FILE="$STATE_DIR/${SAFE_SESSION}.lastfired"
|
|
124
|
+
|
|
125
|
+
COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
|
|
126
|
+
COUNT=$((COUNT + 1))
|
|
127
|
+
echo "$COUNT" > "$COUNTER_FILE"
|
|
128
|
+
|
|
129
|
+
# Count structural 12B mismatches in the trailing window.
|
|
130
|
+
# A mismatch is an assistant turn line where:
|
|
131
|
+
# - stop_reason equals "tool_use" (checked at .stop_reason and
|
|
132
|
+
# .message.stop_reason to handle both common transcript shapes)
|
|
133
|
+
# - the matching content array contains no element with
|
|
134
|
+
# type == "tool_use"
|
|
135
|
+
# Each line is parsed independently; lines that fail to parse as
|
|
136
|
+
# JSON are silently skipped.
|
|
137
|
+
MISMATCHES=$(tail -n "$LOOKBACK" "$TRANSCRIPT_PATH" 2>/dev/null | jq -R -r '
|
|
138
|
+
try (fromjson) catch null | select(. != null) | . as $obj |
|
|
139
|
+
(
|
|
140
|
+
(($obj.stop_reason // $obj.message.stop_reason) == "tool_use")
|
|
141
|
+
and
|
|
142
|
+
(
|
|
143
|
+
(($obj.content // $obj.message.content // []) | type) == "array"
|
|
144
|
+
)
|
|
145
|
+
and
|
|
146
|
+
(
|
|
147
|
+
(($obj.content // $obj.message.content // []) | map(select(.type == "tool_use")) | length) == 0
|
|
148
|
+
)
|
|
149
|
+
) | select(. == true) | "1"
|
|
150
|
+
' 2>/dev/null | wc -l | tr -d ' ')
|
|
151
|
+
|
|
152
|
+
MISMATCHES="${MISMATCHES:-0}"
|
|
153
|
+
|
|
154
|
+
if [ "$MISMATCHES" -lt "$THRESHOLD" ]; then
|
|
155
|
+
exit 0
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
LASTFIRED=$(cat "$LASTFIRED_FILE" 2>/dev/null || echo 0)
|
|
159
|
+
SINCE=$((COUNT - LASTFIRED))
|
|
160
|
+
|
|
161
|
+
if [ "$LASTFIRED" -gt 0 ] && [ "$SINCE" -lt "$COOLDOWN" ]; then
|
|
162
|
+
exit 0
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
echo "$COUNT" > "$LASTFIRED_FILE"
|
|
166
|
+
|
|
167
|
+
cat >&2 <<EOF
|
|
168
|
+
|
|
169
|
+
⚠️ Detected ${MISMATCHES} assistant turn(s) with stop_reason="tool_use"
|
|
170
|
+
but no parseable tool_use block in content, in the trailing
|
|
171
|
+
${LOOKBACK} transcript lines.
|
|
172
|
+
|
|
173
|
+
This is the structural signal for sub-pattern 12B
|
|
174
|
+
(extended-thinking serialization defect), the case filed in #62467.
|
|
175
|
+
When Opus 4.7's extended thinking is active, the assistant turn can
|
|
176
|
+
carry stop_reason="tool_use" yet emit only a thinking block — the
|
|
177
|
+
tool_use block never reaches the harness parser. The reporter
|
|
178
|
+
observed ~20 retry prompts accumulated across 6 sessions before
|
|
179
|
+
giving up; output size and special characters were ruled out, and
|
|
180
|
+
the common factor was Opus 4.7 + extended thinking.
|
|
181
|
+
|
|
182
|
+
Sub-pattern 12B is distinct from 12A (in-context few-shot
|
|
183
|
+
poisoning, #62344, recovered by \`/clear\`). 12B is at the model
|
|
184
|
+
serialization layer, so a fresh session does not recover — the
|
|
185
|
+
defect re-fires on the next extended-thinking turn.
|
|
186
|
+
|
|
187
|
+
Known workarounds (operator-side, at the model layer):
|
|
188
|
+
- Switch to a Claude Sonnet variant for the affected task.
|
|
189
|
+
- Disable extended thinking via the \`/model\` command when
|
|
190
|
+
Opus's standard mode is sufficient for the work.
|
|
191
|
+
- Break the work into smaller sub-tasks that complete without
|
|
192
|
+
the model entering extended thinking.
|
|
193
|
+
|
|
194
|
+
If a single mismatch in the window is informational, sub-pattern
|
|
195
|
+
12B's actual signal is the repeated-failure shape #62467 documents
|
|
196
|
+
(the default threshold of 2 keys off that). If you are seeing
|
|
197
|
+
mismatches reliably above the threshold, the model layer is in the
|
|
198
|
+
state #62467 describes and operator-side hooks cannot recover.
|
|
199
|
+
|
|
200
|
+
References: #62467 (the extended-thinking-serialization central
|
|
201
|
+
case), #62123 (the broader "retry also failed" case, 21 reactions),
|
|
202
|
+
Cluster 12 in the cc-safe-setup tracker:
|
|
203
|
+
https://yurukusa.github.io/cc-safe-setup/cluster-tracker.html#cluster-tool-call-parsing
|
|
204
|
+
|
|
205
|
+
Silence: set CC_THINKING_MISMATCH_DISABLE=1.
|
|
206
|
+
Tune sensitivity: CC_THINKING_MISMATCH_THRESHOLD (default 2),
|
|
207
|
+
CC_THINKING_MISMATCH_LOOKBACK (default 150 lines),
|
|
208
|
+
CC_THINKING_MISMATCH_COOLDOWN (default 30 tool calls).
|
|
209
|
+
|
|
210
|
+
EOF
|
|
211
|
+
|
|
212
|
+
exit 0
|