pub struct VerbRegistry { /* private fields */ }Expand description
Immutable registry that dispatches verb calls to registered packs.
Clone is cheap (Arc-wrapped). Constructed via VerbRegistryBuilder.
Implementations§
Source§impl VerbRegistry
impl VerbRegistry
Sourcepub fn default_namespace(&self) -> &str
pub fn default_namespace(&self) -> &str
This registry’s construction-baked default namespace.
Used as the fallback when a request carries no RequestIdentity
override (ADR-096 Fork 1) and by transports that need to advertise
their own resolved identity when forwarding to a warm daemon.
Sourcepub fn actor_id(&self) -> Option<&str>
pub fn actor_id(&self) -> Option<&str>
This registry’s construction-baked actor identity label, if configured
(ADR-057). None means dispatch mints ActorRef::anonymous() absent a
per-request RequestIdentity override (ADR-096 Fork 1).
Sourcepub fn visible_namespaces(&self) -> &[Namespace]
pub fn visible_namespaces(&self) -> &[Namespace]
This registry’s construction-baked extra read-visibility namespaces
(ADR-007 Rev 4 Rule 3b), used absent a per-request RequestIdentity
override (ADR-096 Fork 1).
Sourcepub fn event_store(&self) -> Option<Arc<dyn EventStore>>
pub fn event_store(&self) -> Option<Arc<dyn EventStore>>
This registry’s configured audit EventStore, if any (ADR-094).
Lets background tasks that hold a VerbRegistry but do not go through
dispatch (e.g. the email channel poll loop) append best-effort
lifecycle events to the same sink gate-check audit rows use, without
threading a second Option<Arc<dyn EventStore>> field through every
caller. None means tracing-only, matching the registry’s own
audit-persistence default.
Sourcepub fn describe_verb(&self, verb: &str) -> Result<Value, RuntimeError>
pub fn describe_verb(&self, verb: &str) -> Result<Value, RuntimeError>
Return the help schema envelope for a verb.
Walks registered packs for the first matching HandlerDef and returns a
structured JSON envelope. Subhandlers carry callable_via_mcp: false.
Unknown verbs return RuntimeError::InvalidInput. Full shape documented
in docs/protocol.md §Request Schema.
Check whether the gate permits writes into ns.
Performs a gate evaluation with verb "authorize" before any background
loop is spawned (ADR-056 §6). Returns Ok(()) when the gate allows the
namespace, or Err(RuntimeError::PermissionDenied{..}) when denied.
Gate errors (implementation failures) are surfaced as
RuntimeError::Internal.
Sourcepub async fn dispatch(
&self,
verb: &str,
params: Value,
) -> Result<Value, RuntimeError>
pub async fn dispatch( &self, verb: &str, params: Value, ) -> Result<Value, RuntimeError>
Dispatch a verb to the first pack that handles it.
Routes through the gate, then invokes the matching pack handler. When
params["help"] == true, short-circuits to describe_verb with no side effects.
Gate errors are fail-open. Full dispatch flow documented in docs/protocol.md.
Equivalent to self.dispatch_with_identity(verb, params, None) — uses
this registry’s construction-baked default_namespace / actor_id /
visible_namespaces.
Sourcepub async fn dispatch_with_identity(
&self,
verb: &str,
params: Value,
identity: Option<RequestIdentity>,
) -> Result<Value, RuntimeError>
pub async fn dispatch_with_identity( &self, verb: &str, params: Value, identity: Option<RequestIdentity>, ) -> Result<Value, RuntimeError>
Dispatch a verb, optionally overriding this registry’s baked identity scalars for exactly this call (ADR-096 Fork 1).
identity = None behaves exactly like Self::dispatch. identity = Some(id) uses id.namespace / id.actor_id / id.visible_namespaces
in place of self.default_namespace / self.actor_id /
self.visible_namespaces for this call’s namespace resolution, gate
request, and token minting. The registry’s own fields are never mutated,
so concurrent calls with different (or no) identity are independent.
See docs/api/pack.md#dispatch_with_identity for why this enables one warm
registry to serve many attribution identities over a shared backend.
Sourcepub async fn dispatch_as(
&self,
verb: &str,
params: Value,
verified_actor: VerifiedActor,
) -> Result<Value, RuntimeError>
pub async fn dispatch_as( &self, verb: &str, params: Value, verified_actor: VerifiedActor, ) -> Result<Value, RuntimeError>
Dispatch a verb under an out-of-band verified actor identity.
verified_actor is a typed VerifiedActor (constructor rejects blank
identifiers) — only code holding a VerbRegistry handle can supply it.
dispatch_as never reads params["actor"] to derive the effective actor;
individual verbs may still accept an actor field for their own documented
business semantics, unrelated to the acting principal. Every pack handler
that reads “who is calling” resolves it from the NamespaceToken the
dispatch boundary mints, so verified_actor becomes exactly the principal
those handlers observe.
Equivalent to dispatch_with_identity(verb, params, Some(identity)) with
identity.actor_id = Some(verified_actor) and every other identity scalar
(namespace, visible namespaces) left at this registry’s construction-baked
value. Self::dispatch and Self::dispatch_with_identity are unaffected.
See docs/api/pack.md#dispatch_as for the embedding-host use case and the
blank-identifier safety rationale.
Sourcepub fn resolvers(&self) -> &[(String, Box<dyn PackByIdResolver>)]
pub fn resolvers(&self) -> &[(String, Box<dyn PackByIdResolver>)]
Registered pack-level by-ID resolvers, in registration order.
Each element is (pack_name, resolver). The kg get and delete handlers
iterate this slice to probe pack-private tables when the standard KG
substrates (entity/note/edge/event) return None for a given UUID.
Sourcepub fn reference_ring(&self) -> &Arc<ReferenceRing> ⓘ
pub fn reference_ring(&self) -> &Arc<ReferenceRing> ⓘ
The daemon-warm recently-referenced ring (unified-verb draft ADR,
Slice 1). Consumed by resolve_reference (Layer 0 stage 2) and by the
resolve verb handler; admitted-to by every successful by-id
dispatch (see the admission block in dispatch_with_identity).
Sourcepub fn find_kind_hook(&self, kind: &str) -> Option<Arc<dyn KindHook>>
pub fn find_kind_hook(&self, kind: &str) -> Option<Arc<dyn KindHook>>
Find a kind hook among the registered packs.
Walks packs in registration order; the first pack that both owns the
kind (declares it in note_kinds() or entity_kinds()) and returns
a hook from kind_hook(kind) wins. Returns None if the kind is
unknown to all packs or no owning pack registered a hook.
Sourcepub fn all_verbs(&self) -> Vec<&'static HandlerDef>
pub fn all_verbs(&self) -> Vec<&'static HandlerDef>
All MCP-exposed handlers across all registered packs (Visibility::Verb only).
Subhandlers (Visibility::Subhandler) are excluded — they are internal
pipeline steps not surfaced on the MCP wire. Returned with 'static
lifetime since pack handlers are &'static [HandlerDef] constants.
Sourcepub fn all_verbs_with_names(&self) -> Vec<(&str, &'static HandlerDef)>
pub fn all_verbs_with_names(&self) -> Vec<(&str, &'static HandlerDef)>
All MCP-exposed handlers paired with the name of the pack that owns them
(Visibility::Verb only).
Subhandlers (Visibility::Subhandler) are excluded from the MCP catalog
Use all_handlers_with_names when internal handlers must
also be enumerated (e.g. runtime introspection).
Sourcepub fn all_handlers_with_names(&self) -> Vec<(&str, &'static HandlerDef)>
pub fn all_handlers_with_names(&self) -> Vec<(&str, &'static HandlerDef)>
All handler definitions across all registered packs, including subhandlers.
Unlike all_verbs, this includes Visibility::Subhandler entries. Useful
for runtime introspection (e.g. list_handlers) and tooling that needs
the complete handler surface.
Sourcepub fn all_note_kinds(&self) -> Vec<&'static str>
pub fn all_note_kinds(&self) -> Vec<&'static str>
Merged set of note kinds across all registered packs (deduplicated, first-seen order preserved).
Sourcepub fn all_entity_kinds(&self) -> Vec<&'static str>
pub fn all_entity_kinds(&self) -> Vec<&'static str>
Merged set of entity kinds across all registered packs (deduplicated, first-seen order preserved).
Sourcepub fn pack_names(&self) -> Vec<&str>
pub fn pack_names(&self) -> Vec<&str>
Names of packs in topological load order.
Sourcepub fn pack_requires(&self, name: &str) -> Option<&'static [&'static str]>
pub fn pack_requires(&self, name: &str) -> Option<&'static [&'static str]>
Declared dependencies for a registered pack.
Sourcepub fn pack_note_kinds(&self, name: &str) -> Option<&'static [&'static str]>
pub fn pack_note_kinds(&self, name: &str) -> Option<&'static [&'static str]>
Note kinds owned by a specific registered pack.
Returns None if no pack with name is registered. The slice is
the pack’s NOTE_KINDS constant — 'static lifetime, no allocation.
Sourcepub fn pack_entity_kinds(&self, name: &str) -> Option<&'static [&'static str]>
pub fn pack_entity_kinds(&self, name: &str) -> Option<&'static [&'static str]>
Entity kinds owned by a specific registered pack.
Returns None if no pack with name is registered. The slice is
the pack’s ENTITY_KINDS constant — 'static lifetime, no allocation.
Sourcepub fn pack_verbs(&self, name: &str) -> Option<&'static [HandlerDef]>
pub fn pack_verbs(&self, name: &str) -> Option<&'static [HandlerDef]>
Handlers declared by a specific registered pack.
Returns None if no pack with name is registered. Each HandlerDef
carries name + description + visibility — sufficient for introspection clients.
Sourcepub fn all_edge_rules(&self) -> Vec<EdgeEndpointRule>
pub fn all_edge_rules(&self) -> Vec<EdgeEndpointRule>
All pack-declared edge endpoint rules across registered packs.
Order follows topological pack registration; duplicates are not deduplicated — validation only checks membership, and an exact-duplicate rule is a harmless restatement.
Sourcepub fn all_entity_types(&self) -> Vec<EntityTypeDef>
pub fn all_entity_types(&self) -> Vec<EntityTypeDef>
All pack-declared entity-type subtypes across registered packs.
Order follows topological pack registration; duplicates are not
deduplicated here — same posture as all_edge_rules.
Consumers compose this with EntityTypeRegistry::builtin() via
EntityTypeRegistry::with_extra to get the boot-time composed registry.
Sourcepub fn all_note_kind_specs(&self) -> Vec<&'static NoteKindSpec>
pub fn all_note_kind_specs(&self) -> Vec<&'static NoteKindSpec>
Collect all NoteKindSpec declarations from every loaded pack.
Used by the runtime for lifecycle introspection and future enforcement.
Sourcepub fn all_validation_rules(&self) -> Vec<&'static ValidationRule>
pub fn all_validation_rules(&self) -> Vec<&'static ValidationRule>
All pack-contributed validation rules across registered packs.
Returns references into the pack-owned 'static slices — no allocation
beyond the outer Vec. Rule IDs are namespaced by pack; callers can
group by rule.id.split_once('/') to attribute rules to their packs.
Sourcepub fn all_schema_plans(&self) -> Vec<SchemaPlan>
pub fn all_schema_plans(&self) -> Vec<SchemaPlan>
Pack-auxiliary schema plans for all registered packs.
Returns one SchemaPlan per pack. Callers (typically the runtime
bootstrap) apply each plan to the pack’s assigned backend. Empty plans
are included so the caller can iterate uniformly; callers that want to
skip empty plans should check plan.is_empty().
Sourcepub fn call_register_embedders(&self, runtime: &KhiveRuntime)
pub fn call_register_embedders(&self, runtime: &KhiveRuntime)
Invoke PackRuntime::register_embedders on every registered pack.
Called by the transport during startup, after the registry is built and
before the first verb dispatch, so that custom embedding providers
contributed by packs are reachable via KhiveRuntime::embedder(name).
Packs whose register_embedders is the default no-op pay no overhead.
The method is idempotent when the underlying registry uses last-wins
semantics for duplicate provider names.
Sourcepub fn call_register_entity_type_validators(&self, runtime: &KhiveRuntime)
pub fn call_register_entity_type_validators(&self, runtime: &KhiveRuntime)
Invoke PackRuntime::register_entity_type_validator on every registered pack.
Called by the transport during startup, after the registry is built and
before the first verb dispatch, so that entity-type validation at the
runtime layer is active for all write paths including direct create_many
callers that bypass the handler layer.
Packs whose register_entity_type_validator is the default no-op pay
no overhead.
Composes all_entity_types once and passes
the same aggregate to every pack, mirroring how install_edge_rules
installs one all_edge_rules() aggregate for the whole registry.
Sourcepub fn call_register_note_mutation_hooks(&self, runtime: &KhiveRuntime)
pub fn call_register_note_mutation_hooks(&self, runtime: &KhiveRuntime)
Invoke PackRuntime::register_note_mutation_hook on every registered pack.
Called by the transport during startup, after the registry is built and
before the first verb dispatch, so that note-mutation notifications at
the runtime layer are active for all write paths — including KG’s
update/delete verbs reaching a kind="memory" note, which have no
crate-level dependency on khive-pack-memory.
Packs whose register_note_mutation_hook is the default no-op pay no
overhead.
Sourcepub async fn call_warm_all(&self)
pub async fn call_warm_all(&self)
Invoke PackRuntime::warm on every registered pack.
Called by the daemon at boot (in a background task) so expensive in-memory
state (ANN indexes) is pre-loaded without blocking request serving.
Sourcepub fn presentation_policy_for(&self, verb: &str) -> VerbPresentationPolicy
pub fn presentation_policy_for(&self, verb: &str) -> VerbPresentationPolicy
Resolve the presentation policy for a verb name.
Walks all registered handlers (including subhandlers) for the first
matching name and returns its declared VerbPresentationPolicy.
Returns Standard for unknown verbs — unknown verbs will fail at
dispatch anyway, so the fallback here is safe.
Sourcepub fn is_subhandler_verb(&self, verb: &str) -> bool
pub fn is_subhandler_verb(&self, verb: &str) -> bool
Returns true if the named verb exists and is tagged
Visibility::Subhandler (internal / operator-only).
Used by the MCP server to gate subhandler invocation at the wire boundary without blocking internal callers that invoke the same verbs through the runtime directly.
Sourcepub fn apply_schema_plans(&self, backend: &StorageBackend)
pub fn apply_schema_plans(&self, backend: &StorageBackend)
Apply all non-empty pack-auxiliary schema plans to the given backend.
This is the centralized startup hook that replaced the previous lazy
per-pack self-bootstrap pattern. Each pack’s SchemaPlan carries
idempotent CREATE TABLE IF NOT EXISTS DDL; calling this more than once
is safe. Empty plans are skipped.
Errors from individual plans are logged via tracing::warn! and not
propagated so that a single pack’s schema failure does not prevent the
rest from loading. Callers that need hard-failure semantics should call
all_schema_plans() and apply each plan individually.
Sourcepub fn all_schema_plans_named(&self) -> Vec<(&'static str, SchemaPlan)>
pub fn all_schema_plans_named(&self) -> Vec<(&'static str, SchemaPlan)>
Pack-auxiliary schema plans with their owning pack names.
Returns (pack_name, SchemaPlan) pairs for every registered pack.
Used by the multi-backend boot path to apply each plan to the pack’s
assigned backend rather than a single shared backend.
Sourcepub fn apply_schema_plans_with_map(
&self,
backend_for_pack: &HashMap<&str, &StorageBackend>,
default_backend: &StorageBackend,
) -> Result<(), PackSchemaCollisionError>
pub fn apply_schema_plans_with_map( &self, backend_for_pack: &HashMap<&str, &StorageBackend>, default_backend: &StorageBackend, ) -> Result<(), PackSchemaCollisionError>
Apply pack-auxiliary schema plans using a per-pack backend map.
For each (pack_name, plan) returned by all_schema_plans_named(),
applies the plan to backend_for_pack[pack_name] when present,
falling back to default_backend for any pack not in the map.
Returns an error when two packs on the same backend declare the same auxiliary table (ADR-028 §7 collision policy: boot failure naming both packs and the conflicting table).
This is the multi-backend boot path (ADR-028). Single-backend callers
should continue using Self::apply_schema_plans.
Trait Implementations§
Source§impl Clone for VerbRegistry
impl Clone for VerbRegistry
Source§fn clone(&self) -> VerbRegistry
fn clone(&self) -> VerbRegistry
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for VerbRegistry
impl !UnwindSafe for VerbRegistry
impl Freeze for VerbRegistry
impl Send for VerbRegistry
impl Sync for VerbRegistry
impl Unpin for VerbRegistry
impl UnsafeUnpin for VerbRegistry
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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