frame-conv 0.2.0

Conversation patterns — request-response, subscription, pub/sub, and workflow over liminal
Documentation
//! Conversation patterns over the liminal participant substrate —
//! request-response and subscription (F-3a), pub/sub and the workflow
//! facade (F-3b): the four patterns this crate maps onto conversations
//! so components interact through conversations rather than direct
//! function calls.
//!
//! # What is here
//!
//! - [`ConversationHandle`] — the transport-agnostic entry (design D4): no
//!   signature names a transport, and the embedded transport arrives later
//!   behind these same types.
//! - **Request-response** (`frame:conv-request@v1`): typed request with a
//!   caller-supplied deadline riding the push-side wall; closed outcome set
//!   ([`RequestOutcome`]); late and duplicate replies have defined, observable
//!   fates on the typed anomaly surface ([`Anomaly`]).
//! - **Subscription** (`frame:conv-subscription@v1`): typed events in the
//!   substrate's proven delivery order ([`SubscriptionItem`] documents the
//!   strength: ordered, contiguous, sender-excluded, membership-forward).
//! - The caller-owned resume boundary ([`ResumeStore`], [`JoinGrant`]):
//!   restore-then-reattach resume replaying the unacked window from the
//!   committed cursor (F-0c §R4, proven).
//! - **Pub/sub** (`frame:conv-pubsub@v1`): caller-minted
//!   [`PublicationId`], substrate-only fan-out, O(1) sequence dedup,
//!   typed [`PublicationItem`] stream with membership news and the typed
//!   gap contract (F-3b R1; the A4-superseded honest contract is in the
//!   module docs).
//! - **The workflow pattern** ([`workflow`]) — one durable conversation
//!   as a typed facade over exactly one aion workflow/run lineage (F-3b
//!   R2): explicit-key open with the honest weaker idempotency contract,
//!   reconstruction from held identity, reopen of terminal reopenable
//!   runs, typed contributions, and event-driven observation with the
//!   exhaustive progress/terminal projection.
//!
//! # What is deliberately NOT here (seams named)
//!
//! - **The embedded transport** — a later optimization behind the SAME
//!   handle types (design D4); its absence is stated, not implied away.
//! - **A schema-as-data registry** — v1's schema IS the typed Rust message
//!   and validation IS serde at both ends (F-3a R1's pinned ruling).
//!
//! # Honest gates carried from the substrate characterization
//!
//! Characterized at published liminal 0.3.0 (`docs/briefs/F-0c-FINDINGS.md`)
//! and RE-CHARACTERIZED at published liminal 0.3.1 — the early-car
//! republish, whose 0.3.0→0.3.1 delta is a haematite 0.6.1 repin plus a
//! dropped always-None config field — by re-running this crate's entire
//! battery, including every live-server suite, green against the =0.3.1
//! pin (2026-07-21, chore/liminal-031-consume). Every gate below held
//! unchanged at 0.3.1:
//!
//! - **Peer death surfaces typed, before the deadline (ASK-4 discharged at
//!   liminal 0.3.2).** Responder death mid-request is delivered, not waited
//!   out: the caller observes [`RequestOutcome::ResponderFailed`] ahead of
//!   the deadline wall, and the subscription stream carries the death
//!   exactly once as [`SubscriptionItem::PeerFailed`] — one death, one
//!   delivery per surface (proven at the socket,
//!   `tests/pattern_crash_resume.rs`). The 0.3.0/0.3.1 truth this bullet
//!   originally recorded — silence, no live producer for the typed
//!   mapping — was superseded when the upstream death-delivery unit landed;
//!   the deadline remains the wall only when nothing is there to die.
//! - **The receive quantum is hardcoded upstream (upstream ASK-2).** The
//!   substrate's 5-second IO quantum is not caller-settable and an elapsed
//!   quantum is distinguishable from a dead socket only by error text; this
//!   crate isolates that seam in one place, treats elapse as a benign
//!   re-arm, and every wait parameter it exposes is a pure wait quantum —
//!   an elapsed wait returns `Ok(None)`-shaped quiet, never a protocol
//!   outcome.
//! - **No backpressure vocabulary exists on the participant surface.** A
//!   slow consumer surfaces nothing to anyone (F-0c §R5); this crate adds
//!   no parallel vocabulary and will inherit the substrate's typed
//!   Accept/Defer/Reject home when the upstream wiring lands (F-3a R5).

pub mod action_dispatch;
pub mod anomaly;
pub mod config;
pub mod envelope;
pub mod error;
pub mod handle;
pub mod id;
pub mod outcome;
pub mod store;
pub mod workflow;

pub(crate) mod finite;
pub(crate) mod seam;
pub(crate) mod track;

pub use action_dispatch::{
    ActionDispatchError, ActionDispatchOutcome, conversation_for_action, dispatch_action,
};
pub use anomaly::{Anomaly, AnomalyCounters};
pub use config::BusAttachment;
pub use envelope::Envelope;
pub use error::{
    AttachError, CallError, CursorCommit, EnvelopeError, LeaveError, PublishError, RefusalClass,
    StoreError,
};
pub use handle::ConversationHandle;
pub use id::{
    ConversationId, ConversationSeq, CorrelationId, MessageKind, ParticipantRef, PatternId,
    PublicationId,
};
pub use outcome::{
    DepartReason, InboundRequest, IncomingRequest, JoinCredential, JoinGrant, LeaveOutcome,
    PublicationItem, PublishReceipt, RequestOutcome, SubscriptionItem,
};
pub use store::ResumeStore;