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