Skip to main content

agent_graph_mcp/
operator_ipc.rs

1//! Separate, versioned operator-only IPC framing.
2use crate::operator_auth::OperatorAction;
3use serde::{Deserialize, Serialize};
4
5pub const PROTOCOL: &str = "agent_graph.operator.v1";
6
7#[derive(Debug, Serialize, Deserialize)]
8#[serde(deny_unknown_fields)]
9pub struct OperatorFrame {
10    pub protocol: String,
11    pub request_id: String,
12    pub action: OperatorAction,
13    pub resource_kind: String,
14    pub resource_id: String,
15    pub expected_state_digest: String,
16    pub nonce: String,
17    pub issued_at: String,
18    pub expires_at: String,
19    pub decision_material: Option<String>,
20}
21
22#[derive(Debug, Serialize, Deserialize)]
23#[serde(deny_unknown_fields)]
24pub struct OperatorResponse {
25    pub protocol: String,
26    pub ok: bool,
27    pub error_code: Option<String>,
28    pub receipt_id: Option<String>,
29}
30
31pub fn validate(frame: &OperatorFrame) -> Result<(), &'static str> {
32    if frame.protocol != PROTOCOL {
33        return Err("OPERATOR_PROTOCOL_UNSUPPORTED");
34    }
35    if frame.request_id.is_empty() || frame.resource_id.is_empty() {
36        return Err("OPERATOR_INVALID_REQUEST");
37    }
38    if frame.nonce.is_empty() {
39        return Err("AUTHORIZATION_NONCE_REQUIRED");
40    }
41    Ok(())
42}