{"record":{"id":"20215d574b6932da","repo":"JuliusBrussee/caveman","slug":"cave-sandbox-conformance-failed","errorCode":null,"errorMessage":"cave_sandbox_conformance_failed","messagePattern":"cave_sandbox_conformance_failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/agent/src/cli.ts","lineNumber":748,"sourceCode":"    preferredTransforms,\n    transformRegistry.capabilities,\n    evalDynamicKinds(approved),\n    {\n      ...(loaded.config.allowedModels === undefined ? {} : { allowedModels: loaded.config.allowedModels }),\n      ...(loaded.config.deniedModels === undefined ? {} : { deniedModels: loaded.config.deniedModels }),\n      ...(loaded.config.forbiddenSafetyClasses === undefined\n        ? {}\n        : { forbiddenSafetyClasses: loaded.config.forbiddenSafetyClasses }),\n    },\n  );\n  const entitled = await engineEntitled();\n  const plannedRuns = candidates.filter((candidate) => !candidate.static_rejection).length * approved.length * 5;\n  const estimatedCeiling = candidates\n    .filter((candidate) => !candidate.static_rejection)\n    .reduce((sum, candidate) => sum + candidate.estimated_cost_usd_per_run * approved.length * 5, 0);\n  process.stdout.write(`search ceiling: $${estimatedCeiling.toFixed(4)} public-catalog estimate · ${plannedRuns} runs\\n`);\n  const sandboxConformance = await verifySandboxConformance();\n  if (!sandboxConformance) throw new Error(\"cave_sandbox_conformance_failed\");\n  const privacyConformance = contextIRIsContentBlind(lowered.ir);\n  if (!privacyConformance) throw new Error(\"cave_privacy_conformance_failed\");\n  const conversations = new Map<string, ConversationState>();\n  const result = await compileAndWrite({\n    agent: loaded.agent,\n    contextIR: lowered.ir,\n    evals: loaded.evals,\n    candidates,\n    baselinePlan: baseline,\n    seeds: [1, 2, 3, 4, 5],\n    config: loaded.config,\n    entitled,\n    sourceSha256: loaded.sourceSha256,\n    catalogSha256: CATALOG_SHA256,\n    transformRegistrySha256: transformRegistry.sha256,\n    runtimeVersion: FRAMEWORK_VERSION,\n    adapterVersion: PI_ADAPTER_VERSION,\n    upstreamVersion: PI_UPSTREAM_VERSION,","sourceCodeStart":730,"sourceCodeEnd":766,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/cli.ts#L730-L766","documentation":"Immediately before the expensive compile step, build re-runs verifySandboxConformance() and hard-fails if the containment probe returns false. This is the same probe doctor reports on (cli.ts:152), but at build time it is a gate, not a diagnostic: a build cannot be produced on a host where the tool sandbox does not contain its probe, because the produced build would be unshippable for sandbox-required tools.","triggerScenarios":"Running `caveman-agent build` on a host whose sandbox fails containment: disabled unprivileged user namespaces, restricted container runtime, sandbox compiled/running in fixture mode, or an OS without the required sandboxing facility. Occurs after config/eval/source loading and the cost-ceiling print, right before compileAndWrite.","commonSituations":"CI containers with hardened seccomp profiles; Debian-based images with kernel.unprivileged_userns_clone=0; macOS/Windows native hosts without the sandbox backend; gVisor/microVM runtimes missing needed syscalls.","solutions":["Fix the environment first: enable unprivileged user namespaces / required sandbox syscalls, or move to a supported runtime (WSL2 on Windows).","Verify with `caveman-agent doctor` — its sandbox check must pass before retrying build.","Never work around by forcing fixture mode for production builds; fixture sandbox is only for local development and doctor's fix text calls this out."],"exampleFix":"# before: hardened CI container\n# (seccomp blocks clone3/userns → probe false → build throws)\ndocker run --security-opt seccomp=default my-ci caveman-agent build\n\n# after: run with the runtime's sandbox-capable profile\ndocker run --security-opt seccomp=unconfined my-ci caveman-agent doctor && \\\n  docker run --security-opt seccomp=unconfined my-ci caveman-agent build","handlingStrategy":"validation","validationCode":"import { verifySandboxConformance } from \"@caveman/agent\";\nasync function assertBuildableEnvironment(): Promise<void> {\n  if (!(await verifySandboxConformance())) {\n    throw new Error(\"sandbox containment failed — fix host environment (userns/seccomp/WSL2) before build\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await build([\"caveman.config.ts\"]);\n} catch (error) {\n  if (error instanceof Error && error.message === \"cave_sandbox_conformance_failed\") {\n    // Environment blocker, raised before compileAndWrite — no partial build is written.\n    // Fix the host (enable unprivileged userns / WSL2 / supported runtime) and re-run.\n    process.exitCode = 2;\n  }\n  throw error;\n}","preventionTips":["Gate CI build jobs on `caveman-agent doctor` (sandbox check must pass) before invoking build.","Enable unprivileged user namespaces and keep seccomp profiles permissive enough for the sandbox on Linux runners.","Never enable sandbox fixture mode to get a build through — the artifact would be unshippable for sandbox-required tools."],"tags":["build","sandbox","environment","security","fail-closed"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}