use chrono::{DateTime, Utc};
use super::types::{COGNITION_SYNTHESIS_SOURCE, FidelityScore, KnowledgeArchetype, KnowledgeFact};
impl KnowledgeFact {
pub fn is_current(&self) -> bool {
self.valid_until.is_none()
}
pub fn is_synthesized_observation(&self) -> bool {
self.archetype == KnowledgeArchetype::Observation
&& self.source_session == COGNITION_SYNTHESIS_SOURCE
}
pub fn quality_score(&self) -> f32 {
let confidence = self.confidence.clamp(0.0, 1.0);
let confirmations_norm = (self.confirmation_count.min(5) as f32) / 5.0;
let balance = self.feedback_up as i32 - self.feedback_down as i32;
let feedback_effect = (balance as f32 / 4.0).tanh() * 0.1;
(0.8 * confidence + 0.2 * confirmations_norm + feedback_effect).clamp(0.0, 1.0)
}
pub fn was_valid_at(&self, at: DateTime<Utc>) -> bool {
let after_start = self.valid_from.is_none_or(|from| at >= from);
let before_end = self.valid_until.is_none_or(|until| at <= until);
after_start && before_end
}
pub fn compute_structural_fidelity(&self) -> f64 {
let mut score: f64 = 0.0;
if !self.source_session.is_empty() && self.source_session != "unknown" {
score += 0.2;
}
if self.confirmation_count >= 2 {
score += 0.2;
}
if self.confidence > 0.7 {
score += 0.2;
}
let days_since_confirmed = Utc::now()
.signed_duration_since(self.last_confirmed)
.num_days();
if days_since_confirmed < 14 {
score += 0.2;
} else if days_since_confirmed < 30 {
score += 0.1;
}
if self.feedback_up > self.feedback_down {
score += 0.2;
} else if self.feedback_up > 0 {
score += 0.1;
}
score.min(1.0)
}
pub fn update_fidelity(&mut self) {
let structural = self.compute_structural_fidelity();
self.fidelity = Some(FidelityScore {
structural,
semantic: structural,
computed_at: Utc::now(),
});
}
}