@@ -498,6 +498,12 @@ pub async fn refresh_watch_interest_for_targets(
498498 DocumentSyncTarget :: WatchSubscription { owner, .. } => {
499499 dirty_realms. insert ( owner. realm_id ) ;
500500 }
501+ DocumentSyncTarget :: GroupAuthorization { .. } => {
502+ dirty_realms. insert ( * net_handle. realm_id ( ) ) ;
503+ }
504+ DocumentSyncTarget :: RealmAuthorization { realm_id } => {
505+ dirty_realms. insert ( * realm_id) ;
506+ }
501507 DocumentSyncTarget :: RealmConfig { realm_id } => {
502508 realms. insert ( * realm_id) ;
503509 dirty_realms. insert ( * realm_id) ;
@@ -1103,6 +1109,65 @@ mod tests {
11031109 assert_eq ! ( table. nodes( realm_id) . map( |nodes| nodes. len( ) ) , Some ( 1 ) ) ;
11041110 }
11051111
1112+ // A consumed empty digest must be re-dirtied by group authorization
1113+ // reconciliation so a later READ grant restores remote interest.
1114+ #[ tokio:: test]
1115+ async fn regrant_restores_digest ( ) {
1116+ let realm_id = RealmId ( [ 6u8 ; 32 ] ) ;
1117+ let ( _dir, ctx, net) = ctx_with_net ( realm_id, [ 72u8 ; 32 ] ) . await ;
1118+ let node_id = net. node_id ( ) ;
1119+ install_realm_config ( & ctx, realm_id, & [ node_id] ) . await ;
1120+ let group_id = Ulid :: r#gen ( ) ;
1121+ let auth_owner = user ( 6 , 3 ) ;
1122+ let watch_owner = user ( 6 , 2 ) ;
1123+ let prefix = metadata_prefix ( group_id, "a" ) ;
1124+ install_authorization ( & ctx, realm_id, node_id, group_id, auth_owner, & [ ] ) . await ;
1125+ create_watch_subscription ( & ctx. storage_handle , watch_owner, prefix. clone ( ) , mask ( ) , 1 )
1126+ . await
1127+ . expect ( "create" ) ;
1128+
1129+ assert ! (
1130+ publish_watch_interest( & ctx, node_id)
1131+ . await
1132+ . expect( "publish" )
1133+ ) ;
1134+ assert ! (
1135+ read_digest( & ctx, realm_id, node_id)
1136+ . await
1137+ . expect( "empty digest" )
1138+ . entries
1139+ . is_empty( )
1140+ ) ;
1141+ assert ! ( read_marker( & ctx, realm_id) . await . is_none( ) ) ;
1142+
1143+ install_authorization (
1144+ & ctx,
1145+ realm_id,
1146+ node_id,
1147+ group_id,
1148+ auth_owner,
1149+ & [ watch_owner] ,
1150+ )
1151+ . await ;
1152+ refresh_watch_interest_for_targets (
1153+ & ctx,
1154+ & [ DocumentSyncTarget :: GroupAuthorization { group_id } ] ,
1155+ )
1156+ . await ;
1157+
1158+ assert ! ( read_marker( & ctx, realm_id) . await . is_some( ) ) ;
1159+ assert ! (
1160+ publish_watch_interest( & ctx, node_id)
1161+ . await
1162+ . expect( "republish" )
1163+ ) ;
1164+ let digest = read_digest ( & ctx, realm_id, node_id)
1165+ . await
1166+ . expect ( "restored digest" ) ;
1167+ assert_eq ! ( digest. entries. len( ) , 1 ) ;
1168+ assert_eq ! ( digest. entries[ 0 ] . path_prefix, prefix) ;
1169+ }
1170+
11061171 #[ tokio:: test]
11071172 async fn refresh_updates_the_net_handle_table ( ) {
11081173 let realm_id = RealmId ( [ 4u8 ; 32 ] ) ;
0 commit comments