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}