@@ -653,6 +653,52 @@ mod tests {
653653 )
654654 }
655655
656+ /// Writes durable evidence straight into the shard, bypassing the
657+ /// runtime scope gate.
658+ ///
659+ /// This is only ever correct for staging state the store contract
660+ /// forbids — a row scoped to another project — so that the reader-side
661+ /// guards can be exercised against it. Everything else must go through
662+ /// [`ObservationStore::persist_observation`].
663+ async fn stage_foreign_scoped_observation (
664+ sessions : & RegisteredGlobalDb ,
665+ write : & AnchoredObservationWrite ,
666+ ) {
667+ let observation = write. observation ( ) ;
668+ let receipt = observation. receipt ( ) ;
669+ let writer = sessions. writer_connection ( ) . unwrap ( ) ;
670+ writer
671+ . execute (
672+ "INSERT INTO sanitization_receipts
673+ (receipt_id, sanitizer_version, payload_digest, receipt_json)
674+ VALUES (?1, ?2, ?3, ?4)" ,
675+ crate :: db:: engine:: params![
676+ receipt. receipt( ) . receipt_id( ) . as_str( ) ,
677+ receipt. receipt( ) . sanitizer_version( ) . as_str( ) ,
678+ observation. payload_reference( ) . digest( ) . as_str( ) ,
679+ serde_json:: to_string( receipt) . unwrap( )
680+ ] ,
681+ )
682+ . await
683+ . unwrap ( ) ;
684+ writer
685+ . execute (
686+ "INSERT INTO observations
687+ (observation_id, payload_digest, receipt_id, observation_json,
688+ committed_cursor_json)
689+ VALUES (?1, ?2, ?3, ?4, ?5)" ,
690+ crate :: db:: engine:: params![
691+ observation. observation_id( ) . as_str( ) ,
692+ observation. payload_reference( ) . digest( ) . as_str( ) ,
693+ receipt. receipt( ) . receipt_id( ) . as_str( ) ,
694+ serde_json:: to_string( observation) . unwrap( ) ,
695+ serde_json:: to_string( write. next_cursor( ) ) . unwrap( )
696+ ] ,
697+ )
698+ . await
699+ . unwrap ( ) ;
700+ }
701+
656702 /// Every test below registers under hook ids unique to that test: the
657703 /// authority registry is process-global, so overlapping keys would make
658704 /// parallel tests observe each other's entries.
@@ -1165,12 +1211,21 @@ mod tests {
11651211 . unwrap ( ) ;
11661212 // Durable evidence carrying a foreign project scope, stored in the
11671213 // shard that the lookup is otherwise authorized against.
1168- observation_store ( & sessions)
1169- . persist_observation ( durable_native_observation ( & id :: < ProjectId > (
1170- "project.native.foreign-scope" ,
1171- ) ) )
1172- . await
1173- . unwrap ( ) ;
1214+ let foreign = durable_native_observation ( & id :: < ProjectId > ( "project.native.foreign-scope" ) ) ;
1215+ // The store contract refuses to create this state: every observation
1216+ // operation is gated on the observation scope matching the bound
1217+ // shard family, so the runtime rejects the write before it reaches
1218+ // the shard. The row can therefore only arrive by corruption or a
1219+ // pre-contract import, which is exactly what the lookup's durable
1220+ // scope check has to survive.
1221+ assert ! (
1222+ observation_store( & sessions)
1223+ . persist_observation( foreign. clone( ) )
1224+ . await
1225+ . is_err( ) ,
1226+ "the runtime must refuse a foreign-scoped write against this shard"
1227+ ) ;
1228+ stage_foreign_scoped_observation ( & sessions, & foreign) . await ;
11741229 let bound_profile_id = sessions. binding ( ) . shard_id . profile_id . clone ( ) ;
11751230
11761231 // Foreign-scoped evidence and no evidence at all both fail closed,
0 commit comments