Technical Overview — epistemic-graph¶
epistemic-graph is the Rust-native compute & storage engine for the agent-utilities ecosystem. It
is a single durable engine that unifies a property graph, vector ANN, SQL, RDF/SPARQL, OWL-2
reasoning, time-series, content-addressed BLOB, full-text, and finance/data-science compute behind
one cross-modal RowSet planner. Python reaches it out-of-process over length-prefixed
MessagePack on UDS/TCP, HMAC-authenticated — there is no PyO3 / in-process FFI — or, on the
edge, embeds it in-process via the embedded feature.
This page is the architectural map. For the operational protocol see Service Mode; for the deep dive (distribution, security, streaming, federation, multimodal) see the master-of-all engine; for build tiers see Tiers & binaries.
One core, two transports¶
flowchart LR
subgraph PyCallers["Python callers"]
AU["agent-utilities GraphComputeEngine"]
CLI["CLI / MCP / UIs / ingestion"]
end
subgraph Edge["Edge / embedded"]
EMB["EmbeddedEngine (in-process, no socket)"]
end
subgraph Server["epistemic-graph-server"]
DISP["dispatch + handlers"]
CORE["GraphCore + GraphRegistry"]
REDB[("redb authoritative store")]
end
AU -->|"length-prefixed MessagePack over UDS / TCP"| DISP
CLI -->|"HMAC-SHA256 framed RPC"| DISP
DISP --> CORE
EMB -->|"direct calls, same core"| CORE
CORE --> REDB
Both transports drive the same GraphCore + redb-authoritative durable rows (via wal::apply +
the server-independent redb_store). The socket path adds Tokio + HMAC; the embedded path is a plain
library handle. One core, two front doors.
The crate workspace (a dependency DAG)¶
The engine is a Cargo workspace whose member crates map 1:1 to an acyclic dependency DAG. A crate may
only use crates to its left; a cycle will not compile, which is the enforcement.
flowchart LR
EGT["eg-types<br/>protocol, wire DTOs, ACL"]
EGANN["eg-ann<br/>IVF-PQ + OPQ + SQ8 + exact/recall"]
EGGEO["eg-geo<br/>geometry · R-tree · CRS · routing (GIS)"]
EGSTREAM["eg-stream<br/>windowed events + CEP NFA"]
EGKV["eg-kvcache<br/>tiered hot/warm/cold KV-block cache"]
EGTEXT["eg-text<br/>Tantivy BM25"]
EGWASM["eg-wasm<br/>WASM UDF sandbox"]
EGCORE["eg-core<br/>GraphCore · registry · broker · agent-memory · task queue"]
EGCOMPUTE["eg-compute<br/>algorithms, finance, datascience, reasoning, ast"]
EGQUERY["eg-query<br/>DataFusion SQL + Cypher"]
EGTSDB["eg-tsdb<br/>time-series + VRL pipelines"]
EGTENSOR["eg-tensor<br/>N-D array store + ops"]
EGRDF["eg-rdf<br/>RDF / SPARQL / OWL / GeoSPARQL"]
EGSHACL["eg-shacl<br/>SHACL Core validation"]
EGSHEX["eg-shex<br/>ShEx shape validation"]
EGPLAN["eg-plan<br/>unified RowSet planner + ops"]
EGGQL["eg-graphql<br/>GraphQL + Apollo Federation"]
EGLAKE["eg-lake<br/>LTAP: Parquet · Delta · Iceberg · LSN as-of"]
FACADE["epistemic-graph<br/>facade + Tokio server + wire adapters + observability + LTAP egress + QoS scheduler + embedded"]
EGT --> EGANN --> EGCORE
EGT --> EGCORE
EGCORE --> EGCOMPUTE --> EGQUERY
EGCOMPUTE --> EGTSDB --> EGTENSOR
EGGEO --> EGRDF
EGCORE --> EGRDF --> EGSHACL
EGRDF --> EGSHEX
EGCORE --> EGGQL --> FACADE
EGCOMPUTE --> EGPLAN
EGCORE --> EGPLAN
EGQUERY --> EGPLAN
EGRDF --> EGPLAN
EGTSDB --> EGPLAN
EGTENSOR --> EGPLAN
EGTEXT --> EGPLAN
EGWASM --> EGPLAN
EGGEO --> EGPLAN
EGSTREAM --> EGPLAN
EGPLAN --> FACADE
EGSHACL --> FACADE
EGSHEX --> FACADE
EGKV --> FACADE
EGQUERY --> EGLAKE --> FACADE
EGTSDB --> EGLAKE
The facade re-exports eg-{types,core,compute} under the historical crate:: paths and adds the
server-side modules (dispatch, handlers, persistence, raft, embedded, the multi-wire adapters, and
the observability listener). Server dispatch is a thin routing table: each Method routes to a
handlers::<domain>::try_handle and the write side-effects (in-flight gauge, dirty mark, WAL enqueue,
CDC emit) stay centralized in the shell so every write handler gets durability + reactivity for free.
Six leaf/modality crates were added in the 2.2.0 cycle: eg-geo (GIS — geometry, R-tree, CRS, routing;
CONCEPT:EG-KG.ontology.singles-concept/255-267/155), eg-tensor (N-D arrays; CONCEPT:EG-KG.storage.content-addressed-dedup), eg-stream (windowed CEP;
CONCEPT:EG-KG.query.pipelined-execution), eg-shacl / eg-shex (RDF shape validation; CONCEPT:EG-KG.ontology.concept-6/133), and
eg-kvcache (LLM KV-block tiering; CONCEPT:EG-KG.memory.byte-bounded-tiers/186/187). The message broker (CONCEPT:EG-KG.compute.message-broker-exchanges
family) and agent-memory primitives (CONCEPT:EG-KG.compute.discounted-return/220/221/222) live in eg-core; the
observability stack (logs/metrics/traces/VRL/federated-search; CONCEPT:AU-KG.ingest.self-ingest-165/172/243) lives in
eg-tsdb + the facade's obs listener. Program B (waves B-1..B-6, CONCEPT:EG-KG.query.gds-call-procedures..320) then added a
seventh leaf crate — eg-lake (LTAP lakehouse interop: Parquet + Delta + Iceberg + LSN as-of;
CONCEPT:EG-KG.storage.lsn-as-snapshot-returns, see lakehouse-ltap) — plus the facade's OTel egress
(OTLP export + Prometheus remote-write; EG-316) and QoS/SLO scheduler (EG-320), and exposed the
agent-memory/scene/trajectory primitives over the wire (EG-KG.memory.eg-batch-decay-caller). See
subsystems for how they compose on the one substrate.
The unified RowSet planner¶
The heart of the "master-of-all" claim is a single closed algebra. A Method::UnifiedQuery (or its
text front-end UnifiedQueryText / UQL) carries a Plan — a list of Ops that each transform a
RowSet (a candidate set of (id, score)), composing graph, vector, SQL, OWL, SPARQL, text, time, and
federation in one execution pipeline.
flowchart LR
subgraph Sources["Source ops (seed the RowSet)"]
SCAN["Scan{label}"]
REASON["Reason{class} — OWL inference"]
SPARQL["SparqlBgp{query,var}"]
FOREIGN["ForeignScan{source} — federation"]
end
subgraph Transforms["Transform ops (RowSet to RowSet)"]
FILTER["Filter{preds} — DataFusion SQL"]
TRAVERSE["Traverse{rel,min,max} — graph BFS"]
RANK["Rank{vector} — ANN cosine"]
RANKTEXT["RankText{query} — BM25"]
FUSE["FuseRrf{left,right,k} — hybrid fusion"]
UDF["Udf{id} — sandboxed WASM"]
ASOF["AsOf / Window — time context"]
end
LIMIT["Limit{k} — top-k"]
OUT["RowSet result"]
Sources --> Transforms --> LIMIT --> OUT
- Source ops seed candidates:
Scan(label),Reason(every individual the OWL reasoner infers to be a class member, including ids with no explicit type edge),SparqlBgp(a SPARQL SELECT's bindings),ForeignScan(rows from a remote engine or HTTP/JSON/SQL foreign source). - Transform ops refine: relational
Filter(real DataFusion), graphTraverse, vectorRank, lexicalRankText, hybridFuseRrf(reciprocal-rank fusion of two sub-plans — a doc strong in both modalities out-ranks one strong in only one),Udf(a registered WASM module run over the rows), and the time-context opsAsOf/Window. - The planner is cost-reordered (CONCEPT:AU-KG.compute.vector/2.209): a selective predicate runs before a broad one, so the most selective stage prunes the candidate set first. The result is served through the version-keyed, RLS-aware result cache (CONCEPT:EG-KG.coordination.distributed-cache-coherence), so a repeated identical query on an unchanged graph hits — and an agent never sees another agent's filtered result.
A worked example in one plan: "members the OWL reasoner infers for Device, that have a partOf
path to a Rack, re-ranked by similarity to a query vector, fused with a BM25 text match, top 10" —
Reason -> Traverse -> Rank fused with Scan -> RankText via FuseRrf -> Limit.
Always-on graph algorithms¶
Beyond the planner, the property-graph core exposes the classic algorithms directly (one round-trip each), computed off the per-graph lock on a structural snapshot so analytics never starves writers (CONCEPT:EG-KG.txn.per-graph-write-isolation):
- Topological sort — Kahn's algorithm (
petgraph::algo::toposort); raises on a cycle. - Cycle detection — DFS coloring; returns the precise cycle path, e.g.
["A","B","C","A"]. - Shortest path — unweighted BFS with predecessor backtrack.
- Blast radius — BFS to
max_depth, returning all downstream transitive dependents. - PageRank / PPR, betweenness, community detection (Louvain), MST, VF2 subgraph isomorphism.
- Distributed Pregel/GAS (cluster tier) — PageRank / connected-components / BFS across graphs that span multiple Raft shards, with incrementally-maintained materialized views.
See the Rust Compute Guide for the procedure to add a capability across the
protocol.rs / dispatch.rs / handlers / client layers, and benchmarks for measured
per-op latency.