docs: reclassify M1a R1.1/R1.3 as blocked on 2020 WCF

Live-probed both against the local Historian 2020 (WCF):

- R1.3 GetServerTimeZoneAsync: Status.GetSystemTimeZoneName returns rc=0 with
  an empty value under a real authenticated handle — a client-side stub in the
  GetServerTime family. gRPC/2023R2-only. Reverted the implementation.
- R1.1 ExecuteSqlCommandAsync: Retrieval.ExeC returns native error type 4 /
  code 51 (InvalidParameter); the contract-3 string-handle ops require an
  unmapped native session/filter registration step (the StartTagQuery wall).

Adds an M1a re-classification note steering future work toward proven
uint-handle / already-wired ops (R1.4 GETHI next) over string-handle ops.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-06-20 15:22:53 -04:00
parent 5e28f8d92e
commit 2246fdd395
2 changed files with 32 additions and 2 deletions
+16 -2
View File
@@ -24,6 +24,20 @@ HCAL replacement, built on the **2023 R2 gRPC transport**. Derived from
> golden-byte/unit-tested here but **cannot be live-verified** without an actual 2023 R2 server.
> Treat gRPC ops as unverified until then; the byte payloads remain the proven 2020 protocol.
> 🔬 **M1a re-classification (2026-06-20).** Two "trivial" items were live-probed against the
> 2020 WCF server and found **not deliverable here**, both for evidence-backed reasons:
> - **R1.3 `GetServerTimeZoneAsync`** — `Status.GetSystemTimeZoneName` is a client-side *stub*
> on 2020 (rc=0, empty value), same family as `GetServerTime`. gRPC/2023R2-only.
> - **R1.1 `ExecuteSqlCommandAsync`** — `ExeC` returns native error 51 (InvalidParameter);
> the contract-3 string-handle ops require an unmapped native session/filter registration
> step (the `StartTagQuery` wall).
>
> Takeaway: the M1a "cheap surface" is *cheap only on the 2023 R2 gRPC front door*. On 2020 WCF,
> the genuinely reachable next items are those that reuse a **proven uint-handle Retrieval op or
> an already-wired call** — e.g. **R1.4 `GetHistorianInfoAsync`** (GETHI is already invoked in
> the event chain) and the extended/localized-property reads (R1.5/R1.6) that ride
> `GetTagInfo*`-style ops. Prefer those before any string-handle (`ExeC`/`QTB`/`QTG`) op.
## Guiding principles
1. **gRPC-first.** New ops go on the `RemoteGrpc` transport (clean protobuf envelope);
@@ -68,9 +82,9 @@ read/browse/status surface is Windows-free and the gRPC stack is the default pat
### 1a. Trivial (XSS each, no new payload format)
| ID | Capability | gRPC op | Notes |
|---|---|---|---|
| R1.1 | `ExecuteSqlCommandAsync` | `Retrieval.ExecuteSqlCommand` | string in → `iRetValue` + status; thin |
| ~~R1.1~~ | ~~`ExecuteSqlCommandAsync`~~ | `Retrieval.ExecuteSqlCommand` | **Blocked on 2020 WCF.** Live-probed 2026-06-20: `ExeC` returns native error type 4 / code **51 (InvalidParameter)** for every handle variant — same unmapped *native session/filter registration* prerequisite that blocks `StartTagQuery`/`QueryTag` (see `implementation-status.md` lines ~982, ~1404). Needs that registration RE'd, or a 2023 R2 gRPC server. Do not wire via guessed calls. |
| R1.2 | `GetRuntimeParameterAsync` | `Status.GetRuntimeParameter` | mirror `GetSystemParameter` |
| R1.3 | `GetServerTimeZoneAsync` | `Status.GetSystemTimeZoneName` | string out |
| ~~R1.3~~ | ~~`GetServerTimeZoneAsync`~~ | `Status.GetSystemTimeZoneName` | **gRPC/2023R2-only.** Verified 2026-06-20: over **2020 WCF** this op is a stub (rc=0, empty value) in the `GetServerTime` family — not shippable here. Build+verify only against a live 2023 R2 server. See `docs/reverse-engineering/wcf-status-localhost.md`. |
### 1b. Bounded (decode one `bytes` payload; SM each)
| ID | Capability | gRPC op | Payload to decode | Depends |