Skip to main content

khive_types/
pack.rs

1//! Pack trait — the declarative composition unit for khive (ADR-025).
2//!
3//! A pack declares vocabulary (note kinds, entity kinds) and verbs. This is
4//! purely static metadata — no I/O, no async. Runtime dispatch lives in
5//! `khive-runtime` (`PackRuntime` trait + `VerbRegistry`).
6//!
7//! This trait lives in khive-types (no_std, zero deps) so downstream crates
8//! can reference pack metadata without pulling in the full runtime.
9
10/// Verb metadata for discovery and documentation.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct VerbDef {
13    pub name: &'static str,
14    pub description: &'static str,
15}
16
17/// A composable module that contributes vocabulary and verbs to the khive runtime.
18///
19/// Packs declare what entity kinds, note kinds, and verbs they introduce.
20/// The runtime merges vocabularies from all loaded packs and rejects
21/// unregistered kinds at the service boundary.
22///
23/// Edge relations remain a closed enum (ADR-021) and are NOT pack-extensible.
24pub trait Pack {
25    /// Short identifier for this pack (e.g. "kg", "tasks").
26    const NAME: &'static str;
27
28    /// Note kinds this pack contributes to the runtime vocabulary.
29    const NOTE_KINDS: &'static [&'static str];
30
31    /// Entity kinds this pack contributes to the runtime vocabulary.
32    const ENTITY_KINDS: &'static [&'static str];
33
34    /// Verbs this pack handles. The runtime routes verb calls to the pack
35    /// that declares them.
36    const VERBS: &'static [VerbDef];
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    struct TestPack;
44
45    impl Pack for TestPack {
46        const NAME: &'static str = "test";
47        const NOTE_KINDS: &'static [&'static str] = &["memo"];
48        const ENTITY_KINDS: &'static [&'static str] = &["widget"];
49        const VERBS: &'static [VerbDef] = &[VerbDef {
50            name: "do_thing",
51            description: "does a thing",
52        }];
53    }
54
55    #[test]
56    fn pack_trait_compiles() {
57        assert_eq!(TestPack::NAME, "test");
58        assert_eq!(TestPack::NOTE_KINDS, &["memo"]);
59        assert_eq!(TestPack::ENTITY_KINDS, &["widget"]);
60        assert_eq!(TestPack::VERBS.len(), 1);
61        assert_eq!(TestPack::VERBS[0].name, "do_thing");
62    }
63}