From b1e24b7cb04a8caa48c02fe30e2161c4066afd8d Mon Sep 17 00:00:00 2001 From: dtzp555 Date: Thu, 28 May 2026 17:52:07 +1000 Subject: [PATCH] fix(sandbox): add OLP_SANDBOX_DISABLED=1 env-var emergency disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-B PI231 live verification surfaced a hard problem: HTTP-path anthropic spawns produce no claude stdout when sandbox-wrapped, while manual exec of the identical wrap script in the same node process DOES produce output. Root cause not yet isolated — likely interaction between SandboxManager's in-process proxy sockets (HTTP/SOCKS Unix sockets in /tmp) and OLP's HTTP request-handler event loop. Until the root cause is debugged and Suite 44-equivalent E2E tests cover the full HTTP request → sandbox spawn → response pipeline, this commit adds an env-var emergency disable: OLP_SANDBOX_DISABLED=1 in the server environment causes bootstrapSandbox() to short-circuit immediately, returning { active: false, reason: '...' }. Provider plugins continue to spawn unsandboxed (matching pre-PR-B behavior). Default remains sandbox-enabled. Only operators with broken HTTP-path sandbox should set the env var (which is everyone on PI231 today, until follow-up debugging completes). Operational follow-up (PI231 right now): setsid env ... OLP_SANDBOX_DISABLED=1 node ~/olp/server.mjs ... → /health.sandbox.active=false → HTTP requests resume working Future PR-B follow-up issues: 1. Reproduce HTTP-path sandbox spawn failure in unit test 2. Investigate in-process proxy lifecycle vs HTTP handler event loop 3. Possibly: switch to per-spawn SandboxManager.initialize() lifecycle 4. Re-enable sandbox by default after fix + Suite 44 HTTP-path coverage Sandbox doctor (PR-A) unchanged. ADR 0014 unchanged (the disable is a runtime gate, not a contract change). Suite 44 negative tests still pass when enabled. Co-Authored-By: Claude Opus 4.7 --- lib/sandbox/manager.mjs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/sandbox/manager.mjs b/lib/sandbox/manager.mjs index b1c8492..29faaec 100644 --- a/lib/sandbox/manager.mjs +++ b/lib/sandbox/manager.mjs @@ -125,6 +125,32 @@ export async function bootstrapSandbox(opts = {}) { : { active: false, reason: _initConfig?.failReason ?? 'sandbox not available' }; } + // OLP_SANDBOX_DISABLED env-var gate (2026-05-28 PR-B emergency disable): + // Live PI231 evidence showed that even with the exit-null guard, HTTP-path + // anthropic spawns produced no claude stdout when wrapped (manual exec of + // the SAME wrap script in the same process did produce output — root cause + // not yet isolated; likely interaction between SandboxManager in-process + // proxy sockets and OLP's request-handler event loop). Until the root cause + // is debugged + Suite 44-equivalent E2E tests cover the HTTP path, the + // sandbox bootstrap is opt-out via OLP_SANDBOX_DISABLED=1 in the server env. + // + // Default is sandbox-enabled (no env var = try-and-bootstrap). Sandbox is + // skipped only when the operator explicitly disables. + // + // Future PR-B follow-up: investigate the in-process proxy lifecycle + // interaction with OLP's HTTP server event loop; capture diagnostic + // transcript; ship Suite 44-equivalent that exercises the full HTTP + // request → sandbox spawn → response pipeline. + if (process.env.OLP_SANDBOX_DISABLED === '1') { + _initialized = true; + _active = false; + _initConfig = { failReason: 'OLP_SANDBOX_DISABLED=1 — sandbox bootstrap skipped by operator' }; + return { + active: false, + reason: 'OLP_SANDBOX_DISABLED=1 — sandbox bootstrap skipped by operator', + }; + } + // Reset state for re-bootstrap _initialized = false; _active = false;