diff --git a/tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/Scripts/CompileSurfaceParityTests.cs b/tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/Scripts/CompileSurfaceParityTests.cs
index 685ff5a8..df3d872f 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/Scripts/CompileSurfaceParityTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/Scripts/CompileSurfaceParityTests.cs
@@ -41,6 +41,68 @@ public class CompileSurfaceParityTests
globals: typeof(TriggerExpressionGlobals));
}
+ ///
+ /// Deeper guard than the top-level name-superset check above: for each
+ /// runtime script-accessor type (,
+ /// , ) every
+ /// public instance METHOD must have a same-name / same-arity counterpart on
+ /// its compile-surface mirror. This catches the regression that motivated this
+ /// test (the WaitAsync overloads were present on the runtime
+ /// but missing from
+ /// , so scripts that
+ /// awaited them passed the design-time gate yet would have failed at the site).
+ ///
+ ///
+ /// Matching is by NAME + PARAMETER COUNT only — the mirror uses
+ /// object?-vs-mirror-type substitutions, so exact parameter-type identity
+ /// is intentionally NOT required; the guard is about API presence, not type
+ /// equality (the design-time compile catches deeper signature drift itself).
+ /// To still catch a single dropped overload within an overload set that shares
+ /// an arity (e.g. the value-form vs predicate-form WaitAsync, both
+ /// 4-parameter), the assertion is by COUNT: the mirror must expose at least as
+ /// many overloads for each (name, arity) as the runtime accessor declares.
+ ///
+ ///
+ [Theory]
+ [MemberData(nameof(AccessorMirrorPairs))]
+ public void CompileAccessorMirror_Covers_RuntimeAccessor_MethodArities(
+ Type runtimeAccessor, Type compileMirror)
+ {
+ var mirrorCounts = PublicInstanceMethodArityCounts(compileMirror);
+ var runtimeCounts = PublicInstanceMethodArityCounts(runtimeAccessor);
+
+ var shortfalls = runtimeCounts
+ .Where(kvp => mirrorCounts.GetValueOrDefault(kvp.Key) < kvp.Value)
+ .OrderBy(kvp => kvp.Key.Name, StringComparer.Ordinal)
+ .ThenBy(kvp => kvp.Key.Arity)
+ .Select(kvp =>
+ $"{kvp.Key.Name}({kvp.Key.Arity} param(s)): runtime has {kvp.Value} "
+ + $"overload(s), mirror has {mirrorCounts.GetValueOrDefault(kvp.Key)}")
+ .ToList();
+
+ Assert.True(
+ shortfalls.Count == 0,
+ $"Compile surface mirror '{compileMirror.Name}' under-covers {shortfalls.Count} "
+ + $"method group(s) on runtime accessor '{runtimeAccessor.Name}': "
+ + $"{string.Join("; ", shortfalls)}. "
+ + "The compile-only mirror must expose a same-name / same-arity method for "
+ + "every public instance method a script can call on the runtime accessor — "
+ + "add the missing method(s) to the ScriptAnalysis compile surface so a "
+ + "script using them cannot pass the design-time gate then fail at the site.");
+ }
+
+ ///
+ /// Runtime script-accessor type ↔ compile-surface mirror pairs guarded by
+ /// .
+ ///
+ public static IEnumerable