pub struct ProfileContract {
pub profile: String,
pub prefixes: Vec<String>,
pub expected_count: usize,
pub registered_count: usize,
pub dead_prefixes: Vec<String>,
pub unexpected_tools: Vec<String>,
pub destructive_tools: Vec<String>,
pub verified_at: String,
pub binary_version: Option<String>,
pub surface_hash: Option<String>,
pub ok: bool,
}Expand description
The profile contract — proof that the advertised surface is the declared surface.
Computed at server startup from the pre-filter (“full”) registry and
the post-filter (registered) registry. ok == false means surface
drift: the boundary is advertising or routing something the declared
profile does not cover, or declares prefixes that match nothing (the
dead-route class the curated galaxy.list regression came from).
Persisted as profile_contract.json in the store root so wm doctor
can grade the last server start against it.
Fields§
§profile: StringDeclared profile name (full, curated, minimal, allowlist).
prefixes: Vec<String>Declared prefixes (["*"] for full).
expected_count: usizeTools the declared profile should register.
registered_count: usizeTools actually registered post-filter.
dead_prefixes: Vec<String>Declared prefixes matching zero tools (dead routes).
unexpected_tools: Vec<String>Registered tools the declared profile does not cover (drift).
destructive_tools: Vec<String>Destructive tools on the registered surface. Informational —
destructive effects are confirm-gated in the dispatch pipeline;
curated deliberately includes memory.delete and friends.
verified_at: StringRFC 3339 timestamp of the check (wm_core::time).
binary_version: Option<String>Package version of the binary that computed the contract.
None = pre-P-PROV-5 contract (serde default keeps them readable).
surface_hash: Option<String>Surface pin (P-PROV-5, 2026-09-10, rug-pull tripwire): hex SHA-256
over the sorted registered tool names (see surface_hash). Any
tool added, removed, or renamed changes the pin; wm doctor
discloses it so a reviewed release surface can be pinned externally.
None = pre-P-PROV-5 contract.
ok: booltrue iff the registered surface is exactly the declared one.
Trait Implementations§
Source§impl Clone for ProfileContract
impl Clone for ProfileContract
Source§impl Debug for ProfileContract
impl Debug for ProfileContract
Source§impl<'de> Deserialize<'de> for ProfileContract
impl<'de> Deserialize<'de> for ProfileContract
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ProfileContract
impl RefUnwindSafe for ProfileContract
impl Send for ProfileContract
impl Sync for ProfileContract
impl Unpin for ProfileContract
impl UnsafeUnpin for ProfileContract
impl UnwindSafe for ProfileContract
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> Fruit for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more