lean_ctx/core/knowledge/
fact.rs1use chrono::{DateTime, Utc};
2
3use super::types::{FidelityScore, KnowledgeFact};
4
5impl KnowledgeFact {
6 pub fn is_current(&self) -> bool {
7 self.valid_until.is_none()
8 }
9
10 pub fn quality_score(&self) -> f32 {
17 let confidence = self.confidence.clamp(0.0, 1.0);
18 let confirmations_norm = (self.confirmation_count.min(5) as f32) / 5.0;
19 let balance = self.feedback_up as i32 - self.feedback_down as i32;
20 let feedback_effect = (balance as f32 / 4.0).tanh() * 0.1;
21
22 (0.8 * confidence + 0.2 * confirmations_norm + feedback_effect).clamp(0.0, 1.0)
26 }
27
28 pub fn was_valid_at(&self, at: DateTime<Utc>) -> bool {
29 let after_start = self.valid_from.is_none_or(|from| at >= from);
30 let before_end = self.valid_until.is_none_or(|until| at <= until);
31 after_start && before_end
32 }
33
34 pub fn compute_structural_fidelity(&self) -> f64 {
37 let mut score: f64 = 0.0;
38 if !self.source_session.is_empty() && self.source_session != "unknown" {
39 score += 0.2;
40 }
41 if self.confirmation_count >= 2 {
42 score += 0.2;
43 }
44 if self.confidence > 0.7 {
45 score += 0.2;
46 }
47 let days_since_confirmed = Utc::now()
48 .signed_duration_since(self.last_confirmed)
49 .num_days();
50 if days_since_confirmed < 14 {
51 score += 0.2;
52 } else if days_since_confirmed < 30 {
53 score += 0.1;
54 }
55 if self.feedback_up > self.feedback_down {
56 score += 0.2;
57 } else if self.feedback_up > 0 {
58 score += 0.1;
59 }
60 score.min(1.0)
61 }
62
63 pub fn update_fidelity(&mut self) {
64 let structural = self.compute_structural_fidelity();
65 self.fidelity = Some(FidelityScore {
66 structural,
67 semantic: structural,
68 computed_at: Utc::now(),
69 });
70 }
71}