Skip to content

app-server: keep thread PermissionProfile immutable#21250

Open
bolinfest wants to merge 1 commit intomainfrom
pr21250
Open

app-server: keep thread PermissionProfile immutable#21250
bolinfest wants to merge 1 commit intomainfrom
pr21250

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented May 5, 2026

Why

Codex is moving permission state from the legacy SandboxPolicy abstraction to PermissionProfile. For existing threads, the actual PermissionProfile value should be durable thread state, not something an app-server client can rewrite through resume, fork, or turn APIs. The active profile name and workspace roots are separate thread state: the name is UI/selection metadata, while workspace roots define how symbolic :project_roots permission entries materialize for that thread.

This separation removes the need for ActivePermissionProfileModification, which was effectively an overlay that let roots mutate the active profile. Roots now live with the thread instead of being carried inside the active profile or inside SandboxPolicy::WorkspaceWrite.

What changed

  • Added thread/session workspace_roots state and persisted it through rollout, thread-store metadata, app-server lifecycle responses, and turn context.
  • Updated app-server thread/resume, thread/fork, and turn/start so existing threads preserve their persisted PermissionProfile value.
  • Kept permissions support on existing app-server threads as active-profile-name selection only, with validation that unknown profile ids return a JSON-RPC error.
  • Allowed workspaceRoots to update independently from cwd; cwd-only updates preserve the existing root list.
  • Removed ActivePermissionProfileModification / PermissionProfileModificationParams from protocol models and generated TypeScript exports.
  • Changed SandboxPolicy::WorkspaceWrite so it no longer owns writable_roots; v2 still accepts legacy writableRoots on deserialization for compatibility and ignores them.
  • Updated app-server docs and regenerated protocol schema fixtures.
  • Fixed CI-only compile fixtures that needed explicit empty workspace_roots, and removed the now-unused codex-utils-sandbox-summary dev dependency.

Verification

  • cargo test -p codex-core --lib
  • cargo test -p codex-core --test all personality_migration
  • cargo test -p codex-app-server-protocol
  • cargo test -p codex-protocol
  • cargo test -p codex-app-server
  • cargo test -p codex-state
  • cargo test -p codex-analytics
  • cargo test -p codex-thread-manager-sample
  • cargo shear
  • just argument-comment-lint
  • just fix -p codex-core
  • just fix -p codex-state -p codex-analytics -p codex-thread-manager-sample
  • just bazel-lock-update
  • just bazel-lock-check

@bolinfest bolinfest requested a review from a team as a code owner May 5, 2026 21:45
@bolinfest bolinfest changed the title Move workspace roots onto thread/session state and stop using active permission profile modifications as an overlay for app-server: keep thread PermissionProfile immutable May 5, 2026
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 11750256e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

workspace_root_writable = true;
} else {
writable_roots.push(path.clone());
unbridgeable_external_write = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve extra roots for the Windows sandbox

When a materialized workspace profile contains both cwd and an additional workspace root (for example from --add-dir/workspaceRoots), this branch records the non-cwd write as unbridgeable_external_write but still returns WorkspaceWrite as soon as cwd is writable. Because WorkspaceWrite no longer carries writable_roots, the compatibility policy only exposes cwd; I checked resolve_windows_restricted_token_filesystem_overrides, which compares those legacy roots with the split filesystem roots and returns windows unelevated restricted-token sandbox cannot enforce split writable root sets on mismatch. This regresses Windows restricted-token runs with additional workspace roots that used to be representable via writable_roots.

Useful? React with 👍 / 👎.

Comment thread codex-rs/exec/src/lib.rs
active_permission_profile,
cwd,
cwd: cwd.clone(),
workspace_roots: vec![cwd],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist response workspace roots in exec rollouts

ThreadStartResponse and ThreadResumeResponse now include the server's effective workspace_roots, but the exec bootstrap event is still hard-coded to vec![cwd]. In codex exec sessions started/resumed with additional roots, the rollout's SessionConfiguredEvent drops those roots; later resume/fork reconstructs permission state from that event and materializes :project_roots with only cwd, so previously writable --add-dir roots are lost. Pass the response roots through here, falling back to cwd only when the response is empty.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@evawong-oai evawong-oai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

…permission profile modifications as an overlay for writable roots. Existing app-server threads now preserve their persisted PermissionProfile value across resume, fork, and turn updates; permissions requests on existing threads only update the active named profile after validating it exists. Workspace roots can be updated independently, and SandboxPolicy::WorkspaceWrite no longer stores its own writable_roots.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants