crates/guest-host/src/lib.rs
//! **The mechanics of running somebody else's `.wasm` inside your process** —
//! lifted out of holger's plugin host so that holger *and* monetize (and the
//! next host) hold one implementation of the parts that have nothing to do with
//! what the guest is for.
//!
//! What is here is exactly what a host needs before it knows a single verb:
//!
//! | module | what it is | needs `wasmtime`? |
//! |---|---|---|
//! | [`limits`] | fuel, a wall-clock deadline, a memory and a table ceiling — every one a **named** refusal, and a configured `0` refused rather than read as "unlimited" | the engine config and limiter do |
//! | [`verify`] | *is this module the one we signed?* A detached CMS signature beside the module (`foo.wasm.p7s`) over the blake3-256 of its bytes, chained to DER roots. Fail-closed when this build cannot verify | no |
//! | [`census`] | a module is named by its **digest**, over the same bytes the signature covers, not by a file name an operator chose | no |
//! | [`convention`] | the export set every guest speaks (`alloc`, `dealloc`, `result_len`, `plugin_abi`, `plugin_manifest`, `plugin_call`) and the packed `ptr << 32 \| len` word | no |
//! | [`module`] | [`module::LoadedModule`]: verify → digest → compile → tick, bounded stores, and the two call shapes with a trap turned into the bound that caused it | yes |
//!
//! What is deliberately **not** here: any payload encoding, any op table, any
//! host import. A host defines its imports on the `Linker` it hands
//! [`module::LoadedModule::instantiate`], and encodes its arguments however it
//! likes — holger's ABI is length-prefixed TLV, monetize's is JSON, and this
//! crate carries bytes.
//!
//! # The two CPU bounds, because they measure different things
//!
//! Fuel counts instructions and is deterministic; the epoch counts wall-clock
//! and is the backstop for time spent *inside a host import*, which fuel does
//! not see. A host that shipped one of them is bounded on paper and unbounded in
//! the case that actually takes it down. See [`limits`].
//!
//! # Refusals carry no application code
//!
//! Each refusal here is a typed error with a plain-language `Display`. A host
//! that keeps a frozen error registry (holger's `holger-plugin-<n>`) prefixes
//! its own code; a host that does not, prints the message. That is the seam
//! that let this crate leave holger without taking `holger-errcode` with it.
pub mod census;
pub mod convention;
pub mod limits;
pub mod verify;
#[cfg(feature = "wasmtime")]
pub mod module;
pub use census::{digest_hex, CensusRow};
pub use convention::{exports, pack, unpack};
pub use limits::{Bound, LimitZero, PluginLimits};
#[cfg(feature = "wasmtime")]
pub use limits::{BoundedLimiter, EpochTicker};
pub use verify::{ModuleTrust, TrustError, SIGNATURE_EXT};
#[cfg(feature = "wasmtime")]
pub use module::{CallError, GuestState, LoadError, LoadedModule};
/// The runtime this crate is built against, re-exported so a host reaches ONE
/// `wasmtime` and cannot end up on a second copy through its own `version =`.
#[cfg(feature = "wasmtime")]
pub use wasmtime;