archipelago 2f99db5e6b fix(01-01): serialize federation node-store writes, close remove-vs-sync race (FED-01)
- Add FEDERATION_STORE_LOCK (tokio::sync::Mutex<()>) guarding every
  load-mutate-save cycle in federation/storage.rs, closing the race where
  the 90s auto-sync loop's stale pre-removal snapshot could silently
  re-save a peer the operator just removed (no error logged anywhere).
- Split load_nodes/save_nodes/tombstone_did/untombstone_did into thin
  locked outer wrappers + lock-free *_inner bodies so remove_node and
  add_node can hold the guard across their whole tombstone+save critical
  section without self-deadlocking (Mutex is not re-entrant).
- Route load_nodes, save_nodes, remove_node, add_node, tombstone_did,
  untombstone_did, set_trust_level, and update_node_state through the
  lock (set_trust_level pulled forward from Task 2's scope — required for
  test_concurrent_writes_do_not_lose_updates, part of Task 1's own
  required-green test suite, to pass; documented in SUMMARY).
- Convert save_nodes_inner to an atomic write: serialize to a sibling
  nodes.json.tmp in the same directory, then tokio::fs::rename onto the
  real path, so a crash mid-write never leaves a partially-written
  nodes.json for a concurrent reader.
- Add 3 new regression tests, two of which are fail-first proven: heavy
  tokio::spawn-based concurrency (not just tokio::join!, since
  remove_node's extra tombstone I/O hop structurally biased a simple
  2-task race toward the safe ordering) reliably reproduced both the lost
  concurrent write and the removed-node-reappears bug pre-fix; both are
  green post-fix along with the existing suite (13/13).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 04:04:08 -04:00
..