Skip to content

app-server: select permission profiles by id#22402

Open
bolinfest wants to merge 1 commit into
pr22401from
pr22402
Open

app-server: select permission profiles by id#22402
bolinfest wants to merge 1 commit into
pr22401from
pr22402

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented May 13, 2026

Why

The app-server should let clients change the thread's named permission profile association and workspace roots without letting them replace the underlying PermissionProfile value outright. The server needs to stay in control of profile definitions while still supporting the operations clients actually need:

  • select a known profile by id
  • preserve the stored effective profile when no selection is provided
  • replace workspaceRoots
  • keep older sandbox-based clients working when their request maps cleanly to a known named profile

Because permissions / workspaceRoots are experimental fields, tightening that contract is preferable to continuing to accept more expressive payloads that the server should not honor.

What Changed

  • thread/start, thread/resume, thread/fork, and turn/start now treat permissions as a profile id (Option<String>) instead of a structured profile payload.
  • App-server request processors resolve that id against the server's known profiles and return a JSON-RPC error when the id is unknown.
  • Omitting permission fields preserves the stored thread PermissionProfile; workspaceRoots can be replaced independently.
  • Add a legacy sandbox compatibility layer so older clients can still send sandbox / sandboxPolicy when it is a no-op or maps to a named profile plus compatible workspace roots.
  • Preserve existing extra workspace roots when older clients repeat sandboxPolicy: workspaceWrite for a cwd that is already a workspace root, while still rebinding roots for a changed cwd and honoring non-empty legacy writableRoots.
  • Validate legacy sandbox compatibility against the exact sandbox projection of the resolved profile after workspace roots are materialized, rather than checking only enforcement and network mode.
  • Preserve rollout-resume permission state without leaking stale active profile names when the latest persisted turn has an unnamed effective profile.
  • Preserve older rollout fileSystemSandboxPolicy data when a TurnContextItem predates the serialized permissionProfile field, so resume keeps deny entries and internal writable-root grants instead of falling back to the coarser legacy sandbox projection.
  • Update the app-server protocol handling and README to document the narrowed lifecycle and turn-level rules.

Compatibility

  • Older app-server clients such as slow-moving IDE integrations continue to work through the legacy sandbox mapping path when their request exactly matches a known named profile.
  • Repeated legacy workspace-write updates no longer drop server-side extra workspace roots, such as roots seeded from --add-dir, when the current cwd is already among the thread roots.
  • Clients can still change the profile name/selection by id and update workspaceRoots, but they cannot submit arbitrary PermissionProfile values through the app-server API.
  • Persisted rollouts keep their latest effective permission profile and workspace roots on resume; if a later turn moved to an unnamed profile, the resumed app-server response no longer reports the earlier active profile name.
  • Rollouts written before permissionProfile was serialized still resume from their serialized filesystem policy when present, which protects split-policy details such as deny rules and Codex-internal writable roots used by memories.
  • The compatibility path intentionally stops at requests that would require inventing a new unnamed profile on the server, or whose legacy sandbox flags do not match the named profile's derived projection.

Verification

The targeted regression coverage here focused on the app-server call paths where older clients or persisted threads could drift from the server's effective permissions:

  • thread_start_selects_permission_profile_by_id
  • thread_resume_running_applies_workspace_roots_and_active_profile_name
  • turn_start_updates_cwd_without_replacing_workspace_roots_v2
  • turn_start_legacy_workspace_sandbox_updates_workspace_roots_for_cwd
  • turn_start_legacy_workspace_sandbox_preserves_extra_roots
  • turn_start_rejects_unknown_permission_selection_before_starting_turn
  • legacy_workspace_sandbox_preserves_current_extra_roots_when_cwd_is_still_a_root
  • legacy_workspace_sandbox_honors_non_empty_legacy_writable_roots
  • legacy_workspace_selection_validation_requires_exact_projection
  • persisted_thread_permission_state_clears_stale_active_profile
  • persisted_thread_permission_state_uses_legacy_turn_context_file_system_policy
  • focused app-server persisted-permission-state tests for active profile and empty workspace-root reconstruction

Stack created with Sapling. Best reviewed with ReviewStack.

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: dc0f61af1f

ℹ️ 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".

Comment thread codex-rs/tui/src/app_server_session.rs Outdated
@bolinfest bolinfest requested a review from a team as a code owner May 13, 2026 02:26
@bolinfest bolinfest force-pushed the pr22402 branch 2 times, most recently from 03e72f1 to 24f01e1 Compare May 13, 2026 03:23
@bolinfest bolinfest force-pushed the pr22401 branch 2 times, most recently from 7336736 to bb76782 Compare May 13, 2026 03:44
@bolinfest bolinfest force-pushed the pr22402 branch 2 times, most recently from f965330 to 1bb4cb8 Compare May 13, 2026 03:52
@bolinfest bolinfest force-pushed the pr22401 branch 2 times, most recently from b9f3284 to 7aa7447 Compare May 13, 2026 05:14
@bolinfest bolinfest force-pushed the pr22402 branch 2 times, most recently from 802324c to 8ce7db8 Compare May 13, 2026 05:31
@bolinfest bolinfest force-pushed the pr22402 branch 3 times, most recently from aa3919e to 188df1b Compare May 13, 2026 06:19
@bolinfest bolinfest force-pushed the pr22402 branch 2 times, most recently from eef356e to daed594 Compare May 13, 2026 06:59
@bolinfest bolinfest force-pushed the pr22402 branch 2 times, most recently from 8eb3d14 to 93aef9b Compare May 13, 2026 15:44
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.

1 participant