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.** ---