File size: 5,803 Bytes
80d7559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// CARRY Quantum Entangled Multi-Agent Module
// Manages complementary agent pairs (Primary COMPUTE + Partner VERIFY/MONITOR)
// sharing explicitly modeled quantum state & entanglement registers.

use std::collections::HashSet;
use crate::quantum::core::QuantumSimulator;

/// Agent Operational Role.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AgentRole {
    PrimaryCompute,
    PartnerVerify,
    PartnerMonitor,
    PartnerCrossCheck,
    PartnerRecover,
}

/// Agent Audit Event.
#[derive(Debug, Clone)]
pub struct AgentEvent {
    pub cycle: usize,
    pub agent_id: String,
    pub role: AgentRole,
    pub action: String,
    pub target_qubits: Vec<usize>,
    pub timestamp_ms: u128,
    pub status: String,
}

/// Agent definition with formal permissions, ownership, and cycle budget.
#[derive(Debug, Clone)]
pub struct Agent {
    pub id: String,
    pub role: AgentRole,
    pub qubit_ownership: HashSet<usize>,
    pub permissions: HashSet<String>,
    pub cycle_budget: usize,
    pub cycles_used: usize,
    pub partner_id: Option<String>,
}

impl Agent {
    pub fn new_primary(id: impl Into<String>, qubits: Vec<usize>, cycle_budget: usize) -> Self {
        let mut permissions = HashSet::new();
        permissions.insert("STATE_PREPARE".to_string());
        permissions.insert("GATE_EXECUTE".to_string());
        permissions.insert("MEASURE".to_string());

        Self {
            id: id.into(),
            role: AgentRole::PrimaryCompute,
            qubit_ownership: qubits.into_iter().collect(),
            permissions,
            cycle_budget,
            cycles_used: 0,
            partner_id: None,
        }
    }

    pub fn new_partner(id: impl Into<String>, partner_primary_id: impl Into<String>, role: AgentRole, qubits: Vec<usize>) -> Self {
        let mut permissions = HashSet::new();
        permissions.insert("INVARIANT_VERIFY".to_string());
        permissions.insert("CROSS_CHECK".to_string());
        permissions.insert("AUDIT_INSPECT".to_string());
        if role == AgentRole::PartnerRecover {
            permissions.insert("RECOVER_STATE".to_string());
        }

        Self {
            id: id.into(),
            role,
            qubit_ownership: qubits.into_iter().collect(),
            permissions,
            cycle_budget: 1000,
            cycles_used: 0,
            partner_id: Some(partner_primary_id.into()),
        }
    }

    pub fn can_perform(&self, action: &str) -> bool {
        self.permissions.contains(action)
    }

    pub fn owns_qubit(&self, qubit: usize) -> bool {
        self.qubit_ownership.contains(&qubit)
    }

    pub fn consume_cycle(&mut self) -> Result<(), String> {
        if self.cycles_used >= self.cycle_budget {
            return Err(format!("AGENT_BUDGET_EXCEEDED: Agent {} exceeded budget {}", self.id, self.cycle_budget));
        }
        self.cycles_used += 1;
        Ok(())
    }
}

/// Complementary Agent Pair containing Primary (COMPUTE) and Partner (VERIFY/MONITOR).
#[derive(Debug, Clone)]
pub struct AgentPair {
    pub primary: Agent,
    pub partner: Agent,
    pub entanglement_group: String,
}

impl AgentPair {
    pub fn new(primary: Agent, partner: Agent, group: impl Into<String>) -> Result<Self, String> {
        if primary.role != AgentRole::PrimaryCompute {
            return Err("Primary agent must have role PrimaryCompute".into());
        }
        if partner.role == AgentRole::PrimaryCompute {
            return Err("Partner agent cannot have role PrimaryCompute".into());
        }

        Ok(Self {
            primary,
            partner,
            entanglement_group: group.into(),
        })
    }

    /// Perform a cross-verification between Primary computation and Partner monitor.
    pub fn cross_verify_state(&self, sim: &QuantumSimulator) -> Result<String, String> {
        // Partner checks state purity & trace
        let purity = sim.state.purity();
        if (purity - 1.0).abs() > 0.05 && sim.state.is_valid_state() {
            // Mixed state / noise detected by partner
            Ok(format!("PARTNER_VERIFIED: State is mixed (purity {:.4})", purity))
        } else if sim.state.is_valid_state() {
            Ok(format!("PARTNER_VERIFIED: State is pure (purity {:.4})", purity))
        } else {
            Err("PARTNER_REJECT: Invalid quantum state detected during cross-verification".into())
        }
    }
}

/// Multi-Agent Coordinator managing active agents, pairs, and audit records.
#[derive(Debug, Default)]
pub struct MultiAgentCoordinator {
    pub agents: Vec<Agent>,
    pub pairs: Vec<AgentPair>,
    pub audit_log: Vec<AgentEvent>,
}

impl MultiAgentCoordinator {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn register_pair(&mut self, pair: AgentPair) {
        self.agents.push(pair.primary.clone());
        self.agents.push(pair.partner.clone());
        self.pairs.push(pair);
    }

    pub fn log_event(&mut self, event: AgentEvent) {
        self.audit_log.push(event);
    }

    pub fn verify_action_permissions(&self, agent_id: &str, action: &str, qubit: usize) -> Result<(), String> {
        let agent = self
            .agents
            .iter()
            .find(|a| a.id == agent_id)
            .ok_or_else(|| format!("Agent {} not found", agent_id))?;

        if !agent.can_perform(action) {
            return Err(format!("UNAUTHORIZED_ACTION: Agent {} lacks permission for {}", agent_id, action));
        }

        if !agent.owns_qubit(qubit) {
            return Err(format!("UNAUTHORIZED_QUBIT: Agent {} does not own qubit {}", agent_id, qubit));
        }

        Ok(())
    }
}