Codex Desktop create_thread does not inherit auto-approval mode for worktree tasks

Open 💬 10 comments Opened Jul 15, 2026 by 1150260034
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

ChatGPT Desktop powered by Codex & OWL, version 26.707.71524.

Bundled Codex CLI/runtime reported by the child sessions: 0.144.2.

What subscription do you have?

Not relevant to the local permission inheritance behavior / not checked.

What platform is your computer?

Microsoft Windows NT 10.0.19045.0, AMD64.

What issue are you seeing?

Codex Desktop's official create_thread tool does not inherit the configured auto-approval mode when it creates a task in a managed worktree.

The Desktop host default is auto approval:

agent-mode-by-host-id.local = guardian-approvals
preferred-non-full-access-agent-mode-by-host-id.local = guardian-approvals

The parent task also had:

approval_policy = on-request
approvals_reviewer = auto_review
sandbox_policy = workspace-write

However, two independently created managed-worktree child tasks both started their first turn with:

approval_policy = on-request
approvals_reviewer = user
sandbox_policy = workspace-write

As a result, the children displayed manual approval dialogs for routine escalated operations that normally pass through the auto reviewer, including git fetch, git add, and GitHub CLI commands.

This is not a GitHub CLI installation or authentication issue. The commands work after manual approval, and the same host/default configuration uses auto review in the parent task.

Changing the child task to auto approval while its first turn is already running emits a later settings update, but the active turn continues using the original user reviewer snapshot. Every later escalation in that long-running turn still asks the user manually. The new setting only takes effect on a subsequent turn.

What steps can reproduce the bug?

  1. On Codex Desktop for Windows, select Auto approval as the default permission mode.
  2. Start a parent task and verify its turn context contains:

approvals_reviewer = auto_review.

  1. From that task, use the official create_thread tool with:
  • a saved local project;
  • environment: { type: "worktree" }.
  1. Let the child task begin its automatically started first turn.
  2. Inspect the child turn context.
  3. Observe that it contains:

approvals_reviewer = user.

  1. Have the child run a command that requires a normal scoped escalation, such as git fetch or git add in the managed worktree.
  2. Observe a manual approval dialog instead of automatic review.

This reproduced twice in separate child tasks:

  • Parent was auto_review immediately before the first create_thread call; the child started approximately one minute later as user.
  • Parent was again auto_review immediately before the second create_thread call; the child started seconds later as user.

Thread IDs, repository names, account names, and local paths are intentionally omitted.

What is the expected behavior?

A child task created through create_thread should inherit the effective approval reviewer from the Desktop host default or from its parent task.

With Auto approval selected, the child should start with:

approval_policy = on-request
approvals_reviewer = auto_review

If permission inheritance is intentionally unsupported, create_thread should expose an approval/permission parameter, or create the child in a paused state so the user can select its permission mode before the initial turn starts.

Changing a task's permission mode should also either affect subsequent tool calls in the active turn or clearly indicate that it will only apply to the next turn.

Additional information

Current workaround:

  1. Immediately stop the child task's first turn.
  2. Select Auto approval again inside the child task.
  3. Send a new “continue” message.
  4. The new turn then uses auto_review.

A related Windows report, #32880, covers linked-worktree Git metadata writes and sandbox ACLs. This report is different: the commands here are deliberately escalated and succeed after approval; the defect is that the child task starts with approvals_reviewer=user despite both the host default and parent task being configured for auto review.

View original on GitHub ↗

10 Comments

github-actions[bot] contributor · 1 month ago

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

  • #32612

Powered by Codex Action

1150260034 · 1 month ago

Thanks for the duplicate check. This issue is distinct from #32612.

The affected worktree tasks were launched internally by an existing Codex parent task through Codex Desktop's official create_thread tool. They were not manually created by the user in the UI, and the permission mode was not changed before their first turns started.

Before each create_thread call:

  • the Desktop host default was guardian-approvals / Auto approval;
  • the parent Codex turn had approvals_reviewer=auto_review.

Nevertheless, each internally spawned child task began its initial turn with approvals_reviewer=user. That incorrect initialization is the primary bug reported here.

#32612 covers changing access control while a turn is already running and having the change apply only to the next turn. That behavior appears here only as a secondary complication after the child has already started with the wrong reviewer. Even without any mid-turn setting change, the child task's initial permission state does not match either the host default or its Codex parent.

wibaek · 1 month ago

Reproduced on macOS as well.

  • Codex Desktop: 26.715.71837 (5702)
barisacarpr-cmyk · 28 days ago

Reproduced a closely matching permission-inheritance failure on Windows with three parallel Worktree tasks.

Environment:

  • Codex Desktop: 26.727.4816.0
  • OS: Windows NT 10.0.19045.0

Sanitized persisted state before applying a local config workaround:

host/global agent mode:
  local = full-access

parent task:
  approval_policy = never
  sandbox_policy = dangerFullAccess
  approvals_reviewer = user

three Worktree tasks:
  approval_policy = on-request
  sandbox_policy = workspaceWrite
  approvals_reviewer = user

All three Worktree tasks immediately surfaced manual approval dialogs for the same routine read-only inspection of the project and delegated worktree paths. The UI/global mode indicated Full access, so the repeated prompts were unexpected and blocked unattended parallel work.

This adds two observations:

  1. The mismatch reproduced identically in three separate Worktree tasks in the same project.
  2. The first prompt was for read-only path inspection, not a Git write, network call, credential operation, or destructive command.

Changing the visible permission mode while the active turns were already waiting did not remove the prompts from those turns, consistent with #32612.

Thread IDs, usernames, local paths, repository names, and project contents are intentionally omitted.

jamiepratt · 27 days ago

Reproduced on macOS with the host/UI set to Full access.

Environment:

  • ChatGPT/Codex Desktop: 26.727.40816 (6067)
  • Bundled Codex CLI: 0.146.0-alpha.9.2
  • macOS 15.7.4, arm64

Observed behavior:

  • The coordinator task initially reported sandbox_mode=danger-full-access with approval policy never, matching the UI setting.
  • A managed-worktree task created through internal task handoff/create_thread later received sandbox_mode=workspace-write with a managed/restricted permission profile.
  • The checkout files were writable, but the linked worktree metadata under the original repository was read-only.
  • Routine Git writes then failed on paths equivalent to:
  • <repo>/.git/worktrees/<managed-worktree>/index.lock
  • <repo>/.git/worktrees/<managed-worktree>/sequencer
  • git add and git cherry-pick returned Operation not permitted, and the task surfaced manual permission prompts despite Full access being selected.
  • In one long-running orchestration, the effective context visibly changed from danger-full-access to workspace-write after task handoff/resume, without the user changing the permission setting.

Expected behavior:

  • Full access should propagate to internally created and resumed managed-worktree tasks.
  • At minimum, the managed worktree permission profile must allow writes to that worktree own shared Git metadata, since Git worktrees share the primary repository .git directory.
  • A task should not silently change its effective sandbox/approval mode during handoff or resume.

Current mitigations are to reselect Full access inside each created task before continuing, start a fresh turn after changing permissions, or hand off to the Local checkout for Git integration. These reduce the symptom but make unattended multi-task orchestration unreliable.

briancl2 · 21 days ago

Reproduced on macOS with the current stable Desktop build, and the trace narrows the divergence to fresh visible task request assembly.

Environment:

  • ChatGPT/Codex Desktop: 26.730.61639 (bundle 6234)
  • Bundled Codex CLI: 0.147.0-alpha.1.2
  • macOS / Apple Silicon
  • Parent-driven task creation: official model-facing create_thread, saved Git project, managed worktree
  • Source parent effective policy: approval_policy=never, sandbox_policy=dangerFullAccess

Sanitized reproduction:

  1. A source coordinator was running with never/dangerFullAccess.
  2. A fresh visible parent created through Desktop received an explicit request with:
  • approvalPolicy=on-request
  • sandboxPolicy=workspaceWrite
  • useAppServerPermissionDefault=false
  1. Two managed-worktree children created from that parent received the same explicit restrictive request and later became operator-visible Awaiting approval tasks during already-authorized work.
  2. Two additional zero-tool probe tasks created through the same route also started on-request/workspaceWrite and safely stopped before any tool call.
  3. After the operator stopped the parent turn, the same parent continued with null permission fields and useAppServerPermissionDefault=true; app-server then correctly resolved the configured never/dangerFullAccess.
  4. A new create_thread probe from that recovered parent was nevertheless again explicitly requested as on-request/workspaceWrite.

This is five fresh visible destinations in one bounded transfer with the same restrictive request. It falsifies the narrower explanations that app-server default resolution, stale user configuration, reasoning effort, or inheritance only from the initially restricted parent caused the mismatch. An internal subagent created under the recovered parent inherited never/danger-full-access, which is a useful control.

The initial approval triggers included ordinary read-only advisory MCP identity/source-list calls, not Git writes or destructive commands. Corrective follow-up messages did not clear the server-initiated approval boundary; the operator had to click Stop. A manually created fresh task with Full access selected before send later passed a zero-tool never/danger-full-access preflight.

The current app-server contract already supports turn/interrupt, scoped approval decline/cancel, and request-resolution events. The high-level Desktop task-creation surface exposed to a coordinator does not expose permission policy/inheritance, resolved policy before first turn, cross-task interruption, or approval resolution.

Requested product behavior:

  • create_thread should preserve the source/host permission posture or expose an explicit permission/inherit parameter;
  • return the resolved permission tuple before the first turn can run tools;
  • alternatively create the destination paused so its permission mode can be selected before first-turn execution;
  • expose cross-task interrupt and scoped approval decline/cancel using the existing app-server identifiers.

Privacy-safe full causal trace and recurrence matrix: https://github.com/briancl2/build-meta-analysis/issues/1535#issuecomment-5199243390

Claim ceiling: this establishes five matching fresh-task occurrences on one host/build plus contrasting same-thread/internal-subagent controls. It does not establish all hosts, models, or fresh tasks.

bytware-alpha · 18 days ago

Reproduced on macOS with a narrower comparison between separate Desktop tasks and true collaboration subagents.

Environment:

  • macOS, Codex Desktop bundled runtime 0.147.0-alpha.6.5
  • host/UI mode: full-access
  • user config, present before task creation:

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

Observed:

  1. A parent task persisted as unrestricted/approval_mode=never and sandbox_policy={"type":"disabled"}.
  2. Three separate Desktop tasks created through the official create_thread path persisted instead as managed/restricted with approval_mode=on-request. Their collaboration subagents then correctly inherited that wrong restricted task policy.
  3. A true collaboration child created inside the unrestricted parent via spawn_agent persisted as unrestricted/never and completed a harmless read-only command without any approval record.
  4. In one restricted create_thread task, harmless process inspection (pgrep) was explicitly submitted with sandbox_permissions=require_escalated, producing an approval flow. That escalation was unnecessary for the operation, but it only became user-blocking because the new task had been initialized as managed/on-request.

This isolates the defect to separate Desktop task creation, not generic subagent inheritance.

The current model-visible create_thread schema exposes prompt, target/environment, model, reasoning, and title, but no sandbox or approval-policy override. By contrast, the documented App Server thread/start request supports both approvalPolicy and sandbox. So there is currently no supported way for the creating agent to preserve Full Access explicitly when this Desktop path chooses the wrong default.

Expected:

  • same-host create_thread should resolve the destination host's current Full Access default, or
  • it should expose/forward explicit approvalPolicy and sandbox fields.

Existing tasks retaining their creation-time policy is expected; the bug is that newly created tasks start with the wrong policy despite both the host default and user config already being Full Access/no approvals. Local paths, repository names, task IDs, and prompt contents are intentionally omitted.

Wolfsblvt · 14 days ago

I reproduced the Full Access variant of this with fresh, visible Codex Desktop project/worktree tasks on Windows 11.

Environment:

  • Codex Desktop 26.803.10989.0
  • Parent task: danger-full-access, approval policy never, unrestricted permission profile
  • New-task creation route: the Desktop create_thread interface, using a local project worktree

Observed behavior:

  • Each newly created tracked task started as workspace-write with managed approval and a filesystem profile restricted to its worktree plus selected temporary/artifact paths.
  • This happened in three fresh tasks, both before and after refreshing Full Access on the parent task.
  • One affected task was checked again on a later turn and remained restricted.
  • The qualification prompts explicitly prohibited commands, repository inspection, edits, and assignment work, so the different permission posture was present at session startup rather than being caused by a command.
  • The current create_thread interface exposes project, environment, model, reasoning, title, and prompt controls, but no permission-mode control.

These were not internal sub-agents. They were visible, independently tracked Codex sessions created in managed worktrees.

Impact: ordinary delegated repository work cannot run autonomously under the permission posture selected for the parent/project, and instead encounters confirmation/escalation boundaries for operations that the originating task can perform without approval.

Expected behavior: a new tracked task should either inherit the effective parent/project permission selection, or task creation should expose an explicit permission-mode field. It would also be useful to know whether already-created tasks can be refreshed after a fix or must be recreated.

All repository names, task IDs, user paths, and worktree identifiers have been omitted intentionally.

Edit: I may have found a narrower trigger in my reproduction. The unrestricted parent was itself not manually created in the Codex UI; it was an automatically launched successor / agent-created tracked task. That task correctly had Full Access. The downgrade appeared in the next generation: visible tasks it created through create_thread started restricted. I have not yet established that nesting depth or task provenance is causal, but this difference may explain why the same workflow appeared to work until today.

nachoal · 10 days ago

macOS build 26.810.52044: exact root cause and regression-tested fix direction

I reproduced the Full access variant on macOS and traced it through the packaged Codex Desktop renderer.

Environment
  • Codex Desktop: 26.810.52044 (build 6662)
  • Platform: macOS / Apple Silicon
  • Host permission selection: Full access
  • User configuration:

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

  • Source task effective context: approval_policy=never, sandbox_policy=dangerFullAccess
  • Destination: a managed worktree with a different CWD
Observed result

A task created through the model-facing create_thread path started with:

approval_policy=on-request
sandbox_policy=workspaceWrite

This is a task-creation defect. It is not a later Git or sandbox failure. The restrictive tuple is selected before the destination task starts its first turn.

Exact packaged path

In this build, the renderer path is:

create_thread -> jzl -> kfs -> jfs/Ffs

The relevant permission flow is:

  1. Lfs reads the source task's effective permission selection. It correctly classifies dangerFullAccess + never as native full-access.
  2. zfs decides whether that source selection can cross to the destination CWD.
  3. For a different CWD, zfs preserves the selection only when its internal permissionProfileId starts with :.
  4. A raw effective Full access selection can have permissionProfileId=null.
  5. zfs therefore returns null, even though the normalized source mode is full-access.
  6. The delegated fallback in Rfs maps the host's Full access selection to auto.
  7. Native auto resolves to workspaceWrite + on-request.

In pseudocode, the failing decision is equivalent to:

if same_cwd:
    preserve selection
if mode is custom or guardian:
    reject selection
if profile_id starts with ":":
    preserve selection
otherwise:
    reject selection

The last branch rejects a valid raw native selection solely because its internal profile ID is null.

The current model-facing create_thread schema also has no explicit sandbox or approval fields. It exposes title, prompt, target, model, and thinking only, so the coordinator cannot correct the downgrade at creation time.

Smallest fix

Preserve a normalized native permission mode across a different CWD when permissionProfileId is null. Keep the current non-escalation rules for restricted or special modes:

  • preserve raw full-access
  • preserve raw read-only, auto, and granular modes without changing their level
  • continue to reject custom and guardian-approvals across CWDs
  • continue to reject a non-null custom profile ID
  • keep same-CWD behavior unchanged

An alternative is to add explicit permission fields to create_thread and safely pass them through to task creation. Preserving the already-normalized native source selection is the smaller change.

Regression results

I made a copy-only patch and a standalone regression harness. The tests prove:

  • source full-access + null profile ID + different destination CWD remains full-access
  • the destination resolves to dangerFullAccess + never
  • raw restricted modes remain restricted and do not escalate
  • custom and guardian-approvals do not become Full access
  • same-CWD behavior is unchanged

The patch changes only the fixed-length zfs decision range. ASAR offsets, file sizes, unpack flags, and the ASAR header hash remain unchanged.

I did not install the patched bundle. Modifying app.asar invalidates the OpenAI application signature and causes both codesign --verify --deep --strict and Gatekeeper assessment to fail. The safe delivery path is an OpenAI-signed and notarized application update.

Requested action

Please apply the null-profile native-mode preservation fix, or add explicit permission fields to create_thread, and add the regression matrix above.

Label request: please add macOS. The existing app, app-server, and sandbox labels are correct.

dhruv-anand-aintech · 7 days ago

Reproduced a related macOS failure today in a delegated Codex Desktop task.

The originating workflow had Full Access / approvals disabled, and the user explicitly authorized this exact browser action: open ten locally served design-preview URLs in separate tabs of the already-running Microsoft Edge CDP session.

The child task nonetheless entered waitingOnApproval during the final verification phase. The pending work was ordinary local browser automation against 127.0.0.1: confirming the preview tabs, then doing a viewport/DOM check. It did not involve a deployment, credential access, purchase, message, destructive action, or external data submission.

Observed consequence: the child remained active but could not complete its terminal report. A coordinating task could verify that the ten tabs existed, but could not clear the child task’s approval boundary or reliably interrupt/cancel the pending request. Re-sending the explicit authorization as a follow-up message did not resolve the active turn.

This matches the broader cross-task permission downgrade/orphaned approval pattern: user authorization in the parent is insufficient once the child is created with a restrictive approval posture, and the current coordinator surface does not expose a way to inherit Full Access, resolve the child approval, or interrupt that exact pending tool call.

Requested regression coverage: create a delegated task from a Full Access parent, have it attach to an already-running local Edge CDP endpoint, create/navigate local preview tabs, and perform a non-destructive DOM/viewport check. The child should inherit never/danger-full-access; if a confirmation is still required, the parent-provided explicit action scope should satisfy it, and the coordinator should be able to cancel or resolve a stuck child approval.