## What changed
Add `CodexThread::replace_dynamic_tools` to replace the tool catalog without starting a turn. Updates apply to subsequent model steps and future turns while preserving in-flight calls; an empty list clears the catalog.
Require host opt-in through `allow_persistent_dynamic_tool_updates` for persistent threads. Persist replacements before publishing them, restore the latest catalog on resume, and preserve replacements and explicit clears through compaction. Keep explicit resume overrides separate from the persisted catalog.
## Testing
Add coverage for pending calls during replacement, replacement and clearing across restart, compaction recovery, resume overrides, submission ordering after caller cancellation, host opt-in, and persistence failures.
GitOrigin-RevId: fd2634906895a9b72ae7892ddd9435dced45eccb
## Why
Standalone thread settings updates cleared the running turn's continuation lineage, preventing recovery after a daemon restart.
## What changed
Preserve continuation lineage while a task is registered. Continue invalidating pending continuations for idle, reserved, and finishing turns, and record started-turn lineage atomically with task registration.
## Testing
Extend settings invalidation coverage to idle, reserved, and finishing turns. Exercise an in-flight reasoning effort update before compaction, then verify cold resume preserves the turn's frozen settings and allows continuation. Wait for thread idle before testing idle continuation.
GitOrigin-RevId: d7c316af6a4c871790bb57f0af9892bb30871ac8
## Why
Capability discovery needs the roots captured with each environment snapshot. Threads sharing an executor can select different roots, and changing environment order must preserve executor skill aliases.
## What changed
- Attach the receiving thread's capability roots when constructing `TurnEnvironmentSelection` at startup and settings updates, including roots loaded from saved history.
- Resolve capability roots from environment snapshots while preserving their original order. Retain startup roots so deselecting and reselecting an environment restores its capabilities.
- Match inherited configuration by environment and workspace so differences in capability root metadata do not interrupt configuration propagation.
## Testing
Add regression coverage for root ordering across environment states and configuration changes, independent root selections on a shared executor, reselection with startup or saved roots, active turn updates, and pending configuration failures reaching child and grandchild threads.
GitOrigin-RevId: 4f2e4bb414d27195a6752406117a6050718a1198
## What changed
Add `TurnEnvironmentRequests` to carry environment requests together with their fallback working directory. Update thread settings overrides and active turn settings to accept requests, constructing `TurnEnvironmentSelection` values in the receiving thread before validation and runtime use.
Adapt app-server callers, reviewer settings, and existing tests to supply requests or explicitly convert runtime selections back into requests.
GitOrigin-RevId: 8028f804bebe3fde553f57bb450f6dca3970cc4a
## What changed
Introduce `TurnEnvironmentRequest` for caller-supplied environment input and construct `TurnEnvironmentSelection` at session startup and app-server settings boundaries. Update thread startup, default environments, and inherited environment handoffs to use requests, with explicit conversions when reusing runtime selections.
Move the environment types into `protocol::environment` while retaining their `protocol` re-exports. Update test fixtures and existing tests to build request inputs separately from runtime selections.
GitOrigin-RevId: 12e7daaece95aae136afae8b055b4dbaebdffc75
## What changed
Add `turn_extension_init` to thread startup and settings, and expose `WithTurnExtensionData` for turn input, recovery, and settings requests. Accept or reject data updates together with the request that supplies them.
Each new turn captures the configured data, including automatically started turns. Accepted steering updates the data for future turns while preserving the running turn's capture. Plain requests preserve the configured data; an empty initializer clears it. The data is not persisted and must be supplied again on cold resume.
Expose `current_turn_extension_data` to retrieve typed data only when the requested turn is still running and has not been cancelled.
## Testing
Add an integration test covering initial capture, accepted and rejected steering, inheritance by an automatic turn, clearing future data without changing the active capture, and rejection of lookups for an earlier turn.
GitOrigin-RevId: dd81eda3e32c7b62d783c772221858f4c0e68264
## Why
Callers need to await acceptance or rejection of thread settings without consuming the thread event stream. Acceptance must precede event delivery because the caller may hold a lock needed by the event consumer.
## What changed
- Add `CodexThread::update_thread_settings` and re-export `ThreadSettingsOverrides` from `core-api`.
- Add an optional reply channel to `Op::ThreadSettings`. Return validation failures as `InvalidRequest` through that channel, retaining error events for callers without a reply channel.
- Reply to successful updates before emitting `ThreadSettingsApplied`, while holding the settings persistence lock through notification.
## Testing
Extend settings constraint coverage to direct replies, including rejection without an error event and successful notification. Verify that acceptance and continuation invalidation precede blocked event delivery, while checkpointing waits for notification.
GitOrigin-RevId: e09b0d3cc4b6750709c173371632f19619e5c250
## Why
Compaction companion records do not represent all resume state, including the last started turn and previous turn settings. The selected multi-agent runtime also needs a persisted value when no companion turn context is present.
## What changed
- Add optional `resume_metadata` to `CompactedItem`, recording the multi-agent version, last started turn ID, and previous turn settings. Preserve the distinction between absent metadata and explicitly empty values while retaining compatibility with older records.
- Capture this metadata under the settings persistence lock alongside the compaction checkpoint.
- Rewrite inherited metadata to use the child agent's runtime, and clear previous turn settings when the child must rebuild context.
- Clear pending continuation state before delivering acceptance of standalone settings updates, while holding the persistence lock.
## Testing
Add coverage for metadata round trips with empty values, legacy reader compatibility, checkpoint companion records, inherited fork metadata, and continuation invalidation while settings event delivery is blocked.
GitOrigin-RevId: f30b7feaa7e2fdb5b65fc3c53b37fd7a7fe27903
## Why
Daemon recovery reloads threads but leaves interrupted work unfinished. Resume eligible work automatically from the saved conversation, even without a connected client.
## What changed
- Attempt one new continuation turn immediately after restoration, including in Plan mode. Mark the old turn interrupted and supply recovery context without creating a user message or granting new authorization.
- Require an idle thread, matching permissions, and the same single local environment configured by the thread. Skip completed, aborted, or superseded work and snapshots without environment identity.
- Add `continue_turn_if_idle` with an atomic previous-turn check so newer tasks or standalone settings changes invalidate pending continuation.
- Preserve the output schema, service tier, and root turn ID, and emit a “Resuming interrupted work” warning when continuation starts.
## Testing
Add daemon restart coverage for continuation without a client, Plan mode, permission and environment mismatches, and legacy snapshots. Add core coverage for preserved continuation metadata, absence of user-message events, rejection of superseded continuations, and exclusion of remote execution from recovery snapshots.
GitOrigin-RevId: 2b290b75d9399fc58258bcda2e85c74e9b5b3b09
## What changed
- Add `disabled_plugin_ids` to thread startup options, settings overrides, snapshots, and persisted turn contexts. Omitted overrides preserve the current list; an empty list clears it.
- Restore the selection on resume and capture it before truncating history for a fork. Prefer the owning thread's latest settings snapshot, falling back only to the latest turn context so stale history cannot resurrect an older selection.
- Freeze the selection at turn admission and retain compatibility with histories that lack the new fields.
## Testing
Add coverage for owned settings, explicit clears, latest-turn fallback, and legacy snapshots. Extend settings tests to cover plugin selection during runtime restoration and compaction, and verify initial turn persistence without extra settings checkpoints in both history modes.
GitOrigin-RevId: 75ffbff5763cd93cc5ac69d73b08b237f59bc009
## Why
Resuming a thread should retain its selected workspace folders, including additional roots and explicit empty selections. Resume overrides also need to survive a subsequent resume when no turn has run.
## What changed
- Persist `runtime_workspace_roots` in startup metadata and thread settings snapshots, separately from explicit environment selections and permission-profile roots.
- Restore roots from the latest snapshot owned by the resumed thread, falling back to owned startup metadata only when no snapshot exists. Honor explicit `runtimeWorkspaceRoots` overrides, retarget the old `cwd` root when `cwd` changes, deduplicate roots, and validate restored paths for the current host.
- Checkpoint effective settings on resume and restored settings after revert. Reload resume configuration if saved workspace roots change during loading.
- Normalize Windows rollout path spellings when matching thread search results, preserving selection of the correct rollout after revert, including compressed rollouts.
## Testing
Add regression coverage for workspace restoration, empty and explicit overrides, foreign paths, compaction and revert, resume checkpoints without recency changes, concurrent settings persistence, and rollout search path matching.
GitOrigin-RevId: d98d9d34dd63934d441120916c61c12b69e7f062
## Why
Resuming a thread without an explicit `cwd` should restore that thread's latest
retained setting. Forked history can contain settings copied from another
thread, while compaction can move the latest setting outside the replay window.
## What changed
- Record the owning thread ID on new settings snapshots and only use snapshots
owned by the resumed thread when restoring `cwd`. Older snapshots without an
owner remain readable but do not override the startup `cwd`.
- Checkpoint the current settings after compaction and serialize checkpoints
with settings updates so the retained history contains an accepted, current
snapshot.
- Cover resume behavior across compaction, forks, reverts, legacy histories,
and concurrent settings updates.
GitOrigin-RevId: 1efc9cf55472d6b88c465c4efe44672a232dbf64
## Why
App-server clients need the explanation and steering instruction returned with a
misalignment policy violation to offer a user-confirmed continuation. Missing or
incomplete details must continue to behave as a terminal block.
## What changed
- Parse optional misalignment classification, explanation, and steering details
from streamed and HTTP Responses errors and propagate them through core errors.
- Include the details in live app-server `error` and `turn/completed` payloads and
export the corresponding protocol schemas and TypeScript types.
- Keep explanations and steering messages out of serialized rollout events and
redact them from debug output.
- Document how clients can resume with `turn/start` after user confirmation.
## Testing
- Cover streamed, HTTP, and WebSocket-wrapped errors, including malformed and
classification-only details.
- Verify live app-server notifications expose resumable details without writing
the explanation or steering message to the rollout.
GitOrigin-RevId: 329258a444c2cd91d0c57ab1720830b33ddcfac5
## Why
Turn settings can change after an input request previews its overrides. Automatic idle work could therefore make a Plan-mode admission decision from stale settings or apply a sparse override built from an outdated collaboration mode.
## What changed
- Evaluate automatic turn admission against both the current and proposed configuration under the settings publication lock.
- Reject automatic work that would enter or leave Plan mode without committing settings or triggering runtime configuration effects.
- Keep model and reasoning-effort overrides sparse until they are merged with the configuration being committed.
- Continue allowing explicit user and recovery turns to make valid mode transitions.
## Testing
Add coverage for concurrent settings changes, sparse model and effort updates, commit-time constraint validation, atomic Plan-mode rejection, and subsequent explicit user submission.
GitOrigin-RevId: 234f06de116bdce7c3a3fb5cac3d15583304a253
## Why
Model requirements must be evaluated against the permissions that will apply
after a settings update. Validating against the current profile can reject a
valid model-and-permission update or allow a later permission-only update to
invalidate the selected model.
## What changed
- Group model, reasoning, service-tier, personality, and approval inputs into
`StepSettings`, with a single apply-and-validate path.
- Apply permission and environment changes before validating step settings, so
auto-review requirements use the proposed effective permissions.
- Revalidate existing step settings when permission or environment changes alter
their constraints, and commit the update only when the complete candidate is
valid.
## Testing
Added unit and integration coverage for atomic model/permission updates,
permission-only revalidation, environment-derived constraints, and both
standalone and turn-start settings operations.
GitOrigin-RevId: f50dfbd300484a09acc51ee4607278f300ca1cd9
## Why
Post-commit work can overlap with another settings write. Reading the session
again afterward could make a settings operation report or use the later state
instead of the state that it committed.
## What changed
- Return the committed configuration and `ThreadSettingsSnapshot` from session
settings updates.
- Use that commit result when creating a turn and emitting
`ThreadSettingsApplied`, while retaining current-state snapshots for
synthesized fork history.
- Route turn-start updates through the shared settings update path.
## Testing
Add coverage for standalone and turn-start updates that pause after committing,
restore different settings concurrently, and verify that each operation keeps
its original configuration and notification snapshot.
GitOrigin-RevId: cee5be9536d2840170893e6eb0c64cd039fb0a96
## 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
- 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