# R0.1 browse over gRPC — StartTagQuery takes an OData filter (2026-06-21) Live-probed `RetrievalService.StartTagQuery` / `QueryTag` against a real **2023 R2** server over the gRPC front door (string-handle = uppercase Open2 storage GUID). Key result: **browse is feasible on 2023 R2** — the 2020 WCF "metadata-server pipe" wall does **not** block here. ## StartTagQuery — CRACKED `StartTagQuery(strHandle, btRequest)` where `btRequest` = the native `marker(26449) + version(1) + WriteHistorianString(filter)` buffer (`HistorianTagQueryProtocol.CreateStartTagQueryAttempt`). The server runs `CMdServer::StartTagQuery::StartActiveTagnamesQuery` over `\\.\pipe\aahMetadataServer\console` and **parses the filter string as OData** (not SQL-LIKE). Swept filters: | filter | result | |---|---| | `startswith(TagName,'Sys')` | ✅ success, 8-byte response | | `contains(TagName,'Sys')` | ✅ success | | `TagName eq 'SysTimeSec'` | ✅ success | | `` (empty) | ✅ success (all tags) | | `Sys*` / `*` | ❌ `ODataFilter ... bad token` | | `TagName like 'Sys%'` / `Name like 'Sys%'` | ❌ rejected | Success response `btResponse` is the 8-byte `(queryHandle:uint, tagCount:uint)` pair (`ParseStartTagQueryResponse`). Live: `startswith(TagName,'Sys')` → tagCount = 220. **Implication for the public API:** browse must translate the SDK's glob filter to OData — `*` → empty, `Pre*` → `startswith(TagName,'Pre')`, `*sub*` → `contains(TagName,'sub')`, exact → `TagName eq '...'`. (Escaping single-quotes in names still TBD.) ## QueryTag — OPEN (one capture away) `QueryTag(strHandle, uiQueryHandle, btRequest)` is the paging call that should return the actual tag-name rows. Every `btRequest` shape tried returns a constant native error **type 4 / code 72** (independent of content: empty, count, column-name historian-string, `$select=TagName`, marker+version+name all give the same `04 48000000`). The constant code regardless of input means the request *framing* is wrong, not the field values — this needs a **native capture** of the real 2023 R2 client driving a browse to recover the exact `QueryTag` `btRequest` (and the row framing in `btResonse`). Do not ship a guessed QueryTag request (project discipline: no guessed wire bytes). Probe helpers live in `Grpc/HistorianGrpcTagClient` (`ProbeStartTagQuery`, `ProbeTagQuerySequence`) and the gated `StartTagQuery_OverGrpc_AcceptsODataFilter` test pins the StartTagQuery+OData result.