Skip to main content

rightkit_agent_engine_protocol/
protocol.rs

1//! Approval policy contracts ported from Codex's portable protocol.
2//!
3//! DIRECT_PORT_RUST (atom `S:I4`): ported verbatim from codex
4//! `codex-rs/protocol/src/protocol.rs:963` (`AskForApproval`,
5//! `SandboxPolicy`'s network-access leg re-cast here as `NetworkAccess`) plus
6//! the granular per-category approval controls added alongside it. See
7//! `docs/canon/daemon-master-canon-atoms.md` (donor-verification correction,
8//! 2026-08-29: Waveloom/Go and Pi/TypeScript are not valid `E→A` sources for
9//! this atom; Codex is the sole donor) for the exact donor revision and
10//! NOTICE entry. No behavioral changes were made at this seam beyond the
11//! module path (`codex_protocol::protocol` -> `rightkit_agent_engine_protocol::protocol`)
12//! and wiring `AskForApproval` onto the host app's own `PermissionMode` ladder
13//! (see `host_policy::types::parse_permission_mode_strict`) rather than
14//! introducing a second approval-mode enum at the seam.
15
16use serde::{Deserialize, Serialize};
17
18/// Determines when an operator is consulted before command execution.
19#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(rename_all = "kebab-case")]
21pub enum AskForApproval {
22    /// Require approval for untrusted projects.
23    #[serde(rename = "untrusted")]
24    UnlessTrusted,
25    /// Ask when policy/model requests it.
26    #[default]
27    OnRequest,
28    /// Apply per-category controls.
29    Granular(GranularApprovalConfig),
30    /// Never ask; return failures directly to model.
31    Never,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35pub struct GranularApprovalConfig {
36    pub sandbox_approval: bool,
37    pub rules: bool,
38    #[serde(default)]
39    pub skill_approval: bool,
40    #[serde(default)]
41    pub request_permissions: bool,
42    pub mcp_elicitations: bool,
43}
44
45impl GranularApprovalConfig {
46    pub const fn allows_sandbox_approval(self) -> bool {
47        self.sandbox_approval
48    }
49    pub const fn allows_rules_approval(self) -> bool {
50        self.rules
51    }
52    pub const fn allows_skill_approval(self) -> bool {
53        self.skill_approval
54    }
55    pub const fn allows_request_permissions(self) -> bool {
56        self.request_permissions
57    }
58    pub const fn allows_mcp_elicitations(self) -> bool {
59        self.mcp_elicitations
60    }
61}
62
63#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "kebab-case")]
65pub enum NetworkAccess {
66    #[default]
67    Restricted,
68    Enabled,
69}
70
71impl NetworkAccess {
72    pub const fn is_enabled(self) -> bool {
73        matches!(self, Self::Enabled)
74    }
75}