[codex] preserve explicit environment cwd (#27995)

## Why

`TurnEnvironmentSelections::new` rewrote the primary environment's
explicit `cwd` to the legacy fallback cwd. For a remote-first selection,
this could replace the remote working directory with a local fallback
path and made the legacy cwd overlay authoritative over
environment-owned state.

## What changed

- Preserve every explicit environment cwd when constructing turn
environment selections.
- Keep `cwd`-only app-server updates compatible by rebuilding the
default environment selections at the requested cwd.
- Cover both explicit primary cwd preservation and cwd-only updates
reaching the model-visible execution environment.

## Testing

- `just test -p codex-core
session_update_settings_does_not_rewrite_sticky_environment_cwds`
- `just test -p codex-core
environment_settings_preserve_explicit_primary_cwd`
- `just test -p codex-app-server
thread_settings_update_cwd_retargets_default_environment`
This commit is contained in:
pakrym-oai
2026-06-15 17:17:34 +00:00
committed by GitHub
parent 495da45643
commit bd4fe31c5a
4 changed files with 99 additions and 47 deletions
+14 -7
View File
@@ -4615,6 +4615,7 @@ async fn session_update_settings_does_not_rewrite_sticky_environment_cwds() {
.environment_selections()
.to_vec()
};
let expected_environments = current_environments.clone();
std::fs::create_dir_all(updated_cwd.as_path()).expect("create project dir");
session
@@ -4628,21 +4629,28 @@ async fn session_update_settings_does_not_rewrite_sticky_environment_cwds() {
.await
.expect("cwd update should succeed");
let session_cwd = {
let (session_cwd, stored_environments) = {
let state = session.state.lock().await;
state.session_configuration.cwd().clone()
(
state.session_configuration.cwd().clone(),
state
.session_configuration
.environment_selections()
.to_vec(),
)
};
let config = session.get_config().await;
let next_turn = session.new_default_turn().await;
assert_eq!(session_cwd, updated_cwd);
assert_eq!(stored_environments, expected_environments);
#[allow(deprecated)]
let turn_cwd = turn_context.cwd.clone();
#[allow(deprecated)]
let next_turn_cwd = next_turn.cwd.clone();
assert_eq!(config.cwd, turn_cwd);
assert_eq!(next_turn_cwd, updated_cwd);
assert_eq!(next_turn.config.cwd, updated_cwd);
assert_eq!(next_turn_cwd, turn_cwd);
assert_eq!(next_turn.config.cwd, turn_cwd);
}
#[tokio::test]
@@ -4678,7 +4686,7 @@ async fn relative_cwd_update_without_environments_resolves_under_session_cwd() {
}
#[tokio::test]
async fn cwd_update_rewrites_sticky_environment_cwd() {
async fn environment_settings_preserve_explicit_primary_cwd() {
let (session, _turn_context) = make_session_and_context().await;
let (original_cwd, environment_cwd, environments) = {
let mut state = session.state.lock().await;
@@ -4706,9 +4714,8 @@ async fn cwd_update_rewrites_sticky_environment_cwd() {
assert_eq!(state.session_configuration.cwd(), &updated_cwd);
assert_eq!(
state.session_configuration.environment_selections()[0].cwd,
PathUri::from_abs_path(&updated_cwd)
PathUri::from_abs_path(&environment_cwd)
);
assert_ne!(environment_cwd, updated_cwd);
}
#[tokio::test]