What comes back
Triples, each naming the memory that asserted it
An agent answering from a graph is otherwise presenting an inference as a fact, with nothing to check it against.
Seeded from a real search
A walk starts from the memory objects a normal retrieval ranked, which have already been checked against who is asking. The graph itself needs no vectors, which is the largest recurring cost a product like this can take on and one we simply do not.
Bounded, so it stays fast
Depth and the number of relationships followed from any one thing are both capped, so a query costs the same whether your graph holds a thousand relationships or a billion. The thing that makes graphs slow is one entity everything connects to, and that is skipped by how connected it is rather than discovered halfway through.
{
"triples": [
{
"subject": { "label": "Northwind", "kind": "entity", "grounded": true },
"predicate": "renews",
"object": { "label": "2026-11-30", "kind": "entity", "grounded": false },
"depth": 1,
"asserted_by": "a3f1c2e8-..."
}
],
"stats": { "withheld_for_entitlement": 4, "truncated": false }
}The architecture
One Postgres. No vector service, no graph engine.
This is the part a self-hosting team is actually weighing, so it is worth being specific about.
A plain edge table
Two tables and an index. No extension, so the schema applies to any Postgres you already run, and nothing fails to install on a database that is missing something.
One bill, not three
A memory layer that needs a relational database, a vector service and a graph engine is three services to run, three to secure and three to pay for. The cheapest graph store is the Postgres you are already paying for.
Semantic search stays optional
Ranking is term overlap unless you name an embedding model. There is no default model and nothing to install, so a deployment that configures nothing takes the same code path it always did.
Your own words
Ground it in the nouns your company already has
Upload a vocabulary and extracted things are matched against it, so you can tell which ones you recognise.
What it does
Turtle, N-Triples, or a plain JSON list for a vocabulary that never was RDF. A match records the term’s stable identifier on the thing and marks it grounded, which the graph colours by.
What it is not
It is a lookup, not a reasoner. No axioms are evaluated, cardinality and disjointness are ignored, and nothing is inferred that your records did not say. Uploading an OWL file gets you the terms and not the restrictions.
Connect one source. The graph builds itself.
Relations come out of the condensation that was happening anyway, so there is nothing extra to turn on.