The storage layer

A typed, bi-temporal knowledge graph

hGraph implements semtype’s data model and enforces constraint validation directly in the graph layer. Every change is tracked across two independent time axes, so prior state is always recoverable, never overwritten.

Typed property graph

Most graph databases treat properties as untyped key-value bags. Labels group nodes by role, but the database itself has no opinion about what a node should contain or what shape its data takes. Schema, when it exists, is typically optional and validated at read time rather than enforced at write time.

hGraph takes a different position. Every entity in the graph is typed through semtype’s type system. Entity types define the shape of properties, the links an entity can participate in, and the constraints those values must satisfy. Type checking happens at the graph layer, not in application code: if a property doesn’t conform to its declared type, the write is rejected before it reaches storage.

The graph distinguishes four vertex types: entities, entity-types, property-types, and data-types. Entity types describe the structure of nodes. Property types define individual fields with semantic meaning: not just “a string called name” but a typed property with its own identity and constraints. Data types describe the shape of values: primitives, objects, arrays, and their compositions.

Links are first-class entities, not second-class edges. A link between two entities is itself an entity with its own type, its own properties, and its own temporal history. Links can point to other links (T-junctions), enabling higher-order relationships without special cases.

Bi-temporal versioning

Real-world data has two independent notions of time. When something actually happened or became true in the domain (decision time), and when the system recorded that fact (transaction time). These two axes are independent: you might record today that a customer moved last month, or correct a record that was wrong from the start.

hGraph tracks both axes for every entity. Each change creates a new version along the transaction time axis. Corrections, where you update what was believed to be true at a prior decision time, create new layers rather than overwriting existing ones. The original record is always recoverable. Nothing is deleted; the history is append-only.

This means you can ask questions that a single-timeline database cannot answer: “What did we believe the customer’s address was on March 1st, as of April 15th?” or “When did we first record this entity, and when was the information it represents actually valid?” Temporal overlap conditions constrain traversals to the right slice of history without application-level filtering.

Corrections are new temporal layers, not mutations. When a value changes, the system creates a new version with its own decision time interval and transaction time entry; the previous version remains at its original coordinates. The graph is a complete audit trail by default. Rollback is a query, not an operation: traverse to the prior temporal coordinates and read what was there.

The store abstraction

hGraph separates the graph model from the storage backend through a store interface. The interface defines operations for reading and writing entities, types, and temporal metadata.

The current implementation is backed by PostgreSQL, which holds a privileged role: it is the authoritative source for temporal-to-vertex validity data and serves as the seed backend for every graph read operation. Entity data is stored as JSONB documents with temporal range columns encoding the bi-temporal coordinates. All intervals follow a canonical left-closed, right-open form. Temporal overlap conditions are enforced as exclusion constraints directly in the database, so the storage layer itself prevents conflicting temporal states rather than relying on application-level validation.

The backend-agnostic interface exists because HashQL’s execution model treats storage backends as compilation targets. Different facets of the graph may live in different stores: relational data in PostgreSQL, vector encodings in a dedicated embedding store, with each backend storing the data it is best suited for. The store interface makes this heterogeneity possible without leaking backend details into the query language.

hgres

hGraph is the storage layer at the heart of hgres, a multi-temporal knowledge graph made for use by both people and AI, where queries are typed programs and database systems are compilation targets.

Return home