Codex Desktop resumes thread with workspace-write sandbox despite UI showing Full Access
Summary
Codex Desktop can show Full Access in the UI while a resumed thread is actually persisted and executed as workspace-write / on-request. After stopping and restarting the same thread several times, the thread kept asking for access even though the UI still indicated Full Access.
Expected behavior
When the UI/global state says Full Access, resumed turns for that thread should start with something equivalent to:
approval_policy=never
sandbox_policy={"type":"danger-full-access"}
permission_profile={"type":"disabled"}
Actual behavior
The thread initially had many turns with:
approval_policy=never
sandbox_policy=danger-full-access
permission_profile=disabled
After a stop/restart/resume sequence, a later turn_context switched to:
approval_policy=on-request
sandbox_policy=workspace-write
network_access=false
permission_profile=managed
The local per-thread row in ~/.codex/state_5.sqlite also showed the restricted state:
approval_mode=on-request
sandbox_policy={"type":"workspace-write","writable_roots":["~/.codex/memories"],"network_access":false,...}
Meanwhile the global app state still showed Full Access, for example:
electron-persisted-atom-state.agent-mode-by-host-id.local = full-access
So the UI/global Full Access state and the persisted per-thread sandbox/approval state diverged.
Impact
The affected thread repeatedly prompts for access and cannot operate as Full Access, even though the UI says it should. Toggling the UI setting is confusing because the visible state already appears correct.
Suspected cause
The thread resume / active-goal continuation path appears to apply or preserve a per-thread workspace-write / on-request override that is not reflected by the visible Full Access UI state.
Workaround
The local workaround was to stop the running turn, fully quit Codex, back up ~/.codex/state_5.sqlite, and rewrite the affected thread row to:
UPDATE threads
SET approval_mode='never',
sandbox_policy='{"type":"danger-full-access"}',
updated_at=strftime('%s','now'),
updated_at_ms=CAST(strftime('%s','now') AS INTEGER) * 1000
WHERE id='<thread-id>';
Then reopen Codex and verify the next turn_context starts with approval_policy=never and sandbox_policy=danger-full-access.
Requested fix
Please make the UI Full Access state and persisted per-thread sandbox/approval state consistent across stop/restart/resume flows, especially for active-goal continuations. If per-thread permission overrides are intended, the UI should expose and repair them instead of showing Full Access while the thread runs under workspace-write / on-request.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗