Skip to main content

weavatrix_memory/analytics/
model.rs

1use crate::{
2    domain::MemoryFact,
3    id::{EntityId, FactId},
4    projection::ProjectionClock,
5    time::Timestamp,
6};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct BeliefRevisionRequest {
11    pub hypothesis: MemoryFact,
12    pub clock: ProjectionClock,
13    pub max_depth: usize,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct Contradiction {
18    pub fact: FactId,
19    pub strength_bps: u16,
20    pub reason: String,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24pub struct CascadeEffect {
25    pub entity: EntityId,
26    pub depth: usize,
27    pub revised_confidence_bps: u16,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
31pub struct BeliefRevisionReport {
32    pub contradictions: Vec<Contradiction>,
33    pub cascade: Vec<CascadeEffect>,
34    pub invalidated_decisions: Vec<EntityId>,
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
38pub struct ReasoningGapRequest {
39    pub clock: ProjectionClock,
40    pub minimum_supports: usize,
41    pub low_confidence_bps: u16,
42    pub unstable_revision_count: usize,
43    pub stale_after_micros: i64,
44    pub max_results: usize,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
48#[serde(rename_all = "snake_case")]
49pub enum GapKind {
50    UnjustifiedDecision,
51    SingleSourceInference,
52    LowConfidenceFoundation,
53    UnstableKnowledge,
54    StaleEvidence,
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct ReasoningGap {
59    pub entity: EntityId,
60    pub fact: Option<FactId>,
61    pub kind: GapKind,
62    pub severity_bps: u16,
63    pub downstream_entities: usize,
64    pub explanation: String,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
68pub struct GapReport {
69    pub gaps: Vec<ReasoningGap>,
70    pub health_bps: u16,
71    pub analyzed_entities: usize,
72    pub analyzed_facts: usize,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
76#[serde(rename_all = "snake_case")]
77pub enum ChangeKind {
78    Initial,
79    Refined,
80    Corrected,
81    Reinforced,
82    Weakened,
83}
84
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86pub struct DriftSnapshot {
87    pub fact: FactId,
88    pub target: EntityId,
89    pub recorded_at: Timestamp,
90    pub confidence_bps: u16,
91    pub change: ChangeKind,
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
95pub struct DriftReport {
96    pub source: EntityId,
97    pub relation: String,
98    pub snapshots: Vec<DriftSnapshot>,
99    pub correction_count: usize,
100    pub stability_bps: u16,
101    pub likely_to_change: bool,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
105#[serde(rename_all = "snake_case")]
106pub enum ConsolidationKind {
107    SupersedeDuplicate,
108    ReviewOrphan,
109    CompactRevisionChain,
110}
111
112#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
113pub struct ConsolidationAction {
114    pub kind: ConsolidationKind,
115    pub keep: Option<FactId>,
116    pub affected_facts: Vec<FactId>,
117    pub affected_entities: Vec<EntityId>,
118    pub rationale: String,
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
122pub struct ConsolidationPlan {
123    pub actions: Vec<ConsolidationAction>,
124    pub projected_savings: usize,
125    pub source_position: Option<u64>,
126}