81 lines
2.5 KiB
Rust
81 lines
2.5 KiB
Rust
use crate::EventRecord;
|
|
use anyhow::Result;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::BTreeMap;
|
|
|
|
/// Deterministic rebuild state from JSONL event log.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RebuildState {
|
|
pub memories: BTreeMap<String, String>, // query_id -> final_memory
|
|
pub event_count: u32,
|
|
pub chunks_seen: u32,
|
|
pub chunks_used: u32,
|
|
}
|
|
|
|
impl RebuildState {
|
|
/// Rebuild from event records (must be deterministic).
|
|
pub fn from_events(events: &[EventRecord]) -> Result<Self> {
|
|
let mut memories = BTreeMap::new();
|
|
let mut chunks_seen = 0;
|
|
let mut chunks_used = 0;
|
|
|
|
// Group events by query
|
|
let mut by_query: BTreeMap<String, Vec<&EventRecord>> = BTreeMap::new();
|
|
for event in events {
|
|
by_query.entry(event.query.clone()).or_insert_with(Vec::new).push(event);
|
|
}
|
|
|
|
// Replay events for each query
|
|
for (query_id, query_events) in by_query {
|
|
let memory = String::new();
|
|
let mut q_seen = 0;
|
|
let mut q_used = 0;
|
|
|
|
for event in query_events {
|
|
// Parse event_type (very simplified)
|
|
if event.event_type.contains("Memory") {
|
|
// Would parse the actual memory update from data
|
|
// For now: assume memory doesn't change without update
|
|
}
|
|
if event.event_type.contains("Evidence") {
|
|
q_used += 1;
|
|
}
|
|
if event.event_type.contains("Gate") {
|
|
q_seen += 1;
|
|
}
|
|
}
|
|
|
|
memories.insert(query_id, memory);
|
|
chunks_seen += q_seen;
|
|
chunks_used += q_used;
|
|
}
|
|
|
|
Ok(Self {
|
|
memories,
|
|
event_count: events.len() as u32,
|
|
chunks_seen,
|
|
chunks_used,
|
|
})
|
|
}
|
|
|
|
/// Serialize to JSONL (must match original byte-for-byte).
|
|
pub fn to_events(&self) -> Vec<EventRecord> {
|
|
// This is a placeholder - real rebuild would deserialize the exact events
|
|
// The key is that deserialization + re-serialization produces identical bytes
|
|
vec![]
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn test_rebuild_empty() {
|
|
let events = vec![];
|
|
let state = RebuildState::from_events(&events).unwrap();
|
|
assert_eq!(state.event_count, 0);
|
|
}
|
|
}
|