Skip to content

tui: add named permission profile picker#21559

Merged
viyatb-oai merged 4 commits into
mainfrom
codex/viyatb/profile-permissions-picker
May 26, 2026
Merged

tui: add named permission profile picker#21559
viyatb-oai merged 4 commits into
mainfrom
codex/viyatb/profile-permissions-picker

Conversation

@viyatb-oai

@viyatb-oai viyatb-oai commented May 7, 2026

Copy link
Copy Markdown
Collaborator

Why

Users who opt into named permission profiles through default_permissions or [permissions.*] should stay in named-profile semantics when they open /permissions. The legacy picker rewrites those users into anonymous preset state, which loses the active profile identity and hides custom configured profiles.

What changed

  • Switch /permissions to a profile-aware picker when profile mode is active.
  • Show friendly built-in labels instead of raw : profile syntax.
  • Include configured custom profiles and their descriptions in the picker.
  • Route selections through the split TUI profile-selection flow below this PR.
  • Add TUI snapshots and regression coverage for built-ins, custom profiles, and conflicting legacy runtime overrides.

Stack

  1. #22931: runtime/session/network propagation for active permission profiles.
  2. #23708: TUI selection plumbing and guardrail flow.
  3. This PR: profile-aware /permissions menu and custom profile display.

UX impact

In profile mode, /permissions shows the same human-facing built-ins users already know:

Default
Auto-review
Full Access
Read Only
locked-down
web-enabled

Selecting locked-down keeps active_permission_profile = Some("locked-down"); selecting a built-in keeps the friendly label while switching to its named built-in profile.

Screenshots

Live $test-tui smoke screenshots uploaded through GitHub attachments:

Profile mode with built-ins and custom profiles

Profile mode permissions picker with custom profiles

Legacy mode remains anonymous preset picker

Legacy permissions picker image Screenshot 2026-05-18 at 2 58 00 PM

Validation

  • git diff --cached --check before commit.
  • Full test run skipped at the user request while pushing the split stack.

@viyatb-oai viyatb-oai requested a review from a team as a code owner May 7, 2026 17:04
@viyatb-oai viyatb-oai requested a review from fcoury-oai May 7, 2026 21:15

@fcoury-oai fcoury-oai left a comment

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.

I found a potential issue with the help of Codex:

When I switch to a different named profile mid-session, the TUI updates correctly and /status shows the new profile.

But then the already-running session does not fully adopt that profile’s runtime state.

It seems like switching from a profile with no managed network proxy to one with profile-specific network policy leaves the live thread on the old proxy/network behavior.

So the UI says “profile B is active,” but the current session can still behave like profile A until a fresh session/thread is started.

Repro

This is the exact repro steps I used to replicate this issue.

Setup in ~/.codex/config.toml:

default_permissions = "locked-down"

[permissions.locked-down.filesystem]
":minimal" = "read"

[permissions.web-enabled.filesystem]
":minimal" = "read"

[permissions.web-enabled.filesystem.":project_roots"]
"." = "write"

[permissions.web-enabled.network]
enabled = true
allow_local_binding = true

[permissions.web-enabled.network.domains]
"example.com" = "allow"

Important shape of the two profiles:

  • locked-down has no network stanza at all
  • web-enabled enables network and adds a profile-specific allowlist for example.com

Steps

  1. Start a fresh Codex TUI session with locked-down active.
  2. Send one trivial prompt so there is a live session/thread.
  3. Run /debug-config.

Observed after step 3:

  • no Session runtime network_proxy block is shown
  1. Run /permissions and switch to web-enabled.
  2. Run /status.

Observed after step 5:

  • /status shows Permissions: Profile web-enabled (...)
  1. Run /debug-config again, in the same session.

Observed after step 6:

  • still no Session runtime network_proxy block
  1. In that same session, ask Codex:
    Use the shell tool to run 'curl -I https://openai.com'

Observed after step 7:

  • the request goes out and reaches OpenAI
  • I got a real HTTP response path, ending in a Cloudflare challenge (HTTP/2 403, cf-mitigated: challenge), which means the outbound request was not blocked by the profile-specific allowlist

Expected
After switching to web-enabled, the live session should pick up the profile’s managed network policy. Since web-enabled only allows example.com, a shell-tool request to https://openai.com should be blocked.

Actual
The UI updates to web-enabled, but the live session does not appear to gain the managed proxy/runtime state for that profile:

  • /status reflects the new profile
  • /debug-config still shows no session network_proxy
  • shell-tool network behavior still allows openai.com

Why this looks like the bug
This matches the code path concern that mid-session /permissions updates the TUI/app config copy, but the live-session override does not carry enough data to fully apply the selected named profile’s runtime network state. It reproduces specifically when switching from a profile with no managed proxy to one that requires a managed proxy.

@viyatb-oai

Copy link
Copy Markdown
Collaborator Author

Addressed the runtime proxy gap in b140e5f.

What changed:

  • /permissions profile selections now carry active_permission_profile through the TUI -> core override path.
  • Core rebuilds the selected profile network proxy spec from the effective config layers when applying an active profile update.
  • The running managed network proxy is replaceable: profile switches can update an existing proxy, start one if the newly selected profile enables it, or drop the old handle if the new profile has no proxy.
  • Added a regression test that switches from a locked profile to a web-enabled profile and asserts the session config picks up the selected profile proxy URL.

Local checks:

  • cargo test -p codex-core session_configuration_apply_active_profile_rebuilds_network_proxy_config (green before final test-name cleanup)
  • cargo test -p codex-core new_turn_refreshes_managed_network_proxy_for_sandbox_change
  • cargo test -p codex-core session_configuration_apply_permission_profile_preserves_supplied_active_profile
  • cargo test -p codex-tui apply_permission_profile_selection_ignores_legacy_harness_overrides
  • cargo test -p codex-tui profile_permissions_selection
  • just fix -p codex-core
  • just fix -p codex-tui
  • cargo clippy -p codex-core --tests -- -D warnings
  • cargo clippy -p codex-tui --tests -- -D warnings
  • git diff --check
  • cargo clean

@viyatb-oai viyatb-oai requested a review from fcoury-oai May 8, 2026 04:59
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch 3 times, most recently from b8a0eec to 653089d Compare May 16, 2026 00:00
@viyatb-oai viyatb-oai changed the base branch from main to codex/viyatb/profile-permissions-runtime May 16, 2026 00:00
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 653089d to 71ea260 Compare May 16, 2026 00:01
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch 2 times, most recently from e1008e8 to 35c7271 Compare May 19, 2026 03:28
viyatb-oai added a commit that referenced this pull request May 19, 2026
## Why

The `/permissions` picker needs a config-level way to distinguish legacy
anonymous presets from named permission-profile mode. That signal cannot
be inferred reliably in the TUI, especially for the edge case where
`default_permissions = ":workspace"` is present without a
`[permissions]` table.

## What changed

- Expose whether the merged config is explicitly in permission-profile
mode.
- Expose the configured custom permission profile IDs alongside the
built-in profile semantics.
- Add regression coverage for profile mode detection and custom profile
metadata, including the `default_permissions = ":workspace"` case.
- Update the thread-manager sample config literal to match the expanded
config shape.

## Stack

1. **This PR**: config metadata needed by downstream permission-profile
consumers.
2. [#22931](#22931): refresh active
permission profiles through runtime/session/network state.
3. [#21559](#21559): switch
`/permissions` to the profile-aware TUI picker.

## Verification

- `cargo check -p codex-thread-manager-sample`
- `cargo test -p codex-core
default_permissions_can_select_builtin_profile_without_permissions_table`
- `cargo test -p codex-core
permissions_profiles_allow_direct_write_roots_outside_workspace_root`
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-runtime branch from 6206636 to 98b8aab Compare May 20, 2026 03:46
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 35c7271 to 9d4d30b Compare May 20, 2026 03:46
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-runtime branch from 98b8aab to 6d4a8df Compare May 20, 2026 04:22
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 9d4d30b to e1d6bf1 Compare May 20, 2026 04:22
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 81b6cf4 to 843a29c Compare May 20, 2026 15:48
@viyatb-oai viyatb-oai changed the base branch from codex/viyatb/profile-permissions-runtime to codex/viyatb/tui-permission-profile-selection May 20, 2026 15:48
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch 3 times, most recently from 7514892 to 85d1f42 Compare May 20, 2026 18:18
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/tui-permission-profile-selection branch from ce7ae38 to ef21b6b Compare May 20, 2026 21:02
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 85d1f42 to 7cb4f6b Compare May 20, 2026 21:02
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/tui-permission-profile-selection branch from ef21b6b to 8e8150c Compare May 20, 2026 21:05
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 7cb4f6b to 39cb064 Compare May 20, 2026 21:07
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/tui-permission-profile-selection branch from 8e8150c to c83b8db Compare May 20, 2026 21:27
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 39cb064 to f6005e7 Compare May 20, 2026 21:28
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/tui-permission-profile-selection branch from c83b8db to 3ee4233 Compare May 20, 2026 21:39
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from f6005e7 to dd22806 Compare May 20, 2026 21:39
viyatb-oai added a commit that referenced this pull request May 20, 2026
## Why

Once a named permission profile is selected, runtime state has to keep
that profile identity intact instead of collapsing back to anonymous
effective permissions. The session refresh path also needs to rebuild
profile-derived network proxy state so active profile switches take
effect consistently.

## What changed

- Preserve the active permission profile through session updates.
- Rebuild profile-derived runtime/network configuration when the active
profile changes.
- Keep the runtime path aligned with the current session configuration
APIs.
- Tighten the affected tests, including the Windows delete-pending
memory-file case that was intermittently tripping CI.

## Stack

1. **This PR**: runtime/session/network propagation for active
permission profiles.
2. [#23708](#23708): TUI selection
plumbing and guardrail flow.
3. [#21559](#21559): profile-aware
`/permissions` menu and custom profile display.

<img width="1296" height="906" alt="image"
src="https://github.com/user-attachments/assets/077fa3a7-80cb-4925-80b1-d2395018d90a"
/>
viyatb-oai added a commit that referenced this pull request May 21, 2026
## Why

The named-profile `/permissions` picker needs a small TUI action path
that can select permission profiles without folding the menu UI and
profile metadata into the same review.

## What changed

- Carry permission-profile selections through the TUI app event flow.
- Persist selected profiles while preserving the existing approval
settings and guardrail prompts.
- Keep the legacy `/permissions` picker behavior in this layer; the
profile-mode menu stays in the follow-up PR.

## Stack

1. [#22931](#22931):
runtime/session/network propagation for active permission profiles.
2. **This PR**: TUI selection plumbing and guardrail flow.
3. [#21559](#21559): profile-aware
`/permissions` menu and custom profile display.

<img width="1632" height="1186" alt="image"
src="https://github.com/user-attachments/assets/69ddcd5e-b57c-468d-8c1d-246916323c15"
/>

## Validation

- `git diff --cached --check` before commit.
- Full test run skipped at the user request while pushing the split
stack.
Base automatically changed from codex/viyatb/tui-permission-profile-selection to main May 21, 2026 15:26

@fcoury-oai fcoury-oai left a comment

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.

Smoke tested the happy path locally in profile mode with a temp CODEX_HOME/config.toml using default_permissions plus custom profiles.

Verified /permissions showed the profile-aware picker with friendly built-in labels and custom profile descriptions, selecting a custom profile emitted the expected “Permissions updated to …” message and became current on reopen, and switching back to Default preserved the friendly built-in label/current state.

Code looks good as well, approved. 👍

@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from dd22806 to 5df6769 Compare May 22, 2026 06:45
@viyatb-oai viyatb-oai enabled auto-merge (squash) May 22, 2026 06:55
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
Co-authored-by: Codex noreply@openai.com
@viyatb-oai viyatb-oai force-pushed the codex/viyatb/profile-permissions-picker branch from 5df6769 to e7e0e56 Compare May 22, 2026 14:51
@viyatb-oai viyatb-oai merged commit f6fd753 into main May 26, 2026
46 of 47 checks passed
@viyatb-oai viyatb-oai deleted the codex/viyatb/profile-permissions-picker branch May 26, 2026 16:39
@github-actions github-actions Bot locked and limited conversation to collaborators May 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants