pub trait PackRuntime: Send + Sync {
// Required methods
fn name(&self) -> &str;
fn note_kinds(&self) -> &'static [&'static str];
fn entity_kinds(&self) -> &'static [&'static str];
fn handlers(&self) -> &'static [HandlerDef];
fn dispatch<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
verb: &'life1 str,
params: Value,
registry: &'life2 VerbRegistry,
token: &'life3 NamespaceToken,
) -> Pin<Box<dyn Future<Output = Result<Value, RuntimeError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
// Provided methods
fn edge_rules(&self) -> &'static [EdgeEndpointRule] { ... }
fn requires(&self) -> &'static [&'static str] { ... }
fn note_kind_specs(&self) -> &'static [NoteKindSpec] { ... }
fn kind_hook(&self, _kind: &str) -> Option<Arc<dyn KindHook>> { ... }
fn schema_plan(&self) -> SchemaPlan { ... }
fn validation_rules(&self) -> &'static [ValidationRule] { ... }
}Expand description
Async dispatch trait for packs (ADR-025).
This is the object-safe behavioral counterpart to khive_types::Pack.
Pack uses const associated items (not object-safe in Rust); this trait
mirrors that metadata as methods and adds async dispatch.
Registration requires P: Pack + PackRuntime — the compiler enforces
that every runtime pack also declares its vocabulary via Pack.
Required Methods§
Sourcefn note_kinds(&self) -> &'static [&'static str]
fn note_kinds(&self) -> &'static [&'static str]
Note kinds this pack owns — must equal <Self as Pack>::NOTE_KINDS.
Sourcefn entity_kinds(&self) -> &'static [&'static str]
fn entity_kinds(&self) -> &'static [&'static str]
Entity kinds this pack owns — must equal <Self as Pack>::ENTITY_KINDS.
Sourcefn handlers(&self) -> &'static [HandlerDef]
fn handlers(&self) -> &'static [HandlerDef]
Handlers this pack registers — must equal <Self as Pack>::HANDLERS.
Sourcefn dispatch<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
verb: &'life1 str,
params: Value,
registry: &'life2 VerbRegistry,
token: &'life3 NamespaceToken,
) -> Pin<Box<dyn Future<Output = Result<Value, RuntimeError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn dispatch<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
verb: &'life1 str,
params: Value,
registry: &'life2 VerbRegistry,
token: &'life3 NamespaceToken,
) -> Pin<Box<dyn Future<Output = Result<Value, RuntimeError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Dispatch a verb call. Returns serialized JSON response.
The registry parameter gives the handler access to the merged
vocabulary and kind hooks across all loaded packs (ADR-030).
The token is an authorized namespace token minted by the dispatch
boundary after gate authorization — handlers must use it directly.
Provided Methods§
Sourcefn edge_rules(&self) -> &'static [EdgeEndpointRule]
fn edge_rules(&self) -> &'static [EdgeEndpointRule]
Pack-extensible edge endpoint rules — must equal <Self as Pack>::EDGE_RULES.
Defaults to empty so existing packs that don’t extend the edge contract
can ignore it (ADR-031).
Sourcefn requires(&self) -> &'static [&'static str]
fn requires(&self) -> &'static [&'static str]
Pack names whose vocabulary this pack references (ADR-037). Defaults to empty so existing packs compile without changes.
Sourcefn note_kind_specs(&self) -> &'static [NoteKindSpec]
fn note_kind_specs(&self) -> &'static [NoteKindSpec]
NoteKindSpec declarations for note kinds this pack owns (ADR-004).
Packs that introduce note kinds with explicit lifecycle semantics declare the spec here. The runtime collects these for introspection and future enforcement. Defaults to empty so existing packs compile without changes.
Sourcefn kind_hook(&self, _kind: &str) -> Option<Arc<dyn KindHook>>
fn kind_hook(&self, _kind: &str) -> Option<Arc<dyn KindHook>>
Optional per-kind hook for shared CRUD specialization (ADR-030).
When a kind is owned by this pack (declared in note_kinds() or
entity_kinds()), returning Some(hook) opts that kind into
pack-specific behavior — defaults, derived properties, side-effect
edges — through the shared create path. Returning None keeps
the kind as plain storage with no specialization.
Sourcefn schema_plan(&self) -> SchemaPlan
fn schema_plan(&self) -> SchemaPlan
Pack-auxiliary schema (ADR-017 §Storage profile and pack-auxiliary schema).
Returns DDL statements for pack-owned tables that are NOT part of the
core substrate schema. Statements are idempotent (CREATE TABLE IF NOT EXISTS) so callers can apply them safely on every registration. Core
substrate tables evolve through versioned migrations (ADR-015); pack
schema is strictly pack-auxiliary.
Defaults to an empty plan — packs that store everything in the core substrate tables (entities, notes, edges, events) return this default.
Plans are aggregated via VerbRegistry::all_schema_plans and applied
at startup via KhiveMcpServer::with_packs (c12). Packs that need their
schema present (e.g. GTD) also self-bootstrap lazily on first call for
robustness in test contexts that create fresh in-memory databases.
Sourcefn validation_rules(&self) -> &'static [ValidationRule]
fn validation_rules(&self) -> &'static [ValidationRule]
Domain-specific validation rules contributed by this pack (ADR-034 §9).
Rule IDs MUST follow the <pack>/<rule-id> namespace convention.
Built-in rules (no pack prefix) are reserved for the khive-runtime
validation infrastructure.
Defaults to empty — packs with no domain-specific rules return &[].
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".