The gateway emits a ReplayGap sentinel MxEvent at the head of a StreamEvents
stream resumed via after_worker_sequence when the requested cursor predates the
oldest retained event. Clients previously ignored it, silently mis-treating a
lossy resume as continuous. Each client now surfaces the sentinel as a distinct,
typed, non-terminal signal (never synthesized, never swallowed) so a consumer can
detect the gap and re-snapshot; resume contract is
after_worker_sequence = oldest_available_sequence - 1.
- .NET: MxEventStreamItem (IsReplayGap/ReplayGap/Event) via new StreamEventItemsAsync
+ AsStreamItemsAsync extension. Build clean, 87 passed.
- Go: EventResult.ReplayGap field + IsReplayGap(); ReplayGap type alias. build/vet/test clean.
- Rust: EventItem enum (Event/ReplayGap); EventStream now yields Result<EventItem, Error>;
CLI renders REPLAY_GAP line / replayGap JSON. fmt/check/test/clippy clean.
- Python: ReplayGap dataclass; stream_events yields pb.MxEvent | ReplayGap. 131 passed.
- Shared docs: ClientLibrariesDesign non-goals reframed (reconnect-replay protocol is
consumable; auto-reconnect stays a non-goal); CrossLanguageSmokeMatrix resume-gap note.
Java client is deferred to the windev batch (no local JRE); CLI-15 stays open until it lands.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
Events()/EventsAfter() previously closed the channel silently when the
16-slot buffer overflowed, indistinguishable from a graceful server end.
Reserve one slot and emit a terminal EventResult wrapping the new exported
ErrSlowConsumer so overflow is always observable. The blocking
SubscribeEvents path (gRPC flow-controlled) is unchanged.
archreview: CLI-01 (P0). Verified: gofmt clean, go build ./..., go test ./... (+ -race) pass.
Regenerate Go proto types from mxaccess_gateway.proto so MxSparseArray,
MxSparseElement, and MxValue_SparseArrayValue appear in the generated
package; add MxSparseArray/MxSparseElement type aliases to types.go;
add Session.WriteArrayElements and the unexported buildSparseArrayValue
builder; add three unit tests covering the sparse oneof structure,
empty-map case, and the round-trip through WriteArrayElements; update
README with default-fill reset semantics and auto-normalize note.
Add Write2/Write2Raw to the Go client Session, mirroring the existing
Write/WriteRaw pair, so all five language clients now expose write2.
Includes three TDD tests covering payload propagation, raw-reply return,
and nil-value rejection.
Client.Go-022 Re-applied Client.Go-015 shape — runWriteBulkVariant drops
the unused secured param and gates -current-user-id /
-verifier-user-id / -user-id behind the secured-only
variants.
Client.Go-023 Re-applied Client.Go-018 shape — bench warm-up and steady-
state loops respect ctx.Err().
Client.Go-024 Added SDK-level tests for WriteBulk / Write2Bulk /
WriteSecuredBulk / WriteSecured2Bulk / ReadBulk and
StreamAlarms via the existing bufconn fake gateway pattern.
Client.Go-025 Five bulk SDK methods short-circuit on empty input without
an RPC round-trip and document the behavior.
Client.Go-026 runBatch widens scanner.Buffer to 16 MiB and emits an
error-with-sentinel if a longer line still arrives, rather
than aborting the session silently.
Client.Go-027 runBatch treats blank lines as skip-and-continue; only EOF
ends the session.
All resolved at 2026-05-24; gofmt + go vet + go build + go test ./... all
green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>