The capture-write harness scenario drives the native 2023 R2 client through a non-streamed
(historical backfill) write so the IL-rewritten GrpcHistoryClient dumps RegisterTags.tagInfos +
AddNonStreamValues.inBuff to the capture NDJSON. Sequence: open write-enabled gRPC -> (optional
--create) AddTag sandbox -> GetTagInfoByName (real TagKey + primes the per-connection cache, the
gate mitigation) -> CreateHistorianDataValueList(NonStreamedOriginal) -> NonStreamedValuesBegin ->
AddNonStreamedValue -> AddNonStreamedValuesEnd -> SendValues (the wire push; only with --commit).
Not yet run — the actual write to the live server awaits explicit confirmation. Built clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
Adds the dnlib instrument command + harness wiring to capture the two non-streamed-write
buffers from the native 2023 R2 client:
- `instrument-grpc-nonstream <GrpcClient.dll> [out]` injects CaptureLogger.LogByteArray at the
entry of GrpcHistoryClient.RegisterTags (byte[] tagInfos) and AddNonStreamValues (byte[] inBuff),
writing the rewrite to docs/reverse-engineering/dnlib-write-copy/grpc2023 (gitignored — derived
AVEVA binary). dnlib preserves the AVEVA public-key identity so aahClientManaged still binds the
rewritten copy under the LoadFrom context (no SN re-verification).
- harness `--grpc-rewrite <dir>` probes that dir first, so the instrumented GrpcClient.dll +
ReverseInstrumentation.dll load ahead of the originals. load-check confirms the rewritten
strong-named copy binds (HistorianConnectionMode.Historian=2; GrpcHistoryClient RegisterTags +
AddNonStreamValues present).
Next: capture-write scenario (open write-enabled -> sandbox tag -> read-prime -> AddNonStreamedValue),
which dumps tagInfos + inBuff to the capture NDJSON. Prod write — confirm before running.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
Added the `connect` scenario to the 2023 R2 capture harness and ran it read-only against the
live server. The native mixed-mode client connects end-to-end over gRPC from this box:
OpenConnection -> True (ErrorCode=Success)
ConnectedToServer = True
ConnectedToServerStorage = True <-- native client HAS the storage-engine session
ConnectedToStoreForward = False
Connection args that work (HistorianConnectionArgs): ServerName, TcpPort=32565,
ConnectionMode=Historian (gRPC), ConnectionType=Process, ReadOnly=true, IntegratedSecurity=false,
UserName/Password (explicit), AllowUnTrustedConnection=true, SecurityInfo=CertificateInfo{
SecurityMode=TransportCertificate, CertificateName=WONDER-SQL-VD03 } (the https:// host over the
loopback tunnel). Creds from HISTORIAN_USER/HISTORIAN_PASSWORD.
Significance: ConnectedToServerStorage=True means the native client establishes the storage
session the pure-managed SDK couldn't — so a write driven through it should route
AddNonStreamValues with a live storage session, and the cache-gate mitigation (read-first)
is promising. Next: IL-rewrite Archestra.Historian.GrpcClient.dll + a write-enabled run to
capture the RegisterTags btTagInfos + AddNonStreamValues btInput (prod write; per-action auth).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
First increment of the native-2023R2-gRPC capture (docs/plans/revision-write-path.md
§"R3.1 capture plan"). Loads the mixed-mode aahClientManaged.dll by path (sibling resolver
over bin/ + msi-extract/.../Bin/x64) and reflects the connection API — no live contact.
load-check result on this box (net481 x64):
- aahClientManaged.dll loads cleanly (no missing VC++ runtime / no BadImageFormat) — confirms
the self-contained mixed-mode assembly runs without an AVEVA install.
- HistorianConnectionMode.Historian = 2 (the 2023 R2 gRPC mode; ClassicHistorian = 1 = legacy)
— the value the live-connect step sets on HistorianConnectionArgs.ConnectionMode.
- GrpcHistoryClient resolves with RegisterTags + AddNonStreamValues present — the IL-rewrite
capture targets are reachable.
Standalone net481 project (not in Histsdk.slnx, like NativeTraceHarness). Next: read-only
gRPC connect + tag read (first live step, per-action auth), then IL-rewrite + write capture.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC