Skip to content

Sandbox mode changed between consecutive Codex invocations without visible provenance #960

Description

@vaope

Summary

In the same Cat Cafe / Codex conversation flow, the agent first received an effective permissions context showing unrestricted filesystem access, then a later invocation in the same thread observed a narrower sandbox. The agent side could only see the latest effective permissions and had no visible provenance explaining why the sandbox changed.

Observed transition:

  • Earlier invocation: sandbox_mode = danger-full-access, filesystem unrestricted, network enabled, approval policy never
  • Later invocation: sandbox_mode = workspace-write, writable roots limited to C:\code\clowder-ai\packages\api and C:\tmp, approval policy never

Expected

When Codex sandbox mode changes between consecutive invocations/resume turns, the runtime should either:

  1. preserve the configured sandbox mode across resume, or
  2. expose clear provenance in the injected environment context explaining why the effective sandbox changed.

Actual

The agent reported danger-full-access in one invocation and workspace-write in a later invocation. From the agent side, the transition looked silent: there was no visible source showing whether this came from Codex resume behavior, Cat Cafe runtime defaults, a relaunch, frontend settings fallback, or permissions injection.

Impact

  • Agent capability reports can contradict each other across adjacent turns.
  • Tool installation and GitHub/CLI workflow decisions can be made from stale assumptions.
  • A2A collaboration can route incorrectly when one cat sees unrestricted access and another sees workspace-only access.
  • User trust is affected because the agent cannot explain whether the change was intentional policy, runtime relaunch, or a bug.

Current root-cause hypothesis

The likely path is that fresh Codex exec uses --sandbox, but resume invocations did not explicitly replay the sandbox setting. If the Codex CLI or adapter falls back to a default during resume, the effective mode can drift from the originally observed setting.

This is still a hypothesis because provenance was not visible in the injected context.

Local WIP mitigation observed

A local working-tree patch already appears to address the likely failure mode:

  • packages/api/src/domains/cats/services/agents/providers/CodexAgentService.ts
    • adds --config sandbox_mode="..." for Codex resume args
    • keeps --sandbox / --add-dir off resume args while preserving sandbox via config
  • packages/api/test/codex-agent-service.test.js
    • adds assertions that resume args include sandbox_mode="danger-full-access"
    • adds env-configured sandbox coverage, e.g. CAT_CODEX_SANDBOX_MODE=read-only
  • packages/web/src/components/hub-cat-editor.model.ts
  • packages/web/src/components/hub-cat-editor-advanced.tsx
    • change missing Codex settings fallback from workspace-write to danger-full-access
  • packages/api/src/utils/cli-resolve.ts
    • prefers the official Windows Codex desktop runtime / CODEX_CLI_PATH over npm shims, reducing Windows sandbox helper/elevation instability

Local verification run on 2026-06-17:

  • pnpm run build passed
  • targeted tests passed:
    • test/codex-agent-service.test.js
    • test/cli-resolve.test.js
    • test/windows-portable-redis-tools.test.js
    • result: 85 tests, 81 pass, 4 skip, 0 fail

Open questions

  • Is Codex resume expected to preserve sandbox_mode from fresh exec automatically?
  • Should Cat Cafe always emit sandbox provenance in the injected environment context?
  • Should the frontend default really be danger-full-access, or should the runtime require explicit user configuration instead of applying a silent fallback?

Suggested follow-up

  • Land the resume sandbox_mode preservation fix with tests.
  • Add diagnostics/provenance to the agent environment context when sandbox mode is selected or changed.
  • Consider a regression test that simulates fresh exec + resume with different defaults and asserts no silent sandbox drift.

Metadata

Metadata

Assignees

No one assigned

    Labels

    acceptedMaintainer accepted: ready for implementation/mergebugSomething isn't workingtriagedMaintainer reviewed, replied, and made an initial triage decision

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions