Skip to main content

stygian_graph/
domain.rs

1//! Domain layer - core business logic
2//!
3//! Contains pure business logic with no infrastructure dependencies.
4//! Domain layer only imports from ports (trait definitions), never from adapters.
5
6/// DAG execution engine using petgraph
7pub mod graph;
8
9/// Graph introspection types and queries
10pub mod introspection;
11
12/// Pipeline types with typestate pattern
13pub mod pipeline;
14
15/// Robots policy value type + decision — recon/production reconciliation (T111).
16pub mod policy;
17
18/// Worker pool executor with backpressure
19pub mod executor;
20
21/// Idempotency tracking system
22pub mod idempotency;
23
24/// API discovery types (response shape, pagination, field inference)
25pub mod discovery;
26
27/// Domain error types
28pub mod error {
29    use thiserror::Error;
30
31    /// Primary error type for the stygian-graph crate
32    ///
33    /// Encompasses all domain-level errors following hexagonal architecture principles.
34    ///
35    /// # Example
36    ///
37    /// ```
38    /// use stygian_graph::domain::error::{StygianError, GraphError};
39    ///
40    /// fn validate_pipeline() -> Result<(), StygianError> {
41    ///     Err(StygianError::Graph(GraphError::CycleDetected))
42    /// }
43    /// ```
44    #[derive(Debug, Error)]
45    pub enum StygianError {
46        /// Graph execution errors
47        #[error("Graph error: {0}")]
48        Graph(#[from] GraphError),
49
50        /// Service interaction errors
51        #[error("Service error: {0}")]
52        Service(#[from] ServiceError),
53
54        /// AI provider errors
55        #[error("Provider error: {0}")]
56        Provider(#[from] ProviderError),
57
58        /// Configuration errors
59        #[error("Config error: {0}")]
60        Config(#[from] ConfigError),
61
62        /// Rate limiting errors
63        #[error("Rate limit error: {0}")]
64        RateLimit(#[from] RateLimitError),
65
66        /// Caching errors
67        #[error("Cache error: {0}")]
68        Cache(#[from] CacheError),
69    }
70
71    /// Graph-specific errors
72    #[derive(Debug, Error)]
73    pub enum GraphError {
74        /// Graph contains a cycle (DAG violation)
75        #[error("Graph contains cycle, cannot execute")]
76        CycleDetected,
77
78        /// Invalid node reference
79        #[error("Node not found: {0}")]
80        NodeNotFound(String),
81
82        /// Invalid edge configuration
83        #[error("Invalid edge: {0}")]
84        InvalidEdge(String),
85
86        /// Pipeline validation failed
87        #[error("Invalid pipeline: {0}")]
88        InvalidPipeline(String),
89
90        /// Execution failed
91        #[error("Execution failed: {0}")]
92        ExecutionFailed(String),
93    }
94
95    /// Service-level errors
96    #[derive(Debug, Error)]
97    pub enum ServiceError {
98        /// Service unavailable
99        #[error("Service unavailable: {0}")]
100        Unavailable(String),
101
102        /// Service timeout
103        #[error("Service timeout after {0}ms")]
104        Timeout(u64),
105
106        /// Service returned invalid response
107        #[error("Invalid response: {0}")]
108        InvalidResponse(String),
109
110        /// Service authentication failed
111        #[error("Authentication failed: {0}")]
112        AuthenticationFailed(String),
113
114        /// Service is rate-limiting; caller should retry after the given delay
115        #[error("Rate limited, retry after {retry_after_ms}ms")]
116        RateLimited {
117            /// Milliseconds to wait before retrying
118            retry_after_ms: u64,
119        },
120    }
121
122    /// AI provider errors
123    #[derive(Debug, Error)]
124    pub enum ProviderError {
125        /// Provider API error
126        #[error("API error: {0}")]
127        ApiError(String),
128
129        /// Invalid API key or credentials
130        #[error("Invalid credentials")]
131        InvalidCredentials,
132
133        /// Token limit exceeded
134        #[error("Token limit exceeded: {0}")]
135        TokenLimitExceeded(String),
136
137        /// Model not available
138        #[error("Model not available: {0}")]
139        ModelUnavailable(String),
140
141        /// Content policy violation
142        #[error("Content policy violation: {0}")]
143        ContentPolicyViolation(String),
144    }
145
146    /// Configuration errors
147    #[derive(Debug, Error)]
148    pub enum ConfigError {
149        /// Missing required configuration
150        #[error("Missing required config: {0}")]
151        MissingConfig(String),
152
153        /// Invalid configuration value
154        #[error("Invalid config value for '{key}': {reason}")]
155        InvalidValue {
156            /// Configuration key
157            key: String,
158            /// Reason for invalidity
159            reason: String,
160        },
161
162        /// Configuration file error
163        #[error("Config file error: {0}")]
164        FileError(String),
165
166        /// TOML parsing error
167        #[error("TOML parse error: {0}")]
168        ParseError(String),
169    }
170
171    /// Rate limiting errors
172    #[derive(Debug, Error)]
173    pub enum RateLimitError {
174        /// Rate limit exceeded
175        #[error("Rate limit exceeded: {0} requests per {1} seconds")]
176        Exceeded(u32, u32),
177
178        /// Quota exhausted
179        #[error("Quota exhausted: {0}")]
180        QuotaExhausted(String),
181
182        /// Retry after duration
183        #[error("Retry after {0} seconds")]
184        RetryAfter(u64),
185    }
186
187    /// Caching errors
188    #[derive(Debug, Error)]
189    pub enum CacheError {
190        /// Cache miss
191        #[error("Cache miss: {0}")]
192        Miss(String),
193
194        /// Cache write failed
195        #[error("Cache write failed: {0}")]
196        WriteFailed(String),
197
198        /// Cache read failed
199        #[error("Cache read failed: {0}")]
200        ReadFailed(String),
201
202        /// Cache eviction failed
203        #[error("Cache eviction failed: {0}")]
204        EvictionFailed(String),
205
206        /// Cache corrupted
207        #[error("Cache corrupted: {0}")]
208        Corrupted(String),
209    }
210
211    /// Domain result type using `StygianError`
212    pub type Result<T> = std::result::Result<T, StygianError>;
213
214    /// Legacy domain error (kept for backward compatibility)
215    #[derive(Debug, Error)]
216    pub enum DomainError {
217        /// Graph contains cycle
218        #[error("Graph contains cycle, cannot execute")]
219        CycleDetected,
220
221        /// Invalid pipeline configuration
222        #[error("Invalid pipeline: {0}")]
223        InvalidPipeline(String),
224
225        /// Execution failed
226        #[error("Execution failed: {0}")]
227        ExecutionFailed(String),
228
229        /// Service error
230        #[error("Service error: {0}")]
231        ServiceError(String),
232    }
233
234    /// Legacy domain result type
235    pub type DomainResult<T> = std::result::Result<T, DomainError>;
236}