rdmsm4x-changelog-20260824-1217-codex-agent-mode-and-stale-thread-approval-policy
Aligned Codex's legacy global agent-mode key to
full-access and normalised 4 stale delegation-thread
approval records; deliberately left 38 restricted-sandbox threads
untouched because flipping them would convert "prompt" into
"auto-reject".
- Host: rdmsm4x (lead) · Session start: 2026-08-24 12:07:09 EDT · Closed: 2026-08-24 12:17:05 EDT
- Scope: rdmsm4x only. No other fleet host touched.
- Trigger: Rich asked why Codex Computer Use always
prompts for permission, then asked to align Codex's per-thread
approvalPolicywith his global bypass-permissions posture.
Findings (no change required)
- macOS TCC was never the cause.
com.openai.codexandcom.openai.sky.CUAServicehold Accessibility + ScreenCapture grants dated 2026-07-13/16/19, unmodified since. - Computer Use prompts arrive as an MCP elicitation
(
codex_approval_kind: "mcp_tool_call",connector_id: "computer-use") from thenode_repl/computer-useserver.approval_policydoes not gate that channel. The durable grant is the "Always allow" item in the▾dropdown beside "Allow this conversation" (persist: "always"), or @-mentioning the app in the composer, which pre-registers it and auto-accepts for that conversation. ~/.codex/config.tomlalready carriesapproval_policy = "never"andsandbox_mode = "danger-full-access", and it IS being inherited: all 30 most recent threads rannever+sandbox: disabled.permission-selection-by-host-id:localandagent-mode-by-host-id.localwere alreadyfull-access. These are the authoritative live settings.- Correction to an earlier claim in-session: an initial read of an unsorted dict dump suggested "many threads are on-request". Sorted counts showed the opposite (419 never / 42 on-request, all recent ones never). The stale entries are historical, not active drift.
Changes applied
1.
~/.codex/.codex-global-state.json (Electron persisted atom
state)
agent-mode:"auto"->"full-access"(legacy top-level key, superseded by the per-host keys which were already correct; aligned so a future audit does not read "auto" and misdiagnose drift)heartbeat-thread-permissions-by-id[*].approvalPolicy:on-request->neverfor the 6 entries whosesandboxPolicy.typewas alreadydangerFullAccess:019c29a9-…,019f811e-…,019f9537-…,019c249c-…,019fcebf-…,01a00768-…- File size 240652 -> 240629 bytes. Re-serialised compact
(
separators=(',',':')), matching the app's own format.
2.
~/.codex/state_5.sqlite (Codex core thread store)
UPDATE threads SET approval_mode='never'
WHERE approval_mode='on-request'
AND (sandbox_policy LIKE '%disabled%' OR sandbox_policy LIKE '%dangerFullAccess%');
-- 4 rows changedThose 4 are one VS Code delegation thread (01a00768-…,
2026-08-16) plus its 3 spawned subagents (Tesla, Descartes, Huygens) — a
dead delegation run.
Deliberately NOT changed, and why
38 core threads (33 managed/restricted + 5
read-only) and 8 Electron records
(workspaceWrite) remain at on-request. Under
Codex semantics, never does not mean
auto-approve when the sandbox blocks an action — it means
auto-reject. Confirmed from the codex binary's own
policy text:
"Approval policy is
granular. Categories set tofalseare automatically rejected instead of prompting the user." "approval required by policy, but AskForApproval is set to Never"
So flipping a restricted-sandbox thread from on-request
to never degrades it (prompt becomes silent refusal) rather
than loosening it. These are also mostly subagent/review threads created
under a permission profile by design, not drift. Left as-is pending
Rich's explicit call.
Safety notes
- ChatGPT.app was quit by Rich before the edit. Verified no process
held either file open (
lsofclean) before writing. - A Codex remote-control app-server
(
codex … app-server --listen unix://, PID 2971, started 2026-08-23 20:47) is still running and was intentionally left alive — it serves remote/phone access to this Mac. SQLite locking makes theUPDATEsafe against it; the unsynchronised last-writer-wins risk was the Electron JSON, and that writer was gone. - Two orphaned Computer Use helpers survive the quit (PID 32895
node_repl, PID 32899SkyComputerUseClient computer-history mcp). Not reaped — not ours to kill, and harmless.
Verification
JSON parse OK
agent-mode = full-access
agent-mode-by-host-id[local] = full-access
permission-selection-by-host-id:local = {"kind":"agent-mode","agentMode":"full-access"}
per-thread policies: never=68 on-request=8 (was never=62 on-request=14)
core DB approval_mode: never=423 on-request=38 (was never=419 on-request=42)
PRAGMA integrity_check = ok
Backups / undo
~/.codex/backups/approvalpolicy-fix-20260824-121549/
contains pre-change copies of .codex-global-state.json,
state_5.sqlite, state_5.sqlite-wal,
state_5.sqlite-shm.
To undo, with ChatGPT.app quit:
cp -p ~/.codex/backups/approvalpolicy-fix-20260824-121549/.codex-global-state.json ~/.codex/
cp -p ~/.codex/backups/approvalpolicy-fix-20260824-121549/state_5.sqlite* ~/.codex/Outstanding owner actions
- Relaunch ChatGPT.app and confirm the composer shows Full
access; the app may rewrite
.codex-global-state.jsonon first quit, which is expected and harmless. - Next time the "Allow ChatGPT to use
?" card appears, open the ▾and report whether "Always allow" is actually offered. If it is not, the cause is upstream in what the sky service advertises aspersistmodes, and no local config can fix it. - Decide whether the 38 restricted-sandbox threads should be flipped anyway (not recommended).
No secrets read, written, or transmitted.