Separate thread settings from environment configuration (#39597)

## 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
This commit is contained in:
sayan-oai authored and copyberry committed 2026-08-20 05:29:12 +00:00
1 parent 8f4a48a6ad
commit d75c85f651
35 files changed
+564 -308

No files matched your search

+18 -3
View File
@@ -123,6 +123,7 @@ use codex_protocol::protocol::SessionSource;
use codex_protocol::protocol::SubAgentSource;
use codex_protocol::protocol::ThreadHistoryMode;
use codex_protocol::protocol::ThreadSettingsOverrides;
use codex_protocol::protocol::ThreadSettingsSnapshot;
use codex_protocol::protocol::ThreadSource;
use codex_protocol::protocol::TurnAbortReason;
use codex_protocol::protocol::TurnContextItem;
@@ -178,6 +179,7 @@ use tracing::warn;
use uuid::Uuid;
use crate::client::ModelClient;
use crate::codex_thread::CodexThreadSettingsOverrides;
use crate::codex_thread::ThreadConfigSnapshot;
#[cfg(test)]
use crate::compact::collect_user_messages;
@@ -1652,6 +1654,20 @@ impl Session {
.thread_config_snapshot(self.services.turn_environments.selections())
}
pub(crate) async fn thread_settings_snapshot(&self) -> ThreadSettingsSnapshot {
let state = self.state.lock().await;
state
.session_configuration
.thread_settings_snapshot(&self.services.turn_environments.selections())
}
pub(crate) async fn restorable_thread_settings(&self) -> CodexThreadSettingsOverrides {
let state = self.state.lock().await;
state
.session_configuration
.restorable_thread_settings(self.services.turn_environments.selections())
}
pub(crate) async fn set_app_server_client_info(
&self,
app_server_client_name: Option<String>,
@@ -3162,9 +3178,8 @@ impl Session {
if !discovery.sandbox_contexts().is_empty() {
extension_data.insert(discovery.sandbox_contexts().clone());
}
} else if !turn_context
.config
.permissions
} else if !environments
.permission_profile_or_else(|| turn_context.permission_profile())
.file_system_sandbox_policy()
.has_full_disk_read_access()
{