Expand description
Lifecycle router skeleton: pre-dispatch validation and adapter resolution.
Lifeloop owns lifecycle event routing as a neutral mechanism. Clients
own product behavior: a client receives the routed event via a
callback and decides what (if anything) to deliver. The router is the
seam that turns a CallbackRequest plus the adapter manifest registry
into a typed RoutingPlan that downstream stages — capability
negotiation, callback invocation, receipt emission, failure mapping —
consume without re-validating wire-level invariants.
§Boundary (issue #7, skeleton slice)
This module owns:
- pre-dispatch validation of
crate::CallbackRequestenvelopes (schema version, non-empty identifiers, frame-context invariants, payload-ref structure); - adapter manifest resolution by both
adapter_idandadapter_version(the two are distinguished failure classes — wrong id is not the same as wrong version of a known id); - synthesis of a typed
RoutingPlanthat names the resolved adapter and preserves opaquePayloadRefs for downstream stages; - the trait seams through which later issues plug in negotiation, callback invocation, receipt emission, and failure mapping.
This module does not own:
- capability negotiation (future router issue) — see
NegotiationStrategy; - callback invocation against renderers (issue #3 will wire a
protocol renderer into
CallbackInvoker) — seeCallbackInvoker; - receipt persistence/emission (future router issue) — see
ReceiptEmitter; - failure-class mapping for receipt synthesis (future router
issue) — see
FailureMapper; - payload body inspection. The router treats
crate::PayloadRefandcrate::PayloadEnvelopebodies as opaque: it does not parse, transform, or pattern-match on payload contents.
§Client compatibility
This module has none. It is provider-neutral by construction. Any historic host-adapter flow that fused lifecycle routing with client product semantics is replaced by Lifeloop routing plus client callbacks — every client (including the first one) becomes a consumer of these seams, not a peer of the router.
Structs§
- Builtin
Adapter Registry - Adapter registry backed by
crate::manifest_registry. - Capability
Request - A client’s capability request for one lifecycle dispatch.
- Capability
Requirement - One requirement in a
CapabilityRequest. - Default
Callback Invoker - Concrete
CallbackInvokerfor issue #14. - Default
Negotiation Strategy - Concrete
NegotiationStrategyfor issue #13. - FnClient
Callback - Adapter that lifts any
Fn(&CallbackRequest, &[PayloadEnvelope]) -> Result<CallbackResponse, E>into aClientCallback. - Idempotency
Key - Composite key the idempotency store uses internally. The spec
scopes idempotency by
(client_id, adapter_id, idempotency_key)— the key type pins that triple so a consumer’s persistent store cannot accidentally collapse the scope. - InMemory
Idempotency Store - In-memory reference
IdempotencyStorebacked by aHashMapbehind aMutexfor interior mutability through&self. - Lifeloop
Failure Mapper - Concrete
FailureMapperfor issue #15. - Lifeloop
Receipt Emitter - Concrete
ReceiptEmitterfor issue #14. - Negotiated
Plan - Negotiation result wrapping a
RoutingPlan. - Receipt
Context - Caller-supplied identifiers and clock value Lifeloop cannot synthesize on its own. Every field except the harness ids is required.
- Routing
Plan - Pre-dispatch routing plan produced by
route. - Sequence
Generator - Per-
lifeloop_run_idmonotonic sequence counter. - Subprocess
Callback Invoker - Subprocess-backed
CallbackInvoker. - Subprocess
Invoker Config - Configuration for
SubprocessCallbackInvoker.
Enums§
- Adapter
Resolution - Resolution outcome for an
(adapter_id, adapter_version)pair. - Capability
Kind - Vocabulary of lifecycle capabilities a client can name in a
CapabilityRequest. - Payload
Placement Decision - Per-payload placement decision produced by negotiation.
- Placement
Rejection - Why a particular
AcceptablePlacementwas rejected during per-payload placement evaluation. - Receipt
Error - Failure variants from receipt emission.
- Route
Error - Reasons the router refused a
crate::CallbackRequestbefore dispatch. - Store
Outcome - Outcome of a successful
IdempotencyStore::put. - Subprocess
Invoker Error - Failure variants surfaced by
SubprocessCallbackInvoker::invoke. - Transport
Error - Coarse shape of a callback-transport failure.
Traits§
- Adapter
Registry - Source of
AdapterManifests the router consults at dispatch time. - Callback
Invoker - Callback invocation seam.
- Client
Callback - Pluggable client-callback seam.
- Failure
Mapper - Failure-class mapping seam.
- Idempotency
Store - Replay-boundary store. Distinct trait so a consumer can plug in a real database without this module knowing.
- Negotiation
Strategy - Capability negotiation seam.
- Receipt
Emitter - Receipt emission seam.
Functions§
- classes_
for_ negotiation_ outcome - Map a
NegotiationOutcometo a(failure_class, retry_class)pair when the outcome blocks dispatch. ReturnsNonefor non-blocking outcomes (Satisfied,Degraded). - failure_
class_ for_ receipt_ error - Map a
ReceiptErrorto aFailureClass. - failure_
class_ for_ route_ error - Map a
RouteErrorto aFailureClass. - failure_
class_ for_ subprocess_ error - Map a
SubprocessInvokerErroronto the sharedFailureClassvocabulary. - failure_
class_ for_ transport - Map a
TransportErrorto aFailureClass. - negotiate
- Negotiate a
CapabilityRequest(and any payload envelopes) against an existingRoutingPlan. - retry_
class_ for - Per-failure default retry-class hint.
- route
- Validate a
CallbackRequestand resolve its adapter against the suppliedAdapterRegistry, producing aRoutingPlan. - synthesize_
request - Synthesize the outbound
CallbackRequestfrom aRoutingPlan. Free function (does not depend on the client type) so tests can inspect what the invoker would dispatch without naming aClientCallback. - transport_
error_ for - Convert a
SubprocessInvokerErrorinto the sharedTransportErrorenum so callers that already speak insuper::LifeloopFailureMapper::map_transport_errorterms can route subprocess failures through the same path.Nonefor variants that are not transport-class (validation, parse, receipt-emitted rejection). - validate_
receipt_ eligible - Validation-layer guard: refuse to plan receipt synthesis for a
receipt.emittedevent.