Memory Phase 2 ignores sandbox_mode=danger-full-access and starts nested macOS sandbox-exec

Open 💬 7 comments Opened Jun 29, 2026 by wi-adam
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What issue are you seeing?

Memory Phase 1 generates raw memories, but Phase 2/global memory consolidation does not produce updated MEMORY.md / memory_summary.md artifacts.

This occurs when Codex itself is already running in a macOS sandboxed context, and the Phase 2 memory worker then attempts to launch/apply another nested macOS sandbox-exec sandbox.

My Codex config explicitly disables Codex's own sandboxing:

sandbox_mode = "danger-full-access"
approval_policy = "never"

[features]
memories = true

Despite that configuration, the memory-consolidation worker appears to start under a nested macOS sandbox-exec / WorkspaceWrite sandbox instead of honoring the effective danger-full-access sandbox mode.

Phase 1 updates:

$HOME/.codex/memories/raw_memories.md

but Phase 2 does not update:

$HOME/.codex/memories/MEMORY.md
$HOME/.codex/memories/memory_summary.md

The consolidation worker rollout shows sandboxing is active even though user config disables it:

cwd=$HOME/.codex/memories
sandbox_policy=WorkspaceWrite
writable_roots=[$HOME/code/random_repo_im_in]
network_access=false

The downstream failure in this macOS environment is:

sandbox-exec: sandbox_apply: Operation not permitted

Given the active sandbox_mode = "danger-full-access" setting, I would not expect the Phase 2 memory worker to invoke macOS sandbox-exec unless that override is intentional and documented.

What steps can reproduce the bug?

  1. On macOS, launch Codex in a sandboxed parent context.

For example, reproduce from the Codex desktop app/runtime if that process is already subject to a macOS sandbox, or otherwise launch the parent Codex process under a macOS sandboxed environment.

  1. Configure Codex with Codex sandboxing disabled:
sandbox_mode = "danger-full-access"
approval_policy = "never"

[features]
memories = true
  1. Start Codex from a project workspace, for example:
$HOME/code/random_repo_im_in
  1. Generate enough memory-relevant activity for Phase 1 and Phase 2 memory processing to run.
  1. Observe that Phase 1 writes:
$HOME/.codex/memories/raw_memories.md
  1. Observe that Phase 2/global consolidation does not update:
$HOME/.codex/memories/MEMORY.md
$HOME/.codex/memories/memory_summary.md
  1. Inspect the memory-consolidation worker rollout/session metadata.

Observed worker state:

cwd=$HOME/.codex/memories
sandbox_policy=WorkspaceWrite
writable_roots=[$HOME/code/random_repo_im_in]
network_access=false
  1. Observe the macOS sandbox failure:
sandbox-exec: sandbox_apply: Operation not permitted

The key reproduction point is that Codex is already running in a macOS sandboxed parent context, and the memory worker still launches with a nested WorkspaceWrite / sandbox-exec sandbox even though the active Codex config requests danger-full-access.

What is the expected behavior?

Codex should honor the configured sandbox mode for internal memory-consolidation workers.

With:

sandbox_mode = "danger-full-access"

the Phase 2/global memory-consolidation worker should not start a nested macOS sandbox-exec / WorkspaceWrite sandbox inside an already sandboxed Codex parent process unless there is a clearly documented, intentional exception.

At minimum, the worker should be able to read and write:

$HOME/.codex/memories

and produce updated:

$HOME/.codex/memories/MEMORY.md
$HOME/.codex/memories/memory_summary.md

If the consolidation worker cannot run because sandbox application fails, Phase 2 should fail/retry the job instead of treating the worker's final response as successful consolidation.

Additional information

The suspected issue is in the Phase 2 memory-consolidation worker setup:

codex-rs/memories/write/src/phase2.rs

The visible failure is a nested macOS sandbox application failure: Codex is already running in a sandboxed parent context, and the Phase 2 worker then attempts to apply another sandbox-exec sandbox.

sandbox-exec: sandbox_apply: Operation not permitted

The important part is that the user-level Codex config has sandboxing disabled:

sandbox_mode = "danger-full-access"
approval_policy = "never"

but the memory-consolidation worker still appears to force a WorkspaceWrite sandbox:

agent_config.cwd = root.clone();

let writable_roots = vec![root];
let consolidation_sandbox_policy = SandboxPolicy::WorkspaceWrite { ... };

agent_config
    .permissions
    .set_legacy_sandbox_policy(consolidation_sandbox_policy, agent_config.cwd.as_path())
    .ok()?;

That means Phase 2 is not honoring the effective sandbox configuration for the internal worker. On macOS this manifests as a nested sandbox-exec attempt that fails with sandbox_apply: Operation not permitted.

There may also be a related runtime state issue after the workspace-roots changes:

c25d905f61ca96ed575cd24e82fc4295465c66d0
permissions: support workspace roots in profiles (#22610)

8a5306ff88b868685ca76cfd5cdda42dca637d10
app-server: use permission ids and runtime workspace roots (#22611)

After #22611, new sessions are wired from:

workspace_roots: config.workspace_roots.clone(),

So if Phase 2 does intentionally create a WorkspaceWrite worker, it also needs to keep Config.workspace_roots in sync with the worker's actual memory-root cwd. In the observed rollout, the worker has:

cwd=$HOME/.codex/memories
writable_roots=[$HOME/code/random_repo_im_in]

which suggests stale parent-project workspace roots are leaking into the worker session.

However, that stale-root behavior is secondary to the main bug report: with sandbox_mode = "danger-full-access", the memory worker should not be starting a nested macOS sandbox in the first place unless that behavior is explicitly intended and made compatible with this environment.

View original on GitHub ↗

7 Comments

github-actions[bot] contributor · 21 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #29503
  • #29915

Powered by Codex Action

wi-adam · 21 days ago

This is not a duplicate of those issues.

wi-adam · 21 days ago

I reproduced this locally and have a proposed patch pushed here:

Root cause I found:

  • phase2::agent::get_config always replaced the memory-consolidation worker sandbox with WorkspaceWrite, even when the effective parent config was danger-full-access.
  • It also updated the nested Permissions object directly, which left Config.workspace_roots carrying the parent project roots while the worker cwd was $CODEX_HOME/memories.

The patch changes Phase 2 worker config so:

  • DangerFullAccess stays DangerFullAccess, avoiding a nested Codex-managed sandbox.
  • ExternalSandbox stays ExternalSandbox, preserving the external sandbox/network state.
  • ReadOnly/WorkspaceWrite still get the locked-down no-network memory-root WorkspaceWrite policy.
  • The update goes through Config::set_legacy_sandbox_policy, keeping Config.workspace_roots synchronized with the worker memory-root cwd.

Validation:

  • Added regression tests for DangerFullAccess, ExternalSandbox, and workspace-root rebinding.
  • Reproduced the stale-root failure before the fix with the new regression test.
  • Ran just fmt.
  • Ran just test -p codex-memories-write.
  • Ran git diff --check.

I tried opening a PR, but GitHub currently blocks non-collaborators from creating PRs against this repository. If a maintainer wants to invite a PR or cherry-pick the commit, the branch above should be ready.

jif-oai contributor · 10 days ago

Hi,
Checking! Thanks :)

jif-oai contributor · 10 days ago

Ok, after digging a bit more, the issue is slightly different from what I initially thought but the sympoms are real

I'll land a fix for this

wi-adam · 10 days ago

Thank you!!

wi-adam · 10 days ago

(I will be curious to see exactly what’s going wrong when the diff lands :) - gotta see where the agents went astray)