Commit Graph

15122 Commits

Author SHA1 Message Date
Michael Bolin
2afc43a17d Merge ebddba6119 into sapling-pr-archive-bolinfest 2026-05-08 17:36:16 -07:00
Michael Bolin
ebddba6119 tests: cover sandbox link write behavior 2026-05-08 17:36:05 -07:00
Michael Bolin
23fdcd9e3f Merge 2f237af389 into sapling-pr-archive-bolinfest 2026-05-08 17:19:35 -07:00
Michael Bolin
d171cae8bd merge commit for archive created by Sapling 2026-05-08 17:19:16 -07:00
Michael Bolin
2f237af389 tests: characterize macOS sandbox link writes 2026-05-08 17:19:00 -07:00
Michael Bolin
a38c8474f3 tests: cover sandbox link write behavior 2026-05-08 17:19:00 -07:00
Michael Bolin
ef87897c5c Merge 5ee77cb024 into sapling-pr-archive-bolinfest 2026-05-08 17:13:47 -07:00
Michael Bolin
762d077472 merge commit for archive created by Sapling 2026-05-08 17:13:29 -07:00
Michael Bolin
5ee77cb024 tests: characterize macOS sandbox link writes 2026-05-08 17:13:22 -07:00
Michael Bolin
b50e4f8225 tests: cover sandbox link write behavior 2026-05-08 17:13:22 -07:00
Michael Bolin
2cc24cb6c2 merge commit for archive created by Sapling 2026-05-08 17:07:18 -07:00
Michael Bolin
e798cf3e40 tests: characterize macOS sandbox link writes 2026-05-08 17:06:58 -07:00
Michael Bolin
953e2ae5a6 Merge 5b07ee6141 into sapling-pr-archive-bolinfest 2026-05-08 17:04:06 -07:00
Michael Bolin
5b07ee6141 tests: cover sandbox link write behavior 2026-05-08 17:03:33 -07:00
Michael Bolin
626a07b5a0 Merge 8874edd5b3 into sapling-pr-archive-bolinfest 2026-05-08 16:15:29 -07:00
Michael Bolin
8874edd5b3 tests: demonstrate macos hard-link sandbox escape 2026-05-08 16:15:11 -07:00
Michael Bolin
024a36c118 merge commit for archive created by Sapling 2026-05-08 14:51:59 -07:00
Michael Bolin
da5505c670 Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 14:51:41 -07:00
Michael Bolin
fdc31c7e15 Merge 998a82daf0 into sapling-pr-archive-bolinfest 2026-05-08 14:51:29 -07:00
Michael Bolin
998a82daf0 ci: check out PR head commits in workflows 2026-05-08 14:51:15 -07:00
Michael Bolin
da5889957c Merge b6dc57e035 into sapling-pr-archive-bolinfest 2026-05-08 14:45:28 -07:00
Michael Bolin
b6dc57e035 apply-patch: avoid sandbox link write-through 2026-05-08 14:41:27 -07:00
Michael Bolin
c56590d0a9 merge commit for archive created by Sapling 2026-05-08 14:40:43 -07:00
Michael Bolin
7402d29902 apply-patch: avoid sandbox link write-through 2026-05-08 14:40:24 -07:00
Michael Bolin
c8910c8233 merge commit for archive created by Sapling 2026-05-08 14:28:40 -07:00
Michael Bolin
3ebbcbca31 apply-patch: avoid sandbox link write-through 2026-05-08 14:28:19 -07:00
Michael Bolin
7a7756ce40 Merge 63d0cc87d3 into sapling-pr-archive-bolinfest 2026-05-08 14:27:56 -07:00
Michael Bolin
63d0cc87d3 Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 14:27:42 -07:00
Michael Bolin
67f7f4bad9 Merge 841a91d42d into sapling-pr-archive-bolinfest 2026-05-08 14:21:49 -07:00
Michael Bolin
841a91d42d apply-patch: avoid sandbox link write-through 2026-05-08 14:21:31 -07:00
Matthew Zeng
2f3a2d7a86 Using cached connector directory for discoverable tools list (#21497)
## Summary

Startup tool construction currently depends on connector directory
metadata for `tool_suggest` discoverables. On a cold directory cache,
that can put slow connector-directory requests on the blocking path even
though the tools array only needs directory data for install
suggestions, not for the live connector MCP tools themselves.

This PR keeps the discoverables path off that cold network fetch:
- read connector directory metadata from cache only when building
discoverable tools
- persist connector directory metadata to
`~/.codex/cache/codex_app_directory/<hash>.json` and use it to hydrate
the in-memory cache on later runs before the normal refresh path updates
it
- use connector-directory-specific cache naming to distinguish this
metadata cache from the separate Codex Apps tools-spec cache

This reduces first-turn startup work without changing how live connector
MCP tools are sourced. Longer term, directory-backed install suggestions
should move to a search-based flow so they no longer need to be inlined
into the tools prompt at all.

## Testing

- `cargo test -p codex-connectors`
- `cargo test -p codex-chatgpt`
- `cargo test -p codex-core
request_plugin_install_is_available_without_search_tool_after_discovery_attempts`
- `cargo test -p codex-core
tool_suggest_uses_connector_id_fallback_when_directory_cache_is_empty`
2026-05-08 14:14:11 -07:00
Michael Bolin
36b7954abe Merge ecb02fdc53 into sapling-pr-archive-bolinfest 2026-05-08 14:05:18 -07:00
Michael Bolin
ecb02fdc53 Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 14:05:11 -07:00
Michael Bolin
b3aba87592 Merge 950d4add9f into sapling-pr-archive-bolinfest 2026-05-08 13:51:28 -07:00
Michael Bolin
950d4add9f Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 13:51:19 -07:00
Michael Bolin
e43a0df84e merge commit for archive created by Sapling 2026-05-08 13:47:46 -07:00
Michael Bolin
f7df27bd44 Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 13:44:26 -07:00
Charlie Marsh
7c9731c9af Enable --deny-warnings for cargo shear (#21616)
## Summary

In https://github.com/openai/codex/pull/21584, we disabled doctests for
crates that lack any doctests. We can enforce that property via `cargo
shear --deny-warnings`: crates that lack doctests will be flagged if
doctests are enabled, and crates with doctests will be flagged if
doctests are disabled.

A few additional notes:

- By adding `--deny-warnings`, `cargo shear` also flagged a number of
modules that were not reachable at all. Some of those have been removed.
- This PR removes a usage of `windows_modules!` (since `cargo shear` and
`rustfmt` couldn't see through it) in favor of simple `#[cfg(target_os =
"windows")]` macros. As a consequence, many of these files exhibit churn
in this PR, since they weren't being formatted by `rustfmt` at all on
main.
- Again, to make the code more analyzable, this PR also removes some
usages of `#[path = "cwd_junction.rs"]` in favor of a more standard
module structure. The bin sidecar structure is still retained, but,
e.g., `windows-sandbox-rs/src/bin/command_runner.rs‎` was moved to
`windows-sandbox-rs/src/bin/command_runner/main.rs`, and so on.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-05-08 20:29:00 +00:00
Michael Bolin
24389ee21d Merge 3f811565a3 into sapling-pr-archive-bolinfest 2026-05-08 13:27:47 -07:00
Michael Bolin
3f811565a3 apply-patch: reject sandbox hard-link writes 2026-05-08 13:27:27 -07:00
pakrym-oai
46e2250bcf [codex] Remove legacy after tool use hooks (#21805)
## Why

The legacy `AfterToolUse` hook path was still wired through core tool
dispatch even though the hooks registry never populated any handlers for
it. The supported hook surface is `PostToolUse`, so the old
infrastructure was dead code on the hot path.

## What changed

- Removed the legacy `AfterToolUse` dispatch from `codex-core` tool
execution.
- Removed the unused legacy hook payload types and exports from
`codex-hooks`.
- Simplified legacy notify handling now that `HookEvent` only carries
`AfterAgent`.

## Validation

- `cargo test -p codex-hooks`
- `cargo test -p codex-core registry`
2026-05-08 13:20:05 -07:00
pakrym-oai
e783341b70 [codex] Delete function-style apply_patch (#21651)
## Why

`apply_patch` is now a freeform/custom tool. Keeping the old
JSON/function-style registration and parsing path left another way for
models and tests to invoke `apply_patch`, which made the tool surface
harder to reason about.

## What changed

- Removed the `ApplyPatchToolType::Function` variant, JSON `apply_patch`
spec, and handler support for function payloads.
- Kept `apply_patch_tool_type = freeform` as the supported model
metadata path, including Bedrock catalog metadata.
- Migrated `apply_patch` tests and SSE fixtures to custom/freeform tool
calls.

## Verification

- `cargo test -p codex-tools -p codex-protocol -p codex-model-provider`
- `cargo test -p codex-core tools::handlers::apply_patch --lib`
- `cargo test -p codex-core --test all
apply_patch_tool_executes_and_emits_patch_events`
- `cargo test -p codex-core --test all
apply_patch_reports_parse_diagnostics`
- `cargo test -p codex-exec test_apply_patch_tool`
- `just fix -p codex-core`
- `just fix -p codex-tools -p codex-protocol -p codex-model-provider -p
codex-exec`
2026-05-08 13:00:57 -07:00
Ahmed Ibrahim
cf941ede15 Revert "Publish Python runtime wheels on release" (#21810)
Reverts openai/codex#21784
2026-05-08 22:37:10 +03:00
Jiaming Zhang
5f4d0ec343 [codex] request desktop attestation from app (#20619)
## Summary

TL;DR: teaches `codex-rs` / app-server to request a desktop-provided
attestation token and attach it as `x-oai-attestation` on the scoped
ChatGPT Codex request paths.

![DeviceCheck attestation
interface](https://raw.githubusercontent.com/openai/codex/dev/jm/devicecheck-diagram-assets/pr-assets/devicecheck-attestation-interface.png)

## Details

This PR teaches the Codex app-server runtime how to request and attach
an attestation token. It does not generate DeviceCheck tokens directly;
instead, it relies on the connected desktop app to advertise that it can
generate attestation and then asks that app for a fresh header value
when needed.

The flow is:

1. The Codex desktop app connects to app-server.
2. During `initialize`, the app can advertise that it supports
`requestAttestation`.
3. Before app-server calls selected ChatGPT Codex endpoints, it sends
the internal server request `attestation/generate` to the app.
4. app-server receives a pre-encoded header value back.
5. app-server forwards that value as `x-oai-attestation` on the scoped
outbound requests.

The code in this repo is mostly protocol and runtime plumbing: it adds
the app-server request/response shape, introduces an attestation
provider in core, wires that provider into Responses / compaction /
realtime setup paths, and covers the intended scoping with tests. The
signed macOS DeviceCheck generation remains owned by the desktop app PR.

## Related PR

- Codex desktop app implementation:
https://github.com/openai/openai/pull/878649

## Validation

<details>
<summary>Tests run</summary>

```sh
cargo test -p codex-app-server-protocol
cargo test -p codex-core attestation --lib
cargo test -p codex-app-server --lib attestation
```

Also ran:

```sh
just fix -p codex-core
just fix -p codex-app-server
just fix -p codex-app-server-protocol
just fmt
just write-app-server-schema
```

</details>

<details>
<summary>E2E DeviceCheck validation</summary>

First validated the signed desktop app boundary directly: launched a
packaged signed `Codex.app`, sent `attestation/generate`, decoded the
returned `v1.` attestation header, and validated the extracted
DeviceCheck token with `personal/jm/verify_devicecheck_token.py` using
bundle ID `com.openai.codex`. Apple returned `status_code: 200` and
`is_ok: true`.

Then ran the fuller app + app-server flow. The packaged `Codex.app`
launched a current-branch app-server via `CODEX_CLI_PATH`, and a local
MITM proxy intercepted outbound `chatgpt.com` traffic. The app-server
requested `attestation/generate` from the real Electron app process, and
the intercepted `/backend-api/codex/responses` traffic included
`x-oai-attestation` on both routes:

```text
GET  /backend-api/codex/responses  Upgrade: websocket  x-oai-attestation: present
POST /backend-api/codex/responses  Upgrade: none       x-oai-attestation: present
```

The captured header decoded to a DeviceCheck token that also validated
with Apple for `com.openai.codex` (`status_code: 200`, `is_ok: true`,
team `2DC432GLL2`).

</details>

---------

Co-authored-by: Codex <noreply@openai.com>
2026-05-08 12:36:02 -07:00
Michael Bolin
a32e80ac17 Merge c816a90aa5 into sapling-pr-archive-bolinfest 2026-05-08 12:20:03 -07:00
Michael Bolin
c816a90aa5 Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 12:19:57 -07:00
pakrym-oai
61142b6169 Remove ToolName display helper (#21465)
## Why

`ToolName::display()` made it too easy to flatten tool identity and
accidentally compare rendered strings. Tool identity should stay
structural until a legacy string boundary actually requires the
flattened spelling.

## What

- Removes `ToolName::display()` and relies on the existing `Display`
impl for messages and errors.
- Adds structural ordering for `ToolName` and uses it for
sorting/deduping deferred tools.
- Carries `ToolName` through tool/sandbox plumbing, flattening only at
legacy boundaries such as hook payloads, telemetry tags, and Responses
tool names.
- Updates MCP normalization tests to assert `ToolName` structure instead
of rendered strings.

## Testing

- `cargo test -p codex-mcp test_normalize_tools`
- `cargo test -p codex-core unavailable_tool`
- `just fix -p codex-protocol`
- `just fix -p codex-mcp`
- `just fix -p codex-core`
2026-05-08 12:17:48 -07:00
alexsong-oai
bbb6bf0a37 Emit accepted line fingerprint analytics (#21601)
## Why

Codex assisted-code attribution needs a client-side accepted-code source
that does not upload raw code. This adds a hash-only analytics event
derived from the turn diff so downstream attribution can compare
accepted Codex lines against commit or PR diffs.

## What Changed

- Parse accepted/effective added lines from the final turn diff and emit
`codex_accepted_line_fingerprints` analytics.
- Hash repo, path, and normalized line content before upload; raw code
and raw diffs are not included in the event.
- Chunk large fingerprint payloads and send accepted-line fingerprint
events in isolated requests while preserving normal batching for other
analytics events.
- Canonicalize Git remote URLs before repo hashing so SSH/HTTPS GitHub
remotes join to the same repo hash.
- Add parser coverage for unified diff hunk lines that look like `+++`
or `---` file headers.

## Verification

- `cargo test -p codex-analytics`
- `cargo test -p codex-git-utils canonicalize_git_remote_url`
- `just fix -p codex-analytics`
- `just bazel-lock-check`
- `git diff --check`
2026-05-08 12:16:24 -07:00
Michael Bolin
18bf41c8fc Merge ab151d008d into sapling-pr-archive-bolinfest 2026-05-08 12:13:21 -07:00
Michael Bolin
ab151d008d Move workspace roots onto thread/session state and stop using active 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. 2026-05-08 12:13:14 -07:00