@@ -48,6 +48,7 @@ use codex_app_server_protocol::ThreadDeletedNotification;
4848use codex_app_server_protocol:: ThreadItem ;
4949use codex_app_server_protocol:: ThreadLoadedListParams ;
5050use codex_app_server_protocol:: ThreadLoadedListResponse ;
51+ use codex_app_server_protocol:: ThreadSettingsUpdatedNotification ;
5152use codex_app_server_protocol:: ThreadSource ;
5253use codex_app_server_protocol:: ThreadStartParams ;
5354use codex_app_server_protocol:: ThreadStartResponse ;
@@ -64,6 +65,7 @@ use codex_app_server_protocol::WarningNotification;
6465use codex_config:: config_toml:: ConfigToml ;
6566use codex_core:: personality_migration:: PERSONALITY_MIGRATION_FILENAME ;
6667use codex_core:: test_support:: all_model_presets;
68+ use codex_exec_server:: LOCAL_ENVIRONMENT_ID ;
6769use codex_features:: FEATURES ;
6870use codex_features:: Feature ;
6971use codex_protocol:: config_types:: CollaborationMode ;
@@ -2532,7 +2534,7 @@ async fn turn_start_exec_approval_decline_v2() -> Result<()> {
25322534}
25332535
25342536#[ tokio:: test]
2535- async fn turn_start_updates_sandbox_and_cwd_between_turns_v2 ( ) -> Result < ( ) > {
2537+ async fn turn_start_explicit_local_environment_updates_legacy_cwd_between_turns ( ) -> Result < ( ) > {
25362538 // TODO(anp): Materialize cwd and shell-display fixtures in the selected remote environment.
25372539 skip_if_remote ! ( Ok ( ( ) ) , "cwd fixtures are only materialized on the host" ) ;
25382540 skip_if_no_network ! ( Ok ( ( ) ) ) ;
@@ -2636,10 +2638,15 @@ async fn turn_start_updates_sandbox_and_cwd_between_turns_v2() -> Result<()> {
26362638 . await ??;
26372639 mcp. clear_message_buffer ( ) ;
26382640
2639- // second turn with workspace-write and second_cwd, ensure exec begins in second_cwd
2641+ // Select a new local cwd without the top-level compatibility parameter. The inherited
2642+ // workspace-write sandbox must follow the local environment cwd.
26402643 let second_turn = mcp
26412644 . send_turn_start_request ( TurnStartParams {
2642- environments : None ,
2645+ environments : Some ( vec ! [ TurnEnvironmentParams {
2646+ environment_id: LOCAL_ENVIRONMENT_ID . to_string( ) ,
2647+ cwd: second_cwd. abs( ) . into( ) ,
2648+ runtime_workspace_roots: None ,
2649+ } ] ) ,
26432650 thread_id : thread. id . clone ( ) ,
26442651 client_user_message_id : None ,
26452652 input : vec ! [ V2UserInput :: Text {
@@ -2648,11 +2655,11 @@ async fn turn_start_updates_sandbox_and_cwd_between_turns_v2() -> Result<()> {
26482655 } ] ,
26492656 responsesapi_client_metadata : None ,
26502657 additional_context : None ,
2651- cwd : Some ( second_cwd . clone ( ) ) ,
2658+ cwd : None ,
26522659 runtime_workspace_roots : None ,
26532660 approval_policy : Some ( codex_app_server_protocol:: AskForApproval :: Never ) ,
26542661 approvals_reviewer : None ,
2655- sandbox_policy : Some ( codex_app_server_protocol :: SandboxPolicy :: DangerFullAccess ) ,
2662+ sandbox_policy : None ,
26562663 permissions : None ,
26572664 model : Some ( "mock-model" . to_string ( ) ) ,
26582665 effort : Some ( ReasoningEffort :: Medium ) ,
@@ -2669,6 +2676,17 @@ async fn turn_start_updates_sandbox_and_cwd_between_turns_v2() -> Result<()> {
26692676 mcp. read_stream_until_response_message ( RequestId :: Integer ( second_turn) ) ,
26702677 )
26712678 . await ??;
2679+ let settings_updated = timeout (
2680+ DEFAULT_READ_TIMEOUT ,
2681+ mcp. read_stream_until_notification_message ( "thread/settings/updated" ) ,
2682+ )
2683+ . await ??;
2684+ let settings_updated: ThreadSettingsUpdatedNotification = serde_json:: from_value (
2685+ settings_updated
2686+ . params
2687+ . context ( "thread/settings/updated should include params" ) ?,
2688+ ) ?;
2689+ assert_eq ! ( settings_updated. thread_settings. cwd, second_cwd. abs( ) ) ;
26722690
26732691 let command_exec_item = timeout ( DEFAULT_READ_TIMEOUT , async {
26742692 loop {
0 commit comments