diff --git a/docs/reverse-engineering/grpc-interface-versions.md b/docs/reverse-engineering/grpc-interface-versions.md index 5bf1b89..a2f91bb 100644 --- a/docs/reverse-engineering/grpc-interface-versions.md +++ b/docs/reverse-engineering/grpc-interface-versions.md @@ -18,8 +18,9 @@ > captured correctly; the table uses a unified column header for readability. > **Status note:** `StatusService.GetStatusInterfaceVersion` returned UiVersion=4, UiError=0 on the live -> 2023 R2 server. Status is classified as reachability-only — its version integer carries no semantic -> meaning for the SDK's byte serializers — so its UiVersion is not gated and not asserted in tests. +> 2023 R2 server. This differs from the historical 0 observed on 2020 WCF — both are reachability-only. +> Status is classified as reachability-only: its version integer carries no semantic meaning for the +> SDK's byte serializers, so its UiVersion is not gated and not asserted in tests. ## Evidence Test diff --git a/src/AVEVA.Historian.Client/HistorianServerVersionGate.cs b/src/AVEVA.Historian.Client/HistorianServerVersionGate.cs index cc69813..8e35bcd 100644 --- a/src/AVEVA.Historian.Client/HistorianServerVersionGate.cs +++ b/src/AVEVA.Historian.Client/HistorianServerVersionGate.cs @@ -29,8 +29,9 @@ internal enum HistorianServiceInterface /// Retrieval (Retr) interface version = 4 /// Transaction (Trx) interface version = 2 /// -/// The Status (Stat) service's GetInterfaceVersion returns 0 (not a real -/// version), so the Status interface is validated for reachability only, never value. +/// The Status (Stat) service's GetInterfaceVersion is not a real version (0 on +/// 2020 WCF, 4 on 2023 R2 gRPC) — it carries no meaning for the byte serializers either way — so +/// the Status interface is validated for reachability only, never value. /// /// A 2023 R2 gRPC server reports History interface version 12 even though it carries the /// same proven 2020 native buffers. That value is captured and accepted (see @@ -59,7 +60,8 @@ internal static class HistorianServerVersionGate /// /// True when the service interface reports a meaningful version that should be matched. - /// Status is reachability-only (its GetInterfaceVersion returns 0). + /// Status is reachability-only (its GetInterfaceVersion is not a real version — + /// 0 on 2020 WCF, 4 on 2023 R2 gRPC). /// public static bool IsValueGated(HistorianServiceInterface service) => service switch { diff --git a/tests/AVEVA.Historian.Client.Tests/GrpcInterfaceVersionEvidenceTests.cs b/tests/AVEVA.Historian.Client.Tests/GrpcInterfaceVersionEvidenceTests.cs index 2d0d854..b90554a 100644 --- a/tests/AVEVA.Historian.Client.Tests/GrpcInterfaceVersionEvidenceTests.cs +++ b/tests/AVEVA.Historian.Client.Tests/GrpcInterfaceVersionEvidenceTests.cs @@ -72,7 +72,8 @@ public sealed class GrpcInterfaceVersionEvidenceTests Assert.Equal(0u, transaction.Error); Assert.Equal(2u, transaction.Version); - // Status: reachability-only — UiError must be 0; UiVersion is intentionally 0 by design. + // Status: reachability-only — assert UiError==0 only; UiVersion is not value-gated + // (observed 4 on 2023 R2 gRPC, 0 on 2020 WCF). Assert.Equal(0u, status.UiError); }