Document the trailing 35 bytes of GetNextQueryResultBuffer rows

Investigation finding only — no behavior change, no new public fields.

Captured a fresh GetNextQueryResultBufferResponse for SysTimeSec via
instrument-wcf-readmessage and compared against the canonical 4-row
OtOpcUaParityTest_001.Counter fixture. Trailing-block structure is
tag-independent:

  bytes 0-2   constant 0x00 0x00 0x01 (sample-format marker)
  bytes 3-10  Int64 FILETIME UTC (duplicate of startTime for raw rows;
              already used by the aggregate parser as the interval start)
  bytes 11-18 zeros (likely end-time slot — populated by aggregate variants)
  bytes 19-26 varies row-to-row even with identical Quality/Value;
              looks like a storage block sequence ID or snapshot offset
  bytes 27,29 flag bytes (0/1 and 0/4 observed); semantics undecoded
  bytes 28, 30-34 zeros

None of bytes 19-34 have a clear user-facing meaning; they appear to be
server-internal storage metadata. Updated the
TryParseGetNextQueryResultBufferRows remarks block with the byte map and
a note that surfacing them as new HistorianSample fields should wait
until a customer actually asks. CLAUDE.md "Remaining gaps" entry updated
to reflect the new partial decode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-04 15:35:48 -04:00
parent 7288f39f5d
commit b05063b195
2 changed files with 19 additions and 5 deletions
+1 -1
View File
@@ -95,7 +95,7 @@ Smaller, isolated items — none block the production read surface:
- Remote TCP transports (`RemoteTcpIntegrated`, `RemoteTcpCertificate`) untested against an actual remote Historian (tests skip without `HISTORIAN_REMOTE_TCP_HOST`).
- Explicit username/password tag-metadata path is wired (validator only blocks no-auth-at-all), but live-verification requires `HISTORIAN_USER`+`HISTORIAN_PASSWORD` set; gated test `GetTagMetadataAsync_ExplicitCredentials_AgainstLocalHistorian` skips otherwise.
- Per-row trailing ~24 bytes of `GetNextQueryResultBuffer` are not decoded (likely per-sample value/source/state metadata).
- Per-row trailing 35 bytes of `GetNextQueryResultBuffer` are now mapped (see `HistorianDataQueryProtocol.TryParseGetNextQueryResultBufferRows` doc comment) — bytes 3-10 = duplicate FILETIME (already used by aggregate parser), bytes 0-2 + 19-34 = server-internal sample/storage metadata with no clear user-facing meaning. No new public fields added; revisit if a customer asks for storage metadata exposure.
- `EnsureTagAsync` distinct `MinRaw`/`MaxRaw` persistence requires `ApplyScaling=true` + a follow-up `UpdateTags` call — not yet wired (no API user has asked).
### Tools Layer