## What changed
- Pass the selected executor's `PathUri` through user command approval requests instead of converting the working directory to a host-native path.
- Make native-path permission helpers explicitly local and require executor-aware permission transforms to receive a `FileSystemSandboxPolicyContext`.
- Cover approved remote commands to verify that the approval request reports the selected remote working directory and execution resumes after approval.
GitOrigin-RevId: 0aa3042f2d7594af6c7d0abf31d7f99cf67d5556
## Why
Directly deserializing the flattened `RolloutLine` envelope can reject nested
decimal values, preventing affected paginated sessions from resuming.
## What changed
- Add canonical string, byte, and reverse-scanner helpers that decode rollout
records through `serde_json::Value` before decoding the flattened item.
- Route rollout readers across session discovery, history, migration, search,
thread storage, and transcript previews through those helpers.
- Remove `Deserialize` from `RolloutLine` so new readers cannot bypass the
canonical persistence decoder.
## Testing
Add coverage that resumes a paginated rollout after a token-count record with
a decimal rate-limit value and verifies that ordinal sequencing continues.
GitOrigin-RevId: 49abac1e0751c073daa5a93a840d8a483fd2d013
## Why
Permission requests can originate in an environment whose path convention differs from the Codex host. Requiring the request working directory to be host-native prevents those requests from reaching interactive approval.
## What changed
- Carry the request `cwd` as a `LegacyAppPathString` through core events and the app-server protocol so the target environment's native representation is preserved.
- Convert the preserved value back to a `PathUri` when materializing permission grants.
- Regenerate the JSON and TypeScript protocol schemas for the updated `cwd` type.
## Testing
- Exercise the app-server permission request round trip with a target-native working directory across host path conventions.
- Verify remote permission requests retain their environment working directory and granted access still unblocks later execution.
GitOrigin-RevId: 97dc9707d9048883d20bab1b69c93871039f3188
## What changed
- Include Windows safety guidance in the `exec_command` tool description when a
single ready environment reports Windows as its executor platform.
- Omit that guidance when the selected executor reports a non-Windows platform.
- Preserve the host-based behavior when platform information is unavailable or
the tool can target multiple environments.
## Testing
- Cover Windows, non-Windows, unknown-platform, and multi-environment tool plans.
- Verify remote environments expose guidance that matches their target OS.
GitOrigin-RevId: 95e09790446c684ffaff2a0be077db426fff4618
## Why
Test fixture setup can take more than five seconds on loaded CI workers, and
failures returned from setup can be obscured when downstream mocks verify their
expectations during teardown.
## What changed
- Add a shared `expect_startup` helper with a 30-second timeout that panics on
either timeout or setup failure before mock teardown runs.
- Use the helper for remote-environment and unified-exec fixture setup, and
allow the same startup window for the initial exec-server requests.
## Testing
Add paused-time tests covering successful startup after five seconds, timeout
reporting, and propagation of setup errors in the presence of unmet mocks.
GitOrigin-RevId: 39db69bde2983acd023a1911a6fad106674e169a
## What changed
- Add effective workspace roots to `EnvironmentConfig` and use them when
materializing permission profiles and filesystem context.
- Preserve selection roots for thread-owned configurations while allowing a
ready environment attachment to supply its resolved roots.
- Propagate resolved roots to child environments and validate both command and
`apply_patch` writes in owner-provided secondary workspaces.
GitOrigin-RevId: 1832c168ce1fc37fa67efc2a472998ab4f448c70
## Why
MCP servers attached to executor environments must retain their owner's
permission profile instead of inheriting the thread-wide sandbox authority.
## What changed
- Resolve and capture a permission profile for each enabled MCP server when
publishing the runtime, and reject calls or elicitations when that authority
is unavailable.
- Use the captured server profile for tool approval decisions, elicitation, and
sandbox metadata, including after runtime refreshes.
- Materialize `:workspace_roots` from `PathUri` values so permissions preserve
the path convention of remote executor environments.
- Give threadless app discovery and resource reads an explicit default
permission profile.
## Testing
Added coverage for per-server elicitation authority, unresolved attachments,
runtime refreshes, restricted tool calls, and foreign-platform workspace roots.
GitOrigin-RevId: 6b188d4b08b29e9971ff7aa68a7785a0cdf9e394
## What changed
- Add Windows sandbox mode, private-desktop behavior, and legacy Landlock selection to each `EnvironmentConfig`.
- Centralize sandbox context construction on `TurnEnvironment`, preserving environment-owned permissions, paths, and backend settings while applying additional permission grants.
- Use the environment-derived context for project instructions, capability discovery, file uploads, and filesystem-oriented tools.
## Testing
- Verify capability discovery uses the selected environment's permission profile and sandbox backends when they differ from the thread defaults.
GitOrigin-RevId: 7ae2fed90c8ada950f2e8431e571e9b2c793c291
## Why
`EnvironmentConfig.network_policy` could describe attachment-owned traffic
restrictions, but core rejected every configured policy because execution did
not enforce it.
## What changed
- Resolve each remote environment's network policy for the selected command
and apply it to the execution-scoped proxy.
- Compose owner rules with controller constraints and saved network decisions
while preserving inherited domain and Unix-socket denials.
- Keep strict allowlists non-expandable, allow reviewable policies to use
network approvals, and reject sandbox escalation that would bypass an owner
policy.
- Reject policies for local execution, disabled managed enforcement, or a
disabled controller proxy.
## Testing
Added coverage for policy composition, scoped remote proxy behavior, approval
and denial flows, offline execution, and unsupported environment authority.
GitOrigin-RevId: d9331f616df24de6cd13ed68196f0ff7b0ca4dd9
## Why
Refreshing a Noise rendezvous bundle after an unauthorized handshake inherited
the initial registry lookup's retry count. If that lookup had exhausted its
retries, a transient registry error during the refresh failed immediately.
## What changed
Reset the registry retry count along with the operation deadline before
requesting a replacement bundle after a `401` handshake response.
## Testing
Extend the initial Noise connection test to exhaust the first lookup's retry
budget, receive a `401`, then verify that an offline replacement lookup is
retried and connects successfully.
GitOrigin-RevId: bcfad50ea32d69855f1c2c4c461022b3ecbbd941
## What changed
- Use `exec_command` and `write_stdin` as the shell tool surface.
- Treat legacy `default`, `local`, and `shell_command` model metadata as `unified_exec`.
- Remove obsolete shell-selection configuration and runtime paths while preserving the feature and policy gates for zsh fork execution.
GitOrigin-RevId: d743cbe598630d73052f1fecad680c4cde17977d
## What changed
- Remove the legacy `shell_command` handler and runtime, leaving `exec_command`
and `write_stdin` as the shell execution tools.
- Treat legacy `shell_command` model metadata as `unified_exec`, and normalize
legacy user opt-outs so they do not disable command execution. Managed feature
requirements and `shell_tool` can still disable it.
- Preserve shell approvals, sandboxing, zsh-fork support, and output truncation
through the unified execution path.
## Testing
- Cover legacy configuration and model-metadata compatibility.
- Exercise unified shell execution, approvals, truncation, and `apply_patch`
serialization across the app-server and core test suites.
GitOrigin-RevId: 5c2fd6164fc3519cdae4944cb9db276b8467311c
## Why
Resumed threads can carry a persisted capability-root location that no longer
matches the location reported by the attached executor.
## What changed
- Refresh matching thread-owned capability roots from the live environment while
preserving persisted roots when the executor reports none.
- Use the same merge behavior for capability-root inspection and per-step MCP
resolution, without changing owner-configured root precedence.
## Testing
Extend the remote-environment resume test to cover both an executor-provided
replacement root and the persisted-root fallback.
GitOrigin-RevId: 0c66195b2406f431a2e156e00d5225a8d22d18b2
## Why
An `apply_patch` path can be replaced with a symlink after verification, allowing an unsandboxed patch operation to reach a different file than the one that was approved.
## What changed
- Add `follow_symlinks` options to executor filesystem reads, writes, metadata lookups, directory creation, and removal, including the corresponding `followSymlinks` protocol fields.
- Implement no-follow filesystem operations on Unix and Windows that reject links in any path component and restrict file access to regular files.
- Run `apply_patch` with symlink traversal disabled when an otherwise-required sandbox is bypassed, while retaining the existing follow-symlink default for standalone callers.
## Testing
- Cover leaf and ancestor symlinks across patch add, update, delete, and move operations, including a path swap after verification.
- Exercise local and remote no-follow filesystem behavior, concurrent directory creation, special-file rejection, and Windows reparse points.
GitOrigin-RevId: 43fd479084891493ce13564fbd894b98f329c6dd
## Why
Environment-owned permission profiles and workspace roots must remain effective
without being persisted or restored as thread-owned settings.
## What changed
- Keep thread settings snapshots and restore data separate from the effective
configuration supplied by the primary environment.
- Use resolved environment permissions, active profiles, workspace roots, and
network policy when building turn context and session events.
- Preserve environment selections when agents are evicted, resumed, or spawned,
and validate owner configuration when it becomes ready.
- Start memory initialization only after the primary environment is configured.
## Testing
- Extend remote-environment and multi-agent tests to cover settings persistence,
owner permission profiles, workspace roots, spawning, eviction, and resume.
GitOrigin-RevId: d82f126981cd0190233020bbdd61d96c70558868
## What changed
- Add environment-provided MCP restrictions for configured and plugin-provided servers.
- Disable attachment-scoped servers while their environment configuration is pending, failed, or unselected, while preserving selected-plugin access and the controller-owned Apps server.
- Apply the resolved policy to runtime startup, model tool exposure, telemetry, OAuth flows, and skill dependency installation.
## Testing
- Cover policy filtering for configured and plugin servers, environment state transitions, Apps ownership, and managed OAuth rejection.
GitOrigin-RevId: 7ca5d4dda14068e758497f88835d5cba685e159e
## Why
Thread settings could replace an owner-provided environment configuration with
`FromThread`, allowing the thread to take ownership of that configuration.
## What changed
Reject environment settings updates that change an existing owner-provided
configuration to `FromThread`.
## Testing
Cover preview and turn settings updates for pending, ready, and failed
owner-provided environments.
GitOrigin-RevId: c516954819447ceb29e2ff9f29fe781ca101ae54
## Why
Filesystem permission paths can use a convention that differs from the host
running Codex. Converting them immediately to native absolute paths can change
the meaning of ambiguous paths such as `/C:/secret` or Windows UNC paths.
## What changed
- Store literal filesystem permission paths as `PathUri` values through the
runtime policy and execution protocol.
- Keep legacy string-based serialization at explicit protocol boundaries and
reject conversions that cannot be represented losslessly.
- Encode native paths as opaque URIs when a normal file URI would imply the
wrong path convention.
## Testing
Added coverage for cross-platform and ambiguous path round trips, UNC path
variants, permission-profile serialization, and deny-policy enforcement.
GitOrigin-RevId: 5247713796d1f2bb4e02f94eb9fc82d4698060f0
## What changed
- Add `EnvironmentNetworkPolicy` as a serializable view of portable domain,
Unix-socket, upstream-proxy, and local-binding restrictions without exposing
controller-owned proxy runtime settings.
- Add an optional `network_policy` field to `EnvironmentConfig` and re-export
the policy and related permission types through the core APIs.
- Reject owner-provided network policies during environment preview and
readiness until runtime enforcement is implemented, while preserving the
existing controller policy when the field is absent.
## Testing
- Cover rejection through both environment preview and readiness, including
preservation of the existing environment selection.
GitOrigin-RevId: 80ad4cf4d4a45632daa7a823e6cf568eb0e8bb80
## What changed
- Add an optional restrictive execution policy to `EnvironmentConfig` and merge it over the active command policy for shell execution and approval decisions.
- Reject environment policies that contain allow rules, so environment configuration can only tighten command access.
- Include the environment policy fingerprint in cached approval keys so policy changes require fresh session approvals.
## Testing
- Cover restrictions overriding saved prefix approvals, policy changes invalidating session approvals, and environment overlays remaining effective when model-specific prefix filtering is active.
GitOrigin-RevId: e94f877549ed5e0f577b8cb52f3c1872c58f029d
## What changed
- Carry `ShellEnvironmentPolicy` in each resolved `EnvironmentConfig` and use
the selected turn environment's policy for shell commands, user shell tasks,
and unified exec.
- Infer the policy from the thread configuration when an environment does not
provide its own resolved configuration.
- Redact the policy from `EnvironmentConfig` debug output because it can contain
explicit environment variable values.
## Testing
- Verify shell handlers and unified exec filter inherited variables according
to the selected environment while preserving its explicit overrides.
GitOrigin-RevId: 9f6a52aa4af60e5f17251a0e1b11e1926b779055
## Why
An environment connection can be available before its owner has supplied the
configuration for a particular thread attachment. Threads need to start without
blocking while ensuring turns do not use that attachment prematurely.
## What changed
- Accept `Pending` environment configuration and resolve each attachment only
after both its shared executor connection and owner configuration are ready.
- Add a `Failed` configuration state and `environment_failed` callback so an
owner can fail one thread's attachment without affecting other threads.
- Keep pending and failed attachments out of capability-root inspection and turn
environments, and allow failed attachments to recover through a ready update.
- Apply owner configuration before waking a waiting turn so its permission
profile, login-shell policy, capability roots, and tools are immediately
consistent.
## Testing
Add an integration test covering non-blocking thread startup, independent ready
and failed callbacks, waiting-turn resumption, installed capability and tool
configuration, and recovery from failure.
GitOrigin-RevId: d587e2025d584c867d782d470b18bf5a1a27b76c
## Why
Environment attachments can either inherit configuration from their thread or
provide their own. Later thread setting updates must refresh inherited
configuration without overwriting attachment-owned permissions and capability
roots.
## What changed
- Resolve each attachment's configuration when it is selected and retain
whether it came from the thread or the attachment owner.
- Apply subsequent thread configuration updates only to thread-owned
attachments, while preserving ownership across snapshots and child threads.
- Keep the resolved configuration with the environment selection so runtime
consumers use a single canonical value.
## Testing
- Extend remote-environment coverage to verify that thread-owned permissions
follow thread updates while owner-provided read-only permissions remain in
effect.
- Cover configuration inheritance, attachment replacement, and owner-configured
capability roots.
GitOrigin-RevId: fe70c4be5f151432b69bf4b141e316faa89036ae
## What changed
- Add a resolved `permission_profile` to each `EnvironmentConfig` and use the
complete attachment config for execution and capability-root selection.
- Let `Ready` environment configurations override thread permissions while
`FromThread` selections continue to inherit them.
- Restrict inherited Guardian environment profiles to read-only permissions.
## Testing
- Add coverage proving that a read-only environment blocks writes even when
the thread permits workspace writes.
- Update environment inheritance, Guardian review, and capability-root tests
for the resolved attachment configuration.
GitOrigin-RevId: 1a313b9e4892b1a579a0e880e322a782b4f6c0a7
## What changed
- Add `EnvironmentConfigState` to `TurnEnvironmentSelection` so each environment attachment can inherit thread configuration or carry ready configuration for its login-shell policy and selected capability roots.
- Apply ready configuration during thread creation and thread-settings updates while reusing the existing environment connection.
- Validate selection configuration before applying settings, rejecting unsupported pending state and invalid capability roots.
## Testing
- Cover attachment-scoped capability roots, ready configuration at thread startup and turn updates, and rejection of invalid selections without changing existing settings.
GitOrigin-RevId: 86cf8f2148fdaa746ea0dd12890ab7b1577d7587
## What changed
- Make `ThreadEnvironments` the source of truth for live environment selections and use it when building configuration snapshots, permission profiles, per-turn configuration, and MCP refresh inputs.
- Keep settings previews side-effect free while applying accepted environment updates consistently to subsequent turns.
- Move `EnvironmentConfig` into `codex-protocol` so environment ownership no longer depends on a core-only type.
## Testing
- Cover environment previews and snapshots, accepted and rejected steer updates, and active-turn environment stability.
GitOrigin-RevId: 7bcf8fb5df1215f720e4e9c419541a51a871aa5e
## What changed
- Add `TurnInputRequest` and typed submission results for atomically starting a turn, steering the active turn, or declining input with a specific reason.
- Expose `start_or_steer_turn`, `start_turn_if_idle`, and `steer_turn` on `CodexThread`, and migrate Core consumers to these APIs.
- Make app-server `turn/start` steer an active regular turn and return that turn's ID. Reject incompatible output schemas and non-steerable turns without applying settings or enqueueing input.
## Testing
- Cover concurrent start-or-steer submissions, accepted and rejected settings updates, output-schema compatibility, idle-start rejection, and app-server steering.
GitOrigin-RevId: dd9b5528d76ec650c019e97af420bc13190ea86a
## Why
World-state snapshots and merge patches are keyed collections of sections. Allowing
their persisted `state` field to contain any JSON value required replay code to
handle shapes that cannot represent world state.
## What changed
- Type `WorldStateItem.state` and snapshot patches as JSON object maps.
- Reconstruct full snapshots directly from those maps and apply patches without
fallible arbitrary-value conversions.
- Regenerate the app-server protocol schema for the object-only representation.
GitOrigin-RevId: 3d7662b74f3dd1f3ccc5fdd0200074c13a73cbe5
## Why
Threads that share an executor environment can require different capability roots and login-shell policies. Treating readiness configuration as executor-wide can expose one thread's settings to another.
## What changed
- Add `CodexThread::environment_ready` and `EnvironmentConfig` so hosts can install capability roots and login-shell policy for an exact thread, environment, and working-directory attachment.
- Validate attachment readiness updates, merge ready attachment roots with persisted thread roots, and refresh MCP capabilities when those roots change.
- Preserve installed environment policy across thread settings updates and child-thread inheritance while resetting it when the selected working directory changes.
## Testing
- Cover attachment config inheritance and reset behavior.
- Verify that threads sharing an executor retain independent model-visible capability roots and login-shell tool schemas across updates.
GitOrigin-RevId: 60e7a296b3e41b835b0413aa2837451e8a55c230
## What changed
- Add `codex-history` for model-history and persisted-rollout domain types, including `RolloutItem`, `RolloutLine`, `CompactedItem`, and initial/resumed history state.
- Re-export the persisted types from `codex-rollout` and update consumers to use the new crate boundary instead of `codex-protocol`.
- Preserve existing rollout serialization, including legacy numeric compacted-window IDs.
## Testing
- Add `codex-history` tests for rollout JSON round trips, compacted-history compatibility, persisted history modes, and multi-agent version selection.
GitOrigin-RevId: 944daa9297ddd231d3aebbdcb05fff4adf8b4e1b
## Why
Deferred environments can become ready after a turn starts. Guardian approval
reviews must use the environment selected for the current step so their working
directory and permission context are not taken from the stale turn snapshot.
## What changed
- Carry `StepContext` through tool execution and approval handling.
- Add a Guardian review context that pairs the parent turn with the current
step's environment snapshot.
- Use that snapshot for Guardian prompts, reviewer sessions, and delegated
reviewer threads while retaining turn-level fallbacks for callers without a
step context.
## Testing
Added an integration test that makes a deferred remote environment ready before
an escalated command and verifies Guardian receives that environment's working
directory and denied-read policy instead of the initial local environment's.
GitOrigin-RevId: 779096bc7d0e0c7453a009c02141029714b9b407
## What changed
- Add end-to-end coverage for a remote environment whose provisioning status is
reported ready before it is selected for a turn.
- Verify that `wait_for_environment` makes remote execution tools and selected
capability-root context available once the transport is ready.
- Update pending-environment and relay tests to cover separate materialization
and readiness reporting, including deferred connection and reconnection.
GitOrigin-RevId: d86d66e8f722e9bafac88b93d93e7c5244a7156e
## What changed
- Register the legacy `shell_command` handler only when exactly one local environment is available, including when unified exec keeps it hidden for compatibility.
- Reserve the unnamespaced `shell_command` name so external tools cannot claim it when the built-in handler is unavailable. Namespaced tools with that name remain supported.
## Testing
- Cover remote and multiple-environment tool plans, unified exec routing, and external tool registration for reserved and namespaced variants.
GitOrigin-RevId: 93834539b31ac8a7fea072bfa4de792bcc3e053b
## Why
With deferred execution, an environment can become ready before a later step
spawns a sub-agent. The child must inherit the environment selections available
to that step.
## What changed
- Use the current step context's environment selections when spawning agents in
both multi-agent implementations.
- Add coverage that waits for a remote environment to become ready, spawns an
agent, and verifies that the child receives both remote and local selections.
GitOrigin-RevId: 97c37d541342bbefc9217bf341a19ebdfead2c76
## Why
When a turn uses multiple environments, the environment context lists each one but did not identify which environment is primary.
## What changed
- Add a `primary` attribute to each environment in multi-environment model context.
- Persist primary selection in world-state snapshots and emit updates when the primary environment changes.
- Restate environments when transitioning between single- and multi-environment context, while preserving the existing single-environment format.
## Testing
- Cover primary-environment changes, single/multi-environment transitions, legacy snapshot compatibility, and deferred-executor promotion after environment startup.
GitOrigin-RevId: 73a1d794a227edef6e9b7844e7f947b7f598dc80
## What changed
- Add `WaitForEnvironmentToolConfig` as thread extension data for overriding the
model-visible tool and `environment_id` descriptions.
- Preserve the default descriptions when no override is provided or when the
configured descriptions exceed the input or serialized tool-spec limits.
- Keep `wait_for_environment` availability gated by the deferred executor
feature independently of whether a host override is present.
## Testing
- Cover default, custom, oversized, and feature-disabled tool configurations.
- Verify the custom descriptions in the deferred-environment integration flow.
GitOrigin-RevId: 6b49a73a434becd99ea5df911be53f3706a17c0a
## Why
Default read-only protections for project metadata should apply when paths such
as `.git`, `.agents`, and `.codex` exist, without causing sandbox setup to
materialize missing paths as ACL targets.
## What changed
- Add an optional `missing_path_behavior` to filesystem sandbox entries and
mark default project-metadata protections with `skip`.
- Preserve the behavior through permission transforms and exec/MCP protocol
serialization while keeping existing path wire variants stable.
- Ignore skip-missing entries when projecting configuration or Windows sandbox
overrides, while retaining explicit metadata carveouts.
## Testing
- Cover protocol round trips for path and special-path entries.
- Verify default metadata protections and Windows explicit carveout handling.
GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
## Why
Changes to the selected working directory can select different `AGENTS.md`
instructions. These updates need to reach the model even when the deferred
executor feature is disabled.
## What changed
- Refresh environment readiness and `AGENTS.md` before capturing each step.
- Record model-visible world-state changes for every session instead of gating
them on the deferred executor feature.
- Preserve the initial environment context without duplicating it.
## Testing
- Cover `AGENTS.md` replacement after a working-directory change.
- Verify that initial environment context remains unique with the deferred
executor both enabled and disabled.
GitOrigin-RevId: ea5dbe590cc049170259e7eccb6a3346fb2ed8e6
## Why
With deferred execution enabled, rebuilding a step context from the latest
thread environment snapshot could apply a settings update to a turn that was
already in progress.
## What changed
- Preserve each turn's captured environment selections when creating later
step contexts.
- Refresh only the readiness of environments that were already starting, while
retaining their original selection order.
- Apply updated environment selections to the next turn.
## Testing
Add coverage for changing the selected workspace while a turn is paused,
verifying that the active turn keeps its original working directory and the
next turn uses the new one.
GitOrigin-RevId: c6f4388c843384ef045b7abdbc303dcfca11d230
## Why
An execution environment marked `starting` is not yet usable, but unrelated work can continue while it becomes ready.
## What changed
- Add developer guidance that explains execution-environment isolation and the resources that become available after startup.
- Tell the model to wait only when the current task needs the starting environment.
- Retain the guidance across world-state updates without duplicating it in request history.
## Testing
- Cover world-state transitions, history retention, rollback handling, and deferred-environment request deduplication.
GitOrigin-RevId: f12f9204d4cbddce50a70eb0998beb6b66cd2fa9
## What changed
- Let deferred environments provide selected capability roots with their ready signal.
- Validate that those roots have unique, non-empty IDs, belong to the registering environment, and stay within the root limit.
- Include roots from ready turn environments when resolving MCP contributions, and refresh the MCP runtime when the selected root set changes.
- Expose the exact ready root set to MCP contributors so executor plugins become available with their environment.
## Testing
- Cover ready-root propagation, validation failures, replacement isolation, reconnection, and MCP plugin availability refresh.
GitOrigin-RevId: ec3498aab1164824025094e96a9b1063b7b731ad
## What changed
- Replace pending WebSocket URL registration with deferred Noise environment
registration that gates connection attempts on an explicit readiness signal.
- Reuse the Noise rendezvous transport after readiness so reconnects request a
fresh connection bundle.
- Preserve terminal errors for failed or dropped registrations and keep late
completion isolated from replacement environments.
## Testing
- Add coverage for readiness gating, registration failure and replacement,
eager Noise connections, and reconnection through a fresh rendezvous bundle.
GitOrigin-RevId: 83e23fa03a02e3b2bdf1a83fe26d7ac461f55cf3
## Why
Multi-environment turns can run against different filesystems, so a single
thread-wide workspace-root list cannot accurately describe every selected
environment.
## What changed
- Add optional `runtimeWorkspaceRoots` to each app-server environment selection.
Omitted roots default to that environment's `cwd`, while an empty list selects
no roots.
- Carry environment-native roots through turn selection, model-visible context,
permission materialization, and tool sandboxing.
- Keep the top-level `runtimeWorkspaceRoots` field as a compatibility input when
constructing default environment selections; explicit selections use their
own roots.
## Testing
- Cover thread and turn API defaults, overrides, empty roots, and schema
round-tripping.
- Verify foreign roots remain model-visible and remote execution applies the
target environment's roots before sandbox selection.
GitOrigin-RevId: c6e7a62883c45c676c153055f46a55ee15a323a4
## Why
Remote environment provisioning can finish after a thread starts, before an
exec-server WebSocket URL is available.
## What changed
- Add `EnvironmentManager::register_pending_environment` and a one-shot
`PendingEnvironmentRegistration` handle that resolves to either a validated
WebSocket URL or a terminal provisioning error.
- Let lazy remote exec-server clients wait for that result, while preserving
reconnection behavior after a successful registration.
- Keep replacement registrations isolated so completing an older handle does
not resolve the current environment with the same ID.
## Testing
Add coverage for successful connection and reconnection, provisioning and
dropped-registration failures, invalid URLs, replacement isolation, and the
deferred-executor startup flow.
GitOrigin-RevId: 5c05be2b72291b77a1f71176d7075b1ad63332a5
## Why
With deferred executors, a turn can begin before a remote environment
attaches. AGENTS.md discovery previously ran only during session setup,
so instructions from a later environment never reached the model or the
session instruction sources.
WorldState persistence has now landed, so this uses the durable
model-visible baseline directly instead of carrying a temporary
resume/fork compatibility path.
## What
- Add an `AgentsMdManager` in `SessionServices` to own host
instructions, loaded state, and refresh caching.
- When `DeferredExecutor` is enabled, refresh AGENTS.md when attached
environment selections change and freeze the result in the corresponding
`StepContext`.
- Represent AGENTS.md as a persisted WorldState section for every
session, with bounded initial, replacement, and removal updates.
- Remove duplicate AGENTS.md state and rendering from
`SessionConfiguration` and `TurnContext`.
- Build initial context, per-request updates, and compaction context
from the same step-scoped value.
- On resume and fork, compare current instructions with the restored
WorldState baseline and inject a replacement exactly once when they
differ.
Builds on #29833, #29835, and #29837.
## Tests
- Covers a remote environment becoming ready mid-turn, with AGENTS.md
appearing on the next request exactly once and updating canonical
instruction sources.
- Covers full, unchanged, replaced, and removed AGENTS.md WorldState
rendering.
- Covers changed instructions across cold resume and fork without
duplicate reinjection.
- Covers remote-v2 compaction retaining creation-time instructions in
the live session and cold resume appending one replacement when the
source changed.
- Ran focused `codex-core` AGENTS.md, WorldState, and context-update
test suites.
## Why
`WorldState` currently remembers its model-visible diff baseline only in
memory. That leaves no durable source for restoring the exact baseline
after resume, fork, rollback, or compaction.
This is the second PR in the WorldState persistence stack, built on
#29833 and following #29249. It records durable state transitions; the
next PR will replay them during rollout reconstruction.
## What
- Add a `world_state` rollout item containing either a full snapshot or
an RFC 7386 JSON Merge Patch.
- Persist a full snapshot after initial context and after compaction
establishes a new context window.
- Persist non-empty patches when later sampling steps or turns advance
the WorldState baseline.
- Write model-visible history before its matching WorldState record, so
an interrupted write can only cause a safe repeated update on replay.
- Preserve WorldState records for full-history forks while excluding
them from thread previews, metadata, and app-server history
materialization.
Older binaries read rollout lines independently, so they skip the
unknown `world_state` records while retaining the rest of the thread.
## Testing
- `just test -p codex-core
snapshot_merge_patch_changes_and_removes_nested_values`
- `just test -p codex-core
world_state_baseline_deduplicates_until_history_is_replaced`
- `just test -p codex-core
deferred_executor_compaction_preserves_then_updates_environment_once`
- `just test -p codex-protocol`
- `just test -p codex-rollout`
- `just test -p codex-state`
- `just test -p codex-thread-store`
- `just test -p codex-app-server-protocol`
## Why
Start moving towards app-server tests defaulting to running against
remote & foreign OS executors. To do so we need a point of indirection
similar to core integration tests' `build_with_auto_env`, but with the
flexibility of letting tests control environment registration if they
need to.
## What
This adds:
- `TestAppServer::new_with_auto_env()` for constructing an app server
with a default environment defined by the test runner (e.g. bazel)
- `TestAppServer::auto_env_params()` for tests to easily acquire turn
env params tailored to the automatic environment
- `TestAppServer::send_thread_start_request_with_auto_env()` to make it
easy for tests to start a thread using the automatic environment
The above methods all fail if the test calling them has set up an
environment where the automatic environment configuration conflicts with
test-created state.
## Validation
Adds a couple of basic smoke tests to the app-server test suite.
Follow-ups will migrate more tests to use it.
## Why
With `DeferredExecutor`, a sampling request can begin while an
environment is still starting. The model can see that pending state, but
needs a way to wait for the environment within the same turn before
continuing.
Environment startup is owned by Core, so the wait tool should use the
same request-frozen `StepContext` that advertised the starting
environment. This keeps tool registration and execution tied to the
exact startup operation the model saw, even if live thread state later
changes.
Supersedes #29735.
## What
- register `wait_for_environment` when the current `StepContext`
contains starting environments
- wait on the selected `StartingTurnEnvironment` shared resolution and
return a bounded ready or failed result
- rebuild the next request normally, removing the wait tool and exposing
ready environment tools, or reporting the environment as unavailable
after failure
## Testing
- `just test -p codex-core deferred_executor_`
- verifies the wait tool is replaced by environment-backed tools after
startup
- verifies startup failure removes both the wait tool and unavailable
environment tools while notifying the model
## Why
Use a clearer name for what happens when this helper sets up a test
environment.
## What
- Rename the builder and its harness wrapper to use `auto_env` instead
of `remote_env` because the helper will set up a local environment if
configured by the build system.
## Why
Core tests should branch on the executor's operating system, not on
runner details such as Docker or Wine. This keeps platform behavior
stable as new test backends are added and reserves Wine-specific skips
for actual runner debt.
## What
- Add `TestTargetOs` and target/host-aware skip helpers while keeping
`TestEnvironment` internal.
- Replace topology enum access with remote predicates and a narrow
Docker accessor.
- Migrate OS-semantic Wine skips, preserve runner-specific gaps, and
document the skip taxonomy.
## Validation
- `just test -p core_test_support`
- `just test -p codex-core
remote_test_env_can_connect_and_use_filesystem`
- `bazel test //codex-rs/core:core-all-wine-exec-test
--test_output=errors` reached test execution; unrelated existing
view-image, path, and timing failures remain.
- `just test -p codex-core` and `just test` reached broad test
execution; this checkout has unrelated helper, sandbox, and timing
failures.