//! Error types for the Prime-Radiant coherence engine. //! //! This module provides a hierarchical error structure with domain-specific //! error types for each bounded context. use crate::types::{EdgeId, NodeId, PolicyBundleId, ScopeId, WitnessId}; use thiserror::Error; // ============================================================================ // TOP-LEVEL ERROR // ============================================================================ /// Top-level error type for the coherence engine #[derive(Debug, Error)] pub enum CoherenceError { /// Error in the knowledge substrate #[error("Substrate error: {0}")] Substrate(#[from] SubstrateError), /// Error in coherence computation #[error("Computation error: {0}")] Computation(#[from] ComputationError), /// Error in governance layer #[error("Governance error: {0}")] Governance(#[from] GovernanceError), /// Error in action execution #[error("Execution error: {0}")] Execution(#[from] ExecutionError), /// Error in storage layer #[error("Storage error: {0}")] Storage(#[from] StorageError), /// Configuration error #[error("Configuration error: {0}")] Config(String), /// Internal error (should not happen in normal operation) #[error("Internal error: {0}")] Internal(String), } // ============================================================================ // SUBSTRATE ERRORS // ============================================================================ /// Errors related to the knowledge substrate (sheaf graph) #[derive(Debug, Error)] pub enum SubstrateError { /// Node not found in graph #[error("Node not found: {0}")] NodeNotFound(NodeId), /// Edge not found in graph #[error("Edge not found: {0}")] EdgeNotFound(EdgeId), /// Dimension mismatch in state vectors or restriction maps #[error("Dimension mismatch: expected {expected}, got {actual}")] DimensionMismatch { /// Expected dimension expected: usize, /// Actual dimension actual: usize, }, /// Invalid restriction map (not compatible with node dimensions) #[error("Invalid restriction map: {0}")] InvalidRestrictionMap(String), /// Graph is in an inconsistent state #[error("Graph inconsistent: {0}")] GraphInconsistent(String), /// Node already exists #[error("Node already exists: {0}")] NodeAlreadyExists(NodeId), /// Edge already exists #[error("Edge already exists: {0}")] EdgeAlreadyExists(EdgeId), /// Serialization error #[error("Serialization error: {0}")] Serialization(String), } // ============================================================================ // COMPUTATION ERRORS // ============================================================================ /// Errors related to coherence computation #[derive(Debug, Error)] pub enum ComputationError { /// Residual computation failed #[error("Residual computation failed for edge {edge}: {reason}")] ResidualFailed { /// The edge that failed edge: EdgeId, /// Reason for failure reason: String, }, /// Energy aggregation failed #[error("Energy aggregation failed: {0}")] AggregationFailed(String), /// Spectral analysis failed #[error("Spectral analysis failed: {0}")] SpectralFailed(String), /// Fingerprint mismatch (cache invalidation) #[error("Fingerprint mismatch: cached {cached}, current {current}")] FingerprintMismatch { /// Cached fingerprint cached: String, /// Current fingerprint current: String, }, /// Numerical instability detected #[error("Numerical instability: {0}")] NumericalInstability(String), } // ============================================================================ // GOVERNANCE ERRORS // ============================================================================ /// Errors related to the governance layer #[derive(Debug, Error)] pub enum GovernanceError { /// Policy bundle not found #[error("Policy bundle not found: {0}")] PolicyNotFound(PolicyBundleId), /// Policy bundle already activated (cannot modify) #[error("Policy bundle already activated: {0}")] PolicyAlreadyActivated(PolicyBundleId), /// Policy bundle not approved (cannot activate) #[error("Policy bundle not approved: {0}")] PolicyNotApproved(PolicyBundleId), /// Invalid signature #[error("Invalid signature from approver")] InvalidSignature, /// Insufficient approvals #[error("Insufficient approvals: required {required}, got {actual}")] InsufficientApprovals { /// Required number of approvals required: usize, /// Actual number of approvals actual: usize, }, /// Witness chain broken #[error("Witness chain broken: expected previous {expected:?}, got {actual:?}")] WitnessChainBroken { /// Expected previous witness expected: Option, /// Actual previous witness actual: Option, }, /// Witness not found #[error("Witness not found: {0}")] WitnessNotFound(WitnessId), /// Witness integrity check failed #[error("Witness integrity check failed: {0}")] WitnessIntegrityFailed(WitnessId), /// Threshold configuration invalid #[error("Invalid threshold configuration: {0}")] InvalidThreshold(String), /// Scope pattern invalid #[error("Invalid scope pattern: {0}")] InvalidScopePattern(String), } // ============================================================================ // EXECUTION ERRORS // ============================================================================ /// Errors related to action execution #[derive(Debug, Error)] pub enum ExecutionError { /// Action denied by coherence gate #[error("Action denied: {reason} (witness: {witness_id})")] Denied { /// Witness ID for the denial witness_id: WitnessId, /// Reason for denial reason: String, }, /// Escalation required #[error("Escalation required to lane {lane}: {reason}")] EscalationRequired { /// Required compute lane lane: u8, /// Reason for escalation reason: String, }, /// Action execution failed #[error("Action execution failed: {0}")] ActionFailed(String), /// No policy bundle configured #[error("No policy bundle configured for scope: {0}")] NoPolicyConfigured(ScopeId), /// Policy bundle expired #[error("Policy bundle expired: {0}")] PolicyExpired(PolicyBundleId), /// Timeout waiting for escalation response #[error("Escalation timeout after {timeout_ms}ms")] EscalationTimeout { /// Timeout in milliseconds timeout_ms: u64, }, /// Human review required but not available #[error("Human review required but not available")] HumanReviewUnavailable, } // ============================================================================ // STORAGE ERRORS // ============================================================================ /// Errors related to the storage layer #[derive(Debug, Error)] pub enum StorageError { /// Database connection failed #[error("Database connection failed: {0}")] ConnectionFailed(String), /// Query execution failed #[error("Query failed: {0}")] QueryFailed(String), /// Transaction failed #[error("Transaction failed: {0}")] TransactionFailed(String), /// Record not found #[error("Record not found: {entity_type} with id {id}")] NotFound { /// Type of entity entity_type: String, /// Entity ID id: String, }, /// Duplicate key violation #[error("Duplicate key: {0}")] DuplicateKey(String), /// Serialization failed #[error("Serialization failed: {0}")] SerializationFailed(String), /// Deserialization failed #[error("Deserialization failed: {0}")] DeserializationFailed(String), /// Event log error #[error("Event log error: {0}")] EventLogError(String), /// Replay failed #[error("Replay failed at sequence {sequence}: {reason}")] ReplayFailed { /// Sequence number where replay failed sequence: u64, /// Reason for failure reason: String, }, } // ============================================================================ // RESULT TYPE ALIAS // ============================================================================ /// Result type alias for coherence operations pub type Result = std::result::Result; /// Result type alias for substrate operations pub type SubstrateResult = std::result::Result; /// Result type alias for computation operations pub type ComputationResult = std::result::Result; /// Result type alias for governance operations pub type GovernanceResult = std::result::Result; /// Result type alias for execution operations pub type ExecutionResult = std::result::Result; /// Result type alias for storage operations pub type StorageResult = std::result::Result; // ============================================================================ // ERROR CONVERSION UTILITIES // ============================================================================ impl From for SubstrateError { fn from(e: bincode::error::EncodeError) -> Self { Self::Serialization(e.to_string()) } } impl From for SubstrateError { fn from(e: bincode::error::DecodeError) -> Self { Self::Serialization(e.to_string()) } } impl From for StorageError { fn from(e: serde_json::Error) -> Self { Self::SerializationFailed(e.to_string()) } } // ============================================================================ // TESTS // ============================================================================ #[cfg(test)] mod tests { use super::*; #[test] fn test_error_display() { let err = SubstrateError::DimensionMismatch { expected: 64, actual: 32, }; assert!(err.to_string().contains("64")); assert!(err.to_string().contains("32")); } #[test] fn test_error_conversion() { let substrate_err = SubstrateError::NodeNotFound(NodeId::new()); let coherence_err: CoherenceError = substrate_err.into(); assert!(matches!(coherence_err, CoherenceError::Substrate(_))); } }