@@ -42,14 +42,12 @@ pub async fn run_command_under_seatbelt(
4242 codex_linux_sandbox_exe : Option < PathBuf > ,
4343) -> anyhow:: Result < ( ) > {
4444 let SeatbeltCommand {
45- full_auto,
4645 allow_unix_sockets,
4746 log_denials,
4847 config_overrides,
4948 command,
5049 } = command;
5150 run_command_under_sandbox (
52- full_auto,
5351 command,
5452 config_overrides,
5553 codex_linux_sandbox_exe,
@@ -73,12 +71,10 @@ pub async fn run_command_under_landlock(
7371 codex_linux_sandbox_exe : Option < PathBuf > ,
7472) -> anyhow:: Result < ( ) > {
7573 let LandlockCommand {
76- full_auto,
7774 config_overrides,
7875 command,
7976 } = command;
8077 run_command_under_sandbox (
81- full_auto,
8278 command,
8379 config_overrides,
8480 codex_linux_sandbox_exe,
@@ -94,12 +90,10 @@ pub async fn run_command_under_windows(
9490 codex_linux_sandbox_exe : Option < PathBuf > ,
9591) -> anyhow:: Result < ( ) > {
9692 let WindowsCommand {
97- full_auto,
9893 config_overrides,
9994 command,
10095 } = command;
10196 run_command_under_sandbox (
102- full_auto,
10397 command,
10498 config_overrides,
10599 codex_linux_sandbox_exe,
@@ -118,7 +112,6 @@ enum SandboxType {
118112}
119113
120114async fn run_command_under_sandbox (
121- full_auto : bool ,
122115 command : Vec < String > ,
123116 config_overrides : CliConfigOverrides ,
124117 codex_linux_sandbox_exe : Option < PathBuf > ,
@@ -132,7 +125,6 @@ async fn run_command_under_sandbox(
132125 . parse_overrides ( )
133126 . map_err ( anyhow:: Error :: msg) ?,
134127 codex_linux_sandbox_exe,
135- full_auto,
136128 )
137129 . await ?;
138130
@@ -402,14 +394,6 @@ async fn run_command_under_windows_session(
402394 std:: process:: exit ( exit_code) ;
403395}
404396
405- pub fn create_sandbox_mode ( full_auto : bool ) -> SandboxMode {
406- if full_auto {
407- SandboxMode :: WorkspaceWrite
408- } else {
409- SandboxMode :: ReadOnly
410- }
411- }
412-
413397async fn spawn_debug_sandbox_child (
414398 program : PathBuf ,
415399 args : Vec < String > ,
@@ -579,12 +563,10 @@ mod windows_stdio_bridge {
579563async fn load_debug_sandbox_config (
580564 cli_overrides : Vec < ( String , TomlValue ) > ,
581565 codex_linux_sandbox_exe : Option < PathBuf > ,
582- full_auto : bool ,
583566) -> anyhow:: Result < Config > {
584567 load_debug_sandbox_config_with_codex_home (
585568 cli_overrides,
586569 codex_linux_sandbox_exe,
587- full_auto,
588570 /*codex_home*/ None ,
589571 )
590572 . await
@@ -593,9 +575,14 @@ async fn load_debug_sandbox_config(
593575async fn load_debug_sandbox_config_with_codex_home (
594576 cli_overrides : Vec < ( String , TomlValue ) > ,
595577 codex_linux_sandbox_exe : Option < PathBuf > ,
596- full_auto : bool ,
597578 codex_home : Option < PathBuf > ,
598579) -> anyhow:: Result < Config > {
580+ // For legacy configs, `codex sandbox` historically defaulted to read-only
581+ // instead of inheriting ambient `sandbox_mode` settings from user/system
582+ // config. Keep that behavior unless this invocation explicitly passes a
583+ // legacy `sandbox_mode` CLI override, which is now the documented writable
584+ // replacement for the removed `--full-auto` flag.
585+ let uses_legacy_sandbox_mode_override = cli_overrides_use_legacy_sandbox_mode ( & cli_overrides) ;
599586 let config = build_debug_sandbox_config (
600587 cli_overrides. clone ( ) ,
601588 ConfigOverrides {
@@ -606,19 +593,14 @@ async fn load_debug_sandbox_config_with_codex_home(
606593 )
607594 . await ?;
608595
609- if config_uses_permission_profiles ( & config) {
610- if full_auto {
611- anyhow:: bail!(
612- "`codex sandbox --full-auto` is only supported for legacy `sandbox_mode` configs; choose a writable `[permissions]` profile instead"
613- ) ;
614- }
596+ if config_uses_permission_profiles ( & config) || uses_legacy_sandbox_mode_override {
615597 return Ok ( config) ;
616598 }
617599
618600 build_debug_sandbox_config (
619601 cli_overrides,
620602 ConfigOverrides {
621- sandbox_mode : Some ( create_sandbox_mode ( full_auto ) ) ,
603+ sandbox_mode : Some ( SandboxMode :: ReadOnly ) ,
622604 codex_linux_sandbox_exe,
623605 ..Default :: default ( )
624606 } ,
@@ -652,9 +634,14 @@ fn config_uses_permission_profiles(config: &Config) -> bool {
652634 . is_some ( )
653635}
654636
637+ fn cli_overrides_use_legacy_sandbox_mode ( cli_overrides : & [ ( String , TomlValue ) ] ) -> bool {
638+ cli_overrides. iter ( ) . any ( |( key, _) | key == "sandbox_mode" )
639+ }
640+
655641#[ cfg( test) ]
656642mod tests {
657643 use super :: * ;
644+ use pretty_assertions:: assert_eq;
658645 use tempfile:: TempDir ;
659646
660647 fn escape_toml_path ( path : & std:: path:: Path ) -> String {
@@ -701,7 +688,7 @@ mod tests {
701688 let legacy_config = build_debug_sandbox_config (
702689 Vec :: new ( ) ,
703690 ConfigOverrides {
704- sandbox_mode : Some ( create_sandbox_mode ( /*full_auto*/ false ) ) ,
691+ sandbox_mode : Some ( SandboxMode :: ReadOnly ) ,
705692 ..Default :: default ( )
706693 } ,
707694 Some ( codex_home_path. clone ( ) ) ,
@@ -711,7 +698,6 @@ mod tests {
711698 let config = load_debug_sandbox_config_with_codex_home (
712699 Vec :: new ( ) ,
713700 /*codex_linux_sandbox_exe*/ None ,
714- /*full_auto*/ false ,
715701 Some ( codex_home_path) ,
716702 )
717703 . await ?;
@@ -735,25 +721,90 @@ mod tests {
735721 }
736722
737723 #[ tokio:: test]
738- async fn debug_sandbox_rejects_full_auto_for_permission_profiles ( ) -> anyhow:: Result < ( ) > {
724+ async fn debug_sandbox_honors_explicit_legacy_sandbox_mode ( ) -> anyhow:: Result < ( ) > {
739725 let codex_home = TempDir :: new ( ) ?;
740- let sandbox_paths = TempDir :: new ( ) ?;
741- let docs = sandbox_paths. path ( ) . join ( "docs" ) ;
742- let private = docs. join ( "private" ) ;
743- write_permissions_profile_config ( & codex_home, & docs, & private) ?;
726+ let codex_home_path = codex_home. path ( ) . to_path_buf ( ) ;
727+ let cli_overrides = vec ! [ (
728+ "sandbox_mode" . to_string( ) ,
729+ TomlValue :: String ( "workspace-write" . to_string( ) ) ,
730+ ) ] ;
744731
745- let err = load_debug_sandbox_config_with_codex_home (
732+ let workspace_write_config = build_debug_sandbox_config (
733+ cli_overrides. clone ( ) ,
734+ ConfigOverrides :: default ( ) ,
735+ Some ( codex_home_path. clone ( ) ) ,
736+ )
737+ . await ?;
738+ let read_only_config = build_debug_sandbox_config (
746739 Vec :: new ( ) ,
740+ ConfigOverrides {
741+ sandbox_mode : Some ( SandboxMode :: ReadOnly ) ,
742+ ..Default :: default ( )
743+ } ,
744+ Some ( codex_home_path. clone ( ) ) ,
745+ )
746+ . await ?;
747+
748+ let config = load_debug_sandbox_config_with_codex_home (
749+ cli_overrides,
747750 /*codex_linux_sandbox_exe*/ None ,
748- /*full_auto*/ true ,
749- Some ( codex_home. path ( ) . to_path_buf ( ) ) ,
751+ Some ( codex_home_path) ,
750752 )
751- . await
752- . expect_err ( "full-auto should be rejected for active permission profiles" ) ;
753+ . await ?;
753754
754- assert ! (
755- err. to_string( ) . contains( "--full-auto" ) ,
756- "unexpected error: {err}"
755+ if cfg ! ( target_os = "windows" ) {
756+ assert_eq ! (
757+ workspace_write_config
758+ . permissions
759+ . file_system_sandbox_policy( ) ,
760+ read_only_config. permissions. file_system_sandbox_policy( ) ,
761+ "workspace-write downgrades to read-only when the Windows sandbox is disabled"
762+ ) ;
763+ } else {
764+ assert_ne ! (
765+ workspace_write_config
766+ . permissions
767+ . file_system_sandbox_policy( ) ,
768+ read_only_config. permissions. file_system_sandbox_policy( ) ,
769+ "test fixture should distinguish explicit workspace-write from read-only"
770+ ) ;
771+ }
772+ assert_eq ! (
773+ config. permissions. file_system_sandbox_policy( ) ,
774+ workspace_write_config
775+ . permissions
776+ . file_system_sandbox_policy( ) ,
777+ ) ;
778+
779+ Ok ( ( ) )
780+ }
781+
782+ #[ tokio:: test]
783+ async fn debug_sandbox_defaults_legacy_configs_to_read_only ( ) -> anyhow:: Result < ( ) > {
784+ let codex_home = TempDir :: new ( ) ?;
785+ let codex_home_path = codex_home. path ( ) . to_path_buf ( ) ;
786+
787+ let read_only_config = build_debug_sandbox_config (
788+ Vec :: new ( ) ,
789+ ConfigOverrides {
790+ sandbox_mode : Some ( SandboxMode :: ReadOnly ) ,
791+ ..Default :: default ( )
792+ } ,
793+ Some ( codex_home_path. clone ( ) ) ,
794+ )
795+ . await ?;
796+
797+ let config = load_debug_sandbox_config_with_codex_home (
798+ Vec :: new ( ) ,
799+ /*codex_linux_sandbox_exe*/ None ,
800+ Some ( codex_home_path) ,
801+ )
802+ . await ?;
803+
804+ assert ! ( !config_uses_permission_profiles( & config) ) ;
805+ assert_eq ! (
806+ config. permissions. file_system_sandbox_policy( ) ,
807+ read_only_config. permissions. file_system_sandbox_policy( ) ,
757808 ) ;
758809
759810 Ok ( ( ) )
0 commit comments