@@ -76,6 +76,21 @@ public async Task ExecuteAsync_uses_sync_policy_path_without_async_override()
7676 Assert . Equal ( "updated" , result . NewState ! . Value ) ;
7777 }
7878
79+ [ Fact ]
80+ public async Task ExecuteAsync_allows_sync_and_async_policies_to_coexist_without_ambiguous_ordering ( )
81+ {
82+ var engine = CreateEngine ( ) ;
83+ var observed = new List < string > ( ) ;
84+
85+ engine . RegisterPolicy ( new ObservedSyncAllowPolicy ( observed ) ) ;
86+ engine . RegisterPolicy ( new ObservedAsyncAllowPolicy ( observed ) ) ;
87+
88+ var result = await engine . ExecuteAsync ( new SampleMutation ( ) , new SampleState ( "initial" ) ) ;
89+
90+ Assert . True ( result . IsSuccess ) ;
91+ Assert . Equal ( [ "async" , "sync" ] , observed ) ;
92+ }
93+
7994 private static IMutationEngine CreateEngine ( Action < MutationEngineOptions > ? configure = null )
8095 {
8196 var services = new ServiceCollection ( ) ;
@@ -113,6 +128,36 @@ public PolicyDecision Evaluate(IMutation<SampleState> mutation, SampleState stat
113128 => PolicyDecision . Allow ( Name , "Synchronous policy allowed the mutation." ) ;
114129 }
115130
131+ private sealed class ObservedSyncAllowPolicy ( List < string > observed ) : IMutationPolicy < SampleState >
132+ {
133+ public string Name => "ObservedSyncAllow" ;
134+ public int Priority => 10 ;
135+ public string ? Description => "Records synchronous policy evaluation order." ;
136+
137+ public PolicyDecision Evaluate ( IMutation < SampleState > mutation , SampleState state )
138+ {
139+ observed . Add ( "sync" ) ;
140+ return PolicyDecision . Allow ( Name , "Synchronous policy allowed the mutation." ) ;
141+ }
142+ }
143+
144+ private sealed class ObservedAsyncAllowPolicy ( List < string > observed ) : IMutationPolicy < SampleState >
145+ {
146+ public string Name => "ObservedAsyncAllow" ;
147+ public int Priority => 100 ;
148+ public string ? Description => "Records asynchronous policy evaluation order." ;
149+
150+ public async Task < PolicyDecision > EvaluateAsync (
151+ IMutation < SampleState > mutation ,
152+ SampleState state ,
153+ CancellationToken cancellationToken = default )
154+ {
155+ await Task . Delay ( 10 , cancellationToken ) ;
156+ observed . Add ( "async" ) ;
157+ return PolicyDecision . Allow ( Name , "Asynchronous policy allowed the mutation." ) ;
158+ }
159+ }
160+
116161 private sealed class AsyncBlockingPolicy : IMutationPolicy < SampleState >
117162 {
118163 public string Name => "AsyncBlocking" ;
0 commit comments