SwarmWriter::open refuses a store holding a record it does not read

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Eureka 2026-11-14 09:35:31 +00:00
commit 211cfe5e82
2 changed files with 19 additions and 0 deletions

View file

@ -506,6 +506,10 @@ impl SwarmWriter {
let mut cache = swarm_cache()?;
cache.add_generic_backing_store(SingleFileMessagePackBackingStore::new(&path))?;
cache.pull_all_backing_stores()?;
// A pull carries a record no registered type claims instead of refusing it; the writer still must not write beside one.
if !cache.foreign_records().is_empty() {
bail!("{} holds a record this swarm store does not read: archive it, nothing migrates it", path.display());
}
Ok(Self { cache, path })
}

View file

@ -271,3 +271,18 @@ fn a_writer_refuses_to_open_over_a_store_holding_a_record_it_does_not_read() {
assert!(refusal.contains("does not read"), "{refusal}");
assert_eq!(std::fs::read(&path).unwrap(), before, "the refused open leaves the store bytes alone");
}
#[test]
fn a_swarm_writer_refuses_to_open_over_a_store_holding_a_record_it_does_not_read() {
let dir = tempfile::tempdir().unwrap();
let path = swarm_path(dir.path());
let mut cache = CultCache::new();
cache.register_entry_type::<OldDial>().unwrap();
cache.add_generic_backing_store(SingleFileMessagePackBackingStore::new(&path)).unwrap();
cache.pull_all_backing_stores().unwrap();
cache.put("dial", &OldDial { heat: "1".into() }).unwrap();
let before = std::fs::read(&path).unwrap();
let refusal = SwarmWriter::open(&path).err().expect("a foreign record refuses the open").to_string();
assert!(refusal.contains("does not read"), "{refusal}");
assert_eq!(std::fs::read(&path).unwrap(), before, "the refused open leaves the store bytes alone");
}