You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] claude_cli provider omits --setting-sources=, so the spawned claude runs the user's hooks (4 LLM calls -> 3h09m CPU, 1225 hook sessions) #295
The claude_cli provider builds a capability-stripped claude -p argv, but does not pass --setting-sources=. The spawned CLI therefore loads the user's settings.json and executes their hooks — SessionStart, UserPromptSubmit, PostToolUse, Stop.
If any of those hooks is itself agent-shaped (a session-memory plugin, a logger that calls back into claude, a formatter that spawns tooling), each LLM call the scanner makes turns into a full hook cycle. On my machine one scan with 4 attempted LLM calls consumed 3h09m of CPU time, 6.1 GB RSS and 2.5 GB swap over 52 minutes of wall clock, and registered 1225 sessions in a session-memory plugin that hooks SessionStart.
The amplification is not linear in the number of LLM calls, because the spawned hooks can enqueue work that spawns further processes. In my case it reached a livelock: hundreds of orphaned sessions retrying against a process cap that the retries themselves kept saturated.
The intent is clearly isolation — tools stripped, MCP servers stripped, slash commands disabled. Hooks are the one capability left connected, and they are the one that can re-enter Claude Code.
The docstring notes --strict-mcp-config is used so "zero MCP servers load". --setting-sources= is the equivalent for settings-derived capabilities, hooks included.
Worth a line in the docstring next to the --strict-mcp-config rationale, since the reason is the same and non-obvious.
Verification
Same prompt, same flags, measured by growth of the hook plugin's log and its session table:
log lines
sessions created
current argv
33
1
with --setting-sources=
0
0
For comparison, the session-memory plugin on the same machine spawns its own claude subprocesses with --setting-sources= --strict-mcp-config, which is why those never recursed.
Notes
Two things made this hard to attribute, which may be worth considering independently:
llm_calls_attempted: 4 in the report metadata is accurate but does not reflect the cost incurred, so the report looks cheap while the machine is saturated.
The work happens in spawned children, so it does not appear under the scanner's own resource usage.
I hit this via a systemd timer running --changed scans unattended, where there was no one watching to notice the machine had 8 cores pinned. Users running the CLI interactively would likely notice sooner, but would still be paying for the extra token usage — the spawned hooks run against the user's own Claude subscription.
Activity
fix(provider): isolate Claude settings hooks in spawned CLI (#295)
fix(provider): align Claude fallback contract with settings isolation (…