Rust-based epistemic graph engine for agent-utilities
Project description
epistemic-graph
One durable, Rust-native engine that is a drop-in substrate for graph · vector · SQL · SPARQL/RDF/OWL · time-series · blob · key-value · message-broker · observability · spatial/GIS · tensor · agent-memory
Every modality is a first-class citizen of one RowSet planner — from a Raspberry Pi to a replicated Raft cluster, from one core.
Honesty first. This README claims only what the code actually does today. Every row in the capability matrix is tagged ✅ supported · 🔶 in-progress · 🗺 roadmap, and the parity roadmap names exactly which gaps are being closed and in which order. If a doc and the code disagree, the code wins — file an issue.
Documentation — the full architecture, the tier/binary map, deployment recipes, the per-interface guides, and the concept registry live in the official documentation.
This is the compute & storage engine for
agent-utilities— a standalone Rust service reached out-of-process over MessagePack/UDS (no PyO3), embedded in-process, or spoken to over the Postgres wire protocol. Contributing? See CONTRIBUTING.md.
The thesis: one engine, every modality
A modern agent platform normally needs a graph database and a vector index and a SQL warehouse and a triple-store + reasoner and a time-series DB and a blob store and a full-text index and a message broker and an observability stack and a GIS engine and an LLM KV-cache — a dozen systems, a dozen copies of the data, a rat's nest of sync pipelines, and a brittle application layer that stitches results back together.
epistemic-graph is the "master of all databases": it speaks the wire protocols of the systems
it replaces (Postgres, MySQL, MSSQL, SQLite, Neo4j Bolt, Redis, S3, AMQP/MQTT/STOMP, PromQL, OTLP) so
existing clients, drivers and ORMs connect unmodified — all resolving to ONE exec path over ONE
store.
epistemic-graph collapses that rack into one durable engine with one unified query planner. Every
modality is a view over the same RowSet algebra, so a single plan can seed candidates from an OWL
inference or a SPARQL pattern, filter them with SQL, traverse the graph, re-rank by vector similarity
and BM25 text, fuse the two, and run a sandboxed WASM UDF — without ever leaving the engine or
marshalling rows back to Python.
It is durable by default: built with the redb feature (folded into every deployment tier), the
persist dir is the authoritative source of truth and an acked write survives kill -9
(commit-before-ack). It scales by configuration alone — the same binary family runs as an embedded
in-process library on a Pi, a single durable server, or a multi-node Raft cluster with cross-shard
transactions.
Drop-in positioning — and the honest parity status
| You run today | epistemic-graph as a drop-in | Current parity |
|---|---|---|
| Postgres (psql / BI / ORM) | pgwire server: SCRAM/trust auth, simple + extended protocol, pg_catalog + information_schema (\d/\dt/\l), CREATE FUNCTION, arrays/ranges + common functions, CREATE EXTENSION |
✅ read SQL · ✅ user tables + DDL + COPY · ✅ compound-WHERE DML + INSERT…SELECT + ON CONFLICT + mixed-store wire transactions · ✅ views/functions |
| Postgres extensions (pgvector / AGE / TimescaleDB / ParadeDB) | vector type + <->/<=>/<#> with ANN index pushdown, AGE cypher(), TimescaleDB hypertables + continuous aggregates, ParadeDB @@@ BM25 |
✅ pgvector · ✅ AGE · ✅ Timescale · ✅ ParadeDB (EG-114/116/117/119) |
| Stardog / GraphDB (RDF triple-store + reasoner) | RDF dataset over the property graph, SPARQL 1.1, OWL 2 EL⁺/RL reasoning, SHACL + ShEx, ICV integrity constraints, GeoSPARQL | ✅ SELECT/ASK/CONSTRUCT/DESCRIBE + UPDATE + /sparql + total-ordering ORDER BY + rich FILTER + content negotiation + SHACL/ICV + JSON-LD/TriG/RDF-XML · 🔶 OWL-DL tableau, SWRL |
| Neo4j (property graph) | native petgraph core + Cypher MATCH…RETURN + writes + GDS algorithms + CALL/UNWIND, plus a native Bolt v4.4 wire |
✅ read traversal, writes (CREATE/MERGE/SET/DELETE), ORDER BY/WITH/aggregation, GDS (PageRank/Louvain/betweenness/Dijkstra/SCC), Bolt drivers (EG-144/159) |
| Pinecone / Milvus (vector DB) | native IVF-PQ + OPQ + SQ8 ANN + exact/flat index + recall harness, persistent, warm-on-start | ✅ (EG-297) |
| InfluxDB / TimescaleDB (time-series) | native redb TSDB: ASOF, gap-fill, time_bucket, OHLC, decay, columnar segments + SQL window frames |
✅ primitives + window functions (EG-089) · 🔶 Op::Window planner op |
| S3 / MinIO (blob) | content-addressed streaming CAS, redb-native or S3-backed, plus an S3 REST serving surface (SigV4-lite) | ✅ (EG-176) |
| Redis (KV / structures) | native RESP2/3 wire over the KV surface (GET/SET/INCR, hashes, lists, sets, sorted-sets) | ✅ (EG-174) |
| SQLite / RocksDB (embedded KV) | EmbeddedEngine in-process handle + generic namespaced KV over the same redb rows |
✅ embedded graph API · ✅ generic KV · ✅ SQLite/MySQL/MSSQL/Bolt wires |
| MySQL / MariaDB / SQL Server (protocol clients) | hand-rolled MySQL (handshake v10), MSSQL-TDS and SQLite-NDJSON listeners over the shared wire core | ✅ connect + query via native drivers · see connecting.md (EG-075/076/077) |
| RabbitMQ / Kafka (message broker) | native broker: exchanges/topic-routing, DLQ, TTL, priority, delayed delivery, consumer-groups + QoS, replayable streams, publisher confirms; AMQP 0.9.1 / MQTT / STOMP wires | ✅ (EG-275–284, EG-281/282) |
| Prometheus / OpenObserve / Jaeger (observability) | obs listener: log ingest + PromQL /api/v1/query + OTLP traces /v1/traces + service-map + VRL-style pipelines + super-cluster federated search |
✅ logs · ✅ PromQL · ✅ traces · ✅ pipelines · ✅ federated (EG-160–165/172/243) |
| PostGIS / GIS (spatial) | native eg-geo: CRS/reprojection, R-tree, GeoJSON/WKB/GPX, XYZ/TMS + MVT tiles, routing/isochrones/TSP, map task-tracking | ✅ (EG-262–267) |
| Apollo GraphQL | Apollo Federation v2 subgraph (_service/_entities, @key) + APQ/depth/complexity hardening |
✅ (EG-295/296) · 🔶 subscriptions/relay |
| vLLM / LMCache (LLM KV-cache) | tiered hot/warm/cold KV-block cache + shared dedup backend + HTTP endpoint (LMCache remote-backend contract) | ✅ (EG-185/186/187) |
| Agent memory (Zep / mem0 / LeanRAG) | bi-temporal AsOf, summary-node tier, episodic→semantic consolidation, decay/reinforce, LeanRAG hierarchical retrieval, NL→query |
✅ (EG-220/221/222/195) · 🔶 NL→query (LLM-optional) |
The point is convergence, not a checkbox: the modalities share one snapshot, one ACID transaction, one security model, and one planner. See the full capability matrix below for the operation-by-operation truth.
Capability matrix
Legend: ✅ supported (implemented & tested) · 🔶 in-progress (partial or being added now) · 🗺 roadmap (designed, not built). Feature flags are the Cargo features that gate each surface; the tier table shows which prebuilt binary carries them.
| Interface | Operation | Status | Feature | Notes |
|---|---|---|---|---|
| SQL | SELECT (joins, aggregates, CTE, window, subquery) |
✅ | query |
DataFusion 43 over nodes + edges; real predicate pushdown (Inexact) |
| SQL | INSERT / UPDATE / DELETE (+ RETURNING) |
✅ | query |
nodes + user tables (KG-2.198); serializable CAS gates |
| SQL | Compound/AND/OR/IN/BETWEEN/IS NULL WHERE DML, INSERT…SELECT, UPDATE…FROM/DELETE…USING, ON CONFLICT upsert |
✅ | query |
EG-045/046/047/048; serializable re-check under the write guard |
| SQL | Mixed-store wire transactions (BEGIN/COMMIT/ROLLBACK + TransactionStatus) |
✅ | pgwire |
EG-049; node + user-table ops, read-your-own-writes; documented non-2PC user-table window |
| SQL | CREATE VIEW/DROP VIEW, CREATE FUNCTION, arrays/ranges + common functions |
✅ | query |
EG-072/118/104; durable view + function catalog |
| SQL | Arbitrary user tables + DDL (CREATE/ALTER ADD COLUMN/DROP), COPY |
✅ | query |
durable redb table catalog (EG-018/EG-020); JOINable to the graph |
| SQL | Columnar segments + window functions (ROW_NUMBER/RANK/LAG/LEAD/OVER(…)) |
✅ | query |
EG-089; struct-of-arrays analytical scan |
| Postgres compat | pg_catalog + information_schema system views (\d/\dt/\l) |
✅ | pgwire |
EG-103; synthesized from live table/view/function catalogs |
| Postgres compat | CREATE EXTENSION catalog · pgvector vector + <->/<=>/<#> + ANN pushdown |
✅ | pgwire |
EG-102/115/116 |
| Postgres compat | AGE cypher() set-returning function, TimescaleDB hypertables + continuous aggregates, ParadeDB @@@ BM25 |
✅ | pgwire |
EG-114/117/119 |
| Postgres wire | listener, simple + extended/prepared protocol | ✅ | pgwire |
EPISTEMIC_GRAPH_PGWIRE_ADDR; also pulled in by cluster |
| Postgres wire | SCRAM-SHA-256 / trust auth, pg_catalog introspection |
✅ | pgwire |
KG-2.202 / KG-2.201; pg user → engine ACL actor |
| SPARQL | SELECT (BGP, paths, FILTER subset, OPTIONAL, UNION, GROUP/agg, BIND, DISTINCT, SLICE) |
✅ | sparql |
spargebra parser compiled to LPG scans |
| SPARQL | ASK / CONSTRUCT / DESCRIBE |
✅ | sparql |
template instantiation + bounded description (gated by rdf, implied by sparql) |
| SPARQL | UPDATE (INSERT/DELETE DATA, DELETE/INSERT WHERE, CLEAR, CREATE/DROP GRAPH) |
✅ | sparql |
eg-rdf/src/update.rs; LOAD intentionally deferred (no HTTP fetch in write path) |
| SPARQL | /sparql HTTP endpoint (W3C SPARQL 1.1 Protocol) |
✅ | sparql-http |
src/server/sparql_http.rs; GET + POST query/update |
| SPARQL | true named graphs (quad dataset) + FROM/FROM NAMED |
✅ | sparql |
GRAPH ?g/constant-IRI over registry graphs (EG-054) |
| SPARQL | ORDER BY total-ordering, VALUES, MINUS, EXISTS/NOT EXISTS, negated property set |
✅ | sparql |
EG-135/125/055/056; fixes the unordered-results correctness gap |
| SPARQL | content negotiation (JSON/XML/CSV/TSV/Turtle/N-Triples), rich FILTER, sub-SELECT, SERVICE federation | ✅ | sparql |
EG-050/053/051/052; SSRF allowlist on SERVICE |
| SPARQL | SHACL + ShEx validation, ICV integrity constraints, GeoSPARQL + RCC8/Egenhofer | ✅ | sparql/geosparql |
EG-132/133/146/261/155 |
| RDF I/O | JSON-LD 1.1, TriG, N-Quads, RDF/XML serialization matrix | ✅ | rdf |
EG-136/137 (alongside Turtle/N-Triples) |
| Cypher | MATCH … WHERE … RETURN … LIMIT (var-length [*m..n]) |
✅ | cypher |
read over a snapshot; WHERE is AND-only today |
| Cypher | writes (CREATE/MERGE/SET/DELETE+DETACH/REMOVE) |
✅ | cypher |
native eg-core mutations (EG-061) |
| Cypher | ORDER BY/SKIP/WITH/OPTIONAL MATCH/OR/aggregation/DISTINCT/UNWIND/CALL |
✅ | cypher |
EG-062/141/142; GDS via CALL gds.* (EG-143/144) |
| Cypher | Neo4j Bolt v4.4 wire (PackStream v2) | ✅ | bolt-wire |
EPISTEMIC_GRAPH_BOLT_ADDR (EG-159); neo4j drivers / cypher-shell |
| GraphQL | read queries (scan + BFS, schema-from-graph, aliases, first/limit, filters) |
✅ | graphql |
byte-equal to Cypher path |
| GraphQL | mutations (createNode/updateNode/deleteNode/addEdge/removeEdge) |
✅ | graphql |
native eg-core mutations |
| GraphQL | Apollo Federation v2 subgraph (_service/_entities, @key) + APQ/depth/complexity hardening |
✅ | graphql |
EG-295/296 |
| GraphQL | subscriptions / fragments / variables / directives / relay pagination | 🔶 | graphql |
poll-only stub; fragments/variables rejected at parse |
| OWL | EL⁺ + RL forward-chaining materialization & classification | ✅ | owl |
pure-Rust; consistency + incremental + justifications |
| OWL | confidence-weighting + Ebbinghaus time-decay | ✅ | owl |
KG-2.236; per-axiom eg:confidence, fact decay |
| OWL | query-time Op::Reason (reasoner seeds a RowSet) |
✅ | owl-plan |
distributed/cross-shard union supported |
| OWL | OWL-DL (tableau, cardinality, allValuesFrom), SWRL user rules |
🗺 | — | out of the EL+RL envelope by design |
| Vector / ANN | IVF-PQ + OPQ + SQ8-refine, persistent (reopen w/o rebuild), warm-on-start | ✅ | ann |
parallel/SIMD brute-force fallback below threshold |
| Vector / ANN | hybrid metadata pre-filter (kNN + allow(id) predicate) |
✅ | ann |
search_filtered (EG-070); filtered during the ADC probe |
| Vector / ANN | exact/flat kNN index + ANN-vs-exact re-rank + recall@k/precision harness | ✅ | ann |
EG-297 |
| Vector / ANN | cross-shard kNN merge | 🗺 | ann |
single-shard today; merge_topk is the leaf primitive |
| Time-series | store + time_bucket, ASOF join, gap-fill LOCF, OHLC, downsample, decay |
✅ | tsdb |
native redb columnar, no DataFusion |
| Time-series | time-ops as unified planner ops (Op::Window) |
🔶 | tsdb |
functions ready; Op::Window is pass-through in the plan today |
| Blob / CAS | content-addressed streaming store (redb-native) | ✅ | blob |
refcount mark-and-sweep GC; bounded RAM |
| Blob / CAS | S3 / MinIO backend behind the same ChunkStore trait |
✅ | blob-s3 |
manifest/linkage byte-identical |
| Blob / CAS | content-defined chunking | 🗺 | blob |
fixed 2 MiB chunks today |
| Key-value | embedded in-process engine API over redb rows | ✅ | embedded |
EmbeddedEngine — no Tokio/socket/HMAC (KG-2.216) |
| Key-value | generic namespaced get/put/scan/cas KV surface over redb |
✅ | redb |
src/server/kv.rs (EG-022); durable, commit-before-ack; not graph-scoped |
| Multi-wire | wire-neutral SQL core (WireProtocol/WireSession, one classify→exec path) |
✅ | wire |
src/server/wire (EG-074); shared by every SQL wire |
| Multi-wire | MySQL / MariaDB wire (handshake v10 + mysql_native_password) |
✅ | mysql-wire |
EPISTEMIC_GRAPH_MYSQL_ADDR (EG-076) |
| Multi-wire | MSSQL TDS wire | ✅ | mssql-wire |
EPISTEMIC_GRAPH_MSSQL_ADDR (EG-077) |
| Multi-wire | SQLite-dialect NDJSON-over-TCP endpoint | ✅ | sqlite-wire |
EPISTEMIC_GRAPH_SQLITE_ADDR (EG-075); .db file I/O 🔶 follow-up |
| Multi-wire | Neo4j Bolt v4.4 wire (PackStream v2, native Cypher) | ✅ | bolt-wire |
EPISTEMIC_GRAPH_BOLT_ADDR (EG-159) |
| Broker | exchanges (direct/topic/fanout) + bindings/routing over the KG-2.303 work-queue | ✅ | broker |
RabbitMQ-class (EG-275) |
| Broker | DLQ · message/queue TTL · priority · delayed/scheduled delivery · consumer-groups + QoS/prefetch | ✅ | broker |
EG-276/277/278/279/280 |
| Broker | replayable append-log streams (Kafka-style offsets/retention) + publisher confirms + manual ack/nack | ✅ | broker |
EG-283/284 |
| Broker wires | AMQP 0.9.1 · MQTT 3.1.1/5.0 · STOMP 1.2 listeners | ✅ | amqp-wire/mqtt-wire/stomp-wire |
EPISTEMIC_GRAPH_{AMQP,MQTT,STOMP}_ADDR (EG-275/281/282) |
| KV / structures | Redis RESP2/3 wire (strings/hashes/lists/sets/sorted-sets) | ✅ | redis-wire |
EPISTEMIC_GRAPH_REDIS_ADDR (EG-174) |
| Object store | S3-compatible REST (bucket/object CRUD, SigV4-lite) over the blob CAS | ✅ | s3-api |
EG-176 |
| Observability | log ingest + PromQL /api/v1/query + OTLP traces /v1/traces + service-dependency map |
✅ | obs/promql/traces |
EPISTEMIC_GRAPH_OBS_ADDR, default :5080 (EG-160/172/163) |
| Observability | VRL-style ingest pipelines (parse/filter/enrich, cross-modal) + super-cluster federated search | ✅ | obs/federation |
EG-165/243 |
| Spatial / GIS | SpatialScan + ST_Within/ST_DWithin, GeoSPARQL + RCC8/Egenhofer, CRS/reproject, R-tree, GeoJSON/WKB/GPX |
✅ | geo/geosparql |
eg-geo (EG-083/261/155/262/263/264); no GEOS/PROJ |
| Spatial / GIS | XYZ/TMS + Mapbox Vector Tiles · weighted routing/isochrones/TSP · map-based task tracking | ✅ | geo |
EG-265/266/267 |
| Document / JSON | deep JSONPath query + durable inverted path-index; PG ->/->>/@> + Mongo $match |
✅ | (core)/query |
Pred::JsonPath (EG-084) |
| Tensor / probabilistic | N-D array store (CAS-backed) + TensorScan/TensorOp; distribution-valued properties |
✅ | tensor |
EG-085/086 |
| Scene-graph / 3D | :SceneObject pose + transform hierarchy + spatial relations (robotics/AR/urban-3D) |
✅ | (core) | EG-087 |
| CEP / streams | windowed event ingest + Op::Cep bounded-NFA pattern match over sliding/tumbling windows |
✅ | stream |
EG-088 |
| Robotics | multimodal sensor fusion (ASOF-aligned) + action/trajectory memory | ✅ | tensor |
EG-098/099 |
| KV-cache (LLM) | tiered hot/warm/cold KV-block cache + shared dedup backend + HTTP endpoint (vLLM/LMCache contract) | ✅ | kvcache |
eg-kvcache (EG-185/186/187) |
| Agent memory | bi-temporal AsOf, decay/reinforce, summary-node tier, episodic→semantic consolidation, LeanRAG retrieval |
✅ | (core) | Op::AsOf (KG-2.250); EG-220/221/222/195 |
| OBDA | R2RML virtual graphs — SPARQL over a foreign source rewrites to ForeignScan (no materialization) |
✅ | federation |
EG-101 |
| RBAC | durable roles + role hierarchy + resource/action grants over per-agent RLS | ✅ | security |
EG-092 |
| Backup / DR | consistent online backup + restore CLI + PITR (Method::Backup/Restore) |
✅ | redb |
EG-090 |
| Full-text | Tantivy BM25 inverted index, RankText + reciprocal-rank fusion |
✅ | text |
composes in the unified planner |
| Unified planner | Scan·Filter·Traverse·Rank·RankText·FuseRrf·Reason·SparqlBgp·Udf·ForeignScan·AsOf·Limit |
✅ | query+ |
each op feature-gated; see UQL |
| Unified planner | Op::Window / Op::Foreign execution |
🔶 | query |
currently pass-through seams |
| UQL | text DSL → wire::Plan (one parse, zero new exec path) |
✅ | (front-end always ships) | dependency-free parser |
| UQL | natural-language → query (Method::NlQuery, /nl, nl_query() UDF) |
🔶 | nl-query |
EG-078/080; LLM-optional seam — inert until an OpenAI-compatible endpoint is configured |
| Durability | redb-authoritative, commit-before-ack (kill -9-safe) |
✅ | redb |
folded into every tier |
| Distribution | openraft replication + automatic failover | ✅ | raft |
cluster tier; off ⇒ byte-for-byte single-node |
| Distribution | cross-shard 2PC (presumed-abort, crash-recoverable) | ✅ | raft |
classic blocking window; 3PC/non-blocking 🗺 |
| Distribution | multi-Raft groups (N-group ring, online reshard, hibernate/rehydrate) | ✅ | raft |
GroupRouter + MultiRaft (KG-2.266/267/268); online ownership move |
| Federation | remote engine / HTTP-JSON / external SQL (sqlx) as a ForeignScan |
✅ | federation(-sql) |
OFF by default; never in pi |
Architecture at a glance
flowchart TB
subgraph Clients["Clients"]
AU["agent-utilities / graph-os"]
PY["epistemic_graph Python client"]
PG["psql / BI / ORM (pgwire)"]
EMB["Embedded in-process caller (Pi/edge)"]
end
subgraph Engine["epistemic-graph-server (one Rust process)"]
T["Transport: length-prefixed MessagePack over UDS / TCP, HMAC-SHA256"]
SEC["Security: per-agent RLS + audit chain + encryption-at-rest"]
PLAN["Unified RowSet planner (cost-reordered, cross-modal)"]
CORE["GraphCore: petgraph + ledger + result cache"]
subgraph Modalities["Modalities (feature-gated, one core)"]
VEC["Vector ANN (eg-ann)"]
SQL["SQL (eg-query / DataFusion)"]
RDF["RDF / SPARQL / OWL (eg-rdf)"]
TS["Time-series (eg-tsdb)"]
TXT["Full-text (eg-text)"]
BLOB["BLOB CAS (blob)"]
WASM["WASM UDF (eg-wasm)"]
end
subgraph Durability["Durability and distribution"]
REDB[("redb authoritative store")]
RAFT["Raft replication + cross-shard 2PC (cluster)"]
CDC["CDC / streaming / subscriptions"]
end
end
AU --> T
PY --> T
PG --> SQL
EMB --> CORE
T --> SEC --> PLAN --> CORE
CORE --> Modalities
CORE --> REDB
REDB <--> RAFT
CORE --> CDC
A single cross-modal plan flows through one snapshot:
flowchart LR
S["Scan / SparqlBgp / Reason<br/>(seed candidates)"] --> F["Filter<br/>(SQL predicates)"]
F --> TR["Traverse<br/>(graph BFS)"]
TR --> R["Rank / RankText<br/>(vector + BM25)"]
R --> FU["FuseRrf<br/>(hybrid rank)"]
FU --> A["AsOf<br/>(bi-temporal)"]
A --> L["Limit"]
See docs/overview.md for the pipeline and docs/architecture/engine.md for the full architecture.
Deployment tiers and the prebuilt binaries
The same engine ships as a small family of prebuilt, size-optimized binaries (release-tiny profile).
A Pi pulls a prebuilt wheel and never compiles. Full build/wheel recipes are in
docs/deployment.md; the feature-composition map is in
docs/architecture/tiers.md.
| Binary | Carries | For |
|---|---|---|
| pi | redb-authoritative + cypher + ann + rdf/sparql/owl + streaming + result-cache + cost — no DataFusion SQL, no Tantivy, no Raft | Raspberry Pi / edge, ultra-lean |
| pi-max | pi + tsdb + blob + security — all pure-Rust, still no C toolchain | Pi "everything without a C compiler" |
| node | pi + DataFusion SQL (query) + GraphQL + Tantivy text + owl-plan + wasm-udf + federation + finance/datascience |
single durable server |
| cluster | node + Raft replication + pgwire + distributed compute + cross-shard 2PC | multi-node HA / SQL clients |
| full | every single-node feature, size-optimized (no raft/pgwire) | workstation / one binary, every feature |
Note: the lean pi tier carries SPARQL
SELECTand OWL reasoning (via theMethod::Owl*RPCs) but not the SQL-backedOp::Reason/Op::SparqlBgpplanner ops — those needowl-plan, which pullsquery(DataFusion) and lands in node. Every tier is redb-authoritative.
Three engine modes + the auto-bundle
agent-utilities reaches an engine through one resolver (EngineResolver, CONCEPT:OS-5.63) by a
single precedence — no per-entrypoint code:
remote -> shared-local -> autostart
A configured remote (Docker on another host) is used as-is and never autostarts; a co-located engine already serving is reused; otherwise a detached, supervised engine is autostarted under a first-one-wins lock and reference-counted idle-shuts-down after its last client disconnects. Details + the decision flow: docs/engine-modes.md.
For the embedded/edge story, the embedded feature gives a SQLite/DuckDB-style in-process handle
(EmbeddedEngine) over the same GraphCore + redb durable rows — no Tokio, no socket, no HMAC — the
"100M agents, a local engine each" path.
Distribution & durability
- redb-authoritative by default. A committed write is fsynced to redb before the client is acked (commit-before-ack); an acked write survives a hard crash. Eviction is read-through-safe.
- In-engine Raft replication (cluster tier,
raft).openraftreplicates the authoritative redb store; the Raft log shares the onegraph.redb(a log append + its graph mutation coalesce into one fsync). Leader failover is automatic. Off ⇒ the write path is byte-for-byte single-node. - Cross-shard 2PC. A transaction spanning multiple Raft groups commits atomically via presumed-abort
two-phase commit, surviving coordinator/participant crashes. Multi-group routing/resharding is a
scaffold today (single
DEFAULT_GROUP); the durable machinery is in place. - Cross-modal ACID. A graph mutation + a vector upsert + a blob reference land in one redb
WriteTransaction— all modalities commit together or none do.
Security & isolation
- Auth is mandatory. Every RPC carries
HMAC-SHA256(secret, request_id); the server refuses to start with an empty secret (--allow-insecureopts out, dev only). The pgwire surface adds SCRAM-SHA-256. - Per-agent Row-Level Security. Once any identity is registered, the read/plan-path
GraphViewis filtered to the rows the caller may see before any query surface (SQL/Cypher/SPARQL/GraphQL/unified) touches it. The result cache keys on the caller's RLS context. - Encryption-at-rest (
security): redb durable value blobs are ChaCha20-Poly1305 AEAD-sealed (pure-Rust RustCrypto, no ring/openssl). - Hash-chained tamper-evident audit log over every durable mutation.
See docs/service_mode.md for the protocol, auth, and isolation policy.
Quickstart, per interface
Native client — out-of-process (the standard path)
from epistemic_graph import SyncEpistemicGraphClient
g = SyncEpistemicGraphClient() # connects/attaches to the UDS engine
g.nodes.add("AgentA", {"type": "coordinator"})
g.nodes.add("AgentB", {"type": "worker"})
g.edges.add("AgentA", "AgentB", {"weight": 1.5})
print("Order:", g.graph.topological_sort())
# OWL/RDFS forward chaining — materialises inferred edges/types in-graph
result = g.reasoning.reason(subclass_relations=[("Dog", "Animal")],
transitive_properties=["ancestor"])
print("Inferred:", result["inferred_count"], "triples")
Postgres wire (pgwire / cluster) — psql, BI tools, ORMs
# start the engine with the wire listener
EPISTEMIC_GRAPH_PGWIRE_ADDR=127.0.0.1:5433 \
epistemic-graph-server --features cluster
# connect with any Postgres client
psql -h 127.0.0.1 -p 5433 -U agent -d epistemic
-- SELECT is full DataFusion: joins, aggregates, CTEs, window functions
SELECT n.id, n.properties->>'type' AS kind
FROM nodes n
WHERE n.properties->>'type' = 'worker';
-- DML on the graph node store, plus arbitrary user tables + DDL
CREATE TABLE metrics (id TEXT PRIMARY KEY, value DOUBLE PRECISION);
INSERT INTO nodes (id, properties) VALUES ('AgentC', '{"type":"worker"}');
UPDATE nodes SET properties = '{"type":"idle"}' WHERE id = 'AgentC';
DELETE FROM nodes WHERE id = 'AgentC';
Arbitrary user tables + DDL (
CREATE/ALTER ADD COLUMN/DROP,COPY) are supported and JOINable to the graph; compound-WHERE DML and wire transactions are 🔶 in-progress.
SPARQL (sparql)
g.rdf.add_triples([("ex:Dog", "rdfs:subClassOf", "ex:Animal")])
rows = g.rdf.sparql("""
SELECT ?s ?o WHERE { ?s rdfs:subClassOf ?o }
""") # SELECT / ASK / CONSTRUCT / DESCRIBE all supported
ASK/CONSTRUCT/DESCRIBE/UPDATEand the W3C/sparqlHTTP endpoint (featuresparql-http) are supported. Content negotiation, rich FILTER, sub-SELECT, SERVICE and MINUS are 🔶 in-progress — see the capability matrix.
Embedded in-process (Pi / edge, embedded feature)
The EmbeddedEngine handle drives the same GraphCore + redb durable rows with no server, socket, or
HMAC — open a persist dir and call core ops as plain methods (SQLite/DuckDB-style).
Batch, never per-element. Every out-of-process call is a serialize → socket → deserialize round trip, not a function call. Ship work as one batch op over data already in the graph; keep tight per-element math in-process. See AGENTS.md and docs/RUST_COMPUTE_GUIDE.md.
Ontology hosting & lifecycle
epistemic-graph is also an ontology server: you load OWL/RDFS as RDF, the engine maps it onto the
property graph, and the EL⁺/RL reasoner materialises the closure (with confidence weights and Ebbinghaus
time-decay). Classification, consistency checking, and incremental re-materialisation are all
in-engine, and inferred members can seed a unified plan via REASON <Class>. See
docs/interfaces/ontology.md for the load → reason → query → evolve
lifecycle.
Documentation
- Capabilities & parity matrix — the operation-by-operation truth table.
- Universal-DB parity roadmap — every gap being closed, with status.
- Technical Overview · Master-of-all engine.
- Per-interface guides: SQL · SPARQL · Cypher · GraphQL · Vector · Time-series · KV & Blob · Ontology lifecycle.
- UQL & the unified planner · Tiers & binaries · Deployment · Engine modes · Service Mode.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file epistemic_graph-2.2.0.tar.gz.
File metadata
- Download URL: epistemic_graph-2.2.0.tar.gz
- Upload date:
- Size: 2.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c59f347b1d8d85c0c8f7163fd3c5c6becc61123e06d3e5d6b1bb84cde1fa7d45
|
|
| MD5 |
63c8e9a0f011d1b39200cd0becab353d
|
|
| BLAKE2b-256 |
b1b432dcef5a441a1783e038dddabff5997179f023c91c04fa2ec3ac4bc1bb75
|
File details
Details for the file epistemic_graph-2.2.0-py3-none-win_amd64.whl.
File metadata
- Download URL: epistemic_graph-2.2.0-py3-none-win_amd64.whl
- Upload date:
- Size: 35.2 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b37f3e278601c0d4e67d66d7fd881cee369abaeefc0614645ae3f3da3388bab
|
|
| MD5 |
c39d19356f01ed8dcbc5c3ca678bf523
|
|
| BLAKE2b-256 |
795e82e3e44f3e22ecf66e8e1a3cd6c404397012b3ec6cb113ee08bf6c3460d8
|
File details
Details for the file epistemic_graph-2.2.0-py3-none-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: epistemic_graph-2.2.0-py3-none-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 34.1 MB
- Tags: Python 3, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba35227f46e542379570160f25027a2b459ef440aa8831be43701912f25c151f
|
|
| MD5 |
3443e0026777a2c1dab0483efd0f3af3
|
|
| BLAKE2b-256 |
451c995c174d4763910adc93abc5f0caa90d05bd737be227e149e695dd9cd23d
|
File details
Details for the file epistemic_graph-2.2.0-py3-none-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: epistemic_graph-2.2.0-py3-none-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 31.7 MB
- Tags: Python 3, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e1059b04f0dd0170953b7514d43b3354dc3de3c4cc7d57adce4db3b65137fa1
|
|
| MD5 |
01b05a9a32f883b2bf347ca0a0b2b9df
|
|
| BLAKE2b-256 |
f2fbeba11c9dc30110bbc804c16851fd1607776c7bd6dfa53f6ec625b6be71e3
|
File details
Details for the file epistemic_graph-2.2.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: epistemic_graph-2.2.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 31.0 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61b59c441d8ffad38a595004d375ec5991b9ff6b024d57ae18f56f0b656ff953
|
|
| MD5 |
3809d8752f3009d4ff4dd0ea6aa2a8b2
|
|
| BLAKE2b-256 |
19759a5d3b9ac3d0b919496a69cf8a3d3b95c4b581ae931b0db7ce099df80cb3
|