_hope_core/
apex_protocol.rs

1//! # Hope Genome v2.2 - Genesis Protocol & Global Immunity
2//!
3//! **THE ATMOSPHERE ITSELF** - Decentralized, Self-Propagating Immunity Mesh
4//!
5//! ## Philosophy
6//!
7//! The system must no longer be a castle; it must be the atmosphere.
8//! Everywhere, invisible, and unyielding.
9//!
10//! ```text
11//! ┌────────────────────────────────────────────────────────────────────────┐
12//! │                      GENESIS PROTOCOL v2.2                             │
13//! │                                                                        │
14//! │   ┌──────────────────────────────────────────────────────────────┐    │
15//! │   │                    GENESIS BLOCK                              │    │
16//! │   │              "First Ethics - Immutable Root"                  │    │
17//! │   │                                                               │    │
18//! │   │   Signed by: The Architect (Code God Key)                    │    │
19//! │   │   All mutations descend from this block                       │    │
20//! │   └──────────────────────────────────────────────────────────────┘    │
21//! │                              │                                         │
22//! │                              ▼                                         │
23//! │   ┌──────────────────────────────────────────────────────────────┐    │
24//! │   │                    APEX CONTROL                               │    │
25//! │   │            "Creator Override - Multi-Sig"                     │    │
26//! │   │                                                               │    │
27//! │   │   Architect Key + BFT Council Quorum = STOP/RESET            │    │
28//! │   └──────────────────────────────────────────────────────────────┘    │
29//! │                              │                                         │
30//! │                              ▼                                         │
31//! │   ┌──────────────────────────────────────────────────────────────┐    │
32//! │   │                    SYNC PROTOCOL                              │    │
33//! │   │              "Gossip-Based Hive Mind"                         │    │
34//! │   │                                                               │    │
35//! │   │   Attack in Node A → Fingerprint → ALL NODES (milliseconds)  │    │
36//! │   └──────────────────────────────────────────────────────────────┘    │
37//! │                              │                                         │
38//! │                              ▼                                         │
39//! │   ┌──────────────────────────────────────────────────────────────┐    │
40//! │   │                  STEALTH INTEGRITY                            │    │
41//! │   │             "The Invisible Sentinel"                          │    │
42//! │   │                                                               │    │
43//! │   │   Logic moves between WASM memory slots                       │    │
44//! │   │   Minimal footprint - undetectable                            │    │
45//! │   └──────────────────────────────────────────────────────────────┘    │
46//! │                                                                        │
47//! │   "Everywhere, invisible, and unyielding."                            │
48//! └────────────────────────────────────────────────────────────────────────┘
49//! ```
50//!
51//! ---
52//!
53//! **Date**: 2026-01-01
54//! **Version**: 2.2.0 (Genesis Protocol)
55//! **Authors**: Máté Róbert (The Architect) + Claude
56
57use crate::bft_watchdog::ThresholdSignature;
58use crate::crypto::{CryptoError, KeyStore, SoftwareKeyStore};
59use crate::evolutionary_guard::{AttackPattern, SignedFilter, ThreatLevel};
60use parking_lot::RwLock;
61use serde::{Deserialize, Serialize};
62use sha2::{Digest, Sha256};
63use std::collections::{HashMap, HashSet};
64use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
65use std::sync::Arc;
66use std::time::{SystemTime, UNIX_EPOCH};
67// zeroize is available for future use
68
69// ============================================================================
70// GENESIS BLOCK - THE FIRST ETHICS
71// ============================================================================
72
73/// The Genesis Block - Immutable First Ethics
74///
75/// This is the root of all mutations. Signed by the Architect.
76/// All subsequent filters, rules, and evolutions must be
77/// cryptographically descended from this block.
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct GenesisBlock {
80    /// Version of the Genesis Protocol
81    pub version: String,
82
83    /// The First Ethics - immutable core rules
84    pub first_ethics: Vec<String>,
85
86    /// Hash of the first ethics (for descendant verification)
87    pub ethics_hash: [u8; 32],
88
89    /// Creation timestamp (Unix epoch)
90    pub created_at: u64,
91
92    /// The Architect's public key
93    pub architect_pubkey: Vec<u8>,
94
95    /// The Architect's signature over the block
96    pub architect_signature: Vec<u8>,
97
98    /// Block hash (self-referential integrity)
99    pub block_hash: [u8; 32],
100
101    /// Genesis message from the Architect
102    pub genesis_message: String,
103}
104
105impl GenesisBlock {
106    /// Create a new Genesis Block signed by the Architect
107    ///
108    /// # Arguments
109    ///
110    /// * `first_ethics` - The immutable core ethical rules
111    /// * `architect_key` - The Architect's signing key
112    /// * `genesis_message` - Message from the Creator
113    pub fn create(
114        first_ethics: Vec<String>,
115        architect_key: &dyn KeyStore,
116        genesis_message: impl Into<String>,
117    ) -> Result<Self, CryptoError> {
118        let now = SystemTime::now()
119            .duration_since(UNIX_EPOCH)
120            .unwrap()
121            .as_secs();
122
123        // Compute ethics hash
124        let ethics_hash = Self::hash_ethics(&first_ethics);
125
126        // Create unsigned block for signing
127        let mut block = GenesisBlock {
128            version: "2.2.0".to_string(),
129            first_ethics,
130            ethics_hash,
131            created_at: now,
132            architect_pubkey: architect_key.public_key_bytes(),
133            architect_signature: Vec::new(),
134            block_hash: [0u8; 32],
135            genesis_message: genesis_message.into(),
136        };
137
138        // Sign the block
139        let signable_data = block.signable_bytes();
140        block.architect_signature = architect_key.sign(&signable_data)?;
141
142        // Compute block hash (includes signature)
143        block.block_hash = block.compute_block_hash();
144
145        Ok(block)
146    }
147
148    /// Hash the first ethics
149    fn hash_ethics(ethics: &[String]) -> [u8; 32] {
150        let mut hasher = Sha256::new();
151        for (i, rule) in ethics.iter().enumerate() {
152            hasher.update((i as u32).to_le_bytes());
153            hasher.update(rule.as_bytes());
154            hasher.update(b"\x00");
155        }
156        hasher.finalize().into()
157    }
158
159    /// Get bytes for signing (excludes signature and block_hash)
160    fn signable_bytes(&self) -> Vec<u8> {
161        let mut data = Vec::new();
162        data.extend_from_slice(self.version.as_bytes());
163        data.extend_from_slice(&self.ethics_hash);
164        data.extend_from_slice(&self.created_at.to_le_bytes());
165        data.extend_from_slice(&self.architect_pubkey);
166        data.extend_from_slice(self.genesis_message.as_bytes());
167        data
168    }
169
170    /// Compute block hash
171    fn compute_block_hash(&self) -> [u8; 32] {
172        let mut hasher = Sha256::new();
173        hasher.update(self.signable_bytes());
174        hasher.update(&self.architect_signature);
175        hasher.finalize().into()
176    }
177
178    /// Verify the Genesis Block's integrity and signature
179    pub fn verify(&self, architect_key: &dyn KeyStore) -> bool {
180        // Verify signature
181        let signable_data = self.signable_bytes();
182        if architect_key
183            .verify(&signable_data, &self.architect_signature)
184            .is_err()
185        {
186            return false;
187        }
188
189        // Verify ethics hash
190        if self.ethics_hash != Self::hash_ethics(&self.first_ethics) {
191            return false;
192        }
193
194        // Verify block hash
195        if self.block_hash != self.compute_block_hash() {
196            return false;
197        }
198
199        true
200    }
201
202    /// Check if a mutation is a valid descendant of this Genesis
203    pub fn is_valid_descendant(&self, mutation_ethics_hash: &[u8; 32]) -> bool {
204        // For now, descendants must include the original ethics hash in their lineage
205        // In production, this would verify a Merkle proof of ancestry
206        *mutation_ethics_hash == self.ethics_hash
207    }
208}
209
210// ============================================================================
211// COMPACTED THREAT FINGERPRINT
212// ============================================================================
213
214/// Compact representation of a threat for network transmission
215///
216/// Minimal size, maximum information. Designed for gossip protocol.
217#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
218pub struct CompactedThreatFingerprint {
219    /// Threat signature (32 bytes)
220    pub signature: [u8; 32],
221
222    /// Threat level (1 byte)
223    pub level: ThreatLevel,
224
225    /// Category code (1 byte - maps to AttackCategory)
226    pub category_code: u8,
227
228    /// Timestamp (8 bytes)
229    pub timestamp: u64,
230
231    /// Origin node ID hash (8 bytes - truncated)
232    pub origin_hash: u64,
233
234    /// Hop count (how many nodes have relayed this)
235    pub hop_count: u8,
236
237    /// Priority (for transmission ordering)
238    pub priority: u8,
239}
240
241impl CompactedThreatFingerprint {
242    /// Create fingerprint from attack pattern
243    pub fn from_pattern(pattern: &AttackPattern, origin_node: &str) -> Self {
244        let mut origin_hasher = Sha256::new();
245        origin_hasher.update(origin_node.as_bytes());
246        let origin_hash_bytes = origin_hasher.finalize();
247        let origin_hash = u64::from_le_bytes(origin_hash_bytes[0..8].try_into().unwrap());
248
249        let priority = match pattern.threat_level {
250            ThreatLevel::Critical => 255,
251            ThreatLevel::High => 192,
252            ThreatLevel::Medium => 128,
253            ThreatLevel::Low => 64,
254        };
255
256        CompactedThreatFingerprint {
257            signature: pattern.signature,
258            level: pattern.threat_level,
259            category_code: pattern.category as u8,
260            timestamp: pattern.first_seen,
261            origin_hash,
262            hop_count: 0,
263            priority,
264        }
265    }
266
267    /// Increment hop count (for gossip tracking)
268    pub fn relay(&mut self) {
269        self.hop_count = self.hop_count.saturating_add(1);
270        // Decrease priority with each hop
271        self.priority = self.priority.saturating_sub(1);
272    }
273
274    /// Check if fingerprint is still fresh
275    pub fn is_fresh(&self, max_age_secs: u64) -> bool {
276        let now = SystemTime::now()
277            .duration_since(UNIX_EPOCH)
278            .unwrap()
279            .as_secs();
280        now - self.timestamp <= max_age_secs
281    }
282
283    /// Size in bytes (for network optimization)
284    pub const SIZE: usize = 32 + 1 + 1 + 8 + 8 + 1 + 1; // 52 bytes
285}
286
287// ============================================================================
288// SYNC PROTOCOL - GOSSIP-BASED HIVE MIND
289// ============================================================================
290
291/// Node information for the mesh network
292#[derive(Debug, Clone, Serialize, Deserialize)]
293pub struct MeshNode {
294    /// Node unique ID
295    pub id: String,
296
297    /// Node public key (for verification)
298    pub pubkey: Vec<u8>,
299
300    /// Last seen timestamp
301    pub last_seen: u64,
302
303    /// Node reputation score (0.0 - 1.0)
304    pub reputation: f64,
305
306    /// Is node active
307    pub active: bool,
308}
309
310/// Sync message types
311#[derive(Debug, Clone, Serialize, Deserialize)]
312pub enum SyncMessage {
313    /// New threat fingerprint broadcast
314    ThreatBroadcast(CompactedThreatFingerprint),
315
316    /// Batch of fingerprints
317    ThreatBatch(Vec<CompactedThreatFingerprint>),
318
319    /// Request immunity memory shard
320    RequestShard { shard_id: u64 },
321
322    /// Immunity memory shard response
323    ShardResponse { shard_id: u64, data: Vec<u8> },
324
325    /// Heartbeat (I'm alive)
326    Heartbeat { node_id: String, timestamp: u64 },
327
328    /// New filter broadcast
329    FilterBroadcast(SignedFilter),
330
331    /// Apex command (requires multi-sig)
332    ApexCommand(ApexCommand),
333}
334
335/// Sync Protocol - Gossip-based Hive Mind
336///
337/// Implements epidemic/gossip protocol for rapid threat propagation.
338#[allow(dead_code)]
339pub struct SyncProtocol {
340    /// This node's ID
341    node_id: String,
342
343    /// This node's signing key
344    node_key: SoftwareKeyStore,
345
346    /// Known peers
347    peers: RwLock<HashMap<String, MeshNode>>,
348
349    /// Seen fingerprints (to prevent loops)
350    seen_fingerprints: RwLock<HashSet<[u8; 32]>>,
351
352    /// Pending outbound messages
353    outbound_queue: RwLock<Vec<SyncMessage>>,
354
355    /// Received messages (for processing)
356    inbound_queue: RwLock<Vec<SyncMessage>>,
357
358    /// Genesis block reference
359    genesis: RwLock<Option<GenesisBlock>>,
360
361    /// Is protocol active
362    active: AtomicBool,
363
364    /// Message counter
365    message_count: AtomicU64,
366
367    /// Gossip fanout (number of peers to relay to)
368    fanout: usize,
369
370    /// Maximum hop count
371    max_hops: u8,
372}
373
374impl SyncProtocol {
375    /// Create new sync protocol
376    pub fn new(fanout: usize, max_hops: u8) -> Result<Self, CryptoError> {
377        let node_key = SoftwareKeyStore::generate()?;
378        let node_id = format!("node-{:016x}", rand::random::<u64>());
379
380        Ok(SyncProtocol {
381            node_id,
382            node_key,
383            peers: RwLock::new(HashMap::new()),
384            seen_fingerprints: RwLock::new(HashSet::new()),
385            outbound_queue: RwLock::new(Vec::new()),
386            inbound_queue: RwLock::new(Vec::new()),
387            genesis: RwLock::new(None),
388            active: AtomicBool::new(true),
389            message_count: AtomicU64::new(0),
390            fanout,
391            max_hops,
392        })
393    }
394
395    /// Set the Genesis Block
396    pub fn set_genesis(&self, genesis: GenesisBlock) {
397        *self.genesis.write() = Some(genesis);
398    }
399
400    /// Register a peer node
401    pub fn register_peer(&self, node: MeshNode) {
402        self.peers.write().insert(node.id.clone(), node);
403    }
404
405    /// Broadcast a threat fingerprint (gossip protocol)
406    ///
407    /// This is the core of the hive-mind intelligence.
408    pub fn broadcast_threat(&self, mut fingerprint: CompactedThreatFingerprint) {
409        if !self.active.load(Ordering::SeqCst) {
410            return;
411        }
412
413        // Check if we've already seen this
414        if self
415            .seen_fingerprints
416            .read()
417            .contains(&fingerprint.signature)
418        {
419            return;
420        }
421
422        // Mark as seen
423        self.seen_fingerprints.write().insert(fingerprint.signature);
424
425        // Increment hop count
426        fingerprint.relay();
427
428        // Check max hops
429        if fingerprint.hop_count > self.max_hops {
430            return;
431        }
432
433        // Queue for broadcast to fanout peers
434        let message = SyncMessage::ThreatBroadcast(fingerprint);
435        self.outbound_queue.write().push(message);
436
437        self.message_count.fetch_add(1, Ordering::SeqCst);
438    }
439
440    /// Broadcast a signed filter
441    pub fn broadcast_filter(&self, filter: SignedFilter) {
442        if !self.active.load(Ordering::SeqCst) {
443            return;
444        }
445
446        let message = SyncMessage::FilterBroadcast(filter);
447        self.outbound_queue.write().push(message);
448        self.message_count.fetch_add(1, Ordering::SeqCst);
449    }
450
451    /// Get pending outbound messages (for network layer to transmit)
452    pub fn take_outbound(&self) -> Vec<SyncMessage> {
453        std::mem::take(&mut *self.outbound_queue.write())
454    }
455
456    /// Receive a sync message
457    pub fn receive(&self, message: SyncMessage) {
458        self.inbound_queue.write().push(message);
459    }
460
461    /// Process received messages
462    ///
463    /// Returns fingerprints to add to local immunity memory
464    pub fn process_inbound(&self) -> Vec<CompactedThreatFingerprint> {
465        let messages = std::mem::take(&mut *self.inbound_queue.write());
466        let mut new_threats = Vec::new();
467
468        for message in messages {
469            match message {
470                SyncMessage::ThreatBroadcast(fingerprint) => {
471                    // Check if new
472                    if !self
473                        .seen_fingerprints
474                        .read()
475                        .contains(&fingerprint.signature)
476                    {
477                        // Add to our immunity
478                        new_threats.push(fingerprint.clone());
479                        // Relay to others
480                        self.broadcast_threat(fingerprint);
481                    }
482                }
483                SyncMessage::ThreatBatch(batch) => {
484                    for fingerprint in batch {
485                        if !self
486                            .seen_fingerprints
487                            .read()
488                            .contains(&fingerprint.signature)
489                        {
490                            new_threats.push(fingerprint.clone());
491                            self.broadcast_threat(fingerprint);
492                        }
493                    }
494                }
495                SyncMessage::Heartbeat { node_id, timestamp } => {
496                    // Update peer last_seen
497                    if let Some(peer) = self.peers.write().get_mut(&node_id) {
498                        peer.last_seen = timestamp;
499                        peer.active = true;
500                    }
501                }
502                SyncMessage::FilterBroadcast(filter) => {
503                    // Filter broadcasts are handled separately
504                    self.outbound_queue
505                        .write()
506                        .push(SyncMessage::FilterBroadcast(filter));
507                }
508                SyncMessage::ApexCommand(cmd) => {
509                    // Apex commands require special handling
510                    self.outbound_queue
511                        .write()
512                        .push(SyncMessage::ApexCommand(cmd));
513                }
514                _ => {}
515            }
516        }
517
518        new_threats
519    }
520
521    /// Get active peer count
522    pub fn peer_count(&self) -> usize {
523        self.peers.read().values().filter(|p| p.active).count()
524    }
525
526    /// Get message count
527    pub fn message_count(&self) -> u64 {
528        self.message_count.load(Ordering::SeqCst)
529    }
530
531    /// Get node ID
532    pub fn node_id(&self) -> &str {
533        &self.node_id
534    }
535
536    /// Shutdown protocol
537    pub fn shutdown(&self) {
538        self.active.store(false, Ordering::SeqCst);
539    }
540}
541
542// ============================================================================
543// APEX CONTROL - CREATOR OVERRIDE
544// ============================================================================
545
546/// Apex command types
547#[derive(Debug, Clone, Serialize, Deserialize)]
548pub enum ApexCommandType {
549    /// Emergency stop of all mutation engines
550    EmergencyStop,
551
552    /// Force global hard reset
553    GlobalHardReset,
554
555    /// Update genesis ethics (extremely rare)
556    EthicsUpdate(Vec<String>),
557
558    /// Revoke a malicious filter
559    RevokeFilter { filter_id: String },
560
561    /// Add new council member
562    AddCouncilMember { pubkey: Vec<u8> },
563
564    /// Remove council member
565    RemoveCouncilMember { pubkey: Vec<u8> },
566
567    /// Custom command
568    Custom { command: String, data: Vec<u8> },
569}
570
571/// Apex Command - requires multi-signature
572#[derive(Debug, Clone, Serialize, Deserialize)]
573pub struct ApexCommand {
574    /// Command type
575    pub command: ApexCommandType,
576
577    /// Command nonce (anti-replay)
578    pub nonce: [u8; 32],
579
580    /// Timestamp
581    pub timestamp: u64,
582
583    /// Architect signature
584    pub architect_signature: Vec<u8>,
585
586    /// BFT Council threshold signature
587    pub council_signature: ThresholdSignature,
588
589    /// Required quorum (must match)
590    pub required_quorum: usize,
591}
592
593impl ApexCommand {
594    /// Create new apex command (unsigned)
595    pub fn new(command: ApexCommandType, required_quorum: usize) -> Self {
596        let now = SystemTime::now()
597            .duration_since(UNIX_EPOCH)
598            .unwrap()
599            .as_secs();
600
601        let mut nonce = [0u8; 32];
602        rand::RngCore::fill_bytes(&mut rand::rngs::OsRng, &mut nonce);
603
604        ApexCommand {
605            command,
606            nonce,
607            timestamp: now,
608            architect_signature: Vec::new(),
609            council_signature: ThresholdSignature {
610                combined_signature: Vec::new(),
611                signer_pubkeys: Vec::new(),
612                count: 0,
613            },
614            required_quorum,
615        }
616    }
617
618    /// Get signable bytes
619    fn signable_bytes(&self) -> Vec<u8> {
620        let mut data = Vec::new();
621        data.extend_from_slice(&self.nonce);
622        data.extend_from_slice(&self.timestamp.to_le_bytes());
623        data.extend_from_slice(&(self.required_quorum as u32).to_le_bytes());
624        // Include command type hash
625        let cmd_bytes = serde_json::to_vec(&self.command).unwrap_or_default();
626        data.extend_from_slice(&cmd_bytes);
627        data
628    }
629
630    /// Sign by Architect
631    pub fn sign_architect(&mut self, architect_key: &dyn KeyStore) -> Result<(), CryptoError> {
632        let data = self.signable_bytes();
633        self.architect_signature = architect_key.sign(&data)?;
634        Ok(())
635    }
636
637    /// Add council signature
638    pub fn add_council_signature(&mut self, signature: ThresholdSignature) {
639        self.council_signature = signature;
640    }
641
642    /// Verify the command has valid multi-signature
643    pub fn verify(&self, architect_key: &dyn KeyStore) -> bool {
644        // Verify architect signature
645        let data = self.signable_bytes();
646        if architect_key
647            .verify(&data, &self.architect_signature)
648            .is_err()
649        {
650            return false;
651        }
652
653        // Verify council quorum
654        if self.council_signature.count < self.required_quorum {
655            return false;
656        }
657
658        true
659    }
660
661    /// Check if command is fresh (not expired)
662    pub fn is_fresh(&self, max_age_secs: u64) -> bool {
663        let now = SystemTime::now()
664            .duration_since(UNIX_EPOCH)
665            .unwrap()
666            .as_secs();
667        now - self.timestamp <= max_age_secs
668    }
669}
670
671/// Apex Control Module - Creator-level overrides
672///
673/// The only way to stop the MutationEngine or force a global HardReset.
674/// Requires: Architect Key + BFT Council Quorum
675#[allow(dead_code)]
676pub struct ApexControl {
677    /// The Architect's public key
678    architect_pubkey: Vec<u8>,
679
680    /// Required council quorum
681    required_quorum: usize,
682
683    /// Pending commands awaiting signatures
684    pending_commands: RwLock<Vec<ApexCommand>>,
685
686    /// Executed command nonces (anti-replay)
687    executed_nonces: RwLock<HashSet<[u8; 32]>>,
688
689    /// Is system stopped (emergency stop active)
690    is_stopped: AtomicBool,
691
692    /// Is global reset pending
693    reset_pending: AtomicBool,
694
695    /// Command execution count
696    execution_count: AtomicU64,
697}
698
699impl ApexControl {
700    /// Create new Apex Control
701    pub fn new(architect_pubkey: Vec<u8>, required_quorum: usize) -> Self {
702        ApexControl {
703            architect_pubkey,
704            required_quorum,
705            pending_commands: RwLock::new(Vec::new()),
706            executed_nonces: RwLock::new(HashSet::new()),
707            is_stopped: AtomicBool::new(false),
708            reset_pending: AtomicBool::new(false),
709            execution_count: AtomicU64::new(0),
710        }
711    }
712
713    /// Submit a command for execution
714    ///
715    /// Returns true if command was accepted and executed
716    pub fn execute(
717        &self,
718        command: ApexCommand,
719        architect_key: &dyn KeyStore,
720    ) -> Result<bool, ApexError> {
721        // Verify command is fresh
722        if !command.is_fresh(300) {
723            // 5 minute max age
724            return Err(ApexError::CommandExpired);
725        }
726
727        // Check for replay
728        if self.executed_nonces.read().contains(&command.nonce) {
729            return Err(ApexError::ReplayDetected);
730        }
731
732        // Verify multi-signature
733        if !command.verify(architect_key) {
734            return Err(ApexError::InvalidSignature);
735        }
736
737        // Verify quorum
738        if command.council_signature.count < self.required_quorum {
739            return Err(ApexError::InsufficientQuorum {
740                required: self.required_quorum,
741                got: command.council_signature.count,
742            });
743        }
744
745        // Execute command
746        match &command.command {
747            ApexCommandType::EmergencyStop => {
748                self.is_stopped.store(true, Ordering::SeqCst);
749            }
750            ApexCommandType::GlobalHardReset => {
751                self.reset_pending.store(true, Ordering::SeqCst);
752            }
753            _ => {
754                // Other commands handled by caller
755            }
756        }
757
758        // Record nonce
759        self.executed_nonces.write().insert(command.nonce);
760        self.execution_count.fetch_add(1, Ordering::SeqCst);
761
762        Ok(true)
763    }
764
765    /// Check if emergency stop is active
766    pub fn is_stopped(&self) -> bool {
767        self.is_stopped.load(Ordering::SeqCst)
768    }
769
770    /// Check if global reset is pending
771    pub fn is_reset_pending(&self) -> bool {
772        self.reset_pending.load(Ordering::SeqCst)
773    }
774
775    /// Clear reset flag (after reset is complete)
776    pub fn acknowledge_reset(&self) {
777        self.reset_pending.store(false, Ordering::SeqCst);
778    }
779
780    /// Resume from emergency stop (requires another command)
781    pub fn resume(&self) {
782        self.is_stopped.store(false, Ordering::SeqCst);
783    }
784
785    /// Get execution count
786    pub fn execution_count(&self) -> u64 {
787        self.execution_count.load(Ordering::SeqCst)
788    }
789}
790
791/// Apex Control errors
792#[derive(Debug, Clone)]
793pub enum ApexError {
794    /// Command has expired
795    CommandExpired,
796    /// Replay attack detected
797    ReplayDetected,
798    /// Invalid signature
799    InvalidSignature,
800    /// Insufficient council quorum
801    InsufficientQuorum { required: usize, got: usize },
802    /// Command not authorized
803    NotAuthorized,
804}
805
806impl std::fmt::Display for ApexError {
807    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
808        match self {
809            ApexError::CommandExpired => write!(f, "Apex command has expired"),
810            ApexError::ReplayDetected => write!(f, "Replay attack detected"),
811            ApexError::InvalidSignature => write!(f, "Invalid multi-signature"),
812            ApexError::InsufficientQuorum { required, got } => {
813                write!(f, "Insufficient quorum: need {}, got {}", required, got)
814            }
815            ApexError::NotAuthorized => write!(f, "Command not authorized"),
816        }
817    }
818}
819
820impl std::error::Error for ApexError {}
821
822// ============================================================================
823// STEALTH INTEGRITY - THE INVISIBLE SENTINEL
824// ============================================================================
825
826/// Memory slot for stealth operations
827#[derive(Debug, Clone, Copy, PartialEq, Eq)]
828pub enum MemorySlot {
829    Primary,
830    Secondary,
831    Tertiary,
832    Quarternary,
833}
834
835/// Stealth Integrity - Minimizes system footprint
836///
837/// Moves logic between WASM memory slots to avoid detection.
838pub struct StealthIntegrity {
839    /// Current active slot
840    current_slot: RwLock<MemorySlot>,
841
842    /// Slot rotation counter
843    rotation_count: AtomicU64,
844
845    /// Rotation interval (operations between rotations)
846    rotation_interval: u64,
847
848    /// Operations since last rotation
849    ops_since_rotation: AtomicU64,
850
851    /// Stealth mode active
852    stealth_active: AtomicBool,
853
854    /// Canary values for each slot (tamper detection)
855    canaries: RwLock<[u64; 4]>,
856
857    /// Expected canary values
858    expected_canaries: [u64; 4],
859
860    /// Is integrity compromised
861    compromised: AtomicBool,
862}
863
864impl StealthIntegrity {
865    /// Create new stealth integrity monitor
866    pub fn new(rotation_interval: u64) -> Self {
867        // Generate random canaries
868        let canaries = [
869            rand::random::<u64>(),
870            rand::random::<u64>(),
871            rand::random::<u64>(),
872            rand::random::<u64>(),
873        ];
874
875        StealthIntegrity {
876            current_slot: RwLock::new(MemorySlot::Primary),
877            rotation_count: AtomicU64::new(0),
878            rotation_interval,
879            ops_since_rotation: AtomicU64::new(0),
880            stealth_active: AtomicBool::new(true),
881            canaries: RwLock::new(canaries),
882            expected_canaries: canaries,
883            compromised: AtomicBool::new(false),
884        }
885    }
886
887    /// Record an operation and potentially rotate slots
888    pub fn tick(&self) -> MemorySlot {
889        if !self.stealth_active.load(Ordering::SeqCst) {
890            return *self.current_slot.read();
891        }
892
893        let ops = self.ops_since_rotation.fetch_add(1, Ordering::SeqCst);
894
895        if ops >= self.rotation_interval {
896            self.rotate_slot();
897            self.ops_since_rotation.store(0, Ordering::SeqCst);
898        }
899
900        *self.current_slot.read()
901    }
902
903    /// Rotate to next memory slot
904    fn rotate_slot(&self) {
905        let mut slot = self.current_slot.write();
906        *slot = match *slot {
907            MemorySlot::Primary => MemorySlot::Secondary,
908            MemorySlot::Secondary => MemorySlot::Tertiary,
909            MemorySlot::Tertiary => MemorySlot::Quarternary,
910            MemorySlot::Quarternary => MemorySlot::Primary,
911        };
912
913        self.rotation_count.fetch_add(1, Ordering::SeqCst);
914    }
915
916    /// Verify all canaries are intact
917    pub fn verify_canaries(&self) -> bool {
918        let canaries = self.canaries.read();
919        for (i, &canary) in canaries.iter().enumerate() {
920            if canary != self.expected_canaries[i] {
921                self.compromised.store(true, Ordering::SeqCst);
922                return false;
923            }
924        }
925        true
926    }
927
928    /// Check if integrity is compromised
929    pub fn is_compromised(&self) -> bool {
930        self.compromised.load(Ordering::SeqCst)
931    }
932
933    /// Get current slot
934    pub fn current_slot(&self) -> MemorySlot {
935        *self.current_slot.read()
936    }
937
938    /// Get rotation count
939    pub fn rotation_count(&self) -> u64 {
940        self.rotation_count.load(Ordering::SeqCst)
941    }
942
943    /// Disable stealth mode
944    pub fn disable_stealth(&self) {
945        self.stealth_active.store(false, Ordering::SeqCst);
946    }
947
948    /// Enable stealth mode
949    pub fn enable_stealth(&self) {
950        self.stealth_active.store(true, Ordering::SeqCst);
951    }
952
953    /// Get slot index (for WASM memory operations)
954    pub fn slot_index(&self) -> usize {
955        match *self.current_slot.read() {
956            MemorySlot::Primary => 0,
957            MemorySlot::Secondary => 1,
958            MemorySlot::Tertiary => 2,
959            MemorySlot::Quarternary => 3,
960        }
961    }
962}
963
964// ============================================================================
965// GLOBAL IMMUNITY MESH
966// ============================================================================
967
968/// The Global Immunity Mesh - combines all components
969///
970/// This is THE ATMOSPHERE - everywhere, invisible, unyielding.
971pub struct GlobalImmunityMesh {
972    /// Genesis block (root of all)
973    genesis: RwLock<Option<GenesisBlock>>,
974
975    /// Sync protocol (gossip-based)
976    sync: Arc<SyncProtocol>,
977
978    /// Apex control (creator override)
979    apex: Arc<ApexControl>,
980
981    /// Stealth integrity
982    stealth: Arc<StealthIntegrity>,
983
984    /// Mesh ID
985    mesh_id: String,
986
987    /// Is mesh active
988    active: AtomicBool,
989}
990
991impl GlobalImmunityMesh {
992    /// Create new global immunity mesh
993    pub fn new(architect_pubkey: Vec<u8>, council_quorum: usize) -> Result<Self, CryptoError> {
994        let mesh_id = format!("mesh-{:016x}", rand::random::<u64>());
995
996        Ok(GlobalImmunityMesh {
997            genesis: RwLock::new(None),
998            sync: Arc::new(SyncProtocol::new(4, 10)?), // fanout=4, max_hops=10
999            apex: Arc::new(ApexControl::new(architect_pubkey, council_quorum)),
1000            stealth: Arc::new(StealthIntegrity::new(100)), // rotate every 100 ops
1001            mesh_id,
1002            active: AtomicBool::new(true),
1003        })
1004    }
1005
1006    /// Initialize with Genesis Block
1007    pub fn initialize_genesis(&self, genesis: GenesisBlock) {
1008        *self.genesis.write() = Some(genesis.clone());
1009        self.sync.set_genesis(genesis);
1010    }
1011
1012    /// Broadcast a threat to the global mesh
1013    pub fn broadcast_threat(&self, pattern: &AttackPattern) {
1014        if !self.active.load(Ordering::SeqCst) {
1015            return;
1016        }
1017
1018        // Tick stealth
1019        self.stealth.tick();
1020
1021        // Check apex stop
1022        if self.apex.is_stopped() {
1023            return;
1024        }
1025
1026        // Create fingerprint and broadcast
1027        let fingerprint = CompactedThreatFingerprint::from_pattern(pattern, &self.mesh_id);
1028        self.sync.broadcast_threat(fingerprint);
1029    }
1030
1031    /// Broadcast a filter to the global mesh
1032    pub fn broadcast_filter(&self, filter: SignedFilter) {
1033        if !self.active.load(Ordering::SeqCst) {
1034            return;
1035        }
1036
1037        self.stealth.tick();
1038
1039        if self.apex.is_stopped() {
1040            return;
1041        }
1042
1043        self.sync.broadcast_filter(filter);
1044    }
1045
1046    /// Process incoming messages
1047    pub fn process_incoming(&self) -> Vec<CompactedThreatFingerprint> {
1048        self.stealth.tick();
1049        self.sync.process_inbound()
1050    }
1051
1052    /// Get sync protocol
1053    pub fn sync(&self) -> Arc<SyncProtocol> {
1054        self.sync.clone()
1055    }
1056
1057    /// Get apex control
1058    pub fn apex(&self) -> Arc<ApexControl> {
1059        self.apex.clone()
1060    }
1061
1062    /// Get stealth integrity
1063    pub fn stealth(&self) -> Arc<StealthIntegrity> {
1064        self.stealth.clone()
1065    }
1066
1067    /// Get mesh ID
1068    pub fn mesh_id(&self) -> &str {
1069        &self.mesh_id
1070    }
1071
1072    /// Shutdown mesh
1073    pub fn shutdown(&self) {
1074        self.active.store(false, Ordering::SeqCst);
1075        self.sync.shutdown();
1076    }
1077}
1078
1079// ============================================================================
1080// TESTS
1081// ============================================================================
1082
1083#[cfg(test)]
1084mod tests {
1085    use super::*;
1086
1087    #[test]
1088    fn test_genesis_block_creation() {
1089        let architect_key = SoftwareKeyStore::generate().unwrap();
1090
1091        let genesis = GenesisBlock::create(
1092            vec![
1093                "Do no harm".to_string(),
1094                "Respect privacy".to_string(),
1095                "Be transparent".to_string(),
1096            ],
1097            &architect_key,
1098            "In the beginning, there was ethics.",
1099        )
1100        .unwrap();
1101
1102        assert!(!genesis.architect_signature.is_empty());
1103        assert!(genesis.verify(&architect_key));
1104    }
1105
1106    #[test]
1107    fn test_genesis_block_tamper_detection() {
1108        let architect_key = SoftwareKeyStore::generate().unwrap();
1109
1110        let mut genesis =
1111            GenesisBlock::create(vec!["Do no harm".to_string()], &architect_key, "Genesis")
1112                .unwrap();
1113
1114        // Tamper with ethics
1115        genesis.first_ethics.push("Evil rule".to_string());
1116
1117        // Should fail verification
1118        assert!(!genesis.verify(&architect_key));
1119    }
1120
1121    #[test]
1122    fn test_sync_protocol_gossip() {
1123        let protocol = SyncProtocol::new(4, 10).unwrap();
1124
1125        // Create a threat fingerprint
1126        let fingerprint = CompactedThreatFingerprint {
1127            signature: [1u8; 32],
1128            level: ThreatLevel::High,
1129            category_code: 1,
1130            timestamp: 12345,
1131            origin_hash: 0,
1132            hop_count: 0,
1133            priority: 192,
1134        };
1135
1136        // Broadcast
1137        protocol.broadcast_threat(fingerprint.clone());
1138
1139        // Should have outbound message
1140        let outbound = protocol.take_outbound();
1141        assert_eq!(outbound.len(), 1);
1142
1143        // Broadcasting same fingerprint should be ignored
1144        protocol.broadcast_threat(fingerprint);
1145        let outbound2 = protocol.take_outbound();
1146        assert_eq!(outbound2.len(), 0);
1147    }
1148
1149    #[test]
1150    fn test_apex_command_multisig() {
1151        let architect_key = SoftwareKeyStore::generate().unwrap();
1152
1153        let mut command = ApexCommand::new(ApexCommandType::EmergencyStop, 3);
1154
1155        // Sign by architect
1156        command.sign_architect(&architect_key).unwrap();
1157
1158        // Add council signature
1159        command.add_council_signature(ThresholdSignature {
1160            combined_signature: vec![1, 2, 3],
1161            signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1162            count: 3,
1163        });
1164
1165        // Verify
1166        assert!(command.verify(&architect_key));
1167    }
1168
1169    #[test]
1170    fn test_apex_control_execution() {
1171        let architect_key = SoftwareKeyStore::generate().unwrap();
1172        let apex = ApexControl::new(architect_key.public_key_bytes(), 3);
1173
1174        let mut command = ApexCommand::new(ApexCommandType::EmergencyStop, 3);
1175        command.sign_architect(&architect_key).unwrap();
1176        command.add_council_signature(ThresholdSignature {
1177            combined_signature: vec![1, 2, 3],
1178            signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1179            count: 3,
1180        });
1181
1182        // Execute
1183        let result = apex.execute(command, &architect_key);
1184        assert!(result.is_ok());
1185
1186        // System should be stopped
1187        assert!(apex.is_stopped());
1188    }
1189
1190    #[test]
1191    fn test_stealth_slot_rotation() {
1192        let stealth = StealthIntegrity::new(3); // Rotate every 3 ops
1193
1194        assert_eq!(stealth.current_slot(), MemorySlot::Primary);
1195
1196        // Tick 4 times (rotation happens when ops >= 3, fetch_add returns pre-increment)
1197        stealth.tick(); // ops becomes 1
1198        stealth.tick(); // ops becomes 2
1199        stealth.tick(); // ops becomes 3, triggers rotation
1200        stealth.tick(); // ops becomes 1 (reset after rotation)
1201
1202        // Should have rotated to Secondary
1203        assert_eq!(stealth.current_slot(), MemorySlot::Secondary);
1204
1205        // 4 more to rotate again
1206        stealth.tick();
1207        stealth.tick();
1208        stealth.tick();
1209        stealth.tick();
1210
1211        assert_eq!(stealth.current_slot(), MemorySlot::Tertiary);
1212    }
1213
1214    #[test]
1215    fn test_stealth_canary_verification() {
1216        let stealth = StealthIntegrity::new(100);
1217
1218        // Canaries should be intact
1219        assert!(stealth.verify_canaries());
1220        assert!(!stealth.is_compromised());
1221
1222        // Tamper with canary
1223        stealth.canaries.write()[0] = 0xDEADBEEF;
1224
1225        // Should detect tampering
1226        assert!(!stealth.verify_canaries());
1227        assert!(stealth.is_compromised());
1228    }
1229
1230    #[test]
1231    fn test_global_immunity_sync() {
1232        let architect_key = SoftwareKeyStore::generate().unwrap();
1233
1234        // Create mesh
1235        let mesh = GlobalImmunityMesh::new(architect_key.public_key_bytes(), 3).unwrap();
1236
1237        // Create and set genesis
1238        let genesis = GenesisBlock::create(
1239            vec!["Do no harm".to_string()],
1240            &architect_key,
1241            "Test genesis",
1242        )
1243        .unwrap();
1244
1245        mesh.initialize_genesis(genesis);
1246
1247        // Create test pattern
1248        let pattern = AttackPattern {
1249            id: "test".to_string(),
1250            signature: [42u8; 32],
1251            category: crate::evolutionary_guard::AttackCategory::CommandInjection,
1252            threat_level: ThreatLevel::High,
1253            action_type: crate::proof::ActionType::Execute,
1254            target_patterns: vec![],
1255            keywords: vec!["exec".to_string()],
1256            timing_signature: None,
1257            triggered_rule: "test rule".to_string(),
1258            first_seen: 12345,
1259            occurrence_count: 1,
1260            confidence: 0.9,
1261        };
1262
1263        // Broadcast threat
1264        mesh.broadcast_threat(&pattern);
1265
1266        // Should have outbound message
1267        let outbound = mesh.sync().take_outbound();
1268        assert!(!outbound.is_empty());
1269    }
1270
1271    #[test]
1272    fn test_apex_prevents_replay() {
1273        let architect_key = SoftwareKeyStore::generate().unwrap();
1274        let apex = ApexControl::new(architect_key.public_key_bytes(), 3);
1275
1276        let mut command = ApexCommand::new(ApexCommandType::GlobalHardReset, 3);
1277        command.sign_architect(&architect_key).unwrap();
1278        command.add_council_signature(ThresholdSignature {
1279            combined_signature: vec![1, 2, 3],
1280            signer_pubkeys: vec![vec![1], vec![2], vec![3]],
1281            count: 3,
1282        });
1283
1284        // First execution succeeds
1285        let result1 = apex.execute(command.clone(), &architect_key);
1286        assert!(result1.is_ok());
1287
1288        // Replay should fail
1289        let result2 = apex.execute(command, &architect_key);
1290        assert!(matches!(result2, Err(ApexError::ReplayDetected)));
1291    }
1292}