Files

505 lines
15 KiB
Rust

//! Domain events for the Prime-Radiant coherence engine.
//!
//! All domain events are persisted to the event log for deterministic replay.
//! This enables:
//! - Temporal ordering of all decisions
//! - Tamper detection via content hashes
//! - Deterministic replay capability
use crate::types::{
EdgeId, Hash, LineageId, NodeId, PolicyBundleId, ScopeId, Timestamp, WitnessId,
};
use serde::{Deserialize, Serialize};
// ============================================================================
// DOMAIN EVENT ENUM
// ============================================================================
/// All domain events in the coherence engine
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum DomainEvent {
// -------------------------------------------------------------------------
// Substrate Events
// -------------------------------------------------------------------------
/// A new node was created in the sheaf graph
NodeCreated {
/// Node ID
node_id: NodeId,
/// Namespace
namespace: String,
/// State dimension
dimension: usize,
/// Event timestamp
timestamp: Timestamp,
},
/// A node's state was updated
NodeUpdated {
/// Node ID
node_id: NodeId,
/// Previous state hash
previous_hash: Hash,
/// New state hash
new_hash: Hash,
/// Event timestamp
timestamp: Timestamp,
},
/// A node was removed from the graph
NodeRemoved {
/// Node ID
node_id: NodeId,
/// Event timestamp
timestamp: Timestamp,
},
/// A new edge was created with restriction maps
EdgeCreated {
/// Edge ID
edge_id: EdgeId,
/// Source node
source: NodeId,
/// Target node
target: NodeId,
/// Edge weight
weight: f32,
/// Event timestamp
timestamp: Timestamp,
},
/// An edge was removed
EdgeRemoved {
/// Edge ID
edge_id: EdgeId,
/// Event timestamp
timestamp: Timestamp,
},
/// Edge weight was updated
EdgeWeightUpdated {
/// Edge ID
edge_id: EdgeId,
/// Previous weight
previous_weight: f32,
/// New weight
new_weight: f32,
/// Event timestamp
timestamp: Timestamp,
},
// -------------------------------------------------------------------------
// Coherence Computation Events
// -------------------------------------------------------------------------
/// Full coherence energy was computed
EnergyComputed {
/// Total energy value
total_energy: f32,
/// Number of edges computed
edge_count: usize,
/// Graph fingerprint
fingerprint: Hash,
/// Computation duration in microseconds
duration_us: u64,
/// Event timestamp
timestamp: Timestamp,
},
/// Incremental energy update was computed
EnergyUpdated {
/// Node that triggered update
trigger_node: NodeId,
/// Number of affected edges
affected_edges: usize,
/// New total energy
new_energy: f32,
/// Delta from previous energy
energy_delta: f32,
/// Event timestamp
timestamp: Timestamp,
},
/// Spectral drift was detected
DriftDetected {
/// Drift magnitude
magnitude: f32,
/// Affected eigenvalue modes
affected_modes: Vec<usize>,
/// Event timestamp
timestamp: Timestamp,
},
/// High-energy edge identified (hotspot)
HotspotIdentified {
/// Edge ID
edge_id: EdgeId,
/// Edge energy
energy: f32,
/// Energy rank (1 = highest)
rank: usize,
/// Event timestamp
timestamp: Timestamp,
},
// -------------------------------------------------------------------------
// Governance Events
// -------------------------------------------------------------------------
/// New policy bundle was created
PolicyCreated {
/// Policy bundle ID
bundle_id: PolicyBundleId,
/// Version
version: String,
/// Required approvals
required_approvals: usize,
/// Event timestamp
timestamp: Timestamp,
},
/// Policy bundle was signed by an approver
PolicySigned {
/// Policy bundle ID
bundle_id: PolicyBundleId,
/// Approver ID (as string for serialization)
approver: String,
/// Current signature count
signature_count: usize,
/// Event timestamp
timestamp: Timestamp,
},
/// Policy bundle reached required approvals
PolicyApproved {
/// Policy bundle ID
bundle_id: PolicyBundleId,
/// Event timestamp
timestamp: Timestamp,
},
/// Policy bundle was activated
PolicyActivated {
/// Policy bundle ID
bundle_id: PolicyBundleId,
/// Previous active policy (if any)
previous_policy: Option<PolicyBundleId>,
/// Event timestamp
timestamp: Timestamp,
},
/// Policy bundle was deprecated
PolicyDeprecated {
/// Policy bundle ID
bundle_id: PolicyBundleId,
/// Replacement policy
replacement: PolicyBundleId,
/// Event timestamp
timestamp: Timestamp,
},
/// Witness record was created
WitnessCreated {
/// Witness ID
witness_id: WitnessId,
/// Action hash
action_hash: Hash,
/// Energy at decision time
energy: f32,
/// Decision (allowed/denied)
allowed: bool,
/// Compute lane assigned
lane: u8,
/// Previous witness in chain
previous_witness: Option<WitnessId>,
/// Event timestamp
timestamp: Timestamp,
},
/// Lineage record was created
LineageCreated {
/// Lineage ID
lineage_id: LineageId,
/// Entity reference
entity_ref: String,
/// Operation type
operation: String,
/// Authorizing witness
witness_id: WitnessId,
/// Event timestamp
timestamp: Timestamp,
},
// -------------------------------------------------------------------------
// Execution Events
// -------------------------------------------------------------------------
/// Action was allowed by the coherence gate
ActionAllowed {
/// Action hash
action_hash: Hash,
/// Scope
scope: ScopeId,
/// Compute lane used
lane: u8,
/// Energy at decision
energy: f32,
/// Witness ID
witness_id: WitnessId,
/// Event timestamp
timestamp: Timestamp,
},
/// Action was denied by the coherence gate
ActionDenied {
/// Action hash
action_hash: Hash,
/// Scope
scope: ScopeId,
/// Reason for denial
reason: String,
/// Energy at decision
energy: f32,
/// Witness ID
witness_id: WitnessId,
/// Event timestamp
timestamp: Timestamp,
},
/// Escalation was triggered
EscalationTriggered {
/// Action hash
action_hash: Hash,
/// From lane
from_lane: u8,
/// To lane
to_lane: u8,
/// Reason
reason: String,
/// Event timestamp
timestamp: Timestamp,
},
/// Human review was requested
HumanReviewRequested {
/// Action hash
action_hash: Hash,
/// Scope
scope: ScopeId,
/// Energy at request
energy: f32,
/// Persistence duration in seconds
persistence_secs: u64,
/// Event timestamp
timestamp: Timestamp,
},
// -------------------------------------------------------------------------
// Threshold Tuning Events (SONA)
// -------------------------------------------------------------------------
/// Regime started for threshold learning
RegimeStarted {
/// Regime ID
regime_id: String,
/// Initial energy
initial_energy: f32,
/// Event timestamp
timestamp: Timestamp,
},
/// Regime ended with outcome
RegimeEnded {
/// Regime ID
regime_id: String,
/// Final quality score
quality: f32,
/// Event timestamp
timestamp: Timestamp,
},
/// Successful pattern was learned
PatternLearned {
/// Pattern type
pattern_type: String,
/// Quality score
quality: f32,
/// Event timestamp
timestamp: Timestamp,
},
/// Threshold was adapted via Micro-LoRA
ThresholdAdapted {
/// Scope affected
scope: ScopeId,
/// Previous threshold
previous_reflex: f32,
/// New threshold
new_reflex: f32,
/// Trigger (energy spike magnitude)
trigger: f32,
/// Event timestamp
timestamp: Timestamp,
},
// -------------------------------------------------------------------------
// Tile Fabric Events
// -------------------------------------------------------------------------
/// Fabric tick completed
FabricTickCompleted {
/// Tick number
tick: u32,
/// Global energy
global_energy: f32,
/// Active tiles
active_tiles: usize,
/// Duration in microseconds
duration_us: u64,
/// Event timestamp
timestamp: Timestamp,
},
/// Evidence threshold crossed in tile
EvidenceThresholdCrossed {
/// Tile ID
tile_id: u8,
/// E-value
e_value: f64,
/// Event timestamp
timestamp: Timestamp,
},
}
impl DomainEvent {
/// Get the event type as a string
pub fn event_type(&self) -> &'static str {
match self {
Self::NodeCreated { .. } => "NodeCreated",
Self::NodeUpdated { .. } => "NodeUpdated",
Self::NodeRemoved { .. } => "NodeRemoved",
Self::EdgeCreated { .. } => "EdgeCreated",
Self::EdgeRemoved { .. } => "EdgeRemoved",
Self::EdgeWeightUpdated { .. } => "EdgeWeightUpdated",
Self::EnergyComputed { .. } => "EnergyComputed",
Self::EnergyUpdated { .. } => "EnergyUpdated",
Self::DriftDetected { .. } => "DriftDetected",
Self::HotspotIdentified { .. } => "HotspotIdentified",
Self::PolicyCreated { .. } => "PolicyCreated",
Self::PolicySigned { .. } => "PolicySigned",
Self::PolicyApproved { .. } => "PolicyApproved",
Self::PolicyActivated { .. } => "PolicyActivated",
Self::PolicyDeprecated { .. } => "PolicyDeprecated",
Self::WitnessCreated { .. } => "WitnessCreated",
Self::LineageCreated { .. } => "LineageCreated",
Self::ActionAllowed { .. } => "ActionAllowed",
Self::ActionDenied { .. } => "ActionDenied",
Self::EscalationTriggered { .. } => "EscalationTriggered",
Self::HumanReviewRequested { .. } => "HumanReviewRequested",
Self::RegimeStarted { .. } => "RegimeStarted",
Self::RegimeEnded { .. } => "RegimeEnded",
Self::PatternLearned { .. } => "PatternLearned",
Self::ThresholdAdapted { .. } => "ThresholdAdapted",
Self::FabricTickCompleted { .. } => "FabricTickCompleted",
Self::EvidenceThresholdCrossed { .. } => "EvidenceThresholdCrossed",
}
}
/// Get the timestamp of the event
pub fn timestamp(&self) -> Timestamp {
match self {
Self::NodeCreated { timestamp, .. }
| Self::NodeUpdated { timestamp, .. }
| Self::NodeRemoved { timestamp, .. }
| Self::EdgeCreated { timestamp, .. }
| Self::EdgeRemoved { timestamp, .. }
| Self::EdgeWeightUpdated { timestamp, .. }
| Self::EnergyComputed { timestamp, .. }
| Self::EnergyUpdated { timestamp, .. }
| Self::DriftDetected { timestamp, .. }
| Self::HotspotIdentified { timestamp, .. }
| Self::PolicyCreated { timestamp, .. }
| Self::PolicySigned { timestamp, .. }
| Self::PolicyApproved { timestamp, .. }
| Self::PolicyActivated { timestamp, .. }
| Self::PolicyDeprecated { timestamp, .. }
| Self::WitnessCreated { timestamp, .. }
| Self::LineageCreated { timestamp, .. }
| Self::ActionAllowed { timestamp, .. }
| Self::ActionDenied { timestamp, .. }
| Self::EscalationTriggered { timestamp, .. }
| Self::HumanReviewRequested { timestamp, .. }
| Self::RegimeStarted { timestamp, .. }
| Self::RegimeEnded { timestamp, .. }
| Self::PatternLearned { timestamp, .. }
| Self::ThresholdAdapted { timestamp, .. }
| Self::FabricTickCompleted { timestamp, .. }
| Self::EvidenceThresholdCrossed { timestamp, .. } => *timestamp,
}
}
/// Compute content hash for integrity
pub fn content_hash(&self) -> Hash {
let serialized = serde_json::to_vec(self).unwrap_or_default();
Hash::digest(&serialized)
}
}
// ============================================================================
// EVENT METADATA
// ============================================================================
/// Metadata for an event in the event log
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventMetadata {
/// Sequence number in the log
pub sequence: u64,
/// Content hash for integrity
pub content_hash: Hash,
/// Signature (if signed)
pub signature: Option<Vec<u8>>,
}
/// A complete event record with metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventRecord {
/// The domain event
pub event: DomainEvent,
/// Event metadata
pub metadata: EventMetadata,
}
// ============================================================================
// TESTS
// ============================================================================
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_event_serialization() {
let event = DomainEvent::NodeCreated {
node_id: NodeId::new(),
namespace: "test".to_string(),
dimension: 64,
timestamp: Timestamp::now(),
};
let json = serde_json::to_string(&event).unwrap();
let decoded: DomainEvent = serde_json::from_str(&json).unwrap();
assert_eq!(event.event_type(), decoded.event_type());
}
#[test]
fn test_event_content_hash() {
let event = DomainEvent::EnergyComputed {
total_energy: 0.5,
edge_count: 100,
fingerprint: Hash::zero(),
duration_us: 1000,
timestamp: Timestamp::now(),
};
let h1 = event.content_hash();
let h2 = event.content_hash();
assert_eq!(h1, h2);
}
}