@@ -6,6 +6,9 @@ use crate::facts::SubAgentThreadStartedInput;
66use crate :: facts:: TrackEventsContext ;
77use codex_login:: default_client:: originator;
88use codex_plugin:: PluginTelemetryMetadata ;
9+ use codex_protocol:: approvals:: NetworkApprovalProtocol ;
10+ use codex_protocol:: models:: PermissionProfile ;
11+ use codex_protocol:: models:: SandboxPermissions ;
912use codex_protocol:: protocol:: SessionSource ;
1013use codex_protocol:: protocol:: SubAgentSource ;
1114use serde:: Serialize ;
@@ -36,6 +39,7 @@ pub(crate) struct TrackEventsRequest {
3639pub ( crate ) enum TrackEventRequest {
3740 SkillInvocation ( SkillInvocationEventRequest ) ,
3841 ThreadInitialized ( ThreadInitializedEvent ) ,
42+ GuardianReview ( Box < GuardianReviewEventRequest > ) ,
3943 AppMentioned ( CodexAppMentionedEventRequest ) ,
4044 AppUsed ( CodexAppUsedEventRequest ) ,
4145 Compaction ( Box < CodexCompactionEventRequest > ) ,
@@ -101,6 +105,179 @@ pub(crate) struct ThreadInitializedEvent {
101105 pub ( crate ) event_params : ThreadInitializedEventParams ,
102106}
103107
108+ #[ derive( Serialize ) ]
109+ pub ( crate ) struct GuardianReviewEventRequest {
110+ pub ( crate ) event_type : & ' static str ,
111+ pub ( crate ) event_params : GuardianReviewEventPayload ,
112+ }
113+
114+ #[ derive( Clone , Copy , Debug , Serialize ) ]
115+ #[ serde( rename_all = "snake_case" ) ]
116+ pub enum GuardianReviewDecision {
117+ Approved ,
118+ Denied ,
119+ Aborted ,
120+ }
121+
122+ #[ derive( Clone , Copy , Debug , Serialize ) ]
123+ #[ serde( rename_all = "snake_case" ) ]
124+ pub enum GuardianReviewTerminalStatus {
125+ Approved ,
126+ Denied ,
127+ Aborted ,
128+ TimedOut ,
129+ FailedClosed ,
130+ }
131+
132+ #[ derive( Clone , Copy , Debug , Serialize ) ]
133+ #[ serde( rename_all = "snake_case" ) ]
134+ pub enum GuardianReviewFailureReason {
135+ Timeout ,
136+ Cancelled ,
137+ PromptBuildError ,
138+ SessionError ,
139+ ParseError ,
140+ }
141+
142+ #[ derive( Clone , Copy , Debug , Serialize ) ]
143+ #[ serde( rename_all = "snake_case" ) ]
144+ pub enum GuardianReviewSessionKind {
145+ TrunkNew ,
146+ TrunkReused ,
147+ EphemeralForked ,
148+ }
149+
150+ #[ derive( Clone , Copy , Debug , Serialize ) ]
151+ #[ serde( rename_all = "lowercase" ) ]
152+ pub enum GuardianReviewRiskLevel {
153+ Low ,
154+ Medium ,
155+ High ,
156+ Critical ,
157+ }
158+
159+ #[ derive( Clone , Copy , Debug , Serialize ) ]
160+ #[ serde( rename_all = "lowercase" ) ]
161+ pub enum GuardianReviewUserAuthorization {
162+ Unknown ,
163+ Low ,
164+ Medium ,
165+ High ,
166+ }
167+
168+ #[ derive( Clone , Copy , Debug , Serialize ) ]
169+ #[ serde( rename_all = "lowercase" ) ]
170+ pub enum GuardianReviewOutcome {
171+ Allow ,
172+ Deny ,
173+ }
174+
175+ #[ derive( Clone , Copy , Debug , Serialize ) ]
176+ #[ serde( rename_all = "snake_case" ) ]
177+ pub enum GuardianApprovalRequestSource {
178+ /// Approval requested directly by the main Codex turn.
179+ MainTurn ,
180+ /// Approval requested by a delegated subagent and routed through the parent
181+ /// session for guardian review.
182+ DelegatedSubagent ,
183+ }
184+
185+ #[ derive( Clone , Debug , Serialize ) ]
186+ #[ serde( tag = "type" , rename_all = "snake_case" ) ]
187+ pub enum GuardianReviewedAction {
188+ Shell {
189+ command : Vec < String > ,
190+ command_display : String ,
191+ cwd : String ,
192+ sandbox_permissions : SandboxPermissions ,
193+ additional_permissions : Option < PermissionProfile > ,
194+ justification : Option < String > ,
195+ } ,
196+ UnifiedExec {
197+ command : Vec < String > ,
198+ command_display : String ,
199+ cwd : String ,
200+ sandbox_permissions : SandboxPermissions ,
201+ additional_permissions : Option < PermissionProfile > ,
202+ justification : Option < String > ,
203+ tty : bool ,
204+ } ,
205+ Execve {
206+ source : GuardianCommandSource ,
207+ program : String ,
208+ argv : Vec < String > ,
209+ cwd : String ,
210+ additional_permissions : Option < PermissionProfile > ,
211+ } ,
212+ ApplyPatch {
213+ cwd : String ,
214+ files : Vec < String > ,
215+ } ,
216+ NetworkAccess {
217+ target : String ,
218+ host : String ,
219+ protocol : NetworkApprovalProtocol ,
220+ port : u16 ,
221+ } ,
222+ McpToolCall {
223+ server : String ,
224+ tool_name : String ,
225+ connector_id : Option < String > ,
226+ connector_name : Option < String > ,
227+ tool_title : Option < String > ,
228+ } ,
229+ }
230+
231+ #[ derive( Clone , Copy , Debug , Serialize ) ]
232+ #[ serde( rename_all = "snake_case" ) ]
233+ pub enum GuardianCommandSource {
234+ Shell ,
235+ UnifiedExec ,
236+ }
237+
238+ #[ derive( Clone , Serialize ) ]
239+ pub struct GuardianReviewEventParams {
240+ pub thread_id : String ,
241+ pub turn_id : String ,
242+ pub review_id : String ,
243+ pub target_item_id : String ,
244+ pub retry_reason : Option < String > ,
245+ pub approval_request_source : GuardianApprovalRequestSource ,
246+ pub reviewed_action : GuardianReviewedAction ,
247+ pub reviewed_action_truncated : bool ,
248+ pub decision : GuardianReviewDecision ,
249+ pub terminal_status : GuardianReviewTerminalStatus ,
250+ pub failure_reason : Option < GuardianReviewFailureReason > ,
251+ pub risk_level : Option < GuardianReviewRiskLevel > ,
252+ pub user_authorization : Option < GuardianReviewUserAuthorization > ,
253+ pub outcome : Option < GuardianReviewOutcome > ,
254+ pub rationale : Option < String > ,
255+ pub guardian_thread_id : Option < String > ,
256+ pub guardian_session_kind : Option < GuardianReviewSessionKind > ,
257+ pub guardian_model : Option < String > ,
258+ pub guardian_reasoning_effort : Option < String > ,
259+ pub had_prior_review_context : Option < bool > ,
260+ pub review_timeout_ms : u64 ,
261+ pub tool_call_count : u64 ,
262+ pub time_to_first_token_ms : Option < u64 > ,
263+ pub completion_latency_ms : Option < u64 > ,
264+ pub started_at : u64 ,
265+ pub completed_at : Option < u64 > ,
266+ pub input_tokens : Option < i64 > ,
267+ pub cached_input_tokens : Option < i64 > ,
268+ pub output_tokens : Option < i64 > ,
269+ pub reasoning_output_tokens : Option < i64 > ,
270+ pub total_tokens : Option < i64 > ,
271+ }
272+
273+ #[ derive( Serialize ) ]
274+ pub ( crate ) struct GuardianReviewEventPayload {
275+ pub ( crate ) app_server_client : CodexAppServerClientMetadata ,
276+ pub ( crate ) runtime : CodexRuntimeMetadata ,
277+ #[ serde( flatten) ]
278+ pub ( crate ) guardian_review : GuardianReviewEventParams ,
279+ }
280+
104281#[ derive( Serialize ) ]
105282pub ( crate ) struct CodexAppMetadata {
106283 pub ( crate ) connector_id : Option < String > ,
0 commit comments