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:
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);