mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
OCP is a PROXY, not a Claude Code session. The proxied client (OpenClaw / an IDE) owns its own context and memory — the HOST's CLAUDE.md and auto-memory must never leak into the agent OCP runs on the user's behalf. buildTuiCmd now adds CLAUDE_CODE_DISABLE_CLAUDE_MDS=1 + CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 to the pane-command env-prefix, unconditionally (proxy purity is not an opt-in). Diagnosis (per Iron Rule 3, diagnose-before-fix) of the earlier "suppression works in recon but not through OCP" gap: it was NEVER an env-delivery bug. The hosts simply have no CLAUDE.md to suppress — PI231 has no ~/.claude/CLAUDE.md, no ~/CLAUDE.md, no ~/.claude/memory, no cwd/walk-up CLAUDE.md. The earlier "recon worked" run was on a machine that DID have a global CLAUDE.md. Different machines, different CLAUDE.md presence — not a code gap. The ~35K one-line-prompt context is therefore the inherent floor (interactive system prompt + built-in tool schemas; MCP is already hard-disabled via --strict-mcp-config), not CLAUDE.md. Verified live 2026-06-02 with a behavioral marker (Iron Rule 2, evidence-first): - Planted /home/tlab/.ocp-tui/work/CLAUDE.md = "end every reply with QUACKMARKER_42". - BEFORE fix, through OCP: "Reply with: hello" -> "hello\n\nQUACKMARKER_42" (host CLAUDE.md obeyed = leaked). - AFTER fix, same marker file present, through OCP: -> "hello" (marker blocked). This proves both that the host CLAUDE.md was being injected AND that the env-prefix delivery of the disable flag reaches claude and stops it. Tests: buildTuiCmd is now exported; +2 regression guards (suppression present; version-pin/entrypoint/MCP-wall retained, auto-mode leaves entrypoint unset). 194 pass. Scope (Iron Rule 11): TUI path only. The -p path has an equivalent but GATED mechanism (CLAUDE_NO_CONTEXT). Making -p unconditionally proxy-pure is a separate decision, noted as a follow-up, not bundled here. ALIGNMENT.md: this changes lib/tui/session.mjs, not server.mjs, so the server.mjs hard requirements do not trigger. TUI is the ADR-0007 proxy-side execution bridge; the two flags are documented Claude Code env vars (the same two the -p path already uses), not invented endpoints — cli.js citation N/A under Rule 2. Closes #4 (TUI portion). Co-authored-by: dtzp555 <dtzp555@gmail.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+12
-1
@@ -185,17 +185,28 @@ export function resolveTuiEntrypointEnv(env, mode = "cli") {
|
|||||||
// A-PATH ONLY: built-in tools are left enabled (acceptable single-user). Deployment B
|
// A-PATH ONLY: built-in tools are left enabled (acceptable single-user). Deployment B
|
||||||
// (guest keys) MUST additionally pass --tools "" per spec §5.2(2) as the credential
|
// (guest keys) MUST additionally pass --tools "" per spec §5.2(2) as the credential
|
||||||
// wall before this argv is reachable for owner_tier=guest — guard that in PR-3 wiring.
|
// wall before this argv is reachable for owner_tier=guest — guard that in PR-3 wiring.
|
||||||
function buildTuiCmd(claudeBin, model, sessionId, ehome, entrypointMode) {
|
export function buildTuiCmd(claudeBin, model, sessionId, ehome, entrypointMode) {
|
||||||
// Deliver claude's env via an `env` prefix on the PANE COMMAND — tmux does NOT forward the
|
// Deliver claude's env via an `env` prefix on the PANE COMMAND — tmux does NOT forward the
|
||||||
// spawning process's environment to the pane, and `new-session -e` needs tmux ≥3.2 (the cloud
|
// spawning process's environment to the pane, and `new-session -e` needs tmux ≥3.2 (the cloud
|
||||||
// host runs 2.7), so this is the only portable, reliable mechanism (verified live 2026-06-01:
|
// host runs 2.7), so this is the only portable, reliable mechanism (verified live 2026-06-01:
|
||||||
// passing {env} to spawnSync left the pane with only HOME). DISABLE_AUTOUPDATER pins the version
|
// passing {env} to spawnSync left the pane with only HOME). DISABLE_AUTOUPDATER pins the version
|
||||||
// (no "What's new" splash that delayed input-readiness); CLAUDE_CODE_ENTRYPOINT labels the
|
// (no "What's new" splash that delayed input-readiness); CLAUDE_CODE_ENTRYPOINT labels the
|
||||||
// billing pool (set below per entrypointMode).
|
// billing pool (set below per entrypointMode).
|
||||||
|
//
|
||||||
|
// CLAUDE_CODE_DISABLE_CLAUDE_MDS + DISABLE_AUTO_MEMORY: OCP is a PROXY, not a Claude Code
|
||||||
|
// session. The proxied client (OpenClaw / an IDE) owns its own context and memory; the HOST's
|
||||||
|
// 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.
|
||||||
const sets = [
|
const sets = [
|
||||||
`HOME=${shq(ehome)}`,
|
`HOME=${shq(ehome)}`,
|
||||||
"DISABLE_AUTOUPDATER=1",
|
"DISABLE_AUTOUPDATER=1",
|
||||||
"CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1",
|
"CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1",
|
||||||
|
"CLAUDE_CODE_DISABLE_CLAUDE_MDS=1",
|
||||||
|
"CLAUDE_CODE_DISABLE_AUTO_MEMORY=1",
|
||||||
];
|
];
|
||||||
const unset = ["CLAUDECODE", "ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN"];
|
const unset = ["CLAUDECODE", "ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN"];
|
||||||
if (entrypointMode === "cli") sets.push("CLAUDE_CODE_ENTRYPOINT=cli");
|
if (entrypointMode === "cli") sets.push("CLAUDE_CODE_ENTRYPOINT=cli");
|
||||||
|
|||||||
+21
-1
@@ -1478,7 +1478,7 @@ await asyncTest("readTuiTranscript throws when no text and cap elapses", async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ── TUI session reaper ───────────────────────────────────────────────────
|
// ── TUI session reaper ───────────────────────────────────────────────────
|
||||||
import { reapStaleTuiSessions, SESSION_PREFIX } from "./lib/tui/session.mjs";
|
import { reapStaleTuiSessions, SESSION_PREFIX, buildTuiCmd } from "./lib/tui/session.mjs";
|
||||||
|
|
||||||
console.log("\nTUI session reaper:");
|
console.log("\nTUI session reaper:");
|
||||||
|
|
||||||
@@ -1486,6 +1486,26 @@ test("SESSION_PREFIX is ocp-tui-", () => {
|
|||||||
assert.equal(SESSION_PREFIX, "ocp-tui-");
|
assert.equal(SESSION_PREFIX, "ocp-tui-");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("\nTUI command construction (proxy-purity / #4):");
|
||||||
|
|
||||||
|
test("buildTuiCmd suppresses host CLAUDE.md + auto-memory (proxy purity, #4)", () => {
|
||||||
|
const cmd = buildTuiCmd("/usr/bin/claude", "claude-haiku", "sid-1", "/home/u", "cli");
|
||||||
|
// OCP is a proxy: the host's CLAUDE.md / auto-memory must never leak into the proxied turn.
|
||||||
|
assert.ok(/(^| )CLAUDE_CODE_DISABLE_CLAUDE_MDS=1( |$)/.test(cmd), "must disable CLAUDE.md injection");
|
||||||
|
assert.ok(/(^| )CLAUDE_CODE_DISABLE_AUTO_MEMORY=1( |$)/.test(cmd), "must disable auto-memory injection");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("buildTuiCmd keeps version pin + entrypoint label + MCP wall", () => {
|
||||||
|
const cli = buildTuiCmd("/usr/bin/claude", "m", "sid-2", "/home/u", "cli");
|
||||||
|
assert.ok(cli.includes("DISABLE_AUTOUPDATER=1"), "version pin retained");
|
||||||
|
assert.ok(cli.includes("CLAUDE_CODE_ENTRYPOINT=cli"), "cli mode labels the subscription pool");
|
||||||
|
assert.ok(cli.includes("--strict-mcp-config") && cli.includes('mcp__*'), "MCP wall retained");
|
||||||
|
// 'auto' mode must NOT pin the entrypoint (claude self-classifies via TTY).
|
||||||
|
const auto = buildTuiCmd("/usr/bin/claude", "m", "sid-3", "/home/u", "auto");
|
||||||
|
assert.ok(!/CLAUDE_CODE_ENTRYPOINT=/.test(auto), "auto mode leaves entrypoint unset");
|
||||||
|
assert.ok(/-u CLAUDE_CODE_ENTRYPOINT/.test(auto), "auto mode unsets any inherited entrypoint");
|
||||||
|
});
|
||||||
|
|
||||||
test("reaper kills ONLY ocp-tui- sessions, never olp-tui-", () => {
|
test("reaper kills ONLY ocp-tui- sessions, never olp-tui-", () => {
|
||||||
const killed = [];
|
const killed = [];
|
||||||
const fakeTmux = (args) => {
|
const fakeTmux = (args) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user