Skip to main content

khive_runtime/runtime/
config_access.rs

1use super::*;
2
3impl KhiveRuntime {
4    /// Return the extra-visible namespaces assembled at config load.
5    ///
6    /// OSS dispatch uses this set to widen the default multi-record read scope
7    /// to `['local'] ∪ visible_namespaces`. Writes are unchanged: always
8    /// pinned to `'local'`. This set is also available as gate/cloud policy
9    /// input.
10    pub fn visible_namespaces(&self) -> &[Namespace] {
11        &self.config.visible_namespaces
12    }
13
14    pub(crate) fn install_visibility_receipt_capability(
15        &mut self,
16        ring: crate::credentials::VisibilityReceiptConfig,
17        credentials: Vec<crate::credentials::CredentialConfig>,
18        capability: crate::visibility_receipts::ReceiptCapability,
19    ) {
20        self.config.credentials = credentials;
21        self.config.visibility_receipts = Some(ring);
22        self.visibility_receipts = Arc::new(capability);
23    }
24
25    /// Snapshot import vocabulary without treating a poisoned registry as an
26    /// unknown kind. Ordinary create validation retains its existing semantics.
27    pub(crate) fn import_entity_kind_registry(&self) -> RuntimeResult<Vec<String>> {
28        self.valid_entity_kinds
29            .read()
30            .map(|kinds| kinds.clone())
31            .map_err(|_| RuntimeError::Internal("entity kind registry lock poisoned".into()))
32    }
33
34    /// Return a reference to the runtime config.
35    pub fn config(&self) -> &RuntimeConfig {
36        &self.config
37    }
38
39    /// Install the host's full declared SQLite topology before pack registration.
40    pub fn with_declared_backend_db_paths(mut self, paths: Arc<[PathBuf]>) -> Self {
41        self.declared_backend_db_paths = paths;
42        self
43    }
44
45    /// All declared SQLite backend paths known to this runtime's host.
46    pub fn declared_backend_db_paths(&self) -> &[PathBuf] {
47        &self.declared_backend_db_paths
48    }
49}
50
51#[cfg(test)]
52mod import_registry_tests {
53    use super::*;
54    #[tokio::test]
55    async fn relaxed_import_propagates_poisoned_kind_registry() {
56        let runtime = KhiveRuntime::memory().unwrap();
57        let token = runtime.authorize(Namespace::local()).unwrap();
58        let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
59            let _guard = runtime.valid_entity_kinds.write().unwrap();
60            panic!("poison import vocabulary");
61        }));
62        assert!(result.is_err());
63        let input = r#"{"format":"khive-kg","version":"0.1","namespace":"local","exported_at":"2026-01-01T00:00:00Z","entities":[{"id":"00000000-0000-0000-0000-000000000001","kind":"Future","name":"Unwritten","created_at":"2026-01-01T00:00:00Z","updated_at":"2026-01-01T00:00:00Z"}],"edges":[]}"#;
64        let error = runtime
65            .import_kg_json_with_policy(
66                input,
67                &token,
68                khive_types::ImportKindPolicy::PreserveUnknown,
69            )
70            .await
71            .unwrap_err();
72        assert!(matches!(error, RuntimeError::Internal(_)), "{error}");
73        assert!(error.to_string().contains("poisoned"));
74        assert!(runtime
75            .get_entity(&token, uuid::Uuid::from_u128(1))
76            .await
77            .is_err());
78    }
79}