@irisrun/channel-core
v0.4.0
Published
Iris channel port — the narrow, replay-safe contract every channel implements: mint the sessionId, own and rotate a single-use continuation token (rotate only on a committed turn; keep it on a non-committed one), an atomic single-use in-flight claim, norm
Readme
@irisrun/channel-core
Own, portable, verifiable state — in front of a human, over any channel. The narrow channel port: the contract every Iris channel implements so durable, resumable, approval-gated sessions are pluggable and replay-safe by construction.
What it is
channel-rest, channel-mcp, and channel-slack all speak the same two-identifier
protocol. This package is that protocol, factored into one driver:
makeChannelSession({ runTurn })— mints thesessionId, owns and rotates a single-use continuation token, and enforces the rotation rule in one place: rotate only on a committed turn (finished/parked); a non-committed turn (contended/aborted) journaled nothing, so it keeps the prior token. The in-flight claim is atomic (taken in the same callback as the token check), so a concurrent replay of a token is refused, not double-applied.start/continueTurn— the high-level API;validateContinue/inFlight/advance— primitives a streaming transport uses to refuse loudly before opening a stream. Refusals are a typed taxonomy:unknown-session·missing-token·stale-token·in-flight.ChannelPort<Platform, Reply>— thenormalizeInbound/emitOutboundcontract a platform adapter implements. A transport reduces to: normalize → drive the session → emit.ChannelEvent/toOutcomeEvent— the one streaming-event vocabulary (record·delta·outcome·error), shared so SSE, WebSocket, and any future transport agree field-for-field.
The proof that channels are interchangeable is a single shared conformance suite
(the importable @irisrun/channel-conformance) that channel-rest, channel-mcp, and
channel-slack all pass — "channels behind one port" is a literal, executed guarantee.
The continuation token is an instance-local ordering credential; the durable
session lives in the StateStore journal. See docs/reference/channel-port-spec.md.
Part of Iris — own, portable, verifiable state.
