From ac28679a1fea1cf11a11fc7500807c104802794c Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sun, 21 Jun 2026 18:12:40 -0400 Subject: [PATCH] M3 R3.1: map the required non-streamed write sequence (OpenStorageConnection is the missing step) Static decompile mining of the 2023 R2 client corroborates the live R3.1 error: the AddNonStreamValues failure is the missing StorageService.OpenStorageConnection, which creates exactly the \.\pipe\aahStorageEngine\console,sid(...) session named in the server error. Mapped the full native sequence: HistoryService.OpenConnection (have) -> StorageService.OpenStorageConnection (MISSING) -> StorageService.RegisterTags -> AddNonStreamValuesBegin (works) -> AddNonStreamValues(btInput) (fails - no console session) -> End(commit). Two hard parts remain, each a live-production decode loop with no static shortcut: (1) reproduce the 12-arg OpenStorageConnection handshake (several args inferred); (2) decode the AddNonStreamValues btInput (C++-built, absent from decompiles; only the 44-byte packed HISTORIAN_VALUE2 is known). Documented in revision-write-path.md. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC --- docs/plans/revision-write-path.md | 44 +++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/docs/plans/revision-write-path.md b/docs/plans/revision-write-path.md index 922a238..c8cbd13 100644 --- a/docs/plans/revision-write-path.md +++ b/docs/plans/revision-write-path.md @@ -81,14 +81,42 @@ gRPC *server* now holds the pipe, not the client). Because the error is identica framing, the blocker is **not** the `btInput` layout — it is a **missing storage-engine console session / tag-registration precondition** for the connection. -**Next step to finish M3 (untested):** establish the StorageService side **before** -`AddNonStreamValues` — `StorageService.OpenStorageConnection`/`OpenStorageConnection2` to open the -console session, then register the tag→storage mapping (`RegisterTags` / `AddTagidPairs` / -`AddShardTagids`), then retry `AddNonStreamValues` and finally `End(bCommit=true)` + SQL read-back on -a sandbox tag. Each of those StorageService ops has its own buffer format to RE. Raw decode artifact: -`artifacts/reverse-engineering/grpc-nonstream-decode/batch1-decode.txt` (gitignored). Probe command: -`grpc-nonstream-decode`; driver: `HistorianGrpcRevisionProbe.ProbeNonStreamedBuffersAsync` (candidate -guess-bytes live in the RE tool, not `src/`). +**Required call sequence (mapped from the 2023 R2 decompile, corroborates the error above):** the +missing precondition is **`StorageService.OpenStorageConnection`** — it creates exactly the +`\\.\pipe\aahStorageEngine\console,sid(...)` console session named in the failure. The native +non-streamed write path is: + +``` +HistoryService.OpenConnection (✅ have it — the Open2 handshake) + → StorageService.OpenStorageConnection (⛔ MISSING — opens the console sid session; SEPARATE + storage session, returns its own uint handle + new GUID) + → StorageService.RegisterTags (register the tag→storage mapping for the session) + → TransactionService.AddNonStreamValuesBegin (✅ works) + → TransactionService.AddNonStreamValues(btInput) (⛔ currently fails here — no console session yet) + → TransactionService.AddNonStreamValuesEnd(bCommit=true) + → StorageService.CloseStorageConnection / HistoryService.CloseConnection +``` + +`OpenStorageConnection` (gRPC `StorageService`) takes 12 args — HostName, EnginePath +(`\\.\pipe\aahStorageEngine\console`), FreeDiskSpace, ProcessName, ProcessId, UserName, Password(+len), +ClientType, ClientVersion, ConnectionMode, ConnectionTimeout, StorageSessionId(in/out) — and returns a +**new** storage `Handle` (uint) + a **new** StorageSessionId GUID (distinct from the Open2 GUID). + +**Two hard parts remain, each a separate live-production decode loop (no static shortcut):** +1. **Reproduce the `OpenStorageConnection` handshake** — several of the 12 args are only inferable from + the decompile (ProcessId, ClientType/Version, ConnectionMode, the password-bytes framing), so the + exact values must be confirmed against the live server. +2. **Decode the `AddNonStreamValues` `btInput`** — built in C++ (`SendNonStreamedValues` vtable call), + **absent from every decompile**; only the 44-byte packed `HISTORIAN_VALUE2` struct is known. Must be + decoded empirically once the console session exists (the batch-1 identical-error result could not + distinguish framings precisely *because* there was no session — with a session, framings should + diverge and the correct one becomes findable). + +Raw decode artifact: `artifacts/reverse-engineering/grpc-nonstream-decode/batch1-decode.txt` +(gitignored). Probe command: `grpc-nonstream-decode`; driver: +`HistorianGrpcRevisionProbe.ProbeNonStreamedBuffersAsync` (candidate guess-bytes live in the RE tool, +not `src/`). **Status: M3 transaction lifecycle proven; full insert blocked on the +OpenStorageConnection handshake + btInput decode — a focused follow-up, each step a live probe.** ---