Delivery vocabulary shared by Connection (stamping + direct turn
delivery) and Client (turn consumption).
The ordering key is a receiver-assigned contiguous per-turn ordinal,
stamped at the single sequential demux point before any per-session
fan-out. It is never read from the peer's _meta: arrival order is not
stable across a reattach onto a new connection, and a peer that supplied
the key could manufacture a gap to force the degraded path. Every
drop/gap decision emits telemetry rather than dropping silently, and the
per-turn namespace that scopes the ordinals is receiver-minted too, so a
peer reusing a turn id cannot alias a stale turn's straggler forward.
Message shapes (the direct turn-delivery channel)
For a turn opened by a session/prompt submitted via
Connection.async_request/6 (reply_to = {:owner, owner, tag}), the
Connection sends owner three message shapes directly, ALL from the
Connection process itself — the same single-sender operation
deliver_outcome/2 already uses for the terminal result — so BEAM's
per-sender-per-receiver FIFO guarantees the owner's mailbox order equals
demux order equals wire order:
{:acp_turn_update, tag, ordinal, notification}— one persession/updatenotification belonging to the turn's session, stamped with a contiguous per-turn ordinal starting at 0.{:acp_turn_end, tag, count}— sent exactly once, immediately before the terminal{:acp_result, tag, outcome};countis the number of:acp_turn_updatemessages the owner should have received (ordinals0..count-1).{:acp_result, tag, outcome}— the terminal delivery (Connection.async_request/6's outcome).
Because the Connection is the single sender of all three shapes, a
consumer needs no settle timer and no reorder buffer on this path:
delivered < count observed at the terminal result is a definite,
synchronous signal of dropped updates, never a race.
The stamp (broadcast path)
t/0 is the per-notification ordering key threaded onto
Connection.Ctx.delivery_stamp for every session/update dispatch
(nil for anything else) — for the multi-sender broadcast path
(subscribe/3, custom session_update/2 overrides) that still fans out
through per-notification dispatch tasks and therefore needs an explicit
key to reconstruct order. turn is the receiver-minted turn token (nil
when the update is out-of-turn — no open prompt turn for the session on
this connection); ordinal is the contiguous per-(session, namespace)
stamp assigned at the demux point; rx_seq is the connection-wide
monotone frame stamp (used by the separate cancel/prompt wire-order
latch).
Summary
Functions
Emit the [:raxol, :acp, :delivery] telemetry event when
:telemetry is loaded; a silent no-op otherwise (this package does not
depend on :telemetry, matching Connection's own optional-telemetry
guard). metadata should include :decision — one of
:emit | :buffer | :gap | :fail — plus whichever of :session, :turn,
:buffered, :ordinal apply at the call site.
Build a Stamp.
Types
@type t() :: %Raxol.AgentClientProtocol.Delivery{ ordinal: non_neg_integer(), rx_seq: non_neg_integer(), turn: reference() | nil }
Per-notification ordering key, receiver-assigned at the demux point.
Functions
@spec emit(map()) :: :ok
Emit the [:raxol, :acp, :delivery] telemetry event when
:telemetry is loaded; a silent no-op otherwise (this package does not
depend on :telemetry, matching Connection's own optional-telemetry
guard). metadata should include :decision — one of
:emit | :buffer | :gap | :fail — plus whichever of :session, :turn,
:buffered, :ordinal apply at the call site.
@spec new(reference() | nil, non_neg_integer(), non_neg_integer()) :: t()
Build a Stamp.