commit fde15d8438e2a227581a210782df17379c652679
parent 640b8b77d039da3b4d1d18827a7d404e32b6e110
Author: triesap <tyson@radroots.org>
Date: Tue, 28 Jul 2026 08:32:29 +0000
event_store: cover addressable visibility drift
- build suppressed addressable visibility through real ingest
- reject a negative stored deletion cutoff through public reads
- detect central and head-projection contract disagreement
- restore SQLite checks before observing each trusted corruption
Diffstat:
1 file changed, 91 insertions(+), 0 deletions(-)
diff --git a/crates/event_store/src/store.rs b/crates/event_store/src/store.rs
@@ -2559,6 +2559,34 @@ mod tests {
store
}
+ async fn suppressed_food_visibility_store() -> (RadrootsEventStore, String) {
+ let store = RadrootsEventStore::open_memory().await.expect("open");
+ let food = food_availability_event(
+ 220,
+ "visibility-drift-carrots",
+ "Visibility Drift Carrots",
+ "Suppressed harvest",
+ "active",
+ Vec::new(),
+ );
+ let food_id = food.id_str().to_owned();
+ let deletion = deletion_event(
+ &fixture_keys(),
+ 230,
+ vec![vec![
+ "a".to_owned(),
+ food_availability_coordinate("visibility-drift-carrots"),
+ ]],
+ );
+ for (observed_at_ms, event) in [(19_100, food), (19_101, deletion)] {
+ store
+ .ingest_event(RadrootsEventIngest::new(event, observed_at_ms))
+ .await
+ .expect("suppressed visibility fixture ingest");
+ }
+ (store, food_id)
+ }
+
fn calendar_date_event(
created_at: u32,
d_tag: &str,
@@ -8527,6 +8555,69 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);",
}
#[tokio::test]
+ async fn current_visibility_rejects_addressable_head_projection_drift() {
+ for (label, bypass_checks, mutation, expected_reason) in [
+ (
+ "negative stored cutoff",
+ true,
+ "UPDATE radroots_event_store_addressable_head_state SET address_reference_cutoff = -1",
+ "stored address deletion cutoff is invalid",
+ ),
+ (
+ "contract disagreement",
+ false,
+ "UPDATE radroots_event_store_addressable_head_state SET contract_id = 'radroots.event.invalid.v1'",
+ "central visibility disagrees with addressable head state",
+ ),
+ ] {
+ let (store, food_id) = suppressed_food_visibility_store().await;
+ let mut connection = store.pool().acquire().await.expect("trusted connection");
+ sqlx::query("DROP TRIGGER radroots_event_store_addressable_state_old_update_guard")
+ .execute(&mut *connection)
+ .await
+ .expect("trusted addressable-state guard removal");
+ if bypass_checks {
+ sqlx::query("PRAGMA foreign_keys = OFF")
+ .execute(&mut *connection)
+ .await
+ .expect("disable trusted foreign-key enforcement");
+ sqlx::query("PRAGMA ignore_check_constraints = ON")
+ .execute(&mut *connection)
+ .await
+ .expect("enable trusted check-constraint bypass");
+ }
+ sqlx::query(mutation)
+ .execute(&mut *connection)
+ .await
+ .expect("trusted addressable-state corruption");
+ if bypass_checks {
+ sqlx::query("PRAGMA ignore_check_constraints = OFF")
+ .execute(&mut *connection)
+ .await
+ .expect("restore check-constraint enforcement");
+ sqlx::query("PRAGMA foreign_keys = ON")
+ .execute(&mut *connection)
+ .await
+ .expect("restore foreign-key enforcement");
+ }
+ drop(connection);
+
+ let error = store
+ .current_event_visibility_v1(food_id.as_str())
+ .await
+ .expect_err("corrupt addressable head projection must fail visibility read");
+ assert!(
+ matches!(
+ error,
+ RadrootsEventStoreError::CurrentVisibilityDrift { ref reason }
+ if reason.contains(expected_reason)
+ ),
+ "{label}: {error}",
+ );
+ }
+ }
+
+ #[tokio::test]
async fn addressable_transition_feed_advances_across_unrelated_kinds() {
let store = RadrootsEventStore::open_memory().await.expect("open");
let first = food_availability_event(