diff --git a/codex-cli/scripts/run_in_container.sh b/codex-cli/scripts/run_in_container.sh
index 01070cf04b1d..607ec297a6c8 100755
--- a/codex-cli/scripts/run_in_container.sh
+++ b/codex-cli/scripts/run_in_container.sh
@@ -92,4 +92,4 @@ quoted_args=""
 for arg in "$@"; do
   quoted_args+=" $(printf '%q' "$arg")"
 done
-docker exec -it "$CONTAINER_NAME" bash -c "cd \"/app$WORK_DIR\" && codex --full-auto ${quoted_args}"
+docker exec -it "$CONTAINER_NAME" bash -c "cd \"/app$WORK_DIR\" && codex --sandbox workspace-write --ask-for-approval on-request ${quoted_args}"
diff --git a/codex-rs/README.md b/codex-rs/README.md
index 31bae56235fc..d219061a350e 100644
--- a/codex-rs/README.md
+++ b/codex-rs/README.md
@@ -59,19 +59,22 @@ To test to see what happens when a command is run under the sandbox provided by
 
 ```
 # macOS
-codex sandbox macos [--full-auto] [--log-denials] [COMMAND]...
+codex sandbox macos [--log-denials] [COMMAND]...
 
 # Linux
-codex sandbox linux [--full-auto] [COMMAND]...
+codex sandbox linux [COMMAND]...
 
 # Windows
-codex sandbox windows [--full-auto] [COMMAND]...
+codex sandbox windows [COMMAND]...
 
 # Legacy aliases
-codex debug seatbelt [--full-auto] [--log-denials] [COMMAND]...
-codex debug landlock [--full-auto] [COMMAND]...
+codex debug seatbelt [--log-denials] [COMMAND]...
+codex debug landlock [COMMAND]...
 ```
 
+To try a writable legacy sandbox mode with these commands, pass an explicit config override such
+as `-c 'sandbox_mode="workspace-write"'`.
+
 ### Selecting a sandbox policy via `--sandbox`
 
 The Rust CLI exposes a dedicated `--sandbox` (`-s`) flag that lets you pick the sandbox policy **without** having to reach for the generic `-c/--config` option:
diff --git a/codex-rs/cli/src/debug_sandbox.rs b/codex-rs/cli/src/debug_sandbox.rs
index c85da0f5f2d0..a08a81a529ed 100644
--- a/codex-rs/cli/src/debug_sandbox.rs
+++ b/codex-rs/cli/src/debug_sandbox.rs
@@ -41,14 +41,12 @@ pub async fn run_command_under_seatbelt(
     codex_linux_sandbox_exe: Option<PathBuf>,
 ) -> anyhow::Result<()> {
     let SeatbeltCommand {
-        full_auto,
         allow_unix_sockets,
         log_denials,
         config_overrides,
         command,
     } = command;
     run_command_under_sandbox(
-        full_auto,
         command,
         config_overrides,
         codex_linux_sandbox_exe,
@@ -72,12 +70,10 @@ pub async fn run_command_under_landlock(
     codex_linux_sandbox_exe: Option<PathBuf>,
 ) -> anyhow::Result<()> {
     let LandlockCommand {
-        full_auto,
         config_overrides,
         command,
     } = command;
     run_command_under_sandbox(
-        full_auto,
         command,
         config_overrides,
         codex_linux_sandbox_exe,
@@ -93,12 +89,10 @@ pub async fn run_command_under_windows(
     codex_linux_sandbox_exe: Option<PathBuf>,
 ) -> anyhow::Result<()> {
     let WindowsCommand {
-        full_auto,
         config_overrides,
         command,
     } = command;
     run_command_under_sandbox(
-        full_auto,
         command,
         config_overrides,
         codex_linux_sandbox_exe,
@@ -117,7 +111,6 @@ enum SandboxType {
 }
 
 async fn run_command_under_sandbox(
-    full_auto: bool,
     command: Vec<String>,
     config_overrides: CliConfigOverrides,
     codex_linux_sandbox_exe: Option<PathBuf>,
@@ -131,7 +124,6 @@ async fn run_command_under_sandbox(
             .parse_overrides()
             .map_err(anyhow::Error::msg)?,
         codex_linux_sandbox_exe,
-        full_auto,
     )
     .await?;
 
@@ -406,14 +398,6 @@ async fn run_command_under_windows_session(
     std::process::exit(exit_code);
 }
 
-pub fn create_sandbox_mode(full_auto: bool) -> SandboxMode {
-    if full_auto {
-        SandboxMode::WorkspaceWrite
-    } else {
-        SandboxMode::ReadOnly
-    }
-}
-
 async fn spawn_debug_sandbox_child(
     program: PathBuf,
     args: Vec<String>,
@@ -583,12 +567,10 @@ mod windows_stdio_bridge {
 async fn load_debug_sandbox_config(
     cli_overrides: Vec<(String, TomlValue)>,
     codex_linux_sandbox_exe: Option<PathBuf>,
-    full_auto: bool,
 ) -> anyhow::Result<Config> {
     load_debug_sandbox_config_with_codex_home(
         cli_overrides,
         codex_linux_sandbox_exe,
-        full_auto,
         /*codex_home*/ None,
     )
     .await
@@ -597,9 +579,14 @@ async fn load_debug_sandbox_config(
 async fn load_debug_sandbox_config_with_codex_home(
     cli_overrides: Vec<(String, TomlValue)>,
     codex_linux_sandbox_exe: Option<PathBuf>,
-    full_auto: bool,
     codex_home: Option<PathBuf>,
 ) -> anyhow::Result<Config> {
+    // For legacy configs, `codex sandbox` historically defaulted to read-only
+    // instead of inheriting ambient `sandbox_mode` settings from user/system
+    // config. Keep that behavior unless this invocation explicitly passes a
+    // legacy `sandbox_mode` CLI override, which is now the documented writable
+    // replacement for the removed `--full-auto` flag.
+    let uses_legacy_sandbox_mode_override = cli_overrides_use_legacy_sandbox_mode(&cli_overrides);
     let config = build_debug_sandbox_config(
         cli_overrides.clone(),
         ConfigOverrides {
@@ -610,19 +597,14 @@ async fn load_debug_sandbox_config_with_codex_home(
     )
     .await?;
 
-    if config_uses_permission_profiles(&config) {
-        if full_auto {
-            anyhow::bail!(
-                "`codex sandbox --full-auto` is only supported for legacy `sandbox_mode` configs; choose a writable `[permissions]` profile instead"
-            );
-        }
+    if config_uses_permission_profiles(&config) || uses_legacy_sandbox_mode_override {
         return Ok(config);
     }
 
     build_debug_sandbox_config(
         cli_overrides,
         ConfigOverrides {
-            sandbox_mode: Some(create_sandbox_mode(full_auto)),
+            sandbox_mode: Some(SandboxMode::ReadOnly),
             codex_linux_sandbox_exe,
             ..Default::default()
         },
@@ -656,9 +638,14 @@ fn config_uses_permission_profiles(config: &Config) -> bool {
         .is_some()
 }
 
+fn cli_overrides_use_legacy_sandbox_mode(cli_overrides: &[(String, TomlValue)]) -> bool {
+    cli_overrides.iter().any(|(key, _)| key == "sandbox_mode")
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
+    use pretty_assertions::assert_eq;
     use tempfile::TempDir;
 
     fn escape_toml_path(path: &std::path::Path) -> String {
@@ -705,7 +692,7 @@ mod tests {
         let legacy_config = build_debug_sandbox_config(
             Vec::new(),
             ConfigOverrides {
-                sandbox_mode: Some(create_sandbox_mode(/*full_auto*/ false)),
+                sandbox_mode: Some(SandboxMode::ReadOnly),
                 ..Default::default()
             },
             Some(codex_home_path.clone()),
@@ -715,7 +702,6 @@ mod tests {
         let config = load_debug_sandbox_config_with_codex_home(
             Vec::new(),
             /*codex_linux_sandbox_exe*/ None,
-            /*full_auto*/ false,
             Some(codex_home_path),
         )
         .await?;
@@ -739,25 +725,90 @@ mod tests {
     }
 
     #[tokio::test]
-    async fn debug_sandbox_rejects_full_auto_for_permission_profiles() -> anyhow::Result<()> {
+    async fn debug_sandbox_honors_explicit_legacy_sandbox_mode() -> anyhow::Result<()> {
         let codex_home = TempDir::new()?;
-        let sandbox_paths = TempDir::new()?;
-        let docs = sandbox_paths.path().join("docs");
-        let private = docs.join("private");
-        write_permissions_profile_config(&codex_home, &docs, &private)?;
+        let codex_home_path = codex_home.path().to_path_buf();
+        let cli_overrides = vec![(
+            "sandbox_mode".to_string(),
+            TomlValue::String("workspace-write".to_string()),
+        )];
 
-        let err = load_debug_sandbox_config_with_codex_home(
+        let workspace_write_config = build_debug_sandbox_config(
+            cli_overrides.clone(),
+            ConfigOverrides::default(),
+            Some(codex_home_path.clone()),
+        )
+        .await?;
+        let read_only_config = build_debug_sandbox_config(
             Vec::new(),
+            ConfigOverrides {
+                sandbox_mode: Some(SandboxMode::ReadOnly),
+                ..Default::default()
+            },
+            Some(codex_home_path.clone()),
+        )
+        .await?;
+
+        let config = load_debug_sandbox_config_with_codex_home(
+            cli_overrides,
             /*codex_linux_sandbox_exe*/ None,
-            /*full_auto*/ true,
-            Some(codex_home.path().to_path_buf()),
+            Some(codex_home_path),
         )
-        .await
-        .expect_err("full-auto should be rejected for active permission profiles");
+        .await?;
 
-        assert!(
-            err.to_string().contains("--full-auto"),
-            "unexpected error: {err}"
+        if cfg!(target_os = "windows") {
+            assert_eq!(
+                workspace_write_config
+                    .permissions
+                    .file_system_sandbox_policy(),
+                read_only_config.permissions.file_system_sandbox_policy(),
+                "workspace-write downgrades to read-only when the Windows sandbox is disabled"
+            );
+        } else {
+            assert_ne!(
+                workspace_write_config
+                    .permissions
+                    .file_system_sandbox_policy(),
+                read_only_config.permissions.file_system_sandbox_policy(),
+                "test fixture should distinguish explicit workspace-write from read-only"
+            );
+        }
+        assert_eq!(
+            config.permissions.file_system_sandbox_policy(),
+            workspace_write_config
+                .permissions
+                .file_system_sandbox_policy(),
+        );
+
+        Ok(())
+    }
+
+    #[tokio::test]
+    async fn debug_sandbox_defaults_legacy_configs_to_read_only() -> anyhow::Result<()> {
+        let codex_home = TempDir::new()?;
+        let codex_home_path = codex_home.path().to_path_buf();
+
+        let read_only_config = build_debug_sandbox_config(
+            Vec::new(),
+            ConfigOverrides {
+                sandbox_mode: Some(SandboxMode::ReadOnly),
+                ..Default::default()
+            },
+            Some(codex_home_path.clone()),
+        )
+        .await?;
+
+        let config = load_debug_sandbox_config_with_codex_home(
+            Vec::new(),
+            /*codex_linux_sandbox_exe*/ None,
+            Some(codex_home_path),
+        )
+        .await?;
+
+        assert!(!config_uses_permission_profiles(&config));
+        assert_eq!(
+            config.permissions.file_system_sandbox_policy(),
+            read_only_config.permissions.file_system_sandbox_policy(),
         );
 
         Ok(())
diff --git a/codex-rs/cli/src/lib.rs b/codex-rs/cli/src/lib.rs
index 3f3448c64c3d..1f396854588a 100644
--- a/codex-rs/cli/src/lib.rs
+++ b/codex-rs/cli/src/lib.rs
@@ -21,10 +21,6 @@ pub use login::run_logout;
 
 #[derive(Debug, Parser)]
 pub struct SeatbeltCommand {
-    /// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
-    #[arg(long = "full-auto", default_value_t = false)]
-    pub full_auto: bool,
-
     /// Allow the sandboxed command to bind/connect AF_UNIX sockets rooted at this path. Relative paths are resolved against the current directory. Repeat to allow multiple paths.
     #[arg(long = "allow-unix-socket", value_parser = parse_allow_unix_socket_path)]
     pub allow_unix_sockets: Vec<AbsolutePathBuf>,
@@ -48,10 +44,6 @@ fn parse_allow_unix_socket_path(raw: &str) -> Result<AbsolutePathBuf, String> {
 
 #[derive(Debug, Parser)]
 pub struct LandlockCommand {
-    /// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
-    #[arg(long = "full-auto", default_value_t = false)]
-    pub full_auto: bool,
-
     #[clap(skip)]
     pub config_overrides: CliConfigOverrides,
 
@@ -62,10 +54,6 @@ pub struct LandlockCommand {
 
 #[derive(Debug, Parser)]
 pub struct WindowsCommand {
-    /// Convenience alias for low-friction sandboxed automatic execution (network-disabled sandbox that can write to cwd and TMPDIR)
-    #[arg(long = "full-auto", default_value_t = false)]
-    pub full_auto: bool,
-
     #[clap(skip)]
     pub config_overrides: CliConfigOverrides,
 
diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs
index 1c2eabf986a3..01e44fd8ca33 100644
--- a/codex-rs/cli/src/main.rs
+++ b/codex-rs/cli/src/main.rs
@@ -1352,16 +1352,12 @@ async fn run_debug_prompt_input_command(
         ));
     }
 
-    let approval_policy = if shared.full_auto {
-        Some(AskForApproval::OnRequest)
-    } else if shared.dangerously_bypass_approvals_and_sandbox {
+    let approval_policy = if shared.dangerously_bypass_approvals_and_sandbox {
         Some(AskForApproval::Never)
     } else {
         interactive.approval_policy.map(Into::into)
     };
-    let sandbox_mode = if shared.full_auto {
-        Some(codex_protocol::config_types::SandboxMode::WorkspaceWrite)
-    } else if shared.dangerously_bypass_approvals_and_sandbox {
+    let sandbox_mode = if shared.dangerously_bypass_approvals_and_sandbox {
         Some(codex_protocol::config_types::SandboxMode::DangerFullAccess)
     } else {
         shared.sandbox_mode.map(Into::into)
@@ -1950,6 +1946,35 @@ mod tests {
         assert!(remove_result.is_err());
     }
 
+    #[test]
+    fn full_auto_no_longer_parses_at_top_level() {
+        let result = MultitoolCli::try_parse_from(["codex", "--full-auto"]);
+
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn exec_full_auto_reports_migration_path() {
+        let cli = MultitoolCli::try_parse_from(["codex", "exec", "--full-auto", "summarize"])
+            .expect("exec should accept removed flag long enough to report a migration path");
+        let Some(Subcommand::Exec(exec)) = cli.subcommand else {
+            panic!("expected exec subcommand");
+        };
+
+        assert_eq!(
+            exec.removed_full_auto_warning(),
+            Some("warning: `--full-auto` is deprecated; use `--sandbox workspace-write` instead.")
+        );
+    }
+
+    #[test]
+    fn sandbox_full_auto_no_longer_parses() {
+        let result =
+            MultitoolCli::try_parse_from(["codex", "sandbox", "linux", "--full-auto", "--"]);
+
+        assert!(result.is_err());
+    }
+
     fn sample_exit_info(conversation_id: Option<&str>, thread_name: Option<&str>) -> AppExitInfo {
         let token_usage = TokenUsage {
             output_tokens: 2,
@@ -2080,14 +2105,13 @@ mod tests {
     }
 
     #[test]
-    fn resume_merges_option_flags_and_full_auto() {
+    fn resume_merges_option_flags() {
         let interactive = finalize_resume_from_args(
             [
                 "codex",
                 "resume",
                 "sid",
                 "--oss",
-                "--full-auto",
                 "--search",
                 "--sandbox",
                 "workspace-write",
@@ -2116,7 +2140,6 @@ mod tests {
             interactive.approval_policy,
             Some(codex_utils_cli::ApprovalModeCliArg::OnRequest)
         );
-        assert!(interactive.full_auto);
         assert_eq!(
             interactive.cwd.as_deref(),
             Some(std::path::Path::new("/tmp"))
diff --git a/codex-rs/exec/src/cli.rs b/codex-rs/exec/src/cli.rs
index cbdf695562a1..2b12898c3cdf 100644
--- a/codex-rs/exec/src/cli.rs
+++ b/codex-rs/exec/src/cli.rs
@@ -35,6 +35,16 @@ pub struct Cli {
     #[arg(long = "ignore-rules", global = true, default_value_t = false)]
     pub ignore_rules: bool,
 
+    /// Legacy compatibility trap for the removed `--full-auto` flag.
+    #[arg(
+        long = "full-auto",
+        hide = true,
+        global = true,
+        default_value_t = false,
+        conflicts_with = "dangerously_bypass_approvals_and_sandbox"
+    )]
+    pub removed_full_auto: bool,
+
     /// Path to a JSON Schema file describing the model's final response shape.
     #[arg(long = "output-schema", value_name = "FILE")]
     pub output_schema: Option<PathBuf>,
@@ -85,6 +95,18 @@ impl std::ops::DerefMut for Cli {
     }
 }
 
+impl Cli {
+    pub fn removed_full_auto_warning(&self) -> Option<&'static str> {
+        if self.removed_full_auto {
+            return Some(
+                "warning: `--full-auto` is deprecated; use `--sandbox workspace-write` instead.",
+            );
+        }
+
+        None
+    }
+}
+
 #[derive(Debug, Default)]
 pub struct ExecSharedCliOptions(SharedCliOptions);
 
@@ -130,7 +152,6 @@ impl FromArgMatches for ExecSharedCliOptions {
 
 fn mark_exec_global_args(cmd: clap::Command) -> clap::Command {
     cmd.mut_arg("model", |arg| arg.global(true))
-        .mut_arg("full_auto", |arg| arg.global(true))
         .mut_arg("dangerously_bypass_approvals_and_sandbox", |arg| {
             arg.global(true)
         })
diff --git a/codex-rs/exec/src/cli_tests.rs b/codex-rs/exec/src/cli_tests.rs
index dfa202884b00..45f2aa330d8a 100644
--- a/codex-rs/exec/src/cli_tests.rs
+++ b/codex-rs/exec/src/cli_tests.rs
@@ -70,3 +70,13 @@ fn parses_config_isolation_flags() {
     assert!(cli.ignore_user_config);
     assert!(cli.ignore_rules);
 }
+
+#[test]
+fn removed_full_auto_flag_reports_migration_path() {
+    let cli = Cli::parse_from(["codex-exec", "--full-auto", "summarize"]);
+
+    assert_eq!(
+        cli.removed_full_auto_warning(),
+        Some("warning: `--full-auto` is deprecated; use `--sandbox workspace-write` instead.")
+    );
+}
diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs
index d4044a728d86..fbc2d7e9ff1f 100644
--- a/codex-rs/exec/src/lib.rs
+++ b/codex-rs/exec/src/lib.rs
@@ -216,6 +216,11 @@ fn exec_root_span() -> tracing::Span {
 }
 
 pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result<()> {
+    #[allow(clippy::print_stderr)]
+    if let Some(message) = cli.removed_full_auto_warning() {
+        eprintln!("{message}");
+    }
+
     if let Err(err) = set_default_originator("codex_exec".to_string()) {
         tracing::warn!(?err, "Failed to set codex exec originator override {err:?}");
     }
@@ -227,6 +232,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
         ephemeral,
         ignore_user_config,
         ignore_rules,
+        removed_full_auto,
         color,
         last_message_file,
         json: json_mode,
@@ -242,7 +248,6 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
         oss_provider,
         config_profile,
         sandbox_mode: sandbox_mode_cli_arg,
-        full_auto,
         dangerously_bypass_approvals_and_sandbox,
         cwd,
         add_dir,
@@ -269,7 +274,7 @@ pub async fn run_main(cli: Cli, arg0_paths: Arg0DispatchPaths) -> anyhow::Result
         .with_writer(std::io::stderr)
         .with_filter(env_filter);
 
-    let sandbox_mode = if full_auto {
+    let sandbox_mode = if removed_full_auto {
         Some(SandboxMode::WorkspaceWrite)
     } else if dangerously_bypass_approvals_and_sandbox {
         Some(SandboxMode::DangerFullAccess)
diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs
index 977fcc4b6d2d..f1efd61ef540 100644
--- a/codex-rs/tui/src/lib.rs
+++ b/codex-rs/tui/src/lib.rs
@@ -696,12 +696,7 @@ pub async fn run_main(
         .cwd
         .clone()
         .filter(|_| matches!(app_server_target, AppServerTarget::Remote { .. }));
-    let (sandbox_mode, approval_policy) = if cli.full_auto {
-        (
-            Some(SandboxMode::WorkspaceWrite),
-            Some(AskForApproval::OnRequest),
-        )
-    } else if cli.dangerously_bypass_approvals_and_sandbox {
+    let (sandbox_mode, approval_policy) = if cli.dangerously_bypass_approvals_and_sandbox {
         (
             Some(SandboxMode::DangerFullAccess),
             Some(AskForApproval::Never),
diff --git a/codex-rs/utils/cli/src/shared_options.rs b/codex-rs/utils/cli/src/shared_options.rs
index b9e47c8d8411..c174a7b5a654 100644
--- a/codex-rs/utils/cli/src/shared_options.rs
+++ b/codex-rs/utils/cli/src/shared_options.rs
@@ -38,17 +38,12 @@ pub struct SharedCliOptions {
     #[arg(long = "sandbox", short = 's')]
     pub sandbox_mode: Option<SandboxModeCliArg>,
 
-    /// Convenience alias for low-friction sandboxed automatic execution.
-    #[arg(long = "full-auto", default_value_t = false)]
-    pub full_auto: bool,
-
     /// Skip all confirmation prompts and execute commands without sandboxing.
     /// EXTREMELY DANGEROUS. Intended solely for running in environments that are externally sandboxed.
     #[arg(
         long = "dangerously-bypass-approvals-and-sandbox",
         alias = "yolo",
-        default_value_t = false,
-        conflicts_with = "full_auto"
+        default_value_t = false
     )]
     pub dangerously_bypass_approvals_and_sandbox: bool,
 
@@ -63,9 +58,8 @@ pub struct SharedCliOptions {
 
 impl SharedCliOptions {
     pub fn inherit_exec_root_options(&mut self, root: &Self) {
-        let self_selected_sandbox_mode = self.sandbox_mode.is_some()
-            || self.full_auto
-            || self.dangerously_bypass_approvals_and_sandbox;
+        let self_selected_sandbox_mode =
+            self.sandbox_mode.is_some() || self.dangerously_bypass_approvals_and_sandbox;
         let Self {
             images,
             model,
@@ -73,7 +67,6 @@ impl SharedCliOptions {
             oss_provider,
             config_profile,
             sandbox_mode,
-            full_auto,
             dangerously_bypass_approvals_and_sandbox,
             cwd,
             add_dir,
@@ -85,7 +78,6 @@ impl SharedCliOptions {
             oss_provider: root_oss_provider,
             config_profile: root_config_profile,
             sandbox_mode: root_sandbox_mode,
-            full_auto: root_full_auto,
             dangerously_bypass_approvals_and_sandbox: root_dangerously_bypass_approvals_and_sandbox,
             cwd: root_cwd,
             add_dir: root_add_dir,
@@ -107,7 +99,6 @@ impl SharedCliOptions {
             *sandbox_mode = *root_sandbox_mode;
         }
         if !self_selected_sandbox_mode {
-            *full_auto = *root_full_auto;
             *dangerously_bypass_approvals_and_sandbox =
                 *root_dangerously_bypass_approvals_and_sandbox;
         }
@@ -128,7 +119,6 @@ impl SharedCliOptions {
 
     pub fn apply_subcommand_overrides(&mut self, subcommand: Self) {
         let subcommand_selected_sandbox_mode = subcommand.sandbox_mode.is_some()
-            || subcommand.full_auto
             || subcommand.dangerously_bypass_approvals_and_sandbox;
         let Self {
             images,
@@ -137,7 +127,6 @@ impl SharedCliOptions {
             oss_provider,
             config_profile,
             sandbox_mode,
-            full_auto,
             dangerously_bypass_approvals_and_sandbox,
             cwd,
             add_dir,
@@ -157,7 +146,6 @@ impl SharedCliOptions {
         }
         if subcommand_selected_sandbox_mode {
             self.sandbox_mode = sandbox_mode;
-            self.full_auto = full_auto;
             self.dangerously_bypass_approvals_and_sandbox =
                 dangerously_bypass_approvals_and_sandbox;
         }
diff --git a/codex-rs/windows-sandbox-rs/sandbox_smoketests.py b/codex-rs/windows-sandbox-rs/sandbox_smoketests.py
index f629a4c6d9d9..f6689587f5ce 100644
--- a/codex-rs/windows-sandbox-rs/sandbox_smoketests.py
+++ b/codex-rs/windows-sandbox-rs/sandbox_smoketests.py
@@ -74,11 +74,13 @@ def run_sbx(
     env.update(ENV_BASE)
     if env_extra:
         env.update(env_extra)
-    # Map policy to codex CLI flags
-    # read-only => default; workspace-write => --full-auto
+    # Map policy to codex CLI overrides.
+    # read-only => default; workspace-write => legacy sandbox_mode override
     if policy not in ("read-only", "workspace-write"):
         raise ValueError(f"unknown policy: {policy}")
-    policy_flags: List[str] = ["--full-auto"] if policy == "workspace-write" else []
+    policy_flags: List[str] = (
+        ["-c", 'sandbox_mode="workspace-write"'] if policy == "workspace-write" else []
+    )
 
     overrides: List[str] = []
     if policy == "workspace-write" and additional_root is not None:
