Skip to main content

microsandbox_protocol/
exec_control.rs

1//! Optional host-only execution control, independent of the agent input byte stream.
2//!
3//! The relay adds this capability to its client-facing Ready payload only. It is never sent to
4//! agentd, persisted in snapshots, or part of the guest message inventory.
5
6use std::fmt;
7
8use serde::{Deserialize, Serialize};
9
10use crate::core::Ready;
11
12//--------------------------------------------------------------------------------------------------
13// Constants
14//--------------------------------------------------------------------------------------------------
15
16/// First host-only execution control contract.
17pub const EXEC_CONTROL_VERSION: u8 = 1;
18/// Framed host-control operation; requires the advertised capability and generation two.
19pub const EXEC_CONTROL_REQUEST: &str = "control.exec.signal";
20/// Physical-delivery result, distinct from an execution's terminal result.
21pub const EXEC_CONTROL_RESPONSE: &str = "control.exec.signal.result";
22
23//--------------------------------------------------------------------------------------------------
24// Types
25//--------------------------------------------------------------------------------------------------
26
27/// Ephemeral authority for the exact agent connection that received this advertisement.
28#[derive(Clone, Serialize, Deserialize)]
29pub struct ExecControlReady {
30    /// Supported host-only contract.
31    pub version: u8,
32    /// Existing local host-control endpoint, resolved by the runtime.
33    pub endpoint: String,
34    /// Random connection capability; invalidated on disconnect and never persisted.
35    pub connection: [u8; 16],
36}
37
38/// Client-facing Ready extension. Keeping this separate preserves existing Ready struct literals.
39#[derive(Serialize)]
40pub struct ExecControlAdvertisement<'a> {
41    /// Original guest capability payload, unchanged.
42    #[serde(flatten)]
43    pub ready: &'a Ready,
44    /// Host-owned route advertised to this one agent connection.
45    pub exec_control: &'a ExecControlReady,
46}
47
48/// Partial Ready reader that ignores unrelated guest capabilities.
49#[derive(Default, Deserialize)]
50pub struct ExecControlDiscovery {
51    /// Absence means that the existing agent path remains authoritative.
52    #[serde(default)]
53    pub exec_control: Option<ExecControlReady>,
54}
55
56/// One signal bound to a still-active agent connection and execution correlation.
57#[derive(Serialize, Deserialize)]
58pub struct ExecControlRequest {
59    /// Contract selected from the advertised capability.
60    pub version: u8,
61    /// Connection authority copied from the original Ready extension.
62    pub connection: [u8; 16],
63    /// Correlation allocated on that connection; never a raw guest PID.
64    pub id: u32,
65    /// Unix signal number.
66    pub signal: i32,
67}
68
69/// Acknowledges physical guest transport admission, not process exit or signal handling.
70#[derive(Debug, Serialize, Deserialize)]
71pub struct ExecControlResponse {
72    /// The complete signal frame reached the guest console transport.
73    pub delivered: bool,
74    /// Stable failure code, including uncertainty after admission.
75    pub error_code: Option<String>,
76    /// Non-sensitive delivery diagnostic.
77    pub error: Option<String>,
78}
79
80//--------------------------------------------------------------------------------------------------
81// Methods
82//--------------------------------------------------------------------------------------------------
83
84impl ExecControlResponse {
85    /// A complete physical write was observed.
86    pub fn delivered() -> Self {
87        Self {
88            delivered: true,
89            error_code: None,
90            error: None,
91        }
92    }
93
94    /// Reject or report delivery uncertainty without inventing an execution result.
95    pub fn error(code: &str, message: impl Into<String>) -> Self {
96        Self {
97            delivered: false,
98            error_code: Some(code.into()),
99            error: Some(message.into()),
100        }
101    }
102}
103
104//--------------------------------------------------------------------------------------------------
105// Trait Implementations
106//--------------------------------------------------------------------------------------------------
107
108impl fmt::Debug for ExecControlReady {
109    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
110        // Ready metadata is commonly logged. Never expose the connection authority there.
111        formatter
112            .debug_struct("ExecControlReady")
113            .field("version", &self.version)
114            .field("endpoint", &self.endpoint)
115            .field("connection", &"[redacted]")
116            .finish()
117    }
118}