Commit Graph
11705 Commits
Author SHA1 Message Date
Michael Bolin 9ffe550c20 Merge d6e24719ca into sapling-pr-archive-bolinfest 2026-04-17 10:52:13 -07:00
Michael Bolin d6e24719ca tests: isolate approval fixtures from host rules 2026-04-17 10:51:06 -07:00
Michael Bolin 752c140077 shell-escalation: carry resolved permission profiles 2026-04-17 10:51:06 -07:00
Michael Bolin 732d6ff614 mcp: include permission profiles in sandbox state 2026-04-17 10:51:05 -07:00
Michael Bolin 68a1513d4c tui: carry permission profiles on user turns 2026-04-17 10:51:05 -07:00
Michael Bolin 610ccd16d0 tui: sync session permission profiles 2026-04-17 10:51:05 -07:00
Michael Bolin 57c5742548 app-server: accept command permission profiles 2026-04-17 10:51:04 -07:00
Michael Bolin fb79f87bac protocol: report session permission profiles 2026-04-17 10:51:04 -07:00
Michael Bolin e2aa60f068 rollout: persist turn permission profiles 2026-04-17 10:49:24 -07:00
Michael Bolin 0164ac62c0 clients: send permission profiles to app-server 2026-04-17 10:49:24 -07:00
Michael Bolin 78e68a1290 app-server: accept permission profile overrides 2026-04-17 10:49:23 -07:00
Michael Bolin d8c4ebdcda app-server: expose thread permission profiles 2026-04-17 10:49:23 -07:00
Michael Bolin 732143ef38 core: derive active permission profiles 2026-04-17 10:49:22 -07:00
Michael Bolin b2781adbc4 exec-server: carry filesystem sandbox profiles 2026-04-17 10:48:55 -07:00
Michael Bolin bf132de734 sandboxing: intersect permission profiles semantically 2026-04-17 10:47:50 -07:00
Michael Bolin 18fc17aeab protocol: canonicalize file system permissions 2026-04-17 10:47:50 -07:00
Michael Bolin e9818a7b52 merge commit for archive created by Sapling 2026-04-17 10:43:21 -07:00
Michael Bolin 884349690f fix: remove unused imports that got past CI 2026-04-17 10:43:09 -07:00
Tom fad3d0f1d0 codex: route thread/read persistence through thread store (#18352)
Summary
- replace the thread/read persisted-load helper with
ThreadStore::read_thread
- move SQLite/rollout summary, name, fork metadata, and history loading
for persisted reads into LocalThreadStore
- leave getConversationSummary unchanged for a later PR

Context
- Replaces closed stacked PR #18232 after PR #18231 merged and its base
branch was deleted.
2026-04-17 10:31:30 -07:00
Felipe Coury d3692b14c9 feat(tui): add clear-context plan implementation (#17499)
## TL;DR

- Adds a second Plan Mode handoff: implement the approved plan after
clearing context.
- Keeps the existing same-thread `Yes, implement this plan` action
unchanged.
- Reuses the `/clear` thread-start path and submits the approved plan as
the fresh thread's first prompt.
- Covers the new popup option, event plumbing, initial-message behavior,
and disabled states in TUI tests.

## Problem

Plan Mode already asks whether to implement an approved plan, but the
only affirmative path continues in the same thread. That is useful when
the planning conversation itself is still valuable, but it does not
support the workflow where exploratory planning context is discarded and
implementation starts from the final approved plan as the only
model-visible handoff.

<img width="1253" height="869" alt="image"
src="https://github.com/user-attachments/assets/90023d75-c330-4919-bed8-518671c3474b"
/>

## Mental model

There are now two implementation choices after a proposed plan. The
existing choice, `Yes, implement this plan`, is unchanged: it switches
to Default mode and submits `Implement the plan.` in the current thread.
The new choice, `Yes, clear context and implement`, treats the proposed
plan as a handoff artifact. It clears the UI/session context through the
same thread-start source used by `/clear`, then submits an initial
prompt containing the approved plan after the fresh thread is
configured.

The important distinction is that the new path is not compaction. The
model receives a deliberate implementation prompt built from the
approved plan markdown, not a summary of the previous planning
transcript. Both implementation choices require the Default
collaboration preset to be available, so the popup does not offer a
coding handoff when the fresh thread would fall back to another mode.

## Non-goals

This change does not alter `/clear`, `/compact`, or the existing
same-context Plan Mode implementation option. It does not add protocol
surface area or app-server schema changes. It also does not carry the
previous transcript path or a generated planning summary into the new
model context.

## Tradeoffs

The fresh-context option relies on the approved plan being sufficiently
complete. That matches the Plan Mode contract, but it means vague plans
will produce weaker implementation starts than a compacted transcript
would. The upside is that rejected ideas, exploratory dead ends, and
planning corrections do not leak into the implementation turn.

The current implementation stores the latest proposed plan in
`ChatWidget` rather than deriving it from history cells at selection
time. This keeps the popup action simple and deterministic, but it makes
the cache lifecycle important: it must be reset when a new task starts
so an old plan cannot be submitted later.

## Architecture

The TUI stores the most recent completed proposed-plan markdown when a
plan item completes. The Plan Mode approval popup uses that cache to
enable the fresh-context option and to build a first-turn prompt that
instructs the model to implement the approved plan in a fresh context.

Selecting the new option emits a TUI-internal
`ClearUiAndSubmitUserMessage` event. `App` handles that event by reusing
the existing clear flow: clear terminal state, reset app UI state, start
a new app-server thread with `ThreadStartSource::Clear`, and attach a
replacement `ChatWidget` with an initial user message. The existing
initial-message suppression in `enqueue_primary_thread_session` ensures
the prompt is submitted only after the new session is configured and any
startup replay is rendered.

## Observability

The previous thread remains resumable through the existing clear-session
summary hint. There is no new telemetry or protocol event for this path,
so debugging should start at the TUI event boundary: confirm the popup
emitted `ClearUiAndSubmitUserMessage`, confirm the app-server thread
start used `ThreadStartSource::Clear`, then confirm the fresh widget
submitted the initial user message after `SessionConfigured`.

## Tests

The Plan Mode popup snapshots cover the new option and preserve the
original option as the first/default action. Unit coverage verifies the
original same-context option still emits `SubmitUserMessageWithMode`,
the new option emits `ClearUiAndSubmitUserMessage` with the approved
plan embedded verbatim, and the clear-context option is disabled when
Default mode is unavailable or no approved plan exists. The broader
`codex-tui` test package passes with the updated fresh-thread
initial-message plumbing.
2026-04-17 14:30:09 -03:00
colby-oai ea84537369 Make app tool hint defaults pessimistic for app policies (#17232)
## Summary
- default missing app tool destructive/open-world hints to true for app
policies
- add regression tests for missing MCP annotations under restrictive app
config
2026-04-17 13:27:49 -04:00
jif-oai cfc23eee3d feat: config aliases (#18140)
Rename `no_memories_if_mcp_or_web_search` →
`disable_on_external_context` with backward compatibility

While doing so, we add a key alias system on our layer merging system.
What we try to avoid is a case where a company managed config use an old
name while the user has a new name in it's local config (which would
make the deserialization fail)
2026-04-17 18:26:09 +01:00
Michael Bolin 523be6ae33 merge commit for archive created by Sapling 2026-04-17 10:20:50 -07:00
Michael Bolin 116a7f8112 fix: remove unused imports that got past CI 2026-04-17 10:20:38 -07:00
Michael Bolin 2c3f574d58 merge commit for archive created by Sapling 2026-04-17 10:08:12 -07:00
Michael Bolin 7f6b8d83fc tests: isolate approval fixtures from host rules 2026-04-17 10:07:49 -07:00
Michael Bolin 37139694a7 shell-escalation: carry resolved permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin b9c66f7e39 mcp: include permission profiles in sandbox state 2026-04-17 10:07:49 -07:00
Michael Bolin 9e5832b1e6 tui: carry permission profiles on user turns 2026-04-17 10:07:49 -07:00
Michael Bolin ffac8a64f6 tui: sync session permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin d4e0e5d619 app-server: accept command permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin 41ebc4d85a protocol: report session permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin 702cfbd778 rollout: persist turn permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin c69a1d8163 clients: send permission profiles to app-server 2026-04-17 10:07:49 -07:00
Michael Bolin f1bf9089df app-server: accept permission profile overrides 2026-04-17 10:07:49 -07:00
Michael Bolin 25420fc5ee app-server: expose thread permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin 98c469c0a7 core: derive active permission profiles 2026-04-17 10:07:49 -07:00
Michael Bolin 9c660d21cb exec-server: carry filesystem sandbox profiles 2026-04-17 10:07:49 -07:00
Michael Bolin 17f71a2e37 sandboxing: intersect permission profiles semantically 2026-04-17 10:07:49 -07:00
Michael Bolin d7e7f53234 protocol: canonicalize file system permissions 2026-04-17 10:07:49 -07:00
Won Park af7b8d551c Guardian -> Auto-Review (#18021)
This PR is a user-facing change for our rebranding of guardian to
auto-review.
2026-04-17 09:56:24 -07:00
Michael Bolin da79a2011f Merge 3be462a6dd into sapling-pr-archive-bolinfest 2026-04-17 09:27:52 -07:00
Michael Bolin 3be462a6dd fix: remove unused imports that got past CI 2026-04-17 09:27:45 -07:00
Michael Bolin d0eff70383 Fix config-loader tests after filesystem abstraction race (#18351)
## Why

`origin/main` picked up two changes that crossed in flight:

- #18209 refactored config loading to read through `ExecutorFileSystem`,
changing `load_requirements_toml` to take a filesystem handle and an
`AbsolutePathBuf`.
- #17740 added managed `deny_read` requirements tests that still called
`load_requirements_toml` with the previous two-argument signature.

Once both landed, `just clippy` failed because the new tests no longer
matched the current helper API.

## What

- Updates the two managed `deny_read` requirements tests to convert the
fixture path to `AbsolutePathBuf` before loading.
- Passes `LOCAL_FS.as_ref()` into `load_requirements_toml` so these
tests follow the filesystem abstraction introduced by #18209.

## Verification

- `just clippy`
- `cargo test -p codex-core load_requirements_toml_resolves_deny_read`
- `cargo test -p codex-core --test all
unified_exec_enforces_glob_deny_read_policy`
2026-04-17 09:20:39 -07:00
pakrym-oai 71e4c6fa17 Move codex module under session (#18249)
## Summary
- rename the core codex module root to session/mod.rs without using
#[path]
- move the codex module directory and tests under core/src/session
- remove session/mod.rs reexports so call sites use explicit child
module paths

## Testing
- cargo test -p codex-core --lib
- cargo check -p codex-core --tests
- just fmt
- just fix -p codex-core
- git diff --check
2026-04-17 16:18:53 +00:00
Michael Bolin 44b233968d Merge e9052bce30 into sapling-pr-archive-bolinfest 2026-04-17 09:05:27 -07:00
Michael Bolin e9052bce30 fix build breakage resulting from merge race 2026-04-17 09:05:20 -07:00
Michael Bolin 48d30e7e74 merge commit for archive created by Sapling 2026-04-17 08:50:01 -07:00
Michael Bolin 67a4a63a82 fix: remove unused imports that got past CI 2026-04-17 08:49:47 -07:00
viyatb-oaiandCodex dae0608c06 feat(config): support managed deny-read requirements (#17740)
## Summary
- adds managed requirements support for deny-read filesystem entries
- constrains config layers so managed deny-read requirements cannot be
widened by user-controlled config
- surfaces managed deny-read requirements through debug/config plumbing

This PR lets managed requirements inject deny-read filesystem
constraints into the effective filesystem sandbox policy.
User-controlled config can still choose the surrounding permission
profile, but it cannot remove or weaken the managed deny-read entries.

## Managed deny-read shape
A managed requirements file can declare exact paths and glob patterns
under `[permissions.filesystem]`:

```toml
# /etc/codex/requirements.toml
[permissions.filesystem]
deny_read = [
  "/Users/alice/.gitconfig",
  "/Users/alice/.ssh",
  "./managed-private/**/*.env",
]
```

Those entries are compiled into the effective filesystem policy as
`access = none` rules, equivalent in shape to filesystem permission
entries like:

```toml
[permissions.workspace.filesystem]
"/Users/alice/.gitconfig" = "none"
"/Users/alice/.ssh" = "none"
"/absolute/path/to/managed-private/**/*.env" = "none"
```

The important difference is that the managed entries come from
requirements, so lower-precedence user config cannot remove them or make
those paths readable again.

Relative managed `deny_read` entries are resolved relative to the
directory containing the managed requirements file. Glob entries keep
their glob suffix after the non-glob prefix is normalized.

## Runtime behavior
- Managed `deny_read` entries are appended to the effective
`FileSystemSandboxPolicy` after the selected permission profile is
resolved.
- Exact paths become `FileSystemPath::Path { access: None }`; glob
patterns become `FileSystemPath::GlobPattern { access: None }`.
- When managed deny-read entries are present, `sandbox_mode` is
constrained to `read-only` or `workspace-write`; `danger-full-access`
and `external-sandbox` cannot silently bypass the managed read-deny
policy.
- On Windows, the managed deny-read policy is enforced for direct file
tools, but shell subprocess reads are not sandboxed yet, so startup
emits a warning for that platform.
- `/debug-config` shows the effective managed requirement as
`permissions.filesystem.deny_read` with its source.

## Stack
1. #15979 - glob deny-read policy/config/direct-tool support
2. #18096 - macOS and Linux sandbox enforcement
3. This PR - managed deny-read requirements

---------

Co-authored-by: Codex <noreply@openai.com>
2026-04-17 08:40:09 -07:00