diff --git a/CONTEXT.md b/CONTEXT.md index 0a9e9dce5..4dc786b81 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -52,7 +52,8 @@ Session; others aggregate elsewhere, such as worktree resolution on its Project. **Durable Session event stream**: One Session Aggregate's durable Event log, read back over SSE. `after` is an exclusive sequence taken from a durable envelope or a sync marker, `follow` continues into live Events, and a single -`log.synced` marker separates replay from live. Retention remains unestablished. +`log.synced` marker separates replay from live. The sequence is not contiguous, the log has no +retention policy, and persistence is a server option that is off by default. _Avoid_: session events (ambiguous with the live stream) **Live event stream**: diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 662f22d12..d2dc51893 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -70,7 +70,11 @@ is revisited at each boundary. The pin therefore stays a deliberate snapshot, refreshed under receipt at milestone boundaries. - **`v2.session.log` resume guarantees** — the pinned document exposes `after` as an optional string, and the generated surface stays faithful to it; ADR-0013 forbids importing the narrower - type upstream's implementation decodes. Retention and replay guarantees are unestablished. + type upstream's implementation decodes. Replay mechanics and retention are established and + carried by canon. What stays open is the wire behaviour nothing upstream pins: no server-level + test covers this route, so the status a malformed `after` answers, and whether an idle `follow` + connection survives an intermediary, are settled only by this repository's own live tests. + Upstream has no production caller that passes `after`, so this SDK is the path's first consumer. - **OpenAPI projection fidelity** — the pinned document loses detail upstream's implementation carries. Confirmed losses are reported upstream ([anomalyco/opencode#44911](https://github.com/anomalyco/opencode/issues/44911), restored by the diff --git a/docs/architecture/client-runtime.md b/docs/architecture/client-runtime.md index 9572f4aee..fd7ead99d 100644 --- a/docs/architecture/client-runtime.md +++ b/docs/architecture/client-runtime.md @@ -270,9 +270,19 @@ local server launcher. Protocol and generated-model rules live in disposes the live response so cancellation interrupts platform response-stream reads that do not observe an async read token; disposal-induced I/O failures remain caller cancellation. - The SDK never auto-reconnects. A live-stream consumer refreshes authoritative state and - resubscribes after failure. Durable continuation is requested explicitly through - `v2.session.log`'s `after` parameter; persistence, retention, and replay guarantees remain - unestablished (research doc 02, `docs/ROADMAP.md`). + resubscribes after failure. +- Durable continuation is requested explicitly through `v2.session.log`'s `after` parameter, an + exclusive aggregate sequence read from a durable envelope or from the sync marker. One + `log.synced` marker reports the watermark the replay was captured at; it is a boundary rather + than a durable event, and under `follow` the events committed while that replay was in flight + arrive after it. Sequences are not contiguous, so a gap is ordinary and no count is derived from + two of them. A cursor past the aggregate's tail is accepted rather than refused and then + suppresses live delivery until the aggregate overtakes it, so a cursor travels only within one + server's lifetime. +- That log has no retention policy: nothing expires, prunes, or caps it, compaction and revert + rewrite projections rather than the log, and rows are deleted only with their session. + Persistence is itself a server option that is off unless the server was started with it, so a + default server answers a replay with the marker alone (`docs/ROADMAP.md`). - The SSE event name is a framing signal. An ordinary payload uses the default `message` name; the operation's declared failure event materializes its cause through generated metadata and throws; any other explicit name is refused. Unknown payload and cause discriminators remain diff --git a/docs/guide/streaming.md b/docs/guide/streaming.md index d13825ef4..22d2c3ca3 100644 --- a/docs/guide/streaming.md +++ b/docs/guide/streaming.md @@ -93,10 +93,12 @@ With `Follow = True`, read through any replayed events until that marker arrives then delivers live events committed after the attachment boundary. The marker is a transition boundary, not a durable event to save as the next `After` value. -> **📎 A note on guarantees**: `after` is a *request*, not a durability promise. How much history -> the server persists or retains, and for how long, is upstream's business and is not something -> this SDK can state on its behalf. The stream does not promise replay after a server restart. -> Treat a returned gap as possible and reconcile with ordinary reads. See the canonical +> **📎 A note on guarantees**: replay depends on the server. Persistence is a server option that is +> off unless the server was started with it, so a default server answers with the marker alone. +> When it is on, nothing expires or prunes the log and entries live until their session is deleted. +> Sequences are not contiguous, so treat a gap as ordinary rather than as loss. Carry a cursor only +> within one server's lifetime: a cursor past the log's tail is accepted rather than refused and +> then suppresses live delivery until the log overtakes it. See the canonical > [server-sent events rules](../architecture/client-runtime.md#server-sent-events). ## 🧩 Unknown events do not break your consumer