use crate::harness::Harness;
use crate::provenance::{AuthorityScope, InstanceId};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct MemoryId(pub String);
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Memory {
pub id: MemoryId,
pub content: String,
pub project: String,
pub topic: String,
pub source: MemorySource,
pub harness: Harness,
pub session_id: Option<String>,
#[cfg_attr(feature = "serde", serde(default))]
pub origin: InstanceId,
#[cfg_attr(feature = "serde", serde(default))]
pub authority: AuthorityScope,
#[cfg_attr(feature = "serde", serde(default = "default_importance"))]
pub importance: f32,
#[cfg_attr(feature = "serde", serde(default))]
pub created_at: String,
}
#[cfg(feature = "serde")]
fn default_importance() -> f32 {
0.5
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum MemorySource {
Explicit,
AutoCapture,
Mined,
Doctrine,
}
impl MemorySource {
pub fn trust_grade(self) -> u64 {
match self {
MemorySource::AutoCapture => 1,
MemorySource::Mined => 2,
MemorySource::Explicit => 3,
MemorySource::Doctrine => 4,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn memory_round_trips_its_fields() {
let m = Memory {
id: MemoryId("mem_01".into()),
content: "Decided to use DeepSeek for extraction.".into(),
project: "ijima".into(),
topic: "mining".into(),
source: MemorySource::Mined,
harness: Harness::Pi,
session_id: Some("sess_7".into()),
origin: InstanceId::local(),
authority: AuthorityScope::local(),
importance: 0.8,
created_at: "123".into(),
};
assert_eq!(m.id.0, "mem_01");
assert_eq!(m.source, MemorySource::Mined);
assert_eq!(m.harness, Harness::Pi);
assert_eq!(m.importance, 0.8);
assert_eq!(m.created_at, "123");
assert_eq!(m.session_id.as_deref(), Some("sess_7"));
}
#[test]
fn doctrine_is_distinct_from_explicit() {
assert!(matches!(MemorySource::Doctrine, MemorySource::Doctrine));
assert_ne!(MemorySource::Doctrine, MemorySource::Explicit);
assert_ne!(MemorySource::Doctrine, MemorySource::Mined);
}
#[test]
fn trust_grade_monotone_in_trust() {
assert_eq!(MemorySource::AutoCapture.trust_grade(), 1);
assert_eq!(MemorySource::Mined.trust_grade(), 2);
assert_eq!(MemorySource::Explicit.trust_grade(), 3);
assert_eq!(MemorySource::Doctrine.trust_grade(), 4);
assert!(
MemorySource::AutoCapture.trust_grade() < MemorySource::Mined.trust_grade()
&& MemorySource::Mined.trust_grade() < MemorySource::Explicit.trust_grade()
&& MemorySource::Explicit.trust_grade() < MemorySource::Doctrine.trust_grade()
);
}
}