mirror of
https://github.com/openai/codex.git
synced 2026-11-09 00:39:32 +00:00
Decouple session isolation from subagent attribution (#44521)
## Why Session isolation relied on Guardian source attribution. An explicit policy lets callers control inherited capabilities independently of how a session is attributed. ## What changed - Add `SessionIsolation` with default `Inherit` and opt-in `Isolated` modes, captured at session startup through `ExtensionDataInit`. - Use the policy to control inherited instructions, extensions, execution rules, and MCP resources. Isolated sessions retain managed execution rules and omit executor-discovered MCP servers. - Explicitly isolate Guardian reviewers while preserving source-based fallback for older callers and saved reviewers. ## Testing Extend delegate tests to cover isolation independently of attribution, update execution-policy coverage to supply the explicit policy, and assert that managed reviewers do not inherit the parent's configured MCP tools. GitOrigin-RevId: f0ab42fa2f0237860ec661e72693ab191216afbf
This commit is contained in:
1 parent
9688359977
commit
ed6dde9fda
14 files changed
+83
-18
No files matched your search
@@ -135,12 +135,7 @@ impl Session {
|
||||
)
|
||||
.await;
|
||||
let mcp_config = self
|
||||
.project_selected_environment_mcp_servers(
|
||||
&session_source,
|
||||
config,
|
||||
&environments,
|
||||
mcp_projection,
|
||||
)
|
||||
.project_selected_environment_mcp_servers(config, &environments, mcp_projection)
|
||||
.await
|
||||
.config;
|
||||
let local_process_cwd = environments
|
||||
@@ -312,7 +307,6 @@ impl Session {
|
||||
.await;
|
||||
let mcp_projection = self
|
||||
.project_selected_environment_mcp_servers(
|
||||
&desired.session_source,
|
||||
&desired.config,
|
||||
&desired.environments,
|
||||
mcp_projection,
|
||||
|
||||
@@ -143,13 +143,12 @@ impl Session {
|
||||
/// Adds effective executor-owned configuration from this exact thread snapshot.
|
||||
pub(super) fn project_selected_environment_mcp_servers<'a>(
|
||||
&'a self,
|
||||
session_source: &'a SessionSource,
|
||||
config: &'a Config,
|
||||
environments: &'a TurnEnvironmentSnapshot,
|
||||
mut projection: McpRuntimeProjection,
|
||||
) -> BoxFuture<'a, McpRuntimeProjection> {
|
||||
Box::pin(async move {
|
||||
if crate::guardian::is_basic_session_source(session_source) {
|
||||
if self.isolation == codex_extension_api::SessionIsolation::Isolated {
|
||||
return projection;
|
||||
}
|
||||
|
||||
@@ -306,7 +305,6 @@ impl Session {
|
||||
) {
|
||||
let mcp_projection = self
|
||||
.project_selected_environment_mcp_servers(
|
||||
&desired.session_source,
|
||||
&desired.config,
|
||||
&desired.environments,
|
||||
mcp_projection,
|
||||
|
||||
@@ -580,7 +580,11 @@ impl Session {
|
||||
config
|
||||
.startup_warnings
|
||||
.extend(user_instruction_provider_warnings);
|
||||
let exec_policy = if crate::guardian::is_basic_session_source(&session_source) {
|
||||
let isolation = thread_extension_init
|
||||
.get::<codex_extension_api::SessionIsolation>()
|
||||
.map(|policy| *policy)
|
||||
.unwrap_or_default();
|
||||
let exec_policy = if isolation == codex_extension_api::SessionIsolation::Isolated {
|
||||
let managed_policy = config
|
||||
.config_layer_stack
|
||||
.requirements()
|
||||
|
||||
@@ -58,6 +58,7 @@ pub(crate) struct Session {
|
||||
/// session.
|
||||
pub(super) features: ManagedFeatures,
|
||||
pub(crate) guardian_context_mode: GuardianContextMode,
|
||||
pub(super) isolation: codex_extension_api::SessionIsolation,
|
||||
pub(crate) windows_sandbox_proxy_settings_mode:
|
||||
codex_sandboxing::WindowsSandboxProxySettingsMode,
|
||||
pub(super) multi_agent_version: OnceLock<MultiAgentVersion>,
|
||||
@@ -860,6 +861,10 @@ impl Session {
|
||||
// Publish the already resolved model before extensions make startup decisions.
|
||||
// Turn construction refreshes this attachment when the selected model changes.
|
||||
thread_extension_init.insert(model_info);
|
||||
let isolation = thread_extension_init
|
||||
.get::<codex_extension_api::SessionIsolation>()
|
||||
.map(|policy| *policy)
|
||||
.unwrap_or_default();
|
||||
let mcp_thread_init = thread_extension_init.clone();
|
||||
let thread_extension_data = codex_extension_api::ExtensionData::new_with_init(
|
||||
thread_id.to_string(),
|
||||
@@ -1582,6 +1587,7 @@ impl Session {
|
||||
managed_network_proxy_refresh_lock: Semaphore::new(/*permits*/ 1),
|
||||
features: config.features.clone(),
|
||||
guardian_context_mode,
|
||||
isolation,
|
||||
windows_sandbox_proxy_settings_mode,
|
||||
multi_agent_version,
|
||||
mcp_refresh: McpRefresh::new(),
|
||||
|
||||
@@ -6701,6 +6701,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
managed_network_proxy_refresh_lock: Semaphore::new(/*permits*/ 1),
|
||||
features: config.features.clone(),
|
||||
guardian_context_mode: GuardianContextMode::from_features(&config.features),
|
||||
isolation: codex_extension_api::SessionIsolation::Inherit,
|
||||
windows_sandbox_proxy_settings_mode:
|
||||
codex_sandboxing::WindowsSandboxProxySettingsMode::Reconcile,
|
||||
multi_agent_version: OnceLock::from(config.multi_agent_version_from_features()),
|
||||
@@ -8874,6 +8875,7 @@ where
|
||||
managed_network_proxy_refresh_lock: Semaphore::new(/*permits*/ 1),
|
||||
features: config.features.clone(),
|
||||
guardian_context_mode: GuardianContextMode::from_features(&config.features),
|
||||
isolation: codex_extension_api::SessionIsolation::Inherit,
|
||||
windows_sandbox_proxy_settings_mode:
|
||||
codex_sandboxing::WindowsSandboxProxySettingsMode::Reconcile,
|
||||
multi_agent_version: OnceLock::from(config.multi_agent_version_from_features()),
|
||||
|
||||
@@ -1257,6 +1257,8 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() {
|
||||
/*state_db*/ None,
|
||||
));
|
||||
|
||||
let mut thread_extension_init = codex_extension_api::ExtensionDataInit::default();
|
||||
thread_extension_init.insert(codex_extension_api::SessionIsolation::Isolated);
|
||||
let (session, io) = Session::spawn(SessionSpawnArgs {
|
||||
config,
|
||||
allow_provider_model_fallback: false,
|
||||
@@ -1291,7 +1293,7 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() {
|
||||
user_shell_override: None,
|
||||
parent_trace: None,
|
||||
environment_selections: Vec::new(),
|
||||
thread_extension_init: codex_extension_api::ExtensionDataInit::default(),
|
||||
thread_extension_init,
|
||||
client_mcp_extensions: ClientMcpExtensions::default(),
|
||||
reserved_thread_id: None,
|
||||
analytics_events_client: None,
|
||||
|
||||
Reference in new issue
Block a user