lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 325d9c7264f9257d1936ab0ae703da7517074bd0
parent 3caf84b8248e8f56c8620255da305756c9a92ca7
Author: triesap <tyson@radroots.org>
Date:   Tue, 28 Jul 2026 08:03:14 +0000

event_store: cover visibility storage drift

- reject stored events without active central visibility authority
- require raw addressable identifiers before state validation
- reject missing addressable head-state authority
- exercise public and transactional error surfaces without source drift

Diffstat:
Mcrates/event_store/src/store.rs | 35+++++++++++++++++++++++++++++++++++
Mcrates/event_store/src/store/current_visibility_v1.rs | 29+++++++++++++++++++++++++++++
2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/crates/event_store/src/store.rs b/crates/event_store/src/store.rs @@ -8376,6 +8376,41 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", } #[tokio::test] + async fn current_visibility_rejects_missing_active_authority() { + let store = RadrootsEventStore::open_memory().await.expect("open"); + let regular = signed_event(KIND_POST, 100, Vec::new(), "missing visibility authority"); + store + .ingest_event(RadrootsEventIngest::new(regular.clone(), 37_100)) + .await + .expect("regular ingest"); + + let mut connection = store.pool().acquire().await.expect("trusted connection"); + sqlx::query("DROP TRIGGER radroots_event_store_source_state_delete_guard") + .execute(&mut *connection) + .await + .expect("trusted source-state guard removal"); + sqlx::query("PRAGMA foreign_keys = OFF") + .execute(&mut *connection) + .await + .expect("disable trusted foreign-key enforcement"); + sqlx::query("DELETE FROM radroots_event_store_source_state") + .execute(&mut *connection) + .await + .expect("trusted active-authority corruption"); + sqlx::query("PRAGMA foreign_keys = ON") + .execute(&mut *connection) + .await + .expect("restore foreign-key enforcement"); + drop(connection); + + assert!(matches!( + store.current_event_visibility_v1(regular.id_str()).await, + Err(RadrootsEventStoreError::CurrentVisibilityDrift { reason }) + if reason.contains("has no current-visibility authority") + )); + } + + #[tokio::test] async fn addressable_transition_feed_advances_across_unrelated_kinds() { let store = RadrootsEventStore::open_memory().await.expect("open"); let first = food_availability_event( diff --git a/crates/event_store/src/store/current_visibility_v1.rs b/crates/event_store/src/store/current_visibility_v1.rs @@ -653,6 +653,35 @@ mod tests { } } + #[tokio::test] + async fn addressable_head_validator_requires_coordinate_and_state_authority() { + let store = RadrootsEventStore::open_memory().await.expect("open store"); + let mut transaction = store.pool().begin().await.expect("transaction"); + let addressable = visibility( + StoredEventClass::Addressable, + RadrootsCurrentVisibilityDecisionV1::Visible, + true, + Some("a"), + Some(visible_evidence()), + ); + + assert!(matches!( + validate_addressable_head_projection(&mut transaction, &addressable, None).await, + Err(RadrootsEventStoreError::CurrentVisibilityDrift { reason }) + if reason.contains("has no raw d tag") + )); + assert!(matches!( + validate_addressable_head_projection( + &mut transaction, + &addressable, + Some("missing-coordinate"), + ) + .await, + Err(RadrootsEventStoreError::CurrentVisibilityDrift { reason }) + if reason.contains("addressable head state is missing") + )); + } + #[test] fn visibility_shape_accepts_each_decision_and_rejects_each_incoherence() { let regular_id = "a".repeat(64);