pub trait KnowledgeGraph: Send + Sync {
// Required methods
fn index<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: Scope,
fact_id: &'life1 FactId,
entities: &'life2 [EntityRef],
text: &'life3 str,
valid_from: Option<DateTime<Utc>>,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn neighbors<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<FactId>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
// Provided methods
fn index_many<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: Scope,
batch: &'life1 [IndexEntry],
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn recall_paths<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<RetrievalPath>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn subgraph<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<GraphView, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn forget<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
fact_id: &'life2 FactId,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
}Expand description
Structured entity graph over stored facts.
Implementations index facts as MENTIONED_IN edges from Entity nodes
to FactRef nodes, plus CO_OCCURS edges between entities seen in
the same fact. neighbors() returns fact ids reachable via direct
MENTIONED_IN plus 1-hop CO_OCCURS sibling traversal — see
Self::neighbors for the precise contract.
Required Methods§
Sourcefn index<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: Scope,
fact_id: &'life1 FactId,
entities: &'life2 [EntityRef],
text: &'life3 str,
valid_from: Option<DateTime<Utc>>,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn index<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
scope: Scope,
fact_id: &'life1 FactId,
entities: &'life2 [EntityRef],
text: &'life3 str,
valid_from: Option<DateTime<Utc>>,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Index a stored fact’s entities into the graph.
valid_from records when the knowledge was valid in the world.
None defaults to recorded_at (now). Pass known_epoch() for
all-time knowledge (regulatory texts, baseline facts).
§Upsert semantics
index() is additive, not replacing — re-indexing the same
FactId with a different entity set adds new MENTIONED_IN edges
and increments CO_OCCURS counts for any newly-co-occurring pairs.
Existing edges are not removed. Callers that need replace
semantics must call forget(fact_id) first (M4). M1 does not ship
forget(); the entire fact-set is append-only until M4.
Sourcefn neighbors<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<FactId>, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn neighbors<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<FactId>, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Return FactIds of facts reachable from entities via:
(a) direct MENTIONED_IN edges, and
(b) 1-hop CO_OCCURS siblings’ MENTIONED_IN edges.
Depth is fixed at 1-hop CO_OCCURS for M1; a hops/max_hops
parameter is deliberately omitted until M5 introduces PathRAG
traversal depth control (no impl currently honors it, so the
signature stays honest about what callers get).
Provided Methods§
Sourcefn index_many<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: Scope,
batch: &'life1 [IndexEntry],
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn index_many<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: Scope,
batch: &'life1 [IndexEntry],
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Index a batch of facts under the same Scope in one call.
Same upsert semantics as Self::index applied per entry.
Default impl loops on Self::index sequentially so
existing backends remain correct without source change;
backends with native bulk-insert (e.g. Neo4j UNWIND) override
for O(1) round-trip per batch.
§Skip-empty contract
Entries whose entities is empty are skipped — no graph
write, no observable side effect. Wrappers (e.g.
ProvenanceKnowledgeGraph) MUST filter the same way before
emitting side-effect ledgers so audit state aligns with
graph state.
§Failure
Fails fast on the first entry that errors — partial progress
is left committed because Self::index is additive (no
rollback across entries). Callers that need atomic batches
must wrap the call in a backend-specific transaction.
Sourcefn recall_paths<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<RetrievalPath>, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn recall_paths<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
entities: &'life2 [EntityRef],
) -> Pin<Box<dyn Future<Output = Result<Vec<RetrievalPath>, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Return one crate::RetrievalPath per (entity, fact_id)
edge reachable from entities via the same traversal as
Self::neighbors. Each hop carries chain_entry: None;
the ProvenanceKnowledgeGraph wrapper attaches provenance
after the inner graph returns.
Default impl returns Ok(Vec::new()) so existing backends
continue to compile against the 0.2 trait surface without
code change until they opt in to per-path output.
Sourcefn subgraph<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<GraphView, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn subgraph<'life0, 'life1, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
limit: usize,
) -> Pin<Box<dyn Future<Output = Result<GraphView, MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Enumerate up to limit nodes of scope’s graph for browsing.
Read-only, retrieval-agnostic — unlike Self::neighbors it needs
no seed entities. GraphView::truncated is set when the scope held
more nodes than limit. When truncated, the retained subset is
backend-defined but stable for a given graph state (the in-memory
backend keeps lowest node-index first). Default impl returns an empty
view so backends compile unchanged until they opt in.
Sourcefn forget<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
fact_id: &'life2 FactId,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn forget<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
scope: &'life1 Scope,
fact_id: &'life2 FactId,
) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Remove a fact’s graph-side index entries. Paired with a
Custom("MemoryForget") provenance event by
ProvenanceKnowledgeGraph so the audit chain records the
deletion even though the chain itself stays append-only.
Default impl is a no-op; backends that support deletion override. Calling on a fact that was never indexed must not be an error.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".