fix(agent): provenance survives compaction; bound alert/session growth; snapshot the WAL
- ProvenanceStore::remap: compaction renumbers cache indices (which are the provenance record ids) but nothing renumbered the ledger, so after any compaction — including the automatic one in delete() — every surviving record's hash was filed under a different record and the next save_or_update raised a bogus High "integrity mismatch" alert. - Pending anomaly alerts are capped (newest 1024 kept). Alerts never block a save, and a session over its write limit alerts on every write, so a caller that didn't drain them grew the queue without bound. - WriteAnomalyDetector tracks at most 4096 sessions, forgetting the least-active half on overflow instead of leaking one entry per session id for the life of the process. - snapshot() copies the pending WAL next to the .h5 copy, so a snapshot is the store as it is now rather than as of the last checkpoint (it used to silently omit up to wal_max_entries recent saves). Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
99b907be04
commit
0744d52639
@@ -105,6 +105,23 @@ impl ProvenanceStore {
|
||||
self.records.insert(provenance.record_id, provenance);
|
||||
}
|
||||
|
||||
/// Renumber records after the store was compacted. `index_map[old]` is
|
||||
/// the record's new id, or `None` if it was removed. Without this, every
|
||||
/// surviving record's hash ends up filed under some other record's id and
|
||||
/// the next integrity check reports a bogus mismatch.
|
||||
pub fn remap(&mut self, index_map: &[Option<usize>]) {
|
||||
let old = std::mem::take(&mut self.records);
|
||||
for (old_id, mut prov) in old {
|
||||
let new_id = usize::try_from(old_id)
|
||||
.ok()
|
||||
.and_then(|i| index_map.get(i).copied().flatten());
|
||||
if let Some(new_id) = new_id {
|
||||
prov.record_id = new_id as u64;
|
||||
self.records.insert(new_id as u64, prov);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve by record ID.
|
||||
pub fn get(&self, record_id: u64) -> Option<&MemoryProvenance> {
|
||||
self.records.get(&record_id)
|
||||
|
||||
Reference in New Issue
Block a user