From b0703ebf8087e411e1114aeceb81d96450ea1b0f Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 21 Jun 2026 14:29:12 -0400 Subject: [PATCH] docs: R0.3 live-verified; correct the auth-blocker note (harness quote bug) R0.3 system-param over gRPC is now LIVE-VERIFIED against the real 2023 R2 server (returned HistorianVersion), alongside the re-confirmed read chain and probe. The apparent NTLM round-1 SEC_E_LOGON_DENIED "blocker" was a test-harness credential-parsing bug, not a server/account/SDK issue: the gitignored creds file stores quoted values and the env-setup must strip surrounding quotes before exporting HISTORIAN_USER/PASSWORD. With quotes stripped, the NAM domain account authenticates and the full chain passes. The round-failure diagnostic added during the hunt (HistorianNativeHandshake.DescribeError) is kept. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC --- docs/plans/hcal-roadmap.md | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/docs/plans/hcal-roadmap.md b/docs/plans/hcal-roadmap.md index f0b5b4b..37a1d0b 100644 --- a/docs/plans/hcal-roadmap.md +++ b/docs/plans/hcal-roadmap.md @@ -25,23 +25,18 @@ HCAL replacement, built on the **2023 R2 gRPC transport**. Derived from - ✅ **R0.4 Probe over gRPC** — `Grpc/HistorianGrpcProbe` (History/Retrieval/Status `GetInterfaceVersion`); `ProbeAsync` routes over gRPC when `Transport==RemoteGrpc`. **LIVE-VERIFIED 2026-06-21** (no credentials required — runs before the auth loop). -- 🟡 **R0.3 System parameter over gRPC** — `Grpc/HistorianGrpcStatusClient.GetSystemParameterAsync` - (`StatusService.GetSystemParameter`); routed in the dialect. Built + unit-tested - (request/response field mapping pinned). **Live-verification pending an auth fix** — see blocker. - Code path is the proven handshake + a single string-in/string-out RPC. +- ✅ **R0.3 System parameter over gRPC** — `Grpc/HistorianGrpcStatusClient.GetSystemParameterAsync` + (`StatusService.GetSystemParameter`); routed in the dialect. Built + unit-tested + **LIVE-VERIFIED + 2026-06-21** against a real 2023 R2 server (returned `HistorianVersion`). Code path is the proven + handshake + a single string-in/string-out RPC. -> ⚠️ **Auth blocker (2026-06-21):** live gRPC ops needing a client handle (R0.1/R0.2/R0.3 and the -> read chain) fail at NTLM **round 1**. The decoded server error is -> `SEC_E_LOGON_DENIED` (0x8009030C) from `aahClientAccessPoint::CServerContext::ProcessClient…` — -> round 0 (NEGOTIATE) succeeds, round 1 (the password-bearing AUTHENTICATE) is denied. The token -> **framing is correct** (a framing fault would surface as `SEC_E_INVALID_TOKEN`); the server parsed -> a valid NTLM message but the credential did not validate. The creds in the gitignored file are -> byte-faithfully parsed (verified) and the domain user logs in via **RDP (Kerberos)**, so the -> probable cause is one of: (a) the file password is **stale** vs the account, or (b) the NAM domain -> **restricts NTLM** ("Network security: Restrict NTLM") — Kerberos/RDP works but NTLM is denied, and -> over the SOCKS/SSH tunnel (host→127.0.0.1, no SPN) the client cannot use Kerberos. Probe (R0.4) is -> unaffected (unauthenticated). Diagnostic: the round-failure exception now decodes the native error -> + a hex/ASCII preview (`HistorianNativeHandshake.DescribeError`). +> ℹ️ **Auth note (2026-06-21, resolved):** an apparent NTLM round-1 `SEC_E_LOGON_DENIED` blocker +> turned out to be a **test-harness credential-parsing bug**, not a server/account/SDK issue — the +> gitignored creds file stores **quoted** values (`"nam\user"`, `"pass"`), and the env-setup must +> **strip surrounding quotes** before exporting `HISTORIAN_USER`/`HISTORIAN_PASSWORD`. With quotes +> stripped, the domain account authenticates and the full read + system-param + probe chain passes +> live. The round-failure diagnostic added during the hunt is kept +> (`HistorianNativeHandshake.DescribeError` decodes the native error + hex/ASCII preview). > ⚠️ **Live-verification constraint:** the local Historian is **2020** (WCF, port 32568) — the > 2023 R2 gRPC endpoint (32565) is absent. M0's gRPC routing (R0.1–R0.4) can be built and