Commit Graph

4570 Commits

Author SHA1 Message Date
Ahmed Ibrahim
d4cbc97a9b Remove unused fuzzy search test import
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 09:54:26 +00:00
Ahmed Ibrahim
d87051f57e Factor in-process request response alias
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 09:37:59 +00:00
Ahmed Ibrahim
ef5a05fa3f Inline in-process request response types
Avoid exposing a private type alias through the app-server public API so the fuzzy-search request-order fix builds cleanly across the rust-ci matrix.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 09:23:26 +00:00
Ahmed Ibrahim
4195e7e808 Preserve in-process fuzzy search request ordering
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 09:11:01 +00:00
Ahmed Ibrahim
d017d0fc35 Stabilize Windows shell and fuzzy search tests
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 08:51:10 +00:00
Ahmed Ibrahim
495ef3f76f Expose nextest failure tail in CI
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 08:10:01 +00:00
Ahmed Ibrahim
7613630080 Annotate nextest failures in CI
Capture nextest output in rust-ci and emit parsed FAIL/LEAK lines as annotations and step-summary text when tests fail.

Also record the isolated Linux test failure on b6e18d2e8 in the flaky-test ledger.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 07:40:42 +00:00
Ahmed Ibrahim
b6e18d2e8c Record validation pass 2
Record the green 9835ec89d CI run and advance the consecutive-pass streak to 2/5.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 07:15:02 +00:00
Ahmed Ibrahim
9835ec89dd Record validation pass 1
Record the green c3b8a0ebf CI run and restart the consecutive-pass streak at 1/5.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 06:19:39 +00:00
Ahmed Ibrahim
c3b8a0ebfa Correct Windows popup selection assertions
Use exact selected preset names in the permissions popup tests and restore the correct Windows expectation for the default unelevated popup opening on Read Only instead of Default.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 05:56:09 +00:00
Ahmed Ibrahim
13c9d91b0f Avoid false matches in permissions popup helper
Match the selected permissions preset by the row name prefix instead of a loose substring search so the Smart Approvals description cannot masquerade as Default during popup navigation.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 05:27:21 +00:00
Ahmed Ibrahim
87941e5d75 Harden remaining Windows permissions popup navigation
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 05:08:11 +00:00
Ahmed Ibrahim
e96d895c9f Stabilize Windows permissions popup navigation
Handle the Windows-only Read Only preset in the generic helper and drive the permission history snapshot tests by the selected label instead of hard-coded key counts.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 04:39:59 +00:00
Ahmed Ibrahim
8bc3d489a3 Relax popup current-label assertions
Match the selected permission preset label directly in the generic history tests instead of assuming the popup always renders a  suffix.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 04:11:56 +00:00
Ahmed Ibrahim
a30e8e2ecb Narrow permissions popup selection helper
Restrict the selection helper to permission preset rows so popup assertions cannot bind to unrelated rendered lines.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 04:07:03 +00:00
Ahmed Ibrahim
fc98d21ad8 Select Smart Approvals in session-configured popup tests
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 03:55:32 +00:00
Ahmed Ibrahim
1b6e21ccc7 Pin snapshot popup navigation to concrete presets
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 03:54:43 +00:00
Ahmed Ibrahim
dc8d5d46da Assert popup selection in permissions history tests
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 03:52:57 +00:00
Ahmed Ibrahim
5dbb9c0048 Stabilize Smart Approvals popup selection test
Co-authored-by: Codex <noreply@openai.com>
2026-03-14 03:28:27 +00:00
Ahmed Ibrahim
b9c655ad46 Stabilize approval matrix write-file command
Replace the approval-matrix shell redirection write path with deterministic Python file I/O and keep scenario-level diagnostics in CI while the flake is being verified.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 03:00:42 +00:00
Ahmed Ibrahim
60f44b4d7c Document flaky test triage
Track CI-history evidence, hypotheses, and the per-commit pass ledger for the flaky-test investigation.

Co-authored-by: Codex <noreply@openai.com>
2026-03-14 02:54:13 +00:00
viyatb-oai
6dc04df5e6 fix: persist future network host approvals across sessions (#14619)
## Summary
- apply persisted execpolicy network rules when booting the managed
network proxy
- pass the current execpolicy into managed proxy startup so host
approvals selected with "allow this host in the future" survive new
sessions
2026-03-14 02:46:10 +00:00
Charley Cunningham
bbd329a812 Fix turn context reconstruction after backtracking (#14616)
## Summary
- reuse rollout reconstruction when applying a backtrack rollback so
`reference_context_item` is restored from persisted rollout state
- build rollback replay from the flushed rollout items plus the rollback
marker, avoiding the extra reread/fallback path
- add regression coverage for rollback after compaction so turn-context
diffing stays aligned after backtracking

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 19:28:31 -07:00
Ahmed Ibrahim
69c8a1ef9e Fix Windows CI assertions for guardian and Smart Approvals (#14645)
- Normalize guardian assessment path serialization to use forward
slashes for cross-platform stability.
- Seed workspace-write defaults in the Smart Approvals
override-turn-context test so Windows and non-Windows selection flows
are consistent.

---------

Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Charles Cunningham <ccunningham@openai.com>
2026-03-14 02:15:58 +00:00
Eric Traut
4b9d5c8c1b Add openai_base_url config override for built-in provider (#12031)
We regularly get bug reports from users who mistakenly have the
`OPENAI_BASE_URL` environment variable set. This PR deprecates this
environment variable in favor of a top-level config key
`openai_base_url` that is used for the same purpose. By making it a
config key, it will be more visible to users. It will also participate
in all of the infrastructure we've added for layered and managed
configs.

Summary
- introduce the `openai_base_url` top-level config key, update
schema/tests, and route the built-in openai provider through it while
- fall back to deprecated `OPENAI_BASE_URL` env var but warn user of
deprecation when no `openai_base_url` config key is present
- update CLI, SDK, and TUI code to prefer the new config path (with a
deprecated env-var fallback) and document the SDK behavior change
2026-03-13 20:12:25 -06:00
Michael Bolin
b859a98e0f refactor: make unified-exec zsh-fork state explicit (#14633)
## Why

The unified-exec path was carrying zsh-fork state in a partially
flattened way.

First, the decision about whether zsh-fork was active came from feature
selection in `ToolsConfig`, while the real prerequisites lived in
session state. That left the handler and runtime defending against
partially configured cases later.

Second, once zsh-fork was active, its two runtime-only paths were
threaded through the runtime as separate arguments even though they form
one coherent piece of configuration.

This change keeps unified-exec on a single session-derived source of
truth and bundles the zsh-fork-specific paths into a named config type
so the runtime can pass them around as one unit.

In particular, this PR introduces this enum so the `ZshFork` variant can
carry the appropriate state with it:

```rust
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum UnifiedExecShellMode {
    Direct,
    ZshFork(ZshForkConfig),
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ZshForkConfig {
    pub(crate) shell_zsh_path: AbsolutePathBuf,
    pub(crate) main_execve_wrapper_exe: AbsolutePathBuf,
}
```

This cleanup was done in preparation for
https://github.com/openai/codex/pull/13432.

## What Changed

- Replaced the feature-only `UnifiedExecBackendConfig` split with
`UnifiedExecShellMode` in `codex-rs/core/src/tools/spec.rs`.
- Derived the unified-exec mode from session-backed inputs when building
turn `ToolsConfig`, and preserved that mode across model switches and
review turns.
- Introduced `ZshForkConfig`, which stores the resolved zsh-fork
`AbsolutePathBuf` values for the configured `zsh` binary and `execve`
wrapper.
- Threaded `ZshForkConfig` through unified-exec command construction and
the zsh-fork preparation path so zsh-fork-specific runtime code consumes
a single config object instead of separate path arguments.
- Added focused tests for constructing zsh-fork mode only when session
prerequisites are available, and updated the zsh-fork expectations to be
target-platform aware.

## Testing

- `cargo test -p codex-core zsh_fork --lib`


---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/14633).
* #13432
* __->__ #14633
2026-03-13 17:20:01 -07:00
Ahmed Ibrahim
7fa5201365 Use parser-specific realtime voice enum (#14636)
Model realtime session output voices with an enum and map by parser so
v1 uses fathom and v2 uses alloy.

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 16:17:13 -07:00
Ahmed Ibrahim
e9050e3e64 Fix realtime transcription session.update tools payload (#14635)
Only attach session tools for Realtime v2 conversational sessions, and
omit tools in transcription mode so realtime startup no longer fails
with unknown parameter errors.

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 16:08:58 -07:00
Andrei Eternal
9a44a7e499 [hooks] stop continuation & stop_hook_active mechanics (#14532)
Stop hooks now receive `stop_hook_active` and enable stop hooks to loop
forever if they'd like to. In the initial hooks PR, we implemented a
simpler mechanic that the stop-blocking could only happen once in a row

- support stop hook adding a continuation prompt to add a further task
- if multiple stop-blocks happen that have continuation prompts, they
are concatenated

example run:
```
› hey :)


• Running SessionStart hook: lighting the observatory

SessionStart hook (completed)
  warning: Hi, I'm a session start hook for wizard-tower (startup).
  hook context: Startup context: A wimboltine stonpet is an exotic cuisine from hyperspace

• Aloha :) Happy to jam with you. What are we building today?

• Running Stop hook: updating the guards

Stop hook (blocked)
  warning: Wizard Tower Stop hook continuing conversation
  feedback: cook the stonpet

• Aloha, here’s the hyperspace move for cooking a wimboltine stonpet:

  1. Sear the stonpet in a hot pan with moon-oil until the edges shimmer.
  2. Add star-lime, black salt, and a little fermented nebula paste.
  3. Lower the heat and let it braise for 8 cosmic minutes with a splash of comet broth.
  4. Finish with sky herbs and serve over warm asteroid rice.

  The vibe: crispy outside, tender center, deep interdimensional savor.

• Running Stop hook: updating the guards

Stop hook (completed)
  warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
```

.codex/config.toml
```
[features]
codex_hooks = true
```

.codex/hooks.json
```
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/bin/python3 .codex/hooks/session_start_demo.py",
            "timeoutSec": 10,
            "statusMessage": "lighting the observatory"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/usr/bin/python3 .codex/hooks/stop_demo_block.py",
            "timeoutSec": 10,
            "statusMessage": "updating the guards"
          }
        ]
      }
    ]
  }
}
```

.codex/hooks/session_start_demo.py
```
#!/usr/bin/env python3

import json
import sys
from pathlib import Path


def main() -> int:
    payload = json.load(sys.stdin)
    cwd = Path(payload.get("cwd", ".")).name or "wizard-tower"
    source = payload.get("source", "startup")
    source_label = "resume" if source == "resume" else "startup"
    source_prefix = (
        "Resume context:"
        if source == "resume"
        else "Startup context:"
    )

    output = {
        "systemMessage": (
            f"Hi, I'm a session start hook for {cwd} ({source_label})."
        ),
        "hookSpecificOutput": {
            "hookEventName": "SessionStart",
            "additionalContext": (
                f"{source_prefix} A wimboltine stonpet is an exotic cuisine from hyperspace"
            ),
        },
    }
    print(json.dumps(output))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
```

.codex/hooks/stop_demo_block.py
```
#!/usr/bin/env python3

import json
import sys


def main() -> int:
    payload = json.load(sys.stdin)
    stop_hook_active = payload.get("stop_hook_active", False)
    last_assistant_message = payload.get("last_assistant_message") or ""
    char_count = len(last_assistant_message.strip())

    if stop_hook_active:
        system_message = (
            "Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop."
        )
        print(json.dumps({"systemMessage": system_message}))
    else:
        system_message = (
            f"Wizard Tower Stop hook continuing conversation"
        )
        print(json.dumps({"systemMessage": system_message, "decision": "block", "reason": "cook the stonpet"}))

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
```
2026-03-13 15:51:19 -07:00
Charley Cunningham
467e6216bb Fix stale create_wait_tool reference (#14639)
## Summary
- replace the stale `create_wait_tool()` reference in `spec_tests.rs`
- use `create_wait_agent_tool()` to match the actual multi-agent tool
rename from `#14631`
- fix the resulting `codex-core` spec-test compile failure on current
`main`

## Context
`#14631` renamed the model-facing multi-agent tool from `wait` to
`wait_agent` and renamed the corresponding spec helper to
`create_wait_agent_tool()`.

One `spec_tests.rs` call site was left behind, so current `main` fails
to compile `codex-core` tests with:
- `cannot find function create_wait_tool`

Using `create_wait_agent_tool()` is the correct fix here;
`create_exec_wait_tool()` would point at the separate exec wait tool and
would not match the renamed multi-agent toolset.

## Testing
- not rerun locally after the rebase

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:35:25 -07:00
Charley Cunningham
bc24017d64 Add Smart Approvals guardian review across core, app-server, and TUI (#13860)
## Summary
- add `approvals_reviewer = "user" | "guardian_subagent"` as the runtime
control for who reviews approval requests
- route Smart Approvals guardian review through core for command
execution, file changes, managed-network approvals, MCP approvals, and
delegated/subagent approval flows
- expose guardian review in app-server with temporary unstable
`item/autoApprovalReview/{started,completed}` notifications carrying
`targetItemId`, `review`, and `action`
- update the TUI so Smart Approvals can be enabled from `/experimental`,
aligned with the matching `/approvals` mode, and surfaced clearly while
reviews are pending or resolved

## Runtime model
This PR does not introduce a new `approval_policy`.

Instead:
- `approval_policy` still controls when approval is needed
- `approvals_reviewer` controls who reviewable approval requests are
routed to:
  - `user`
  - `guardian_subagent`

`guardian_subagent` is a carefully prompted reviewer subagent that
gathers relevant context and applies a risk-based decision framework
before approving or denying the request.

The `smart_approvals` feature flag is a rollout/UI gate. Core runtime
behavior keys off `approvals_reviewer`.

When Smart Approvals is enabled from the TUI, it also switches the
current `/approvals` settings to the matching Smart Approvals mode so
users immediately see guardian review in the active thread:
- `approval_policy = on-request`
- `approvals_reviewer = guardian_subagent`
- `sandbox_mode = workspace-write`

Users can still change `/approvals` afterward.

Config-load behavior stays intentionally narrow:
- plain `smart_approvals = true` in `config.toml` remains just the
rollout/UI gate and does not auto-set `approvals_reviewer`
- the deprecated `guardian_approval = true` alias migration does
backfill `approvals_reviewer = "guardian_subagent"` in the same scope
when that reviewer is not already configured there, so old configs
preserve their original guardian-enabled behavior

ARC remains a separate safety check. For MCP tool approvals, ARC
escalations now flow into the configured reviewer instead of always
bypassing guardian and forcing manual review.

## Config stability
The runtime reviewer override is stable, but the config-backed
app-server protocol shape is still settling.

- `thread/start`, `thread/resume`, and `turn/start` keep stable
`approvalsReviewer` overrides
- the config-backed `approvals_reviewer` exposure returned via
`config/read` (including profile-level config) is now marked
`[UNSTABLE]` / experimental in the app-server protocol until we are more
confident in that config surface

## App-server surface
This PR intentionally keeps the guardian app-server shape narrow and
temporary.

It adds generic unstable lifecycle notifications:
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`

with payloads of the form:
- `{ threadId, turnId, targetItemId, review, action? }`

`review` is currently:
- `{ status, riskScore?, riskLevel?, rationale? }`
- where `status` is one of `inProgress`, `approved`, `denied`, or
`aborted`

`action` carries the guardian action summary payload from core when
available. This lets clients render temporary standalone pending-review
UI, including parallel reviews, even when the underlying tool item has
not been emitted yet.

These notifications are explicitly documented as `[UNSTABLE]` and
expected to change soon.

This PR does **not** persist guardian review state onto `thread/read`
tool items. The intended follow-up is to attach guardian review state to
the reviewed tool item lifecycle instead, which would improve
consistency with manual approvals and allow thread history / reconnect
flows to replay guardian review state directly.

## TUI behavior
- `/experimental` exposes the rollout gate as `Smart Approvals`
- enabling it in the TUI enables the feature and switches the current
session to the matching Smart Approvals `/approvals` mode
- disabling it in the TUI clears the persisted `approvals_reviewer`
override when appropriate and returns the session to default manual
review when the effective reviewer changes
- `/approvals` still exposes the reviewer choice directly
- the TUI renders:
- pending guardian review state in the live status footer, including
parallel review aggregation
  - resolved approval/denial state in history

## Scope notes
This PR includes the supporting core/runtime work needed to make Smart
Approvals usable end-to-end:
- shell / unified-exec / apply_patch / managed-network / MCP guardian
review
- delegated/subagent approval routing into guardian review
- guardian review risk metadata and action summaries for app-server/TUI
- config/profile/TUI handling for `smart_approvals`, `guardian_approval`
alias migration, and `approvals_reviewer`
- a small internal cleanup of delegated approval forwarding to dedupe
fallback paths and simplify guardian-vs-parent approval waiting (no
intended behavior change)

Out of scope for this PR:
- redesigning the existing manual approval protocol shapes
- persisting guardian review state onto app-server `ThreadItem`s
- delegated MCP elicitation auto-review (the current delegated MCP
guardian shim only covers the legacy `RequestUserInput` path)

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:27:00 -07:00
Charley Cunningham
e3cbf913e8 Fix wait_agent expectations in core tests (#14637)
## Summary
- update stale core tool-spec expectations from `wait` to `wait_agent`
- update the prompt-caching tool-name assertion to match the renamed
tool
- fix the Bazel regressions introduced after #14631 renamed the
multi-agent wait tool

## Testing
- cargo test -p codex-core tools::spec::tests
- cargo test -p codex-core
suite::prompt_caching::prompt_tools_are_consistent_across_requests

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:15:59 -07:00
pakrym-oai
cb7d8f45a1 Normalize MCP tool names to code-mode safe form (#14605)
Code mode doesn't allow `-` in names and it's better if function names
and code-mode names are the same.
2026-03-13 14:50:16 -07:00
Ruslan Nigmatullin
f8f82bfc2b app-server: add v2 filesystem APIs (#14245)
Add a protocol-level filesystem surface to the v2 app-server so Codex
clients can read and write files, inspect directories, and subscribe to
path changes without relying on host-specific helpers.

High-level changes:
- define the new v2 fs/readFile, fs/writeFile, fs/createDirectory,
fs/getMetadata, fs/readDirectory, fs/remove, fs/copy RPCs
- implement the app-server handlers, including absolute-path validation,
base64 file payloads, recursive copy/remove semantics
- document the API, regenerate protocol schemas/types, and add
end-to-end tests for filesystem operations, copy edge cases

Testing plan:
- validate protocol serialization and generated schema output for the
new fs request, response, and notification types
- run app-server integration coverage for file and directory CRUD paths,
metadata/readDirectory responses, copy failure modes, and absolute-path
validation
2026-03-13 14:42:20 -07:00
Ahmed Ibrahim
36dfb84427 Stabilize multi-agent feature flag (#14622)
- make multi_agent stable and enabled by default
- update feature and tool-spec coverage to match the new default

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 14:38:15 -07:00
Ahmed Ibrahim
cfd97b36da Rename multi-agent wait tool to wait_agent (#14631)
- rename the multi-agent tool name the model sees to wait_agent
- update the model-facing prompts and tool descriptions to match

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 14:38:05 -07:00
Won Park
6720caf778 Slash copy osc52 wsl support (#13201)
This PR is a followup to the /copy feature to support WSL and SSH!
2026-03-13 14:00:58 -07:00
pakrym-oai
477a2dd345 Add code_mode_only feature (#14617)
Summary
- add the code_mode_only feature flag/config schema and wire its
dependency on code_mode
- update code mode tool descriptions to list nested tools with detailed
headers
- restrict available tools for prompt and exec descriptions when
code_mode_only is enabled and test the behavior

Testing
- Not run (not requested)
2026-03-13 13:30:19 -07:00
Michael Bolin
ef37d313c6 fix: preserve zsh-fork escalation fds across unified-exec spawn paths (#13644)
## Why

`zsh-fork` sessions launched through unified-exec need the escalation
socket to survive the wrapper -> server -> child handoff so later
intercepted `exec()` calls can still reach the escalation server.

The inherited-fd spawn path also needs to avoid closing Rust's internal
exec-error pipe, and the shell-escalation handoff needs to tolerate the
receive-side case where a transferred fd is installed into the same
stdio slot it will be mapped onto.

## What Changed

- Added `SpawnLifecycle::inherited_fds()` in
`codex-rs/core/src/unified_exec/process.rs` and threaded inherited fds
through `codex-rs/core/src/unified_exec/process_manager.rs` so
unified-exec can preserve required descriptors across both PTY and
no-stdin pipe spawn paths.
- Updated `codex-rs/core/src/tools/runtimes/shell/zsh_fork_backend.rs`
to expose the escalation socket fd through the spawn lifecycle.
- Added inherited-fd-aware spawn helpers in
`codex-rs/utils/pty/src/pty.rs` and `codex-rs/utils/pty/src/pipe.rs`,
including Unix pre-exec fd pruning that preserves requested inherited
fds while leaving `FD_CLOEXEC` descriptors alone. The pruning helper is
now named `close_inherited_fds_except()` to better describe that
behavior.
- Updated `codex-rs/shell-escalation/src/unix/escalate_client.rs` to
duplicate local stdio before transfer and send destination stdio numbers
in `SuperExecMessage`, so the wrapper keeps using its own
`stdin`/`stdout`/`stderr` until the escalated child takes over.
- Updated `codex-rs/shell-escalation/src/unix/escalate_server.rs` so the
server accepts the overlap case where a received fd reuses the same
stdio descriptor number that the child setup will target with `dup2`.
- Added comments around the PTY stdio wiring and the overlap regression
helper to make the fd handoff and controlling-terminal setup easier to
follow.

## Verification

- `cargo test -p codex-utils-pty`
- covers preserved-fd PTY spawn behavior, PTY resize, Python REPL
continuity, exec-failure reporting, and the no-stdin pipe path
- `cargo test -p codex-shell-escalation`
- covers duplicated-fd transfer on the client side and verifies the
overlap case by passing a pipe-backed stdin payload through the
server-side `dup2` path

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/13644).
* #14624
* __->__ #13644
2026-03-13 20:25:31 +00:00
Owen Lin
014e19510d feat(app-server, core): add more spans (#14479)
## Description

This PR expands tracing coverage across app-server thread startup, core
session initialization, and the Responses transport layer. It also gives
core dispatch spans stable operation-specific names so traces are easier
to follow than the old generic `submission_dispatch` spans.

Also use `fmt::Display` for types that we serialize in traces so we send
strings instead of rust types
2026-03-13 13:16:33 -07:00
canvrno-oai
914f7c7317 Override local apps settings with requirements.toml settings (#14304)
This PR changes app and connector enablement when `requirements.toml` is
present locally or via remote configuration.

For apps.* entries:
- `enabled = false` in `requirements.toml` overrides the user’s local
`config.toml` and forces the app to be disabled.
- `enabled = true` in `requirements.toml` does not re-enable an app the
user has disabled in config.toml.

This behavior applies whether or not the user has an explicit entry for
that app in `config.toml`. It also applies to cloud-managed policies and
configurations when the admin sets the override through
`requirements.toml`.

Scenarios tested and verified:
- Remote managed, user config (present) override
- Admin-defined policies & configurations include a connector override:
  `[apps.<appID>]
enabled = false`
- User's config.toml has the same connector configured with `enabled =
true`
  - TUI/App should show connector as disabled
  - Connector should be unavailable for use in the composer
  
- Remote managed, user config (absent) override
- Admin-defined policies & configurations include a connector override:
  `[apps.<appID>]
enabled = false`
  - User's config.toml has no entry for the the same connector
  - TUI/App should show connector as disabled
  - Connector should be unavailable for use in the composer
  
- Locally managed, user config (present) override
  - Local requirements.toml includes a connector override:
  `[apps.<appID>]
enabled = false`
- User's config.toml has the same connector configured with `enabled =
true`
  - TUI/App should show connector as disabled
  - Connector should be unavailable for use in the composer

- Locally managed, user config (absent) override
  - Local requirements.toml includes a connector override:
  `[apps.<appID>]
enabled = false`
  - User's config.toml has no entry for the the same connector
  - TUI/App should show connector as disabled
  - Connector should be unavailable for use in the composer




<img width="1446" height="753" alt="image"
src="https://github.com/user-attachments/assets/61c714ca-dcca-4952-8ad2-0afc16ff3835"
/>
<img width="595" height="233" alt="image"
src="https://github.com/user-attachments/assets/7c8ab147-8fd7-429a-89fb-591c21c15621"
/>
2026-03-13 12:40:24 -07:00
Ahmed Ibrahim
d58620c852 Use subagents naming in the TUI (#14618)
- rename user-facing TUI multi-agent wording to subagents
- rename the surfaced slash command to `subagents` and update
tests/snapshots

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 19:08:38 +00:00
Ruslan Nigmatullin
50558e6507 app-server: Add platform os and family to init response (#14527)
This allows the client to pick os-specific behavior while interacting
with the app server, e.g. to use proper path separators.
2026-03-13 19:07:54 +00:00
Ahmed Ibrahim
3aabce9e0a Unify realtime v1/v2 session config (#14606)
## Summary
- unify realtime websocket settings under `[realtime]` (`version` and
`type`)
- remove `realtime_conversation_v2` and select parser/session mode from
config

## Testing
- not run (per request)

---------

Co-authored-by: Codex <noreply@openai.com>
2026-03-13 11:35:38 -07:00
Eric Traut
9dba7337f2 Start TUI on embedded app server (#14512)
This PR is part of the effort to move the TUI on top of the app server.
In a previous PR, we introduced an in-process app server and moved
`exec` on top of it.

For the TUI, we want to do the migration in stages. The app server
doesn't currently expose all of the functionality required by the TUI,
so we're going to need to support a hybrid approach as we make the
transition.

This PR changes the TUI initialization to instantiate an in-process app
server and access its `AuthManager` and `ThreadManager` rather than
constructing its own copies. It also adds a placeholder TUI event
handler that will eventually translate app server events into TUI
events. App server notifications are accepted but ignored for now. It
also adds proper shutdown of the app server when the TUI terminates.
2026-03-13 12:04:41 -06:00
zbarsky-openai
8567e3a5c7 [bazel] Bump up cc and rust toolchains (#14542)
This lets us drop various patches and go all the way to a very clean
setup.

In case folks are curious what was going on... we were depending on the
toolchain finding stdlib headers as sibling files of `clang++`, and for
linking we were providing a `-resource-dir` containing the runtime libs.
However, some users of the cc toolchain (such as rust build scripts) do
the equivalent of `$CC $CCFLAGS $LDFLAGS` so the `-resource-dir` was
being passed when compiling, which suppressed the default stdlib header
location logic. The upstream fix was to swap to using `-isystem` to pass
the stdlib headers, while carefully controlling the ordering to simulate
them coming from the resource-dir.
2026-03-13 18:01:38 +00:00
sayan-oai
9f2da5a9ce chore: clarify plugin + app copy in model instructions (#14541)
- clarify app mentions are in user messages
- clarify what it means for tools to be provided via `codex_apps` MCP
- add plugin descriptions (with basic sanitization) to top-level `##
Plugins` section alongside the corresponding plugin names
- explain that skills from plugins are prefixed with `plugin_name:` in
top-level `##Plugins` section

changes to more logically organize `Apps`, `Skills`, and `Plugins`
instructions will be in a separate PR, as that shuffles dev + user
instructions in ways that change tests broadly.

### Tests
confirmed in local rollout, some new tests.
2026-03-13 10:57:41 -07:00
Jack Mousseau
59b588b8ec Improve granular approval policy prompt (#14553) 2026-03-13 10:42:17 -07:00
Won Park
958f93f899 sending back imagaegencall response back to responseapi (#14558)
Sending back the ResponseItem::ImageGenerationCall as is, because it is
now supported from the API-side.
2026-03-13 17:29:19 +00:00
iceweasel-oai
6b3d82daca Use a private desktop for Windows sandbox instead of Winsta0\Default (#14400)
## Summary
- launch Windows sandboxed children on a private desktop instead of
`Winsta0\Default`
- make private desktop the default while keeping
`windows.sandbox_private_desktop=false` as the escape hatch
- centralize process launch through the shared
`create_process_as_user(...)` path
- scope the private desktop ACL to the launching logon SID

## Why
Today sandboxed Windows commands run on the visible shared desktop. That
leaves an avoidable same-desktop attack surface for window interaction,
spoofing, and related UI/input issues. This change moves sandboxed
commands onto a dedicated per-launch desktop by default so the sandbox
no longer shares `Winsta0\Default` with the user session.

The implementation stays conservative on security with no silent
fallback back to `Winsta0\Default`

If private-desktop setup fails on a machine, users can still opt out
explicitly with `windows.sandbox_private_desktop=false`.

## Validation
- `cargo build -p codex-cli`
- elevated-path `codex exec` desktop-name probe returned
`CodexSandboxDesktop-*`
- elevated-path `codex exec` smoke sweep for shell commands, nested
`pwsh`, jobs, and hidden `notepad` launch
- unelevated-path full private-desktop compatibility sweep via `codex
exec` with `-c windows.sandbox=unelevated`
2026-03-13 10:13:39 -07:00