From 211cfe5e8244672fd78a38f44441f1183e28c7b9 Mon Sep 17 00:00:00 2001 From: Eureka Date: Sat, 14 Nov 2026 09:35:31 +0000 Subject: [PATCH] SwarmWriter::open refuses a store holding a record it does not read Co-Authored-By: Claude Sonnet 5.5 --- crates/mind-body/src/control.rs | 4 ++++ crates/mind-body/src/control/tests.rs | 15 +++++++++++++++ 2 files changed, 19 insertions(+) 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"); +}