pub struct KhiveConfig {
pub db: Option<String>,
pub engines: Vec<EngineConfig>,
pub actor: ActorConfig,
pub runtime: RuntimeSectionConfig,
pub backends: Vec<BackendConfig>,
pub packs: HashMap<String, PackConfig>,
pub git_write: GitWriteSectionConfig,
pub storage: StorageSectionConfig,
}Expand description
Top-level khive configuration loaded from khive.toml or config.toml.
Sections consumed today:
[[engines]]: embedding engine declarations[actor]: default namespace / identity (OSS actor model)[runtime]: runtime knobs (namespace, brain_profile)[[backends]]: storage backend declarations (ADR-028)[packs.<name>]: per-pack backend assignments (ADR-028)
Unknown keys are silently ignored by serde — forward-compatible.
Fields§
§db: Option<String>Typed only so a top-level db key can be rejected loudly by
KhiveConfig::validate instead of being silently ignored as an
unknown key. Not a supported config-file storage selector: single-file
database selection is --db/KHIVE_DB, and storage topology is
[[backends]].path.
engines: Vec<EngineConfig>Embedding engine declarations.
actor: ActorConfigDefault actor identity for this khive instance.
When present, actor.id feeds configuration identity and gate/attribution
policy input. A non-'local' actor.id is folded into the default READ
visible-set at config load (ADR-007 Rev 4 Rule 3b) — it widens what default
multi-record reads return, but never routes writes or sets default_namespace.
Cloud model derives actor identity from an authenticated token.
runtime: RuntimeSectionConfigRuntime knobs: namespace overrides, brain profile, etc.
backends: Vec<BackendConfig>Named storage backends (ADR-028).
When absent or empty, a single implicit main backend is used and all
packs share it — identical to pre-ADR-028 behavior.
packs: HashMap<String, PackConfig>Per-pack backend assignments (ADR-028).
Maps pack name to backend name. Packs absent from this map fall back to
the main backend. Validated at load time: every referenced backend name
must appear in backends.
git_write: GitWriteSectionConfigGit-write policy allowlist (ADR-108 Amendment). Absent or empty
allowed fails closed — khive-pack-git’s write verbs are
unavailable until this section is populated.
storage: StorageSectionConfigStorage-layer config not covered by [[backends]] (ADR-111
Amendment 2: [storage.blob]’s fs/s3 selector).
Implementations§
Source§impl KhiveConfig
impl KhiveConfig
Sourcepub fn load(path: Option<&Path>) -> Result<Option<Self>, ConfigError>
pub fn load(path: Option<&Path>) -> Result<Option<Self>, ConfigError>
Load and validate a KhiveConfig from an explicit path.
Search order:
pathargument (explicit override — e.g. from--config/KHIVE_CONFIG)./.khive/config.toml(project-local config, relative to the MCP server cwd)
The project-local default collocates config with the khive-test.db that already
lives under .khive/ in each project directory. ~/.khive/config.toml is searched
by KhiveConfig::load_with_home_fallback when the project-local file is absent.
If the resolved file does not exist, returns Ok(None).
A missing config is not an error — callers fall back to the env-var path.
If the file exists but cannot be parsed, returns a ConfigError.
After parsing, validate() runs and any logical errors are returned.
Sourcepub fn load_with_home_fallback(
path: Option<&Path>,
db_path: Option<&Path>,
) -> Result<Option<Self>, ConfigError>
pub fn load_with_home_fallback( path: Option<&Path>, db_path: Option<&Path>, ) -> Result<Option<Self>, ConfigError>
Load config with the full resolution order:
- Explicit
path(from--config/KHIVE_CONFIG) ./khive.toml(project-local, project root)<db-dir>/config.toml(project-local, anchored to the resolved database’s own directory — seeproject_config_anchor_dir)~/.khive/config.toml(user-global)
Returns the first file found, or Ok(None) when none exist.
Parse errors are propagated immediately — a malformed config is always
an error regardless of which tier it came from.
db_path should be the same database path the caller is about to open
(or has already resolved). Passing it makes tier 3 resolve identically
for any two processes that target the same database, regardless of
their process working directory — this is what lets a thin client and
a warm daemon serving the same database agree on one config file. Pass
None when no database path is known yet; tier 3 then falls back to
the process cwd, matching the pre-existing behavior.
Sourcepub fn validate(&self) -> Result<(), ConfigError>
pub fn validate(&self) -> Result<(), ConfigError>
Validate the parsed config for logical consistency.
Checks:
- Exactly one engine has
default = true(when the list is non-empty). - Engine names are unique.
fusion_weight, when present, is> 0.
Model name validity is checked lazily at runtime (the config loader does
not import lattice_embed directly to keep the dep surface minimal).
Sourcepub fn default_engine(&self) -> Option<&EngineConfig>
pub fn default_engine(&self) -> Option<&EngineConfig>
Return the engine flagged default = true, or None if the list is empty.
Trait Implementations§
Source§impl Clone for KhiveConfig
impl Clone for KhiveConfig
Source§fn clone(&self) -> KhiveConfig
fn clone(&self) -> KhiveConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for KhiveConfig
impl Debug for KhiveConfig
Source§impl Default for KhiveConfig
impl Default for KhiveConfig
Source§fn default() -> KhiveConfig
fn default() -> KhiveConfig
Source§impl<'de> Deserialize<'de> for KhiveConfig
impl<'de> Deserialize<'de> for KhiveConfig
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 KhiveConfig
impl RefUnwindSafe for KhiveConfig
impl Send for KhiveConfig
impl Sync for KhiveConfig
impl Unpin for KhiveConfig
impl UnsafeUnpin for KhiveConfig
impl UnwindSafe for KhiveConfig
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,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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