security-guidance: SessionStart builds a 304 MB SDK venv with no credentials check, and ignores SECURITY_GUIDANCE_DISABLE
Summary
hooks/ensure_agent_sdk.py runs on every SessionStart and builds a ~304 MB venv (~/.claude/security/agent-sdk-venv, 3,831 files) to install claude_agent_sdk. That SDK exists solely to power the LLM commit/push/Stop reviews.
main() decides whether to build using six gates — Python version, SDK on syspath, a build sentinel, an existing venv, a --target fallback, and a signal-kill cooldown. It checks none of the three things that determine whether the SDK will ever be used:
- API credentials.
grep -iE 'ANTHROPIC_API_KEY|AUTH_TOKEN|credential' hooks/ensure_agent_sdk.pyreturns nothing.llm.py:123gates every LLM path onHAS_API_CREDENTIALS, but the bootstrap never consults it. ENABLE_STOP_REVIEW/ENABLE_COMMIT_REVIEW. Both are read only insecurity_reminder_hook.py. A user who explicitly turned the reviews off still gets the venv.SECURITY_GUIDANCE_DISABLE— the documented master kill switch.security_reminder_hook.py:164-170describes it as disabling "the plugin entirely," but it is read only there.ensure_agent_sdk.py's imports areimportlib.util, json, os, subprocess, sys, time, pathliband_base.state_dir— the kill switch never reaches it.
So on a machine with no credentials, the plugin's own kill switch does not stop SessionStart from building a 304 MB venv for a feature that cannot run.
Evidence
From this machine's ~/.claude/security/log.txt + log.txt.1, 2026-07-29 → 2026-08-14 (16 days):
| Observation | Value |
|---|---|
| Stop reviews that ran | 0 of 315 — all logged LLM review disabled or no API credentials |
| Commit reviews that ran | 0 of 227 — 224 logged the same, 3 no review line |
| LLM API calls made, ever | 0 (grep for request/token/agent-sdk-query markers: no hits) |
agent-sdk-venv size |
318,800,844 B (304 MiB), 3,831 files |
| Installed for | claude_agent_sdk 0.2.115, built 2026-07-10 |
ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN are both unset here, and have been for the life of that venv.
Second effect: a 300-second re-spawn loop
Because the SDK is installed in the venv and not importable from system Python, _sdk_on_syspath() is false on every run. security_reminder_hook.py:2112-2148 therefore spawns a detached ensure_agent_sdk.py every 300 s for the whole session. Observed live: ~/.claude/security/.sdk_bootstrap_spawned advanced 10:50 → 10:55 during a single session.
Each of those re-spawns then pays the sg-python.sh interpreter probe and lands on NOOP_VENV, whose check is itself a subprocess — measured at ~1.3–1.4 s for <venv>/Scripts/python.exe -c "import claude_agent_sdk" (the call at ensure_agent_sdk.py:496).
Deleting the venv does not help
main() short-circuits to NOOP_VENV only when venv_py.exists() and the import succeeds. With the venv removed, no system SDK, no --target install and no cooldown file, the next SessionStart falls straight through to the build branch and re-creates all 304 MB. There is no supported way to opt out — SECURITY_GUIDANCE_DISABLE=1 does not reach this code path (see above), so the only workaround is disabling the whole plugin.
Suggested fix
Add a credentials/enablement gate at the top of main(), before the venv probe:
if sys.version_info < (3, 10):
return HOOK_PY_INCOMPATIBLE, "hook_py", ...
# NEW: the SDK only powers LLM review. If review can't or won't run,
# building a 304 MB venv is pure cost.
if not _llm_review_possible(): # credentials AND not disabled
return SKIP_NO_CREDENTIALS, "", ""where _llm_review_possible() mirrors llm.py's HAS_API_CREDENTIALS and honours SECURITY_GUIDANCE_DISABLE / ENABLE_SECURITY_REMINDER / ENABLE_STOP_REVIEW / ENABLE_COMMIT_REVIEW. A new stable outcome code keeps the telemetry split clean.
Building lazily — on the first review that actually has credentials — would work equally well and would also cover the case where a user adds a key mid-session.
At minimum, SECURITY_GUIDANCE_DISABLE=1 should be honoured here, since the code comment already promises it "disables the plugin entirely."
Environment
security-guidance2.0.6- Claude Code 2.1.232, native install
- Windows 11 Pro 26200, Git Bash
- Python 3.12.3 (venv built by
c:\python312\python.exe -m venv --clear)
Split out from #5330 as requested there.
Source: anthropics/claude-plugins-official