@@ -574,6 +574,7 @@ impl Session {
574574 auth_manager : Arc :: clone ( & auth_manager) ,
575575 otel_event_manager,
576576 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
577+ exec_policy_overrides : Mutex :: new ( Vec :: new ( ) ) ,
577578 } ;
578579
579580 let sess = Arc :: new ( Session {
@@ -846,11 +847,35 @@ impl Session {
846847 . await
847848 }
848849
850+ pub ( crate ) async fn remember_allowed_prefix ( & self , prefix : & [ String ] ) {
851+ {
852+ let mut overrides = self . services . exec_policy_overrides . lock ( ) . await ;
853+ if overrides. iter ( ) . any ( |existing| existing == prefix) {
854+ return ;
855+ }
856+ overrides. push ( prefix. to_vec ( ) ) ;
857+ }
858+
859+ let codex_home = {
860+ let state = self . state . lock ( ) . await ;
861+ state
862+ . session_configuration
863+ . original_config_do_not_use
864+ . codex_home
865+ . clone ( )
866+ } ;
867+
868+ if let Err ( err) = crate :: exec_policy:: persist_allow_rule ( & codex_home, prefix) . await {
869+ warn ! ( "failed to persist execpolicy allow rule: {err}" ) ;
870+ }
871+ }
872+
849873 /// Emit an exec approval request event and await the user's decision.
850874 ///
851875 /// The request is keyed by `sub_id`/`call_id` so matching responses are delivered
852876 /// to the correct in-flight turn. If the task is aborted, this returns the
853877 /// default `ReviewDecision` (`Denied`).
878+ #[ allow( clippy:: too_many_arguments) ]
854879 pub async fn request_command_approval (
855880 & self ,
856881 turn_context : & TurnContext ,
@@ -859,6 +884,7 @@ impl Session {
859884 cwd : PathBuf ,
860885 reason : Option < String > ,
861886 risk : Option < SandboxCommandAssessment > ,
887+ allow_prefix : Option < Vec < String > > ,
862888 ) -> ReviewDecision {
863889 let sub_id = turn_context. sub_id . clone ( ) ;
864890 // Add the tx_approve callback to the map before sending the request.
@@ -887,6 +913,7 @@ impl Session {
887913 reason,
888914 risk,
889915 parsed_cmd,
916+ allow_prefix,
890917 } ) ;
891918 self . send_event ( turn_context, event) . await ;
892919 rx_approve. await . unwrap_or_default ( )
@@ -2636,6 +2663,7 @@ mod tests {
26362663 auth_manager : Arc :: clone ( & auth_manager) ,
26372664 otel_event_manager : otel_event_manager. clone ( ) ,
26382665 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
2666+ exec_policy_overrides : Mutex :: new ( Vec :: new ( ) ) ,
26392667 } ;
26402668
26412669 let turn_context = Session :: make_turn_context (
@@ -2714,6 +2742,7 @@ mod tests {
27142742 auth_manager : Arc :: clone ( & auth_manager) ,
27152743 otel_event_manager : otel_event_manager. clone ( ) ,
27162744 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
2745+ exec_policy_overrides : Mutex :: new ( Vec :: new ( ) ) ,
27172746 } ;
27182747
27192748 let turn_context = Arc :: new ( Session :: make_turn_context (
0 commit comments