diff --git a/crates/mind-body/src/control.rs b/crates/mind-body/src/control.rs index 161899d..64de05d 100644 --- a/crates/mind-body/src/control.rs +++ b/crates/mind-body/src/control.rs @@ -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 }) } diff --git a/crates/mind-body/src/control/tests.rs b/crates/mind-body/src/control/tests.rs index 0db9742..83d9719 100644 --- a/crates/mind-body/src/control/tests.rs +++ b/crates/mind-body/src/control/tests.rs @@ -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::().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"); +}