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).