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 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 (issue #287).
Called by dispatch when params["help"] == true. Walks all registered
packs to find the first HandlerDef whose name matches verb, then
returns a structured envelope:
{
"verb": "recall",
"pack": "memory",
"description": "...",
"category": "Assertive",
"params": [
{ "name": "query", "type": "string", "required": true, "description": "..." },
...
]
}For Visibility::Subhandler handlers the envelope carries
"visibility": "internal" and "callable_via_mcp": false so that
callers who discover the schema via help=true see the same
non-callable status that dispatch would enforce (ue-help-introspection C1).
Returns Err(RuntimeError::InvalidInput(...)) when the verb is unknown
to all loaded packs — identical to the error the normal dispatch path
would emit (so callers get consistent feedback for unknown verbs).
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.
When multiple packs declare the same verb, the first registered pack wins.
help=true interception (issue #287): when params contains
"help": true, dispatch is short-circuited before gate evaluation and
pack invocation. The call returns a schema envelope for the verb:
{ verb, pack, description, category, params: [{name, type, required, description}] }.
This is a read-only introspection path; no side effects occur.
The configured Gate is consulted before dispatch
(ADR-018). Deny decisions return
RuntimeError::PermissionDenied immediately — the pack is never
invoked. Allow decisions proceed to pack dispatch as before.
Every gate consultation emits one tracing::info!(... "gate.check") event
with a structured audit_event field (ADR-018). When a EventStore
is configured via VerbRegistryBuilder::with_event_store, an Event
is also persisted to the Event substrate (ADR-018; ADR-004/ADR-005). Storage errors are logged
via tracing::warn! and never propagated.
When gate.check itself returns an error (gate infrastructure failure),
the error is logged via tracing::warn! and dispatch proceeds (fail-open,
consistent with ADR-018 “Fail-open on gate Err”). No audit event
is persisted for an errored gate check — no decision was produced.
The synthesized GateRequest carries ActorRef::anonymous() and the
operation’s namespace — pulled from params["namespace"] when present
(including an explicit empty string, which KhiveRuntime::ns also
preserves), otherwise the registry’s default namespace (configured via
VerbRegistryBuilder::with_default_namespace). Gate-visible
namespace and runtime-visible namespace MUST stay aligned; coercing an
empty string here while the runtime keeps "" would create an
authorization/audit blind spot on the namespace field governed by ADR-018.
Transports that have richer caller context (auth headers, session
info) will gain a sibling dispatch path in a follow-up.
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 (ADR-030) 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 (ADR-017 §Visibility filtering,
F118). 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
(ADR-017 §Visibility filtering, F118-F123). 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 (ADR-017 §Introspection).
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 (ADR-037).
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 like kkernel pack handler (ADR-076).
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 (ADR-031).
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_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 (ADR-004).
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 (ADR-034 §9).
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 (ADR-017).
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
(ADR-031 extension — pack embedder hook).
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 async fn call_warm_all(&self)
pub async fn call_warm_all(&self)
Invoke PackRuntime::warm on every registered pack (ADR-049).
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 (ADR-045 §6).
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 (ADR-017 §Visibility) 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 (ADR-017 §c12 startup application).
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.
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 more