wasm-capability-contract 0.4.0

Generic, domain-agnostic capability pattern: CapabilityEngine/CapabilityRegistry/CapabilityDispatcher trait shapes + component/capability types. Trait definitions only -- see wasm-capability-core for this pattern's own default implementation, extracted from agent-runtime's ADR-001 (agent-runtime#31, ADR-011).
Documentation
//! [`ComponentManifest`] — identity, limits, and declared capabilities of one component.

use serde::{Deserialize, Serialize};

use crate::ResourceLimits;

/// Declares what a Wasm component is, what it declares it needs to run.
///
/// Checked by a real `ComponentValidator` implementor before the
/// component's route is ever registered — a component whose manifest
/// fails validation must never reach the host's dispatch engine.
///
/// The one `entity` in this crate: `component_id` is a stable identity
/// that outlives changes to contract version or anything else here, so
/// equality is by `component_id` alone (see [`PartialEq`] below), not
/// full structural equality the way a `vo`/`dto` compares.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComponentManifest {
    /// Stable identifier for this component, independent of version.
    pub component_id: String,
    /// The byte-ABI contract version this component was compiled against.
    pub contract_version: String,
    /// Name of the component's exported handler function.
    pub handler_export: String,
    /// Resource bounds the host must enforce for this component.
    pub resource_limits: ResourceLimits,
    /// Capability names this component declares it needs (e.g.
    /// `"some-capability"`). Anything not also present in the route's
    /// granted `Vec<CapabilityGrant>` is denied — ADR-001's
    /// deny-by-default posture.
    pub capabilities: Vec<String>,
}

/// Identity-based, not structural: two manifests with the same
/// `component_id` are the same component even if every other field
/// differs (e.g. a redeploy that bumps `contract_version`) -- the
/// entity persists across such changes.
impl PartialEq for ComponentManifest {
    fn eq(&self, other: &Self) -> bool {
        self.component_id == other.component_id
    }
}

impl Eq for ComponentManifest {}