Platform · Architecture in depth

The Runtime, in Depth

The payoff: what runs in production is generated from, and stays true to, the knowledge your experts approved, and it scales across your data without a re-architecture.

This page goes under the hood of how verified knowledge runs at scale, the graph engine, the schema language it compiles to, and how it distributes. It is written for technical evaluators, with a short summary above each diagram so the through-line stays clear whether or not you read the diagrams themselves.

Back to Architecture & Standards
On this page
The graph engine

Where Verified Knowledge Runs

Once your knowledge is proved, it runs over your live data in an engine whose structure comes straight from that proved knowledge, not a database schema someone maintains by hand. Built on a distributed, battle-tested foundation, it keeps what runs in production from ever quietly drifting away from the knowledge your experts approved.

System architecture of the OntoTelliect Graph Engine: the BFO-typed core, its storage and messaging tiers, and the wire protocol surface generated from the compiled schema.
The engine end to end. The storage core, the messaging tier and the protocol surface, all three shaped by the schema you compiled, never by a hand-maintained data model.

The OntoTelliect™ Graph Engine

A BFO 2020-typed distributed hypergraph, built on an eleven-year fork of Microsoft Trinity (SIGMOD 2013), the engine Microsoft Research reports running as a server cluster behind the Microsoft Knowledge Graph, also known as Satori. Four layers, read top to bottom: how systems connect, how the knowledge is enforced, how it is represented, and what it runs on. The organizing idea is that your ontology is the type system, so what runs in production cannot drift from what your experts approved.

Access
clients & transport

How your systems talk to the engine — over ordinary network protocols your developers already know, in both directions.

Native TCP/RPC and a gRPC binary tunnel One handler pipeline, either transport The engine can push to clients, not only answer them
How it works

A single symmetric runtime serves both transports through one handler pipeline, so behavior does not diverge between them. The wire protocol surface is not a fixed API. It is generated from whichever OGSL schema you compile, so the protocols an engine exposes are a property of your schema instead of of our product. The reference BFO 2020 schema yields 95 protocols across fifteen categories, 56 of them BFO operations. The rest cover graph-theoretic algorithms, collaborative intelligence, push automation and backpressure. Compile a different schema and the surface changes with it. Server-to-client push is supported through reverse RPC, which is what makes live, streaming execution possible rather than request-response only.

Verification
proof, not assertion

The graph refuses to accept what your knowledge forbids. Consistency is established by proof before data is admitted, never policed by application code afterwards.

Theorem provers sit inside the engine Entailment is decided by refutation The BFO 2020 registry is discharged by the prover
How it works

The ATP substrate is reached through OntoEnact™, backed by z3, cvc5, vampire, and ontoprover. Entailment is decided the rigorous way, by refuting the theory together with the negation of the claim. The graph engine’s own BFO 2020 axiom catalogue (355 entries, one more than the compiler’s 354 because it carries an additional engine-level axiom) is discharged at the level of the whole theory, not by a runtime check per axiom — see the axiom count and what is actually enforced at runtime below.

BFO hypergraph
the type system

Your ontology is the type system. Concepts are the cells and relationships are the edges, so a malformed relationship cannot be stored in the first place.

Cells are ontological kinds; relations are hyperedges Graph traversal follows typed relationships Zero-copy access, no serialization tax
355
BFO 2020 axioms
cataloged

The graph refuses what its type system forbids, and the theorem prover checks the axiom set as a whole. Runtime validators cover the core families — parthood, dependence, disjointness, space and time, and not every axiom individually.

How it works

Roughly 35 entity types with a verb surface growing from 40 toward 80, and about 174 relation-to-field mappings, traversed through LIKQ fan-out search. Accessors read directly from memory by byte pointer, so type safety here costs nothing at runtime.

Storage substrate
in-memory, distributed

Underneath is a mature distributed memory engine, so this is proved knowledge running on infrastructure with a long production lineage, not a research prototype.

Native in-memory with disk persistence and full CRUD Static and dynamic clustering Deterministic routing across nodes
How it works

An eleven-year fork of Microsoft Trinity (SIGMOD 2013), the distributed MemoryCloud lineage behind the Microsoft Knowledge Graph (Satori) — re-typed end to end to BFO 2020 (ISO/IEC 21838-2). Deterministic FNV-1a hash routing, with 256 trunks and 128 GB per node as configurable defaults.
Provenance: Reasonics forked Microsoft’s Graph Engine in 2015 and has re-typed it to BFO ever since: to BFO 2 initially, then to BFO 2020 once ISO/IEC 21838-2 was published in 2021. Source for the engine lineage: Shao, Li, Wang and Xia, “Trinity Graph Engine and its Applications”, IEEE Data Engineering Bulletin, 2017. §6 describes a cluster of Trinity servers serving the Microsoft Knowledge Graph in real time, and notes that it is also known as the Satori knowledge graph. Trinity is a Microsoft Research project instead of a supported Microsoft product. The fork, the BFO typing, and everything above it are ours.

Where this stands today — honest framing

The configuration we ship today is a single node. On one machine it holds 100.7 million BFO-typed cells resident in about 55 GB, serving TCP/RPC and gRPC at the same time, with every protocol its schema declares registered and dispatching. That is a capacity measurement taken from a running engine. It is not a throughput benchmark: we have not run an audited workload against it and do not claim one. The distributed cluster is real, inherited capability with multi-partition fan-out wired, but we would rather tell you what is shipped than what is possible.

How it works

Static and dynamic Trinity clustering is battle-tested in its original lineage and the fan-out path is wired here. Throughput figures quoted internally — such as a heartbeat floor above 5,000 operations per second, are test gates used in our own build, never published benchmarks.

The type system running in production is the ontology your experts approved.

Powered by OntoMotion™
The representation

How the Knowledge Is Represented

Inside the engine, every concept and relationship is a formally typed node, so the graph can only ever represent what your ontology actually allows. It refuses to store what the logic forbids, ruling out whole classes of bad or contradictory data before they can reach the systems that depend on them.

The BFO-typed hypergraph: 35 entity categories and a verb surface that grows from 40 to 80 operations, governed by a 355-axiom BFO 2020 registry.
Why it is a hypergraph, not a table. Relations connect any number of entities at once, and every node and edge carries the BFO category the axioms are written against.

The BFO-Typed Hypergraph

The graph refuses to represent what the standard forbids. Because both the things and the relationships between them are ontologically typed, a contradiction cannot be quietly stored and discovered later. It is rejected as it is written.

Cells, the things

Every entity in the graph is filed under one of four fundamental categories from the standard, so nothing is stored as a loose, untyped record.

Continuant Occurrent Spatial region Temporal region
How it works

The graph root partitions every cell into BFO’s four leaves of Entity. Each cell type carries a BFO IRI and its hyphenated CLIF name, and is read through zero-copy byte-pointer accessors rather than serialized objects, roughly 465 accessors generated from 146 cell definitions.

Relations, the connections

Relationships are first-class entities with their own identity and time, not just pointers between records, so “this was part of that, during that period” is something the graph natively knows.

part of has participant inheres in realizes concretizes occupies region
How it works

Each relation is a hyperedge cell whose endpoints are cell-id lists, stored temporalized as three-place facts indexed by time. Logical properties such as transitivity and antisymmetry are enforced, alongside Allen interval verbs for time and RCC-8 verbs for space. The visible chip “part of” is the plain-English form of the canonical BFO/CLIF relation continuant-part-of.

Asking the graph a question

Queries walk typed relationships instead of joining tables, so a question is expressed the way a domain expert would phrase it: start here, follow this relationship, keep what matches.

StartFrom(cell) .FollowEdge(ContinuantPartOf) .VisitNode(predicate)
How it works

LIKQ fan-out search resolves in-process on a single node, or across nodes through RPC hypergraph-query processors. Zero-copy accessors keep individual cell reads in the sub-microsecond range.

Consistency is proved, never asserted, and here is the honest state of it

Theory-level consistency is discharged by the theorem provers, not claimed by the store. Two layers do two different jobs. The provers settle whether the theory itself is consistent. Generated runtime validators enforce the per-fact constraints as data is written, and they ship in every target language.

How it works

The catalogue runs to around 355 BFO 2020 axioms. Runtime validators are generated into all five SDK languages, covering relation algebra (transitivity, symmetry, antisymmetry, reflexivity, irreflexivity), category disjointness, dependence constraints such as inherence uniqueness and the quality-bearer requirement, mereology, and RCC spatial relations. Theory-level questions still go to the ATP substrate through OntoEnact, because whether a theory admits a model is a different question from whether a fact being written breaks a constraint.

The engine grades its own grounding

You can ask a running engine how well grounded its own ontology is, and it will tell you where it falls short. A substrate report scores seven dimensions: grounding-chain completeness, schema conformance, axiom coverage, relation-property compliance, category conformance, entailment, and ATP consistency. It returns a composite alongside the specific gaps behind each one. How many concepts lack a BFO IRI. How many cell types are ungoverned. Which ancestor chain fails to reach the root universal.

A companion pass proposes repairs for those gaps, and it is deliberately conservative about which it will act on. Deterministic repairs the top-level ontology fully licenses are proposed at confidence 1.0. Anything inferred sits below a threshold and is marked for human review instead of applied. A third class, such as a broken ancestor chain, is reported and never auto-patched, because no amount of confidence makes it safe to guess. Gaps the tool declines are counted and the reasons are retrievable.

This is the same discipline as the prover verdicts. The system is allowed to say it does not know, and a low-confidence suggestion is never quietly promoted into a fact.

A substrate health tile showing scored dimensions with their headline figures and the dimensions needing attention.
The substrate report as a health tile. Dimensions that fall short are surfaced with their own headline number rather than folded into the composite.

A contradiction cannot sit in this graph long enough for anyone to read it.

Powered by OntoMotion™
The schema language

OGSL — the Ontological Graph Schema Language

The graph's structure is written in a schema language that is itself derived from your verified ontology and proved before use, so when the knowledge changes, the structure regenerates instead of drifting, sparing your teams the expensive re-engineering that keeping software current with changing rules normally demands.

The OGSL language surface: eight top-level declarations, 35 entity categories plus relations, nine formula variants and twelve verbs, binding Trinity storage layout to BFO 2020.
What the language actually declares. Storage layout on one side, the BFO binding and the axioms on the other, in a single declaration the compiler can check against the proved theory.

One Proved Schema for the Whole Stack

A schema language that carries meaning alongside structure. Ordinary schemas describe how data is shaped. This one also records which formal concept each structure stands for, which is what lets the storage layer be checked against your ontology instead of merely described by it.

OGSL is a specified language. The engine we forked shipped its own schema language. We replaced it instead of extending it, and wrote OGSL from scratch with ontological grounding as a first-class construct instead of a comment. It carries a published EBNF grammar that has been through real revisions: v0.32.0, then v0.40.0, now v0.50.0.

The v0.50.0 grammar runs to four EBNF documents and roughly 4,900 lines: 145 productions for the core language, 144 for the BFO 2020 extensions, 55 for reactive streams, 30 for transaction logic. Those four map one-to-one onto the four layers described below. Every production in the core grammar is covered by the compiler, and a missing one fails the build.

Core grammar
the storage schema

Describes how data is physically laid out, and stays fully compatible with the underlying storage engine, so nothing is lost in translation.

How it works

Eight top-level declarations over a type system that is 100% compatible with the storage engine’s own schema language, with roughly 125 attribute keys across 26 categories.

BFO 2020 extensions
the ontology layer

Binds each of those structures to a formal category from the standard, so the schema carries meaning instead of only shape.

How it works

35 entity categories plus relations, and 65 canonical CLIF verbs, organized across top-level, mid-level, and domain-level ontology tiers. Deliberately CLIF-only, no OWL or RDF in the schema layer, so nothing enters through a weaker representation.

Reactive streams
runtime bindings

Declares how live data flows through the graph, including what happens when producers outpace consumers.

How it works

Reactive stream bindings with configurable backpressure policies, keyed publish/subscribe channels, and a five-stage pipeline configuration.

Transaction logic Newest layer
operational state

Expresses how state legitimately changes over time, so a process, not just a fact, can be verified.

How it works

Native Bonner–Kifer serial-Horn transaction logic, specified in the v0.50.0 grammar as its own EBNF document and executed by the runtime. Nine formula variants, twelve update verbs, three composition operators. It transpiles down to CLIF, so a transaction program is also a valid Common Logic text and the same provers that check your facts can reason about how your state is allowed to change.

What grounding actually looks like
03.BFO2020.Schema.EnhancedEntities.ogsl

One structure, bound to one formal concept. Read it as: this is the BFO universal entity, here is its identifier in the standard, here are the eight axioms that govern it, here is the formula they reduce to, and here is the cell the engine will actually store.

Nobody writes this by hand, and it is not meant to be written by hand. OGSL is deliberately verbose. It carries the ontological binding, the axiom identifiers, the storage layout and the codegen targets in one place, because a schema that leaves any of those implicit cannot be checked against the ontology.

Verbosity is the cost of being machine-checkable, so a machine pays it. The Graph Engine IDE authors OGSL for you, driven by the visual model and the OGSL design surface. The text stays readable so a person can review, diff and reason about it, which is the half that matters at audit time.

#ontologyspec {
    bfo: {
        category:   Entity;
        iri:        "BFO:0000001";
        clifname:   "entity";
        label:      "Entity";
        definition: "An entity is anything that exists or has existed. The most
                     general BFO 2020 universal, partitioned exhaustively into
                     continuants and occurrents.";
        level:      TLO;
    }
    clif: {
        module:       "universal-declaration";
        axioms:       [nmq-1, mbf-1, uns-1, qaf-1, oap-1, lqn-1, nis-1, bee-1];
        outdiscourse: ["entity", "continuant", "occurrent", "particular",
                       "universal", "instance-of", "exists-at"];
        formulas: [
            "(forall (x) (if (entity x) (or (continuant x) (occurrent x))))"
        ];
    }
    validation: { ontoenact: strict; phase: both; }
    codegen:    { targets: [csharp, cpp, rust, go, java]; }
}

[BFO_IRI: "BFO:0000001",
 BFO_CLIFName: "entity",
 BFO_Label: "Entity",
 BFO_TLO,
 BFO_Universal,
 CLIF_Source: "universal-declaration.cl",
 BFO_AxiomIds: "nmq-1,mbf-1,uns-1,qaf-1,oap-1,lqn-1,nis-1,bee-1",
 GraphNode,
 HyperNode,
 OntoEnact: "strict",
 AxiomValidation: "both",
 GenerateValidator: true,
 Observable,
 CodeGen_Target: "all"]
cell EntityEnhanced {
    // Fixed-width fields first, so the cell packs for zero-copy reads
    [BFO_TemporalParameter]
    DateTime CreatedTimestamp;

    [BFO_TemporalParameter]
    DateTime ModifiedTimestamp;

    bool IsActive;

    // BFO 2020 category, which is what makes type checking possible
    [Index, BFO_Role: "Category"]
    string Category;

    [Index, BFO_Role: "Identifier"]
    string EntityId;
}
Why this matters

Because the binding is written into the schema itself, the theorem provers can check the storage layer against the ontology, and the graph engine, the generated code, and the proof all refer to the same definition. Nothing has to be kept in sync by hand.

Powered by OntoMotion™
Scale

How It Distributes

The engine is designed to run across a cluster, spreading your data out while keeping every result consistent, so the platform grows with your data instead of forcing a re-architecture as you scale. Today's published performance figures are single-machine. The distributed design is built in from the start.

Distributed runtime: one logical MemoryCloud spanning nodes, each running the same modules in the same order, with 95 wire protocols generated from the reference schema.
Same modules, same order, every node. One logical memory space across the cluster, so a query does not care which machine holds the data.

Distributed Runtime and Scale

The same engine runs on a laptop and across a cluster, so an evaluation does not have to be rebuilt to become a deployment. What changes as you grow is the number of machines, never the model of how results are produced.

One engine, four ways to run it
Server
holds data and answers
Proxy
routes without storing
Client
connects and queries
Embedded
runs inside your application
How work is spread across machines
Placement is deterministic
the same entity always lands on the same node, so provenance stays stable and a rerun is reproducible rather than merely similar
Writes fan out across partitions
nodes share nothing, which is what allows capacity to grow by adding machines
Three deployment topologies
Embedded runs the engine inside your own application process. Availability groups give you a fixed roster of nodes. Azure Service Fabric handles dynamic membership, where nodes join and leave while the cluster is running. All three sit on the same memory fabric, so the model of how results are produced does not change between them.
Four replication modes, chosen per deployment
Mirroring copies everything to every replica — highest fault tolerance, capacity capped at the smallest replica. Sharding partitions with no redundancy — capacity is the sum of every node, and losing one loses its shard. Mirrored sharding combines the two and is the usual production answer. Unrestricted distributes by hash and guarantees tolerance once a replica minimum is met. The trade is the ordinary one between capacity and redundancy, made explicit so you choose it and not inherit it.
Known capacity limits
per-node memory and connection limits are configurable, and the shipped defaults are documented instead of left as an unknown
How it works

Routing uses a deterministic FNV-1a hash, so placement is idempotent and provenance-stable. Multi-partition write fan-out replicates across a share-nothing cluster. Static and dynamic cluster modes run over the same MemoryCloud substrate, with 256 trunks, 128 GB per-node capacity and a 1,000-connection client limit as shipped defaults. All three are configurable.

Two channels — worth not confusing
The in-process bus
Decouples components inside a single process only. It never crosses a process boundary.
The wire
Every hop between processes or machines travels the native wire — described in the engine architecture above.

The distinction matters because it determines what is actually distributed and what only looks that way.

What we have and have not measured

The clustering capability is real and inherited from a battle-tested lineage, and the fan-out path is wired, but we have not benchmarked it multi-node ourselves, and we will not present inherited pedigree as our own measurement.

How it works

The shipped configuration is single-node, as noted in the engine architecture above. Throughput figures used internally, on the order of 10,000 to 50,000 events per second with a P99 latency target of 20 ms, are test gates in our own build, not published multi-node benchmarks.

Powered by OntoMotion™
Live execution

Streaming, Full-Duplex Execution

Once verified workflows are running, the engine and your systems hold a symmetric, full-duplex conversation, either side can start work, stream data, or observe decisions as they are made. Long-running processes stay live and auditable rather than fire-and-forget, keeping people and systems in the loop on every decision at the moment it happens, not after the fact.

Symmetric full-duplex streaming over RO-LSP and native gRPC, where either side can initiate, carrying twelve command messages.
Either side can start the conversation. The engine pushes progress as a workflow runs, instead of making the client poll for it.

Watch a Workflow Think

Every decision the engine takes is emitted as it happens, so an operator sees the reasoning unfold instead of polling for a final answer, and the audit trail is the stream itself, never a report reconstructed afterwards.

Either side can start the conversation
Your systems send
Start Trigger Data update State query Cancel Suspend Resume Subscribe
⇆  Execute workflow
both sides talk at once for the length of the run
⇆  Observe patterns
the engine pushes only what you asked to watch
⇆  Stream data
either side can supply data the other needs mid-run
The engine reports
Started Progress Decision Node completed Pattern detected Data request Completed Failed
How it works

Twelve command messages and roughly fifteen event messages over three bidirectional RPCs. Because the connection is symmetric and full-duplex, the engine can request data mid-run and the client can suspend, resume, or cancel a workflow already in flight, including heartbeat and session control.

One definition, two transports

The message shapes are defined once and projected onto both a network protocol and an in-process native interface. Your developers get the same payload either way, and nothing is re-specified by hand for the second surface.

Over the network — gRPC on HTTP/2 In process — native, zero-copy
How it works

A single wire definition carrying decision records, prover dispositions, and audit entries generates protobuf3 for gRPC and repr(C) plain-data structures for the native FFI. The same payload appears on both surfaces — never JSON on either, so there is no serialization tax and no divergence between them. The gRPC surface also carries RO-LSP (Reason-Oriented Language Server Protocol), the interface IDEs and editors connect through.

Not just workflows, the whole reasoning surface

Streaming is not a special case bolted onto workflow execution. A client can watch a proof, a compile, or a live ontology edit unfold the same way.

Watch a proof run Reason incrementally Watch a compile Edit an ontology live Follow a reasoning trace Collaborate in session
How it works

Roughly 22 streaming RPCs across about 46 protocol definitions cover the reasoning suite, which is what makes a live IDE experience, or an agent that reacts as reasoning progresses, possible rather than aspirational.

Either side can open the conversation, over whichever transport you already run.

Powered by OntoMotion™
Founding Partner Program

Want a working session on the architecture? Let’s set one up.

Request a Demo