Skip to main content

termivar_scanner/
knowledge.rs

1//! Thread-safe in-memory knowledge base for evidence-driven reasoning.
2//!
3//! ## Runtime scope
4//!
5//! - **Build:** always/default.
6//! - **Execution:** Surface B uses the base as deterministic reasoning state.
7//!   Surface A's opt-in legacy runner also records bounded probe receipts and
8//!   verifier-owned manual-review outcomes from phases 5, 7, 8, and 9.
9//! - **Default `termivar scan`:** yes, through Surface B; legacy knowledge writes
10//!   require the explicit `legacy-scan` path and its acknowledgement flag.
11//! - **Support:** implemented and tested.
12//!
13//! See `docs/internals/runtime-map.md`.
14//!
15//! The base owns ontology, instance relationships, evidence, facts, and
16//! hypotheses, but deliberately contains no detection, scoring, planning, or
17//! persistence behavior. Producers can write observations in any order;
18//! referential integrity is therefore eventual so discovery modules remain
19//! independent from one another.
20
21use std::collections::{BTreeSet, HashMap};
22use std::fmt;
23use std::sync::Arc;
24
25use termivar_core::{
26    EntityId, Evidence, EvidenceId, Fact, Hypothesis, KnowledgeEntity, KnowledgePredicate,
27    KnowledgeRelation, Ontology, RelationId,
28};
29
30/// Opaque, process-local identity shared by one knowledge base and its snapshots.
31///
32/// The identity is deliberately neither serialized nor exposed publicly. It
33/// prevents a snapshot or verifier receipt produced by one in-memory authority
34/// from being committed to a different authority that happens to contain the
35/// same records and revision counters.
36#[derive(Clone, Default)]
37pub(crate) struct KnowledgeAuthority(Arc<()>);
38
39impl KnowledgeAuthority {
40    pub(crate) fn is_same_as(&self, other: &Self) -> bool {
41        Arc::ptr_eq(&self.0, &other.0)
42    }
43}
44
45impl fmt::Debug for KnowledgeAuthority {
46    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
47        formatter.write_str("KnowledgeAuthority(<opaque>)")
48    }
49}
50
51mod index;
52mod relations;
53mod snapshot;
54mod store;
55mod writes;
56
57use index::{collect_indexed, index};
58use writes::{
59    bump_ontology_revision, bump_subject_revision, identity_conflict, subject_revision,
60    validate_revisions,
61};
62
63pub use relations::{
64    MAX_KNOWLEDGE_RELATION_ENTITY_ID_BYTES, MAX_KNOWLEDGE_RELATION_EVIDENCE_IDS,
65    MAX_KNOWLEDGE_RELATION_EVIDENCE_ID_BYTES, MAX_KNOWLEDGE_RELATION_ID_BYTES,
66    MAX_KNOWLEDGE_RELATION_KIND_BYTES,
67};
68pub use snapshot::KnowledgeSnapshot;
69pub use store::KnowledgeBase;
70pub(crate) use writes::HypothesisStateTransition;
71pub use writes::{KnowledgeBaseError, KnowledgeBaseStats, KnowledgeRecordKind, KnowledgeWrite};
72
73#[derive(Debug, Default)]
74struct KnowledgeState {
75    ontology: Ontology,
76    ontology_revision: u64,
77    subject_revisions: HashMap<EntityId, u64>,
78    evidence: HashMap<EvidenceId, Evidence>,
79    facts: HashMap<String, Fact>,
80    hypotheses: HashMap<String, Hypothesis>,
81    entities: HashMap<EntityId, KnowledgeEntity>,
82    relations: HashMap<RelationId, KnowledgeRelation>,
83    evidence_by_subject: HashMap<EntityId, BTreeSet<EvidenceId>>,
84    evidence_by_predicate: HashMap<KnowledgePredicate, BTreeSet<EvidenceId>>,
85    /// Reverse derivation lineage: parent evidence ID -> derived child IDs.
86    /// Forward lineage (child -> parents) is carried by each record's origin.
87    derivation_children: HashMap<EvidenceId, BTreeSet<EvidenceId>>,
88    facts_by_subject: HashMap<EntityId, BTreeSet<String>>,
89    facts_by_predicate: HashMap<KnowledgePredicate, BTreeSet<String>>,
90    hypotheses_by_subject: HashMap<EntityId, BTreeSet<String>>,
91    hypotheses_by_predicate: HashMap<KnowledgePredicate, BTreeSet<String>>,
92    relations_from: HashMap<EntityId, BTreeSet<RelationId>>,
93    relations_to: HashMap<EntityId, BTreeSet<RelationId>>,
94}
95
96impl KnowledgeBase {
97    /// Returns this store's opaque in-memory authority without taking the
98    /// knowledge-state lock or cloning a subject snapshot.
99    pub(crate) fn authority(&self) -> &KnowledgeAuthority {
100        &self.authority
101    }
102}
103
104/// Compatibility alias for the original storage-oriented name.
105#[deprecated(note = "use KnowledgeBase; the base also owns ontology semantics")]
106pub type KnowledgeStore = KnowledgeBase;
107
108/// Compatibility alias for [`KnowledgeBaseError`].
109#[deprecated(note = "use KnowledgeBaseError")]
110pub type KnowledgeStoreError = KnowledgeBaseError;
111
112/// Compatibility alias for [`KnowledgeBaseStats`].
113#[deprecated(note = "use KnowledgeBaseStats")]
114pub type KnowledgeStoreStats = KnowledgeBaseStats;
115
116#[cfg(test)]
117#[path = "knowledge/knowledge_tests.rs"]
118mod tests;