/goal continuation can reuse stale permission context after Full Access/custom permissions

Open 💬 5 comments Opened Jun 23, 2026 by rudy774

Summary

Codex Desktop can continue a /goal run with stale permission settings even when the visible/global configuration is Full Access with approval_policy = "never".

This appears to be a /goal-specific path: current thread/goal/set sends only goal fields, while normal turn/start and thread/settings/update carry the current permission context. If the goal RPC immediately wakes a continuation, that continuation can inherit stale live/persisted thread settings.

Observed case

  • User-reported session/thread id: 019ef286-ba82-7eb0-bcad-2a85f8798cda
  • Platform: Windows Codex Desktop
  • App version observed in local logs: 26.616.71553
  • Effective user config at the time of repair:
approval_policy = "never"
sandbox_mode = "danger-full-access"
default_permissions = ":danger-full-access"

[windows]
sandbox = "elevated"

Evidence from local state/log inspection

  • The affected thread/state had stale approval_mode = 'on-request' with a managed/restricted sandbox policy despite global Full Access config.
  • The global heartbeat file had stale workspaceWrite / on-request permission contexts for several goal-related entries.
  • Normalizing the persisted state back to approval_mode = 'never' and full-access/disabled sandbox restored the expected behavior locally.
  • As of public main at e476fc16ce810495cbfabe4f815d20947da0ba79, ThreadGoalSetParams still contains only thread_id, objective, status, and token_budget.
  • turn/start and thread/settings/update already carry/apply approvalPolicy, approvalsReviewer, sandboxPolicy, and permissions.

Root cause hypothesis

/goal uses thread/goal/set, then goal runtime effects can immediately start or resume autonomous continuation. Because thread/goal/set does not carry the current permission context, that continuation can run under stale live/persisted thread settings that predate the user's current Full Access/custom-permissions selection.

This matches the user-visible symptom: normal turns may work after permission changes, but /goal can reintroduce old approval prompts or restricted sandbox behavior.

Proposed fix direction

I prepared a local patch draft against main that does the following:

  • Adds optional fields to ThreadGoalSetParams: approval_policy, approvals_reviewer, sandbox_policy, and permissions.
  • Sends the current permission context from TUI /goal set/status calls.
  • Resolves named/custom permission profiles in the app server before applying goal changes.
  • Adds CodexThread::apply_thread_settings_overrides(...) and applies goal permission context before set_thread_goal(...).apply_runtime_effects(...) can wake continuation.
  • Updates generated TypeScript and JSON schema fixtures.

I could not open a PR directly from this environment because the GitHub connector reports push: false for openai/codex and no PR-creation tool is exposed. The local patch passed git diff --check; generated JSON fixtures parse with ConvertFrom-Json. I could not run cargo fmt, cargo check, or Rust tests because cargo, rustc, and rustfmt are not installed on PATH in this Windows Codex Desktop environment.

Related issues

  • openai/codex#22090 describes essentially the same /goal stale permission context failure and was closed, but current public main still appears to lack permission context on ThreadGoalSetParams.
  • openai/codex#24326 was closed as a duplicate with similar full-access goal continuation behavior.
  • openai/codex#28574, openai/codex#28776, and openai/codex#28988 also look related to permission persistence/full-access prompt regressions.

Could someone on the Codex team confirm whether the intended fix is to propagate/apply permission context through thread/goal/set, or whether this should instead reuse the existing thread/settings/update path before goal runtime effects are applied?

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗