hippmem_core/model/unit.rs
1//! MemoryUnit core types: MemoryUnit, MemoryContent, WriteContext, Provenance, and lifecycle/stage enums.
2//!
3//! Corresponds to 02#memoryunit, 02#memorycontent, 02#writecontext, 02#memorylifecycle, 02#provenance.
4
5use crate::ids::MemoryId;
6use crate::model::links::{ActivationState, AssociationKeys, AssociationLink};
7use crate::model::understanding::MemoryUnderstanding;
8use crate::score::UnitScore;
9use crate::time::Timestamp;
10use serde::{Deserialize, Serialize};
11
12/// Memory unit: HIPPMEM's core data object — not an ordinary document, but a network node of a three-layer structure of "content + associations + activation history".
13///
14/// Corresponds to 02#memoryunit, traceable to whitepaper §5.1.
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub struct MemoryUnit {
17 /// Serialization version number, currently = 1 (ADR-005).
18 pub schema_version: u16,
19 /// Unique memory ID (ULID, u128).
20 pub id: MemoryId,
21 /// Creation time (UTC milliseconds).
22 pub created_at: Timestamp,
23 /// Last modification time (invariant: >= created_at).
24 pub updated_at: Timestamp,
25 /// Memory content (raw/summary/normalized).
26 pub content: MemoryContent,
27 /// Environmental context at write time.
28 pub context: WriteContext,
29 /// Structured understanding result.
30 pub understanding: MemoryUnderstanding,
31 /// Multi-dimensional recall keys.
32 pub association_keys: AssociationKeys,
33 /// Out-edges of this memory (invariant: deduplicated by (target_id, link_type), no self-loops).
34 pub links: Vec<AssociationLink>,
35 /// Activation history.
36 pub activation: ActivationState,
37 /// Lifecycle state.
38 pub lifecycle: MemoryLifecycle,
39 /// Provenance.
40 pub provenance: Provenance,
41 /// Current stage of the staged memory.
42 pub stage: MemoryStage,
43}
44
45/// Memory content: carries raw text, summary, normalized text, language, and content type.
46///
47/// Corresponds to 02#memorycontent, traceable to whitepaper §5.2.
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct MemoryContent {
50 /// Raw text (immutable).
51 pub raw: String,
52 /// Summary (filled in the enriched/consolidated stage).
53 pub summary: Option<String>,
54 /// Normalized text (noise removal / case normalization; filled in the indexed stage).
55 pub normalized: Option<String>,
56 /// Language.
57 pub language: Language,
58 /// Content type.
59 pub content_type: ContentType,
60}
61
62/// Language enum. Corresponds to the Chinese/English tokenization path selection in ADR-018.
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
64pub enum Language {
65 /// Chinese
66 Zh,
67 /// English
68 En,
69 /// Code snippet
70 Code,
71 /// Mixed Chinese/English
72 Mixed,
73 /// Reserved: BCP-47 numeric code
74 Other(u16),
75}
76
77/// Content type enum. Each type has a different decay-protection level and importance baseline.
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
79pub enum ContentType {
80 /// User statement
81 UserStatement,
82 /// Assistant observation
83 AssistantObservation,
84 /// Tool result
85 ToolResult,
86 /// Decision
87 Decision,
88 /// Preference
89 Preference,
90 /// Event
91 Event,
92 /// Task state
93 TaskState,
94 /// Project knowledge
95 ProjectKnowledge,
96 /// Reflection
97 Reflection,
98 /// Correction
99 Correction,
100}
101
102// ── WriteContext ──
103
104/// Write context: environmental information such as session, task, and project at write time.
105/// All fields are retained (constitution C3); the first version may leave them empty.
106///
107/// Corresponds to 02#writecontext, traceable to whitepaper §5.3.
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109pub struct WriteContext {
110 /// Conversation ID.
111 pub conversation_id: Option<u64>,
112 /// Session instance ID.
113 pub session_id: Option<u64>,
114 /// Project ID.
115 pub project_id: Option<u64>,
116 /// Task ID.
117 pub task_id: Option<u64>,
118 /// User ID.
119 pub user_id: Option<u64>,
120 /// Local time at write.
121 pub local_time: Timestamp,
122 /// Preceding adjacent memory IDs (for temporal-proximity recall).
123 pub preceding_memory_ids: Vec<MemoryId>,
124 /// Source references.
125 pub source_refs: Vec<SourceRef>,
126}
127
128/// Source reference: describes where a memory's content came from.
129#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
130pub struct SourceRef {
131 /// Source type.
132 pub kind: SourceKind,
133 /// URI / file path / external system ID / memory ID string.
134 pub locator: String,
135 /// Position in the source text (optional).
136 pub span: Option<TextSpan>,
137}
138
139/// Source type enum.
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
141pub enum SourceKind {
142 /// Conversation
143 Conversation,
144 /// File
145 File,
146 /// Tool
147 Tool,
148 /// External system
149 ExternalSystem,
150 /// Points to another memory
151 MemoryRef,
152 /// Other
153 Other,
154}
155
156/// Byte offset span in text (start <= end).
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
158pub struct TextSpan {
159 /// Start byte offset.
160 pub start: u32,
161 /// End byte offset.
162 pub end: u32,
163}
164
165// ── MemoryStage / MemoryLifecycle ──
166
167/// Staged memory stage. Unidirectional: Raw → Indexed → Enriched → Consolidated.
168///
169/// Corresponds to 02#memorystage, traceable to whitepaper §6.1.
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
171pub enum MemoryStage {
172 /// Raw content persisted
173 Raw,
174 /// Basic immediate dimensions completed
175 Indexed,
176 /// Strong semantic dimensions filled in
177 Enriched,
178 /// Summarization/merging/long-term evolution completed
179 Consolidated,
180}
181
182/// Memory lifecycle state machine.
183///
184/// Corresponds to 02#memorylifecycle, traceable to whitepaper §5.1, §8.
185#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
186pub enum MemoryLifecycle {
187 /// Active
188 Active,
189 /// Compressed into a summary memory
190 Compressed {
191 /// Target summary memory ID.
192 into: MemoryId,
193 },
194 /// Archived
195 Archived,
196 /// Superseded by a new memory
197 Superseded {
198 /// The superseding memory ID.
199 by: MemoryId,
200 },
201 /// Outdated but retained for historical significance
202 Deprecated,
203 /// Explicitly negated by the user
204 Negated {
205 /// The negator (correcting memory) ID.
206 by: MemoryId,
207 },
208}
209
210// ── Provenance ──
211
212/// Provenance: the source, evidence, generation method, and reliability of a memory.
213///
214/// Corresponds to 02#provenance, traceable to whitepaper §5.1, risk 5.
215#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
216pub struct Provenance {
217 /// Source type.
218 pub origin: SourceKind,
219 /// Who produced this understanding/memory.
220 pub generated_by: GeneratedBy,
221 /// Reliability.
222 pub reliability: UnitScore,
223 /// Evidence references.
224 pub evidence_refs: Vec<SourceRef>,
225 /// Marks from each consolidation/correction.
226 pub revision_history: Vec<RevisionMark>,
227}
228
229/// Generator: who produced this understanding/memory.
230#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
231pub enum GeneratedBy {
232 /// Direct user input
233 UserDirect,
234 /// Which extraction backend (e.g. "anthropic-claude" / "deterministic")
235 Extractor {
236 /// Backend identifier name.
237 backend: String,
238 },
239 /// Generated by background consolidation (e.g. summary)
240 Consolidation,
241 /// Rule-based generation
242 Rule,
243}
244
245/// Revision mark: the time and reason of each consolidation/correction.
246#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
247pub struct RevisionMark {
248 /// Revision time.
249 pub at: Timestamp,
250 /// Revision reason.
251 pub reason: String,
252 /// Reviser.
253 pub by: GeneratedBy,
254}