lifeloop-cli 0.3.0

Provider-neutral lifecycle abstraction and normalizer for AI harnesses
Documentation
//! Verifies the 0.1.1 domain module aliases (`event`, `manifest`, `adapters`,
//! `capability`) resolve to the same items as their canonical crate-root or
//! `router` counterparts. Compile-only checks for types (the `let _: T = u`
//! bindings unify only if `T` and the inferred type of `u` are the same item)
//! plus runtime function-pointer-equality checks for functions.
//!
//! If any alias drifts (e.g. someone replaces a re-export with a wrapper
//! struct), this test fails to compile or to run.

#![allow(dead_code, unused_imports)]

// ============================================================================
// event
// ============================================================================

fn _event_kind_alias_matches() {
    let canonical_value: lifeloop::LifecycleEventKind =
        lifeloop::LifecycleEventKind::SessionStarting;
    let aliased_value: lifeloop::event::LifecycleEventKind = canonical_value;
    let _: lifeloop::LifecycleEventKind = aliased_value;
}

fn _event_lifecycle_event_kinds_alias_matches() {
    let canonical: fn() -> Vec<lifeloop::LifecycleEventKind> = lifeloop::lifecycle_event_kinds;
    let aliased: fn() -> Vec<lifeloop::LifecycleEventKind> = lifeloop::event::lifecycle_event_kinds;
    assert_eq!(canonical as usize, aliased as usize);
}

// ============================================================================
// manifest — every `pub use` from the manifest submodule has a check below
// ============================================================================

fn _manifest_adapter_manifest_alias(x: lifeloop::AdapterManifest) {
    let _: lifeloop::manifest::AdapterManifest = x;
}

fn _manifest_registered_adapter_alias(x: lifeloop::RegisteredAdapter) {
    let _: lifeloop::manifest::RegisteredAdapter = x;
}

fn _manifest_conformance_level_alias(x: lifeloop::ConformanceLevel) {
    let _: lifeloop::manifest::ConformanceLevel = x;
}

fn _manifest_placement_class_alias(x: lifeloop::ManifestPlacementClass) {
    let _: lifeloop::manifest::ManifestPlacementClass = x;
}

fn _manifest_lifecycle_event_support_alias(x: lifeloop::ManifestLifecycleEventSupport) {
    let _: lifeloop::manifest::ManifestLifecycleEventSupport = x;
}

fn _manifest_placement_support_alias(x: lifeloop::ManifestPlacementSupport) {
    let _: lifeloop::manifest::ManifestPlacementSupport = x;
}

fn _manifest_context_pressure_alias(x: lifeloop::ManifestContextPressure) {
    let _: lifeloop::manifest::ManifestContextPressure = x;
}

fn _manifest_receipts_alias(x: lifeloop::ManifestReceipts) {
    let _: lifeloop::manifest::ManifestReceipts = x;
}

fn _manifest_session_identity_alias(x: lifeloop::ManifestSessionIdentity) {
    let _: lifeloop::manifest::ManifestSessionIdentity = x;
}

fn _manifest_session_rename_alias(x: lifeloop::ManifestSessionRename) {
    let _: lifeloop::manifest::ManifestSessionRename = x;
}

fn _manifest_renewal_alias(x: lifeloop::ManifestRenewal) {
    let _: lifeloop::manifest::ManifestRenewal = x;
}

fn _manifest_renewal_reset_alias(x: lifeloop::ManifestRenewalReset) {
    let _: lifeloop::manifest::ManifestRenewalReset = x;
}

fn _manifest_renewal_continuation_alias(x: lifeloop::ManifestRenewalContinuation) {
    let _: lifeloop::manifest::ManifestRenewalContinuation = x;
}

fn _manifest_approval_surface_alias(x: lifeloop::ManifestApprovalSurface) {
    let _: lifeloop::manifest::ManifestApprovalSurface = x;
}

fn _manifest_telemetry_source_alias(x: lifeloop::ManifestTelemetrySource) {
    let _: lifeloop::manifest::ManifestTelemetrySource = x;
}

fn _manifest_known_degradation_alias(x: lifeloop::ManifestKnownDegradation) {
    let _: lifeloop::manifest::ManifestKnownDegradation = x;
}

fn _manifest_registry_fn_alias() {
    let canonical: fn() -> Vec<lifeloop::RegisteredAdapter> = lifeloop::manifest_registry;
    let aliased: fn() -> Vec<lifeloop::RegisteredAdapter> = lifeloop::manifest::manifest_registry;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _manifest_lookup_manifest_fn_alias() {
    let canonical: fn(&str) -> Option<lifeloop::RegisteredAdapter> = lifeloop::lookup_manifest;
    let aliased: fn(&str) -> Option<lifeloop::RegisteredAdapter> =
        lifeloop::manifest::lookup_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

// ============================================================================
// adapters — every `pub use` from the adapters submodule has a check below
// ============================================================================

fn _adapters_manifest_registry_fn_alias() {
    let canonical: fn() -> Vec<lifeloop::RegisteredAdapter> = lifeloop::manifest_registry;
    let aliased: fn() -> Vec<lifeloop::RegisteredAdapter> = lifeloop::adapters::manifest_registry;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_lookup_manifest_fn_alias() {
    let canonical: fn(&str) -> Option<lifeloop::RegisteredAdapter> = lifeloop::lookup_manifest;
    let aliased: fn(&str) -> Option<lifeloop::RegisteredAdapter> =
        lifeloop::adapters::lookup_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_codex_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::codex_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::codex_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_claude_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::claude_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::claude_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_hermes_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::hermes_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::hermes_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_openclaw_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::openclaw_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::openclaw_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_gemini_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::gemini_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::gemini_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

fn _adapters_opencode_manifest_fn_alias() {
    let canonical: fn() -> lifeloop::AdapterManifest = lifeloop::opencode_manifest;
    let aliased: fn() -> lifeloop::AdapterManifest = lifeloop::adapters::opencode_manifest;
    assert_eq!(canonical as usize, aliased as usize);
}

// ============================================================================
// capability — every `pub use` from the capability submodule has a check below
// ============================================================================

fn _capability_kind_alias(x: lifeloop::router::CapabilityKind) {
    let _: lifeloop::capability::CapabilityKind = x;
}

fn _capability_request_alias(x: lifeloop::router::CapabilityRequest) {
    let _: lifeloop::capability::CapabilityRequest = x;
}

fn _capability_requirement_alias(x: lifeloop::router::CapabilityRequirement) {
    let _: lifeloop::capability::CapabilityRequirement = x;
}

fn _capability_default_negotiation_strategy_alias(x: lifeloop::router::DefaultNegotiationStrategy) {
    let _: lifeloop::capability::DefaultNegotiationStrategy = x;
}

fn _capability_negotiated_plan_alias(x: lifeloop::router::NegotiatedPlan) {
    let _: lifeloop::capability::NegotiatedPlan = x;
}

fn _capability_payload_placement_decision_alias(x: lifeloop::router::PayloadPlacementDecision) {
    let _: lifeloop::capability::PayloadPlacementDecision = x;
}

fn _capability_placement_rejection_alias(x: lifeloop::router::PlacementRejection) {
    let _: lifeloop::capability::PlacementRejection = x;
}

fn _capability_negotiate_fn_alias() {
    // Bind to a concrete function-pointer type first. This locks the alias
    // contract on the full signature (not just identity) and avoids the
    // `function_casts_as_integer` lint that fires on bare `fn-item as usize`.
    type NegotiateFn = fn(
        &lifeloop::router::RoutingPlan,
        &lifeloop::router::CapabilityRequest,
        &[lifeloop::PayloadEnvelope],
    ) -> lifeloop::router::NegotiatedPlan;
    let canonical: NegotiateFn = lifeloop::router::negotiate;
    let aliased: NegotiateFn = lifeloop::capability::negotiate;
    assert_eq!(canonical as usize, aliased as usize);
}

// ============================================================================
// runtime entry point — only the function-pointer checks need to actually run;
// the `let _: T = x` checks above are compile-only.
// ============================================================================

#[test]
fn function_aliases_unify_with_canonical_paths() {
    _event_lifecycle_event_kinds_alias_matches();
    _manifest_registry_fn_alias();
    _manifest_lookup_manifest_fn_alias();
    _adapters_manifest_registry_fn_alias();
    _adapters_lookup_manifest_fn_alias();
    _adapters_codex_manifest_fn_alias();
    _adapters_claude_manifest_fn_alias();
    _adapters_hermes_manifest_fn_alias();
    _adapters_openclaw_manifest_fn_alias();
    _adapters_gemini_manifest_fn_alias();
    _adapters_opencode_manifest_fn_alias();
    _capability_negotiate_fn_alias();
}