diff --git a/desktop/src-tauri/src/managed_agents/reconcile.rs b/desktop/src-tauri/src/managed_agents/reconcile.rs index 90f05c5750..3817a4a41b 100644 --- a/desktop/src-tauri/src/managed_agents/reconcile.rs +++ b/desktop/src-tauri/src/managed_agents/reconcile.rs @@ -104,6 +104,16 @@ fn reconcile_agents_in_dir_at( continue; } + // Once a verified kind:30179 head is canonical, this JSON record is + // only a local compatibility cache. Re-publishing its legacy kind:30177 + // projection at boot would let stale disk state race the aggregate's + // transactionally bound projection (and could resurrect a deleted + // generation). Relay-authoritative records are reconciled through the + // PMA read-back path instead. + if record.relay_authority.is_relay_authoritative() { + continue; + } + if retain_agent_record(&conn, keys, record)? { reconciled += 1; } diff --git a/desktop/src-tauri/src/managed_agents/reconcile/tests.rs b/desktop/src-tauri/src/managed_agents/reconcile/tests.rs index c9269dbf00..2b621a3710 100644 --- a/desktop/src-tauri/src/managed_agents/reconcile/tests.rs +++ b/desktop/src-tauri/src/managed_agents/reconcile/tests.rs @@ -159,6 +159,37 @@ fn missing_record_is_never_tombstoned() { assert!(survivor.is_some(), "missing record must stay retained"); } +#[test] +fn relay_authoritative_record_is_never_republished_by_legacy_boot_reconcile() { + let dir = TempDir::new().unwrap(); + let keys = nostr::Keys::generate(); + let pubkey = "9".repeat(64); + let mut record = sample_record(&pubkey, "relay-authoritative-agent"); + record.relay_authority = crate::managed_agents::RelayAuthority::relay_authoritative( + crate::managed_agents::authority::RelayAuthorityEvidence { + generation: 7, + private_event_id: "a".repeat(64), + }, + ); + write_store(&dir, &[record]); + + assert_eq!(reconcile_agents_in_dir(dir.path(), &keys).unwrap(), 0); + + let conn = open_retention_db(&dir.path().join("retention.db")).unwrap(); + assert!(get_pending_sync(&conn).unwrap().is_empty()); + assert!( + get_retained_event( + &conn, + KIND_MANAGED_AGENT, + &keys.public_key().to_hex(), + &pubkey, + ) + .unwrap() + .is_none(), + "legacy reconcile must not synthesize a 30177 from an authoritative cache" + ); +} + #[test] fn keyless_record_is_skipped() { let dir = TempDir::new().unwrap();