lib

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

commit 957a5066ea2da319f886c6015a0f40dbaf4d7fea
parent fb687f02c56e331c5528871ceab399c689811d0f
Author: triesap <tyson@radroots.org>
Date:   Tue, 28 Jul 2026 09:17:49 +0000

event_store: cover transition event authority

- reject over-limit coordinates and negative suppression cutoffs
- detect signed-row and registry admission drift
- require matching addressable coordinate authority
- reject retractions of non-admitted stored events

Diffstat:
Mcrates/event_store/src/store.rs | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+), 0 deletions(-)

diff --git a/crates/event_store/src/store.rs b/crates/event_store/src/store.rs @@ -2634,6 +2634,31 @@ mod tests { store } + async fn non_admitted_retraction_corruption_store() -> RadrootsEventStore { + let store = RadrootsEventStore::open_memory().await.expect("open"); + let malformed = signed_event( + 30_402, + 280, + vec![vec!["d".to_owned(), "non-admitted-retraction".to_owned()]], + "malformed FoodAvailability", + ); + let admitted = food_availability_event( + 290, + "non-admitted-retraction", + "Admitted Retraction Carrots", + "Admitted harvest", + "active", + Vec::new(), + ); + for (observed_at_ms, event) in [(19_500, malformed), (19_501, admitted)] { + store + .ingest_event(RadrootsEventIngest::new(event, observed_at_ms)) + .await + .expect("non-admitted retraction fixture ingest"); + } + store + } + async fn transition_feed_error_after_trusted_corruption( store: &RadrootsEventStore, additional_guards: &[&'static str], @@ -9584,6 +9609,73 @@ CREATE TABLE aux.event_transport_observation (event_id TEXT);", } #[tokio::test] + async fn addressable_transition_feed_rejects_stored_event_authority_drift() { + for (label, store, guards, mutations, expected_reason) in [ + ( + "coordinate wire bound", + food_availability_audit_corruption_store().await, + &[][..], + &[ + "UPDATE radroots_event_store_addressable_head_transition SET d_tag = replace(hex(zeroblob(4097)), '00', 'x')", + ][..], + "coordinate is outside wire bounds", + ), + ( + "negative suppression cutoff", + suppressed_food_visibility_store().await.0, + &[][..], + &[ + "UPDATE radroots_event_store_addressable_head_transition SET address_reference_cutoff = -1 WHERE transition_seq = 2", + ][..], + "address_reference_cutoff", + ), + ( + "signed event fields", + food_availability_audit_corruption_store().await, + &["DROP TRIGGER radroots_event_store_event_envelopes_raw_update_guard"][..], + &["UPDATE event_envelopes SET content = 'corrupt' WHERE kind = 30402"][..], + "disagrees with its signed raw JSON", + ), + ( + "registry admission", + food_availability_audit_corruption_store().await, + &["DROP TRIGGER radroots_event_store_event_envelopes_derived_update_guard"][..], + &[ + "UPDATE event_envelopes SET contract_id = 'radroots.event.invalid.v1' WHERE kind = 30402", + ][..], + "disagrees with registry-v7 admission", + ), + ( + "coordinate authority", + food_availability_audit_corruption_store().await, + &["DROP TRIGGER radroots_event_store_event_coordinate_delete_guard"][..], + &["DELETE FROM radroots_event_store_event_coordinate"][..], + "has no matching addressable coordinate authority", + ), + ( + "non-admitted retraction", + non_admitted_retraction_corruption_store().await, + &[][..], + &[ + "UPDATE radroots_event_store_addressable_head_transition SET retracted_event_id = (SELECT raw_head_event_id FROM radroots_event_store_addressable_head_transition WHERE transition_seq = 1), retracted_event_seq = (SELECT raw_head_event_seq FROM radroots_event_store_addressable_head_transition WHERE transition_seq = 1) WHERE transition_seq = 2", + ][..], + "retracts an event that is not admitted", + ), + ] { + let error = + transition_feed_error_after_trusted_corruption(&store, guards, mutations).await; + assert!( + matches!( + error, + RadrootsEventStoreError::AddressableTransitionCorruption { ref reason } + if reason.contains(expected_reason) + ), + "{label}: {error}", + ); + } + } + + #[tokio::test] async fn raw_addressable_heads_use_the_first_opaque_d_value_or_empty() { let store = RadrootsEventStore::open_memory().await.expect("open"); let missing = signed_event(39_990, 30, Vec::new(), "missing");