lifeloop-cli 0.3.0

Provider-neutral lifecycle abstraction and normalizer for AI harnesses
Documentation
//! 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::CallbackRequest`] envelopes
//!   (schema version, non-empty identifiers, frame-context invariants,
//!   payload-ref structure);
//! * adapter manifest resolution by both `adapter_id` *and*
//!   `adapter_version` (the two are distinguished failure classes —
//!   wrong id is not the same as wrong version of a known id);
//! * synthesis of a typed [`RoutingPlan`] that names the resolved
//!   adapter and preserves opaque `PayloadRef`s 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`]) — see
//!   [`CallbackInvoker`];
//! * 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::PayloadRef`] and [`crate::PayloadEnvelope`] bodies 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.

mod callbacks;
mod failure_mapping;
mod negotiation;
mod plan;
mod receipts;
mod seams;
mod subprocess;
mod validation;

pub use callbacks::{ClientCallback, DefaultCallbackInvoker, FnClientCallback, synthesize_request};
pub use failure_mapping::{
    LifeloopFailureMapper, TransportError, classes_for_negotiation_outcome,
    failure_class_for_receipt_error, failure_class_for_route_error, failure_class_for_transport,
    retry_class_for, validate_receipt_eligible,
};
pub use negotiation::{
    CapabilityKind, CapabilityRequest, CapabilityRequirement, DefaultNegotiationStrategy,
    NegotiatedPlan, PayloadPlacementDecision, PlacementRejection, negotiate,
};
pub use plan::{RoutingPlan, route};
pub use receipts::{
    IdempotencyKey, IdempotencyStore, InMemoryIdempotencyStore, LifeloopReceiptEmitter,
    ReceiptContext, ReceiptError, SequenceGenerator, StoreOutcome,
};
pub use seams::{CallbackInvoker, FailureMapper, NegotiationStrategy, ReceiptEmitter};
pub use subprocess::{
    SubprocessCallbackInvoker, SubprocessInvokerConfig, SubprocessInvokerError,
    failure_class_for_subprocess_error, transport_error_for,
};
pub use validation::{AdapterRegistry, AdapterResolution, BuiltinAdapterRegistry, RouteError};