mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-24 06:25:08 +00:00
fix(tui): pass --safe-mode so the host CLAUDE.md cannot leak into proxied turns (#187)
OCP is a proxy: the operator's private ~/.claude/CLAUDE.md and auto-memory must never enter a proxied turn's context. The pane already sets CLAUDE_CODE_DISABLE_CLAUDE_MDS + CLAUDE_CODE_DISABLE_AUTO_MEMORY, but on newer claude (2.1.216) those env vars no longer suppress the injection, so a proxied turn can obey the operator's private CLAUDE.md instead of the caller's prompt — a leak of private context into API responses. Add --safe-mode to the interactive spawn argv (gated off on the streaming and OCP_TUI_FULL_TOOLS paths). Docs + tests updated. Co-authored-by: sumlin <3495838+sumlin@users.noreply.github.com>
This commit is contained in:
+32
-3
@@ -389,9 +389,15 @@ export function buildTuiCmd(claudeBin, model, sessionId, ehome, entrypointMode,
|
||||
// CLAUDE.md and auto-memory must NEVER leak into the agent OCP runs on the user's behalf.
|
||||
// Without these, claude loads the host's project/user CLAUDE.md + memory into every proxied
|
||||
// turn — verified live 2026-06-02: a cwd CLAUDE.md ("end every reply with QUACKMARKER_42") was
|
||||
// obeyed by the proxied turn until these flags were set, after which it was not. Unconditional
|
||||
// by design (not gated): proxy purity is not an opt-in. Harmless on hosts with no CLAUDE.md
|
||||
// (the common case — they suppress nothing). Mirrors the -p path's CLAUDE_NO_CONTEXT vars.
|
||||
// obeyed by the proxied turn until these flags were set, after which it was not. Mirrors the
|
||||
// -p path's CLAUDE_NO_CONTEXT vars. Harmless on hosts with no CLAUDE.md (they suppress nothing).
|
||||
//
|
||||
// These env vars stopped being sufficient on newer claude: they are present in the pane's
|
||||
// environment yet the host CLAUDE.md is still injected into the turn's context, so a proxied
|
||||
// turn again obeys the operator's private CLAUDE.md instead of the caller's prompt — a leak of
|
||||
// the operator's private context into API responses. The robust suppression is the --safe-mode
|
||||
// flag added to the argv below; these env vars are kept as belt-and-braces for the two argv
|
||||
// paths that cannot take --safe-mode (see the safeModeArgs note near the return).
|
||||
const sets = [
|
||||
`HOME=${shq(ehome)}`,
|
||||
"DISABLE_AUTOUPDATER=1",
|
||||
@@ -482,9 +488,32 @@ export function buildTuiCmd(claudeBin, model, sessionId, ehome, entrypointMode,
|
||||
// so the OFF argv is byte-for-byte the pre-streaming argv.
|
||||
const settingsArgs = stream && stream.settings ? ["--settings", shq(stream.settings)] : [];
|
||||
|
||||
// --safe-mode: disable ALL customizations (host CLAUDE.md, skills, plugins, hooks, MCP
|
||||
// servers, custom commands/agents, output styles, ...) while leaving auth, model selection,
|
||||
// built-in tools, and permissions untouched (claude 2.1.216 --help). This is the robust
|
||||
// replacement for the CLAUDE_CODE_DISABLE_CLAUDE_MDS / _AUTO_MEMORY env vars above, which no
|
||||
// longer suppress the host CLAUDE.md on newer claude — so the operator's private CLAUDE.md
|
||||
// could otherwise leak into a proxied API response. Unlike --bare, --safe-mode does NOT drop
|
||||
// the interactive session off the subscription pool (it keeps auth + model selection), so the
|
||||
// billing classifier stays cc_entrypoint=cli.
|
||||
//
|
||||
// NOT applied when the pane deliberately relies on a customization --safe-mode would strip,
|
||||
// because those would break SILENTLY:
|
||||
// - streaming (settingsArgs present): the MessageDisplay hook is a HOOK, which --safe-mode
|
||||
// disables — every streamed turn would then fire zero deltas (tui.streamZeroDeltaTurns)
|
||||
// and fall back to buffered, defeating OCP_TUI_STREAM.
|
||||
// - OCP_TUI_FULL_TOOLS=1: grants an MCP / skills / agent surface (--mcp-config, ...) that
|
||||
// --safe-mode disables wholesale.
|
||||
// Those two opt-in paths keep the env-var suppression above as their best-effort fallback.
|
||||
const safeModeArgs =
|
||||
settingsArgs.length === 0 && process.env.OCP_TUI_FULL_TOOLS !== "1"
|
||||
? ["--safe-mode"]
|
||||
: [];
|
||||
|
||||
return [
|
||||
envPrefix,
|
||||
shq(claudeBin),
|
||||
...safeModeArgs,
|
||||
"--model", shq(model),
|
||||
"--session-id", sessionId,
|
||||
...toolArgs,
|
||||
|
||||
Reference in New Issue
Block a user