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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
This commit is contained in:
Joseph Doherty
2026-06-21 18:12:40 -04:00
parent 8fbb868813
commit ac28679a1f
+36 -8
View File
@@ -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.**
---