---
title: "Channel live delivery follows durable commit"
version: "en"
---

> Documentation Index
> Fetch the complete documentation index at: https://botharness.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Channel live delivery follows durable commit

> Status: Accepted

# Channel live delivery follows durable commit

For #141, the current Channel message log is the durable authority. A **committed Channel message** becomes visible to other clients only after its append succeeds. The Host then publishes a process-local notification to subscribers of that Channel. An Orchestrator `channel_send` call may also have a presentation-only draft while its arguments stream; the draft is never a Channel message, Source Event, Inbox input, or second live-message store.

The Client first reads a Channel snapshot through `botharness/channelMessages`, including a monotonically increasing Channel revision. While that Channel is selected, it keeps one authenticated SSE connection at `/api/botharness/stream`. Each `channel/message` frame contains the committed message and revision. The Host replays committed rows after the requested revision when the stream opens, including reconnects via `Last-Event-ID`. The Client ignores duplicate revisions and message IDs, and re-reads the authoritative snapshot on a revision gap or invalid cursor. Local send reconciliation is immediate and does not wait for Orchestrator or Assignment work.

For a live PersonaBot reply, the Host globally observes DSH's process-local `agent/assistant-stream` for the active Orchestrator Session and uses DSH's shared `BlockAssembler` to project only explicit `channel_send` tool-call arguments. A draft is scoped to an LLM attempt and Channel; the Host checks Channel access, tolerates incomplete JSON, and abandons an inbound preview before publishing it in a different explicit Channel. Assignment output and ordinary Orchestrator final text never enter this path. The Host broadcasts `channel/draft`, `channel/draft-settled`, and `channel/draft-abandoned` with an attempt ID and a process-local monotonic draft revision; a reconnect receives a full transient baseline. Draft revisions are separate from durable Channel message revisions and are never SSE replay IDs. The Client discards previews and re-reads committed history on a gap, and batches streaming Markdown updates to an animation frame. A Host restart intentionally cannot replay drafts from Channel history.

Draft consumers have three classes. **Presentation** may show or discard the preview freely. **Speculative** consumers may act early only when the action can be interrupted and fully rolled back; they must handle abandonment, retargeting, and a changed attempt. **Durable or irreversible** consumers—including TTS publication, Bot Inbox admission, notifications with external effects, and audit history—must wait for the committed Channel message. A draft never becomes a Channel message, Source Event, Inbox input, or second live-message store.

Provider spike (2026-09-22, #144): an isolated real-model DM run produced 16 increasing body previews from `channel_send` tool-call deltas, one settlement, zero abandonments, one contiguous draft revision sequence, and a 31-character final preview. Every observed body was a prefix of the next. The tracker also rejects a non-dense DSH chunk index, but prefix monotonicity is an observation of this provider run, not a cross-provider guarantee; presentation must accept replacement or abandonment. The same run committed one Bot reply and displayed it in the authenticated DSH Client.

The SSE route is registered through DSH Connection Fetch with the **full** `/api/…` pathname; it does not intercept the API gateway's single `/api` RPC slot. This keeps unary commands and reads on the existing Typert bridge. Channel authorization remains the current authenticated local-profile boundary; per-actor Channel access controls follow the Messaging authority in later slices.

When #46 moves Channel facts to the operational database, the transaction commit replaces the NDJSON append as the publication boundary, and the revision/replay contract must follow the new authority without dual writes. Presence, activity, and unread projections are not `channel/message` frames.

Update (2026-09-22, #143): `channelTimeline` is now the Client's initial and recovery read model, replacing the bounded `channelMessages` snapshot described above; the older endpoint remains for compatibility. ADR-0061 records the opaque cursor and visible-window policy. The commit-before-publish SSE boundary in this ADR is unchanged.

Source: https://botharness.ai/dev/adr/0054-channel-live-delivery-follows-durable-commit/index.mdx
