Merge fix-event-gate-characterization: gRPC event-row item is capture-gated (SQL ground truth)

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-22 08:12:31 -04:00
2 changed files with 28 additions and 12 deletions
+15 -5
View File
@@ -39,8 +39,17 @@ reuses the proven 2020 WCF byte serializers/parsers unchanged inside protobuf
**Everything still open is gated — none is a pure-code task:**
1. **gRPC event ROW retrieval** (`ReadEventsAsync` #2) — chain + StartEventQuery
work; `GetNextEventQueryResultBuffer` long-polls on no data. Needs an
**event-bearing 2023 R2 server**. Bounded ≤30s, throws on no-row.
work; `GetNextEventQueryResultBuffer` long-polls and returns zero rows.
**Re-characterized 2026-06-22: this is capture-gated, NOT server-gated.** The
earlier "needs an event-bearing 2023 R2 server" assumption is **disproven**
the live 2023 R2 server *is* event-bearing (SQL ground truth via the INSQL
linked server: `Runtime.dbo.Events` = 19,356 rows in the last 30 days /
90,944 in 365 days), yet the **empty-filter** gRPC event query still yields
zero rows over that exact 30-day window and long-polls to the deadline. So
the gap is in the empty-filter request shape (filter / namespace / event-tag
registration), not data availability. Needs a **fresh native gRPC
event-query capture** to see what the stock 2023 R2 client sends. Bounded
≤30s, throws on no-row.
2. **R4.3 active-SF magnitude** — needs an **SF-active server** (D2 storage-engine
console handle).
3. **SendEvent over gRPC****capture-gated**: no distinct RPC, framing uncaptured.
@@ -58,9 +67,10 @@ reuses the proven 2020 WCF byte serializers/parsers unchanged inside protobuf
8. **Deferred-by-design** items (`write-commands` D1D3, non-analog tag create,
etc.) — bounded out until an explicit customer/user demand signal.
To move any remaining item you need a **different server** (event-bearing or
SF-active), a **fresh native capture** (SendEvent gRPC framing), or a **demand
signal** to unlock a deferred item. Live-server gRPC probe recipe: set
To move any remaining item you need a **fresh native capture** (gRPC event-query
empty-filter framing — item 1; SendEvent gRPC framing — item 3), a **different
server** (SF-active for item 2), or a **demand signal** to unlock a deferred
item. Live-server gRPC probe recipe: set
`HISTORIAN_GRPC_HOST`/`_PORT 32565`/`_TLS true`/`_DNSID` + domain creds (strip
quotes — `reference_wonder_sql_vd03_credentials`) and run the gated
`HistorianGrpcIntegrationTests`.
@@ -487,13 +487,19 @@ public sealed class HistorianGrpcIntegrationTests
// Plan #2: ReadEvents over gRPC. The chain runs end-to-end and StartEventQuery succeeds
// (no InvalidOperationException), but — confirmed live 2026-06-22 — GetNextEventQueryResultBuffer
// LONG-POLLS when the query has no rows: the gRPC server blocks to the deadline instead of
// returning the synchronous 5-byte code-85 terminal the 2020 WCF op returns. The idle dev box
// holds no events, so the orchestrator reaches its no-data terminal with zero rows and (rather
// than assert a possibly-false "no events" empty) throws ProtocolEvidenceMissingException.
// This pins that current reality and that the chain stays BOUNDED (no multi-minute hang) via
// the short registration + poll deadlines. Flip to asserting parsed rows once an event-bearing
// 2023 R2 server is available. (Set a small HISTORIAN_GRPC_TIMEOUT to keep this snappy.)
// LONG-POLLS and returns zero rows: the gRPC server blocks to the deadline instead of
// returning the synchronous 5-byte code-85 terminal the 2020 WCF op returns, so the orchestrator
// reaches its no-data terminal with zero rows and (rather than assert a possibly-false "no events"
// empty) throws ProtocolEvidenceMissingException.
//
// IMPORTANT (2026-06-22): the zero rows are NOT "no events on the server". Verified against the
// live 2023 R2 box, which holds 19,356 events in the last 30 days (SQL ground truth via the INSQL
// linked server, Runtime.dbo.Events). The EMPTY-FILTER gRPC event query simply does not match
// them. So the gate here is the empty-filter request shape (filter / namespace / event-tag
// registration), NOT data availability — this is capture-gated (needs a native gRPC event-query
// capture), not server-gated. Flip to asserting parsed rows once that capture lands and the
// request is corrected. The chain stays BOUNDED (no multi-minute hang) via the short
// registration + poll deadlines. (Set a small HISTORIAN_GRPC_TIMEOUT to keep this snappy.)
HistorianClient client = new(BuildOptions(host));
DateTime endUtc = DateTime.UtcNow;