diff options
| author | Adam Malczewski <[email protected]> | 2026-06-12 19:00:29 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-12 19:00:29 +0900 |
| commit | d66585333ee5764700c67a81eaec015b0026f8f1 (patch) | |
| tree | 6e1ac455c2ecbf3c442fce9f73fdaed8fb71fade /.dispatch/wire.reference.md | |
| parent | 1764e3e5dff836255d121a933dd92542368346f9 (diff) | |
| download | dispatch-web-d66585333ee5764700c67a81eaec015b0026f8f1.tar.gz dispatch-web-d66585333ee5764700c67a81eaec015b0026f8f1.zip | |
feat(chat): consume CR-5 history windowing — server-windowed cold loads + show-earlier backfill
Re-pinned [email protected]>0.10.0 + [email protected]>0.6.1 (reply
frontend-history-windowing-handoff.md); re-mirrored both .dispatch references.
- HistorySync port gains optional { limit?, beforeSeq? } (CR-5 params); the
app's createHistorySync appends them to GET /conversations/:id.
- COLD-cache fresh load now fetches ?sinceSeq=0&limit=<floor(0.75xL)> — a huge
conversation no longer ships whole to show 192 chunks. A warm-cache tail sync
stays unwindowed (windowing a tail that outgrew the limit would leave a
silent seq gap behind the cache).
- hasEarlier now derives from the [email protected] CONTRACT (1-based gap-free seqs):
loaded window starting above seq 1 => older history exists — covering both
locally-trimmed AND server-windowed transcripts (the watermark stays as the
merge floor only).
- showEarlier(): local cache first; when the cache doesn't reach far enough
back, backfills the missing older run via ?beforeSeq=<oldestKnown>&limit=
and persists it (next page-in is local). latestSeq windowed-read caveat is
satisfied structurally (tail cursor derives from the cache's max seq).
- live-probe: +6 CR-5 checks (seq origin, newest-k ascending, short-chat
exactness, beforeSeq paging, 400 validation x2). NOT yet run live — backend
was down at commit time; run pending.
- backend-handoff.md: CR-5 RESOLVED, pins/mirrors current. 602 tests green x2.
Diffstat (limited to '.dispatch/wire.reference.md')
| -rw-r--r-- | .dispatch/wire.reference.md | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/.dispatch/wire.reference.md b/.dispatch/wire.reference.md index 40f94cf..1d761bf 100644 --- a/.dispatch/wire.reference.md +++ b/.dispatch/wire.reference.md @@ -4,8 +4,14 @@ > types WITHOUT following the `file:` dep symlink out of this repo (which hangs on a permission > prompt). Your CODE still imports `@dispatch/wire` normally — this file is for READING only. > -> **Orchestrator:** SNAPSHOT of `[email protected]` (the metrics types below + the `user-message` turn event -> shipped + version-bumped). Regenerate whenever `@dispatch/wire` changes. +> **Orchestrator:** SNAPSHOT of `[email protected]` (doc-only bump: the 1-based gap-free seq guarantee +> codified on `StoredChunk`). Regenerate whenever `@dispatch/wire` changes. +> +> **2026-06-12 delta (CR-5 history windowing — package bumped `0.6.0` → `0.6.1`, DOC-ONLY):** the +> per-conversation `seq` numbering is now a WRITTEN CONTRACTUAL GUARANTEE on `StoredChunk`: +> **1-based, monotonic, gap-free** — a conversation's first chunk is always `seq === 1` and +> numbering never skips. A client holding only a windowed suffix of the log derives "older chunks +> exist server-side" purely from `oldestLoaded.seq > 1` (no `earliestSeq`/`hasOlder` field exists). > > **2026-06-12 delta (CR-3 user-message handoff — package bumped `0.5.0` → `0.6.0`, ADDITIVE):** adds a > new `AgentEvent` union member `TurnInputEvent` (`{ type: "user-message"; conversationId; turnId; text }`) @@ -168,11 +174,17 @@ export interface ChatMessage { /** * A persisted chunk plus its sync metadata. The append-only conversation log - * stamps every chunk with a monotonic, gap-free, per-conversation `seq` (the - * sync cursor, assigned in append order) and records the `role` of the message - * it belongs to. This makes a flat seq-ordered stream both incrementally - * syncable ("give me chunks after seq N") and regroupable into messages by the - * client. `chunk` is the content unit — `Chunk` carries no storage/sync cursor + * stamps every chunk with a **1-based**, monotonic, gap-free, per-conversation + * `seq` (the sync cursor, assigned in append order) and records the `role` of + * the message it belongs to. This makes a flat seq-ordered stream both + * incrementally syncable ("give me chunks after seq N") and regroupable into + * messages by the client. + * + * The 1-based start is a CONTRACTUAL GUARANTEE (not an implementation detail): + * a conversation's first chunk is always `seq === 1` and numbering never skips, + * so a client holding only a windowed suffix of the log can derive "older + * chunks exist server-side" purely from `oldestLoaded.seq > 1` — no separate + * has-older flag is needed (or provided). `chunk` is the content unit — `Chunk` carries no storage/sync cursor * (`seq` lives here on the envelope, not on the chunk, since it is assigned by * the store and the provider has no use for it). A chunk MAY still carry * generation provenance assigned at production time (e.g. a tool chunk's |
