ricecoder_learning/
intent_tracking_integration.rs

1/// Integration of IntentTracker with LearningManager
2///
3/// Provides methods for tracking architectural intent and detecting drift
4/// as part of the learning system.
5
6use crate::drift_detector::{DriftDetectionConfig, DriftDetector};
7use crate::error::Result;
8use crate::intent_tracker::{
9    ArchitecturalDecision, ArchitecturalEvolution, ArchitecturalSummary, DriftDetection,
10    IntentTracker,
11};
12use crate::models::LearnedPattern;
13use std::sync::Arc;
14use tokio::sync::RwLock;
15
16/// Intent tracking integration for the learning manager
17pub struct IntentTrackingIntegration {
18    /// Intent tracker for architectural decisions
19    intent_tracker: Arc<RwLock<IntentTracker>>,
20    /// Drift detector for identifying deviations
21    drift_detector: Arc<RwLock<DriftDetector>>,
22}
23
24impl IntentTrackingIntegration {
25    /// Create a new intent tracking integration
26    pub fn new() -> Self {
27        Self {
28            intent_tracker: Arc::new(RwLock::new(IntentTracker::new())),
29            drift_detector: Arc::new(RwLock::new(DriftDetector::new())),
30        }
31    }
32
33    /// Create with custom drift detection configuration
34    pub fn with_drift_config(config: DriftDetectionConfig) -> Self {
35        Self {
36            intent_tracker: Arc::new(RwLock::new(IntentTracker::new())),
37            drift_detector: Arc::new(RwLock::new(DriftDetector::with_config(config))),
38        }
39    }
40
41    /// Record an architectural decision
42    pub async fn record_decision(
43        &self,
44        decision_type: String,
45        description: String,
46        rationale: String,
47    ) -> Result<ArchitecturalDecision> {
48        let mut tracker = self.intent_tracker.write().await;
49        tracker.record_decision(decision_type, description, rationale)
50    }
51
52    /// Get a decision by ID
53    pub async fn get_decision(&self, decision_id: &str) -> Result<ArchitecturalDecision> {
54        let tracker = self.intent_tracker.read().await;
55        tracker.get_decision(decision_id)
56    }
57
58    /// List all architectural decisions
59    pub async fn list_decisions(&self) -> Vec<ArchitecturalDecision> {
60        let tracker = self.intent_tracker.read().await;
61        tracker.list_decisions()
62    }
63
64    /// Identify architectural patterns from decisions
65    pub async fn identify_patterns(&self) -> Result<Vec<LearnedPattern>> {
66        let tracker = self.intent_tracker.read().await;
67        tracker.identify_patterns()
68    }
69
70    /// Record architectural evolution between versions
71    pub async fn record_evolution(
72        &self,
73        from_version: String,
74        to_version: String,
75        description: String,
76    ) -> Result<ArchitecturalEvolution> {
77        let mut tracker = self.intent_tracker.write().await;
78        tracker.record_evolution(from_version, to_version, description)
79    }
80
81    /// Get evolution history
82    pub async fn get_evolution_history(&self) -> Vec<ArchitecturalEvolution> {
83        let tracker = self.intent_tracker.read().await;
84        tracker.get_evolution_history()
85    }
86
87    /// Detect architectural drift
88    pub async fn detect_drift(
89        &self,
90        decision_id: &str,
91        drift_type: String,
92        description: String,
93    ) -> Result<DriftDetection> {
94        let mut tracker = self.intent_tracker.write().await;
95        tracker.detect_drift(decision_id, drift_type, description)
96    }
97
98    /// Get all drift detections
99    pub async fn get_drift_detections(&self) -> Vec<DriftDetection> {
100        let tracker = self.intent_tracker.read().await;
101        tracker.get_drift_detections()
102    }
103
104    /// Get drift detections for a specific decision
105    pub async fn get_drift_for_decision(&self, decision_id: &str) -> Vec<DriftDetection> {
106        let tracker = self.intent_tracker.read().await;
107        tracker.get_drift_for_decision(decision_id)
108    }
109
110    /// Update decision confidence based on observations
111    pub async fn update_decision_confidence(
112        &self,
113        decision_id: &str,
114        confidence: f32,
115    ) -> Result<()> {
116        let mut tracker = self.intent_tracker.write().await;
117        tracker.update_decision_confidence(decision_id, confidence)
118    }
119
120    /// Increment occurrence count for a decision
121    pub async fn increment_occurrence(&self, decision_id: &str) -> Result<()> {
122        let mut tracker = self.intent_tracker.write().await;
123        tracker.increment_occurrence(decision_id)
124    }
125
126    /// Get summary of architectural state
127    pub async fn get_summary(&self) -> ArchitecturalSummary {
128        let tracker = self.intent_tracker.read().await;
129        tracker.get_summary()
130    }
131
132    /// Register an established pattern for drift detection
133    pub async fn register_pattern_for_drift_detection(
134        &self,
135        pattern: LearnedPattern,
136    ) -> Result<()> {
137        let mut detector = self.drift_detector.write().await;
138        detector.register_pattern(pattern)
139    }
140
141    /// Check if a decision deviates from established patterns
142    pub async fn check_deviation(
143        &self,
144        decision: &ArchitecturalDecision,
145        pattern_type: &str,
146    ) -> Result<Option<DriftDetection>> {
147        let mut detector = self.drift_detector.write().await;
148        detector.check_deviation(decision, pattern_type)
149    }
150
151    /// Detect inconsistencies in decision application
152    pub async fn detect_inconsistency(
153        &self,
154        decision_id: &str,
155        expected_behavior: &str,
156        actual_behavior: &str,
157    ) -> Result<DriftDetection> {
158        let mut detector = self.drift_detector.write().await;
159        detector.detect_inconsistency(decision_id, expected_behavior, actual_behavior)
160    }
161
162    /// Detect pattern violations
163    pub async fn detect_violation(
164        &self,
165        decision_id: &str,
166        violation_description: &str,
167    ) -> Result<DriftDetection> {
168        let mut detector = self.drift_detector.write().await;
169        detector.detect_violation(decision_id, violation_description)
170    }
171
172    /// Get all detected drifts from the detector
173    pub async fn get_detector_drifts(&self) -> Vec<DriftDetection> {
174        let detector = self.drift_detector.read().await;
175        detector.get_drifts()
176    }
177
178    /// Get drifts by severity
179    pub async fn get_drifts_by_severity(&self, severity: &str) -> Vec<DriftDetection> {
180        let detector = self.drift_detector.read().await;
181        detector.get_drifts_by_severity(severity)
182    }
183
184    /// Get drifts for a specific decision from the detector
185    pub async fn get_detector_drifts_for_decision(
186        &self,
187        decision_id: &str,
188    ) -> Vec<DriftDetection> {
189        let detector = self.drift_detector.read().await;
190        detector.get_drifts_for_decision(decision_id)
191    }
192
193    /// Clear all detected drifts
194    pub async fn clear_detector_drifts(&self) {
195        let mut detector = self.drift_detector.write().await;
196        detector.clear_drifts();
197    }
198
199    /// Get drift statistics
200    pub async fn get_drift_statistics(&self) -> crate::drift_detector::DriftStatistics {
201        let detector = self.drift_detector.read().await;
202        detector.get_statistics()
203    }
204
205    /// Perform comprehensive drift detection on all decisions
206    pub async fn perform_comprehensive_drift_detection(&self) -> Result<Vec<DriftDetection>> {
207        let tracker = self.intent_tracker.read().await;
208        let decisions = tracker.list_decisions();
209
210        let mut all_drifts = Vec::new();
211
212        for decision in decisions {
213            // Check for deviations from patterns
214            let patterns = tracker.identify_patterns()?;
215            for pattern in patterns {
216                let mut detector = self.drift_detector.write().await;
217                if let Ok(Some(drift)) = detector.check_deviation(&decision, &pattern.pattern_type) {
218                    all_drifts.push(drift);
219                }
220            }
221        }
222
223        Ok(all_drifts)
224    }
225
226    /// Get a comprehensive report of architectural state
227    pub async fn get_comprehensive_report(&self) -> ArchitecturalReport {
228        let summary = self.get_summary().await;
229        let decisions = self.list_decisions().await;
230        let evolution = self.get_evolution_history().await;
231        let drifts = self.get_drift_detections().await;
232        let detector_drifts = self.get_detector_drifts().await;
233        let drift_stats = self.get_drift_statistics().await;
234
235        ArchitecturalReport {
236            summary,
237            total_decisions: decisions.len(),
238            total_evolution_records: evolution.len(),
239            total_drifts: drifts.len() + detector_drifts.len(),
240            drift_statistics: drift_stats,
241        }
242    }
243}
244
245impl Default for IntentTrackingIntegration {
246    fn default() -> Self {
247        Self::new()
248    }
249}
250
251/// Comprehensive report of architectural state
252#[derive(Debug, Clone)]
253pub struct ArchitecturalReport {
254    /// Summary of architectural state
255    pub summary: ArchitecturalSummary,
256    /// Total number of decisions
257    pub total_decisions: usize,
258    /// Total number of evolution records
259    pub total_evolution_records: usize,
260    /// Total number of drifts detected
261    pub total_drifts: usize,
262    /// Drift statistics
263    pub drift_statistics: crate::drift_detector::DriftStatistics,
264}
265
266#[cfg(test)]
267mod tests {
268    use super::*;
269
270    #[tokio::test]
271    async fn test_intent_tracking_integration_creation() {
272        let integration = IntentTrackingIntegration::new();
273        let summary = integration.get_summary().await;
274        assert_eq!(summary.total_decisions, 0);
275    }
276
277    #[tokio::test]
278    async fn test_record_decision() {
279        let integration = IntentTrackingIntegration::new();
280        let decision = integration
281            .record_decision(
282                "layering".to_string(),
283                "Implement layered architecture".to_string(),
284                "Separation of concerns".to_string(),
285            )
286            .await
287            .expect("Failed to record decision");
288
289        assert_eq!(decision.decision_type, "layering");
290        let decisions = integration.list_decisions().await;
291        assert_eq!(decisions.len(), 1);
292    }
293
294    #[tokio::test]
295    async fn test_record_evolution() {
296        let integration = IntentTrackingIntegration::new();
297        let evolution = integration
298            .record_evolution(
299                "0.1.0".to_string(),
300                "0.2.0".to_string(),
301                "Added async patterns".to_string(),
302            )
303            .await
304            .expect("Failed to record evolution");
305
306        assert_eq!(evolution.from_version, "0.1.0");
307        let history = integration.get_evolution_history().await;
308        assert_eq!(history.len(), 1);
309    }
310
311    #[tokio::test]
312    async fn test_detect_drift() {
313        let integration = IntentTrackingIntegration::new();
314        let decision = integration
315            .record_decision(
316                "layering".to_string(),
317                "Layered architecture".to_string(),
318                "Separation of concerns".to_string(),
319            )
320            .await
321            .expect("Failed to record decision");
322
323        let drift = integration
324            .detect_drift(
325                &decision.id,
326                "violation".to_string(),
327                "Direct layer bypass detected".to_string(),
328            )
329            .await
330            .expect("Failed to detect drift");
331
332        assert_eq!(drift.severity, "high");
333        let drifts = integration.get_drift_detections().await;
334        assert_eq!(drifts.len(), 1);
335    }
336
337    #[tokio::test]
338    async fn test_get_comprehensive_report() {
339        let integration = IntentTrackingIntegration::new();
340        integration
341            .record_decision(
342                "layering".to_string(),
343                "Layered architecture".to_string(),
344                "Separation of concerns".to_string(),
345            )
346            .await
347            .expect("Failed to record decision");
348
349        let report = integration.get_comprehensive_report().await;
350        assert_eq!(report.total_decisions, 1);
351    }
352}