Live-probed both R1.3 and R1.4 against a real 2023 R2 server over the gRPC StatusService; implemented the one that carries an evidence-backed value. R1.3 GetServerTimeZoneAsync — SHIPPED: - StatusService.GetSystemTimeZoneName(uiHandle) returns the real server zone over RemoteGrpc (the 2020 WCF op is a client-side stub returning empty). - HistorianGrpcStatusClient.GetSystemTimeZoneNameAsync -> dialect routing -> public HistorianClient.GetServerTimeZoneAsync. Non-gRPC transports fail closed with ProtocolEvidenceMissingException (no empty-string lie). - Golden message-shape unit test + non-gRPC guardrail unit test + gated live test. 271 unit tests pass. R1.4 GetHistorianInfoAsync (EventStorageMode) — bounded out on gRPC too: - gRPC GetHistorianInfo is the same named-value query as 2020 WCF (only HistorianVersion resolves); EventStorageMode + 7 variants fail on both GetHistorianInfo and GetSystemParameter. The 518-byte struct is filled by a native vtable+648 HCAL call, not the gRPC op (per the 2023 R2 decompile), so the field is never on the wire. Not shipped on any transport. Closes the roadmap's open "build against a live 2023 R2 server" caveat. Also correct the stale M3 roadmap section: D2 already proved Transaction.AddNonStreamValues* rides the storage-engine pipe (STransactPipeClient2 -> aaStorageEngine), not WCF — same wall as R4.2 — so M3-over-WCF is blocked, not "the path that is NOT the gated cache push". Docs: hcal-roadmap.md, wcf-historian-info.md, wcf-status-localhost.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
7.0 KiB
WCF Status Evidence
Commands:
dotnet run --no-build --project tools\AVEVA.Historian.ReverseEngineering -- wcf-status localhost 32568
dotnet run --no-build --project tools\AVEVA.Historian.ReverseEngineering -- wcf-status localhost 32568 Version
Confirmed:
- The local status endpoint is
net.tcp://localhost:32568/Stat. IStatusServiceContract2is a static WCF contract namedStatin namespaceaa. The managed definitions now includeGetSystemParameter,GETHI,PNGS, andPNGP.GetInterfaceVersionreturns code0, version0on the local 2020 install.- The decompiled
CStatusConnectionWCF.GetServerTimeimplementation is a WCF-path stub that returns success without calling theStatservice. The managed direct call likewise returns code0with size0and no buffer.
Observed sanitized localhost results:
GetSystemTimeZoneName(handle: 0)returns code4and no value.IsDBCaseSensitive(handle: 0)returns code4.GetSystemParameter(handle: 0, "Version")returnsfalsewith no error buffer.
Re-tested 2026-06-20 with a real authenticated client handle (full Open2 auth
chain), not handle: 0:
GetSystemParameter(handle, "HistorianVersion")→ real version string (works; shipped asGetSystemParameterAsync).GetSystemTimeZoneName(handle)→ return code0x00000000(success) but an empty value string. Same channel/handle that makesGetSystemParameterreturn real data, so this is the op's own behavior, not an auth/marshalling gap.GetSystemTimeZoneNameis a member of theGetServerTimestub family: the 2020 WCF path returns success without producing a value (the native client computes the zone locally). It only becomes a real round-trip on the 2023 R2 gRPC front door (Status.GetSystemTimeZoneName), which is absent on this box.
Interpretation:
Statendpoint routing is confirmed, but status operations that require a real client handle are not usable until managed session open is solved.GetServerTimeshould not be promoted into the public SDK as a real server time call from this WCF path; native evidence shows it is a no-op stub here.GetServerTimeZoneAsync(roadmap R1.3) is NOT a trivial WCF op on 2020 — it is a stub returning empty. Do not ship it over the 2020 WCF transport. Deliver it only against a live 2023 R2 gRPC server. Reclassified indocs/plans/hcal-roadmap.md.
GETRP / GetRuntimeParameter (roadmap R1.2) — DONE, live-verified 2026-06-20
Captured the native HistorianAccess.GetRuntimeParameter(List<string>, out List<object>)
WCF traffic with scripts/Capture-RuntimeParam.ps1 (instrument-wcf-{write,read}message).
Findings:
- The WCF op is
aa/Stat/GETRP—bool GETRP(string handle, byte[] pRequestBuff, out byte[] pResponseBuff, out byte[] errorBuffer), i.e. the same string-handle + request/response-buffer shape as GETHI, not the simpleGetSystemParameter(uint, string)shape the roadmap originally assumed. - The
string handleis the Open2 storage-session GUID (the valueParseOpenConnectionResponsereads fromoutBuff[5..21]), sent UPPERCASE, dash-separated, no braces (ToString("D").ToUpperInvariant()). - Unlike GETHI (which the earlier probe found blocked), GETRP succeeds from the pure-managed
client with that handle:
GetRuntimeParameter("HistorianVersion")→20,0,000,000. pRequestBuff=54 67 01 00(sig+version) + uint nameCount + per name(uint charCount + UTF-16LE).pResponseBuff= version(1) + uint resultCount + CRetVariant(0x43VT_BSTR + uint16 payloadLen + uint16 charCount + UTF-16LE).
Shipped as HistorianClient.GetRuntimeParameterAsync(name). See
HistorianRuntimeParameterProtocol, golden WcfRuntimeParameterProtocolTests, and the
handle-format lead in wcf-string-handle-wall.md §Update (retry GETHI/ExeC uppercased).
R1.3 timezone + R1.4 EventStorageMode — re-confirmed bounded out (2026-06-21)
Both were already classified 2023R2/gRPC-only; re-verified from two fresh angles that corroborate it more strongly than the original op-level probes:
- Runtime DB schema (
Runtime.dbo, the server's own source of truth): theSystemParametertable has no timezone parameter and noEventStorageMode(onlyEventStorageDuration/EventStorageLogPath). The server timezone exists only as per-block storage artifacts (HistoryBlock.TimeZoneOffset= e.g. 240 min,wwTimeZone= e.g. "Eastern Daylight Time") and aTimeZonereference/lookup table;StorageShard.TimeZoneIdis NULL. So the timezone is a DST-specific, SQL-only, OS-derived value, not a clean server-config field exposed by any op. - Parameter-op probe (
StringHandleProbeDiagnosticTests.TimezoneAndStorageMode_ParameterProbe):GetSystemParameterandGetRuntimeParameter(GETRP) were asked for every timezone candidate (TimeZone/ServerTimeZone/SystemTimeZone/TimeZoneName/SystemTimeZoneName/TimeStampRule/ServerTime) and every storage-mode candidate (EventStorageMode/StorageMode/EventStorage/EventStorageDuration). All returned null (GetSystemParameter) or threwProtocolEvidenceMissingException(GETRP — non-string/empty response); only theHistorianVersioncontrol returned a value (20,0,000,000). Note:TimeStampRule/EventStorageDurationdo exist in theSystemParametertable yetGetSystemParameterAsyncreturns null for them — the shipped op only surfaces a whitelisted subset (a possible future widening, unrelated to R1.3/R1.4).
Conclusion: R1.3 GetServerTimeZoneAsync and R1.4 GetHistorianInfoAsync (EventStorageMode) are not
deliverable as server ops on 2020. The only 2020 route to the timezone is a SQL read of
HistoryBlock/TimeZone via ExecuteSqlCommand (R1.1) — a DST-specific value over a different
mechanism than the roadmap's Status.GetSystemTimeZoneName. EventStorageMode has no 2020
representation at all (it is a 2023 R2 event-storage-architecture field). Deliver both only against a
live 2023 R2 gRPC server.
Resolution against the live 2023 R2 gRPC server (2026-06-21) — the two diverged
Both ops were taken to the real 2023 R2 box (History iface 12) over the gRPC StatusService:
- R1.3
GetServerTimeZoneAsync— SHIPPED.StatusService.GetSystemTimeZoneName(uiHandle)returns the real Windows zone name "Eastern Daylight Time" (the 2020 stub returned empty).HistorianClient.GetServerTimeZoneAsyncroutes overRemoteGrpc; the non-gRPC transports throwProtocolEvidenceMissingException(fail-closed, no empty-string lie). Golden message-shape + non-gRPC guardrail unit tests + gated live test. - R1.4
GetHistorianInfoAsync(EventStorageMode) — bounded out on gRPC too. Over gRPC,GetHistorianInfois the same named-value query as 2020 WCF (onlyHistorianVersionresolves);EventStorageMode+ 7 variants fail on bothGetHistorianInfoandGetSystemParameter. The 518-byte struct is C++-HCAL-internal (native vtable+648), not on the wire. Not shipped on any transport. Seewcf-historian-info.md.