Commit Graph

13805 Commits

Author SHA1 Message Date
Michael Bolin
9e1efea152 Merge 63ed7a6e87 into sapling-pr-archive-bolinfest 2026-04-28 09:23:52 -07:00
Michael Bolin
63ed7a6e87 core tests: configure profiles directly 2026-04-28 09:23:43 -07:00
Michael Bolin
4e1a59cc02 Merge 9f7581f589 into sapling-pr-archive-bolinfest 2026-04-28 09:22:11 -07:00
Michael Bolin
9f7581f589 core tests: configure profiles directly 2026-04-28 09:22:04 -07:00
Michael Bolin
c8f367c0b1 Merge 95f520d74f into sapling-pr-archive-bolinfest 2026-04-28 09:20:47 -07:00
Michael Bolin
95f520d74f core tests: configure profiles directly 2026-04-28 09:20:36 -07:00
Michael Bolin
b137bd144a Merge 44a6fc86a7 into sapling-pr-archive-bolinfest 2026-04-28 09:19:22 -07:00
Michael Bolin
44a6fc86a7 core tests: configure profiles directly 2026-04-28 09:19:12 -07:00
Michael Bolin
2b84aa1fd0 Merge 222eed63b8 into sapling-pr-archive-bolinfest 2026-04-28 09:16:22 -07:00
Michael Bolin
222eed63b8 core tests: migrate more turns to permission profiles 2026-04-28 09:16:09 -07:00
Michael Bolin
592ccc3a63 merge commit for archive created by Sapling 2026-04-28 09:13:24 -07:00
Michael Bolin
3628e8ed28 core tests: build user turns from permission profiles 2026-04-28 09:13:07 -07:00
Michael Bolin
0cf46843ab core tests: submit turns with permission profiles 2026-04-28 09:13:07 -07:00
Michael Bolin
804f1f9349 tui: use permission profiles for sandbox state 2026-04-28 09:12:39 -07:00
Michael Bolin
a0d85176b7 merge commit for archive created by Sapling 2026-04-28 09:05:34 -07:00
Michael Bolin
97d16ca739 core tests: build user turns from permission profiles 2026-04-28 09:05:15 -07:00
Michael Bolin
d2b4dfd88a core tests: submit turns with permission profiles 2026-04-28 09:05:15 -07:00
Michael Bolin
0cf8fdcdf9 tui: use permission profiles for sandbox state 2026-04-28 09:05:15 -07:00
Michael Bolin
cea526f657 merge commit for archive created by Sapling 2026-04-28 08:58:49 -07:00
Michael Bolin
16b458c044 core tests: submit turns with permission profiles 2026-04-28 08:58:32 -07:00
Michael Bolin
d189d69fc6 Merge 05359f18b5 into sapling-pr-archive-bolinfest 2026-04-28 08:56:36 -07:00
Michael Bolin
05359f18b5 core tests: submit turns with permission profiles 2026-04-28 08:56:23 -07:00
Michael Bolin
517f3f739c tui: use permission profiles for sandbox state 2026-04-28 08:56:07 -07:00
Michael Bolin
967213873b Merge d92aa0c7b3 into sapling-pr-archive-bolinfest 2026-04-28 08:47:31 -07:00
Michael Bolin
d92aa0c7b3 tui: use permission profiles for sandbox state 2026-04-28 08:47:22 -07:00
Michael Bolin
202ee55a4b Merge 346a2a10db into sapling-pr-archive-bolinfest 2026-04-27 23:09:53 -07:00
Michael Bolin
346a2a10db permissions: add built-in default profiles 2026-04-27 23:09:37 -07:00
Michael Bolin
0a32c8b396 app-server-protocol: mark permission profiles experimental (#19899)
## Why

`PermissionProfile` is now the canonical internal permissions
representation, but the app-server wire shape is still intentionally
unstable while the migration continues. Stable app-server clients should
not see or generate code for these fields until the wire format settles.

## What changed

- Marks every app-server v2 field that sends `PermissionProfile` as
experimental, including `command/exec`, `thread/start`, `thread/resume`,
`thread/fork`, and `turn/start` request/response payloads.
- Enables per-field experimental inspection for `command/exec`, so
`permissionProfile` is gated without making the entire method
experimental.
- Fixes the generated TypeScript schema filter to be comment-aware. The
previous scanner treated apostrophes inside doc comments as string
delimiters, so some experimental fields leaked into stable TypeScript
even though stable JSON was filtered correctly.

## Verification

- `cargo test -p codex-app-server-protocol`










---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19899).
* #19900
* __->__ #19899
2026-04-28 06:08:34 +00:00
Michael Bolin
caec9525f9 Merge fa0ea1d501 into sapling-pr-archive-bolinfest 2026-04-27 23:03:59 -07:00
Michael Bolin
fa0ea1d501 permissions: add built-in default profiles 2026-04-27 23:03:53 -07:00
Michael Bolin
d4af210cf1 merge commit for archive created by Sapling 2026-04-27 22:52:23 -07:00
Michael Bolin
3afcb5a68c app-server-protocol: mark permission profiles experimental 2026-04-27 22:52:00 -07:00
Michael Bolin
983b51ba54 permissions: add built-in default profiles 2026-04-27 22:52:00 -07:00
Michael Bolin
341550c275 permissions: store thread sessions as profiles (#19776)
## Why

After thread sessions have a required `PermissionProfile`, the TUI no
longer needs to cache a separate legacy `SandboxPolicy` in
`ThreadSessionState`. Keeping the legacy field would reintroduce two
permission authorities in the session cache and make later
replay/switching logic easier to get wrong.

This PR keeps legacy app-server compatibility at the ingestion boundary:
old `sandbox` response values are still accepted, but they are
immediately converted to a cwd-anchored profile.

## What Changed

- Removes `ThreadSessionState.sandbox_policy`.
- Updates active-session permission syncing to write only the current
`PermissionProfile`.
- Updates thread-read/replay/test fixtures to use profiles as the cached
session permission source.
- Leaves legacy `sandbox` fields in app-server request/response protocol
paths unchanged; those are compatibility boundaries and are converted
before entering cached TUI state.

## Verification

- `cargo test -p codex-tui thread_session_state::tests --lib`
- `cargo test -p codex-tui
inactive_thread_started_notification_initializes_replay_session --lib`
- `cargo test -p codex-tui thread_events --lib`
- `just fix -p codex-tui`




































---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19776).
* #19900
* #19899
* __->__ #19776
2026-04-28 05:49:58 +00:00
Eric Traut
92fb848065 Allow large remote app-server resume responses (#19920)
## Why

Remote TUI resume uses the app-server websocket client. That client
inherited tungstenite's default `16 MiB` frame limit, so a large saved
session could make `thread/resume` return a single JSON-RPC response
frame that the client rejected before the TUI could deserialize or
render it.

Fixes #19837

## What Changed

- Configure the remote app-server websocket client with a bounded `128
MiB` max frame/message size.
- Preserve the concrete remote worker exit reason when completing
pending requests after a transport/read failure instead of replacing it
with a generic channel-closed error.
- Add a regression test that sends a single `>16 MiB` JSON-RPC response
frame and verifies the typed request succeeds.

Note: This isn't a perfect fix. It really just moves the limit to a much
larger value. I looked at a bunch of other potential fixes (both
server-side and client-side), and they all involved significant
complexity, had backward-compatibility impact, or impacted performance
of common use cases. This simple fix should address the vast majority of
remote use cases.

## Verification

I reproed the problem locally using a long rollout. Verified that fix
addresses connection drop.
2026-04-27 22:44:10 -07:00
Michael Bolin
1ca52ec077 Merge 6d8772f845 into sapling-pr-archive-bolinfest 2026-04-27 22:31:07 -07:00
Michael Bolin
6d8772f845 permissions: add built-in default profiles 2026-04-27 22:30:51 -07:00
Michael Bolin
3c01c311c1 app-server-protocol: mark permission profiles experimental 2026-04-27 22:30:51 -07:00
Michael Bolin
360da3fd0b permissions: store thread sessions as profiles 2026-04-27 22:30:51 -07:00
Michael Bolin
fc2a69107c permissions: derive snapshot sandbox projections (#19775)
## Why

`ThreadConfigSnapshot` is used by app-server and thread metadata code as
a stable view of active runtime settings. Keeping both `sandbox_policy`
and `permission_profile` in the snapshot duplicates permission state and
makes it possible for the legacy projection to drift from the canonical
profile.

The legacy `sandbox` value is still needed at app-server compatibility
boundaries, so this PR derives it on demand from the snapshot profile
and cwd instead of storing it.

## What Changed

- Removes `ThreadConfigSnapshot.sandbox_policy`.
- Adds `ThreadConfigSnapshot::sandbox_policy()` as a compatibility
projection from `permission_profile` plus `cwd`.
- Updates app-server response/metadata code and tests to call the
projection only where legacy fields still exist.
- Keeps snapshot construction profile-only so split filesystem rules,
disabled enforcement, and external enforcement remain represented by the
canonical profile.

## Verification

- `cargo test -p codex-app-server
thread_response_permission_profile_preserves_enforcement --lib`
- `cargo test -p codex-core
dispatch_reclaims_stale_global_lock_and_starts_consolidation --lib`



































---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19775).
* #19900
* #19899
* #19776
* __->__ #19775
2026-04-27 22:30:47 -07:00
Michael Bolin
1cfeb5020c Merge 293cd35d55 into sapling-pr-archive-bolinfest 2026-04-27 22:07:04 -07:00
Michael Bolin
293cd35d55 permissions: add built-in default profiles 2026-04-27 22:06:53 -07:00
Michael Bolin
4f36ff27e5 app-server-protocol: mark permission profiles experimental 2026-04-27 22:06:53 -07:00
Michael Bolin
6c6150cfc8 permissions: store thread sessions as profiles 2026-04-27 22:06:53 -07:00
Michael Bolin
5e966fd4b2 permissions: derive snapshot sandbox projections 2026-04-27 22:06:53 -07:00
Michael Bolin
bf38def44e permissions: make SessionConfigured profile-only (#19774)
## Why

`SessionConfiguredEvent` is the internal event that tells clients what
permissions are active for a session. Emitting both `sandbox_policy` and
`permission_profile` leaves two possible authorities and forces every
consumer to decide which one to honor. At this point in the migration,
the profile is expressive enough to represent managed, disabled, and
external sandbox enforcement, so the internal event can be profile-only.

The wire compatibility concern is older serialized events or rollout
data that only contain `sandbox_policy`; those still need to
deserialize.

## What Changed

- Removes `sandbox_policy` from `SessionConfiguredEvent` and makes
`permission_profile` required.
- Adds custom deserialization so old payloads with only `sandbox_policy`
are upgraded to a cwd-anchored `PermissionProfile`.
- Updates core event emission and TUI session handling to sync
permissions from the profile directly.
- Updates app-server response construction to derive the legacy
`sandbox` response field from the active thread snapshot instead of from
`SessionConfiguredEvent`.
- Updates yolo-mode display logic to treat both
`PermissionProfile::Disabled` and managed unrestricted filesystem plus
enabled network as full-access, while still preserving the distinction
between no sandbox and external sandboxing.

## Verification

- `cargo test -p codex-protocol session_configured_event --lib`
- `cargo test -p codex-protocol serialize_event --lib`
- `cargo test -p codex-exec session_configured --lib`
- `cargo test -p codex-app-server
thread_response_permission_profile_preserves_enforcement --lib`
- `cargo test -p codex-core
session_configured_reports_permission_profile_for_external_sandbox
--lib`
- `cargo test -p codex-tui session_configured --lib`
- `cargo test -p codex-tui
yolo_mode_includes_managed_full_access_profiles --lib`


































---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19774).
* #19900
* #19899
* #19776
* #19775
* __->__ #19774
2026-04-27 22:06:47 -07:00
Eric Traut
5ba908d179 Avoid persisting ShutdownComplete after thread shutdown (#19630)
## Why

Fixes #19475.

`codex exec` can finish successfully and then emit an `ERROR` on stderr:

```text
failed to record rollout items: thread <id> not found
```

That happens because shutdown closes the live thread writer before
emitting `ShutdownComplete`. The terminal event was still using the
normal `send_event_raw` path, so it tried to append rollout items
through a recorder that had already been removed. The answer is correct,
but wrappers that treat stderr as failure can retry completed exec runs.

This looks like a likely recent regression from
[#18882](https://github.com/openai/codex/pull/18882), which routed live
thread writes through `ThreadStore` and added the shutdown-time live
writer close. I have not bisected this, so the PR treats #18882 as the
likely source based on the affected shutdown code path rather than a
proven first-bad commit.

## What Changed

`ShutdownComplete` now bypasses rollout persistence after thread
shutdown and is delivered directly to clients. The shutdown path still
records the protocol event in the rollout trace before delivery,
preserving trace visibility without attempting a post-shutdown
thread-store append.

The change also adds a regression test with the in-memory thread store
to assert that shutdown creates and shuts down the live thread without
appending another item after shutdown.
2026-04-27 22:02:08 -07:00
Eric Traut
b7e5588d18 Clarify PR template invitation requirement (#19912)
Addresses #19856

## Summary
- Clarifies that external code contributions are invitation only.
- Points contributors to `docs/contributing.md` for the full policy
instead of using the previous warning phrasing.
2026-04-27 21:45:15 -07:00
Michael Bolin
7dc6345136 merge commit for archive created by Sapling 2026-04-27 21:40:17 -07:00
Michael Bolin
e97f5f5117 permissions: add built-in default profiles 2026-04-27 21:38:52 -07:00