app-server: reload config for Windows thread forks

git-stack-id: aaron/app-server-in-memory-config---4ivokd7wtu-snl
git-stack-title: app-server: add in-memory config layer
This commit is contained in:
Aaron Levine
2026-06-03 20:37:14 -07:00
parent 9a5113ad73
commit 37f9c6d53a
2 changed files with 51 additions and 17 deletions
@@ -3188,23 +3188,7 @@ impl ThreadRequestProcessor {
})?;
let history_cwd = Some(source_thread.cwd.clone());
// Persist Windows sandbox mode.
let mut cli_overrides = cli_overrides.unwrap_or_default();
if cfg!(windows) {
match WindowsSandboxLevel::from_config(&self.config) {
WindowsSandboxLevel::Elevated => {
cli_overrides
.insert("windows.sandbox".to_string(), serde_json::json!("elevated"));
}
WindowsSandboxLevel::RestrictedToken => {
cli_overrides.insert(
"windows.sandbox".to_string(),
serde_json::json!("unelevated"),
);
}
WindowsSandboxLevel::Disabled => {}
}
}
let cli_overrides = cli_overrides.unwrap_or_default();
let request_overrides = if cli_overrides.is_empty() {
None
} else {
@@ -10,6 +10,8 @@ use codex_app_server_protocol::JSONRPCError;
use codex_app_server_protocol::JSONRPCMessage;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::RequestId;
#[cfg(windows)]
use codex_app_server_protocol::SandboxPolicy;
use codex_app_server_protocol::ServerNotification;
use codex_app_server_protocol::SessionSource;
use codex_app_server_protocol::ThreadForkParams;
@@ -674,6 +676,54 @@ async fn thread_fork_surfaces_cloud_config_bundle_load_errors() -> Result<()> {
Ok(())
}
#[cfg(windows)]
#[tokio::test]
async fn thread_fork_reloads_windows_sandbox_config_instead_of_startup_snapshot() -> Result<()> {
let codex_home = TempDir::new()?;
std::fs::write(
codex_home.path().join("config.toml"),
"[windows]\nsandbox = \"elevated\"\n",
)?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
.send_thread_start_request(ThreadStartParams::default())
.await?;
let start_response: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(start_id)),
)
.await??;
let start_response: ThreadStartResponse = to_response(start_response)?;
assert!(
matches!(start_response.sandbox, SandboxPolicy::WorkspaceWrite { .. }),
"elevated Windows sandbox config should select workspace-write defaults"
);
std::fs::write(codex_home.path().join("config.toml"), "")?;
let fork_id = mcp
.send_thread_fork_request(ThreadForkParams {
thread_id: start_response.thread.id,
..Default::default()
})
.await?;
let fork_response: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(fork_id)),
)
.await??;
let fork_response: ThreadForkResponse = to_response(fork_response)?;
assert!(
matches!(fork_response.sandbox, SandboxPolicy::ReadOnly { .. }),
"fork should resolve the updated config.toml instead of pinning startup Windows sandbox state"
);
Ok(())
}
#[tokio::test]
async fn thread_fork_ephemeral_remains_pathless_and_omits_listing() -> Result<()> {
let server = create_mock_responses_server_repeating_assistant("Done").await;