GLASS BOXExplainable AI
Knowledge Graph
Power Consultancy logo Power Consultancy

The twin itself, live

Every node below is a real entity, every edge a real database row. Nothing on this page is drawn from a cache or a slide.

01 · The vocabulary

The closed schema, parsed live

The ontology is frozen: exactly these classes and relations exist, versioned, changed only as a new logged version. This diagram is not a picture of the schema, it is the schema: fetched at page load from the same ontology.schema.ttl file every engine and every refusal reads. Anything not declared here cannot be silently invented anywhere in the system.

Parsing the ontology…

02 · The digital twin

The live instance graph

The twin is one append-only table of events. Interpreted through the vocabulary above, those rows form this graph, reassembled by a live query on every render. Click any node to open its raw event rows. Click any edge to see the single database row that asserted it.

Deriving the graph live from the events table…

03 · The database, as it is

Two tables. That is the whole schema.

This is not a simplified view of a bigger system. The entire database behind everything on this site is two tables: events, the twin itself, append-only, one fact per row, and prov_log, the audit ledger, one row per question ever asked. Both shown below live, newest first. Click any events row to open that entity's full history.

events the twin: every fact, both clocks, never updated, never deleted
event_identity_idfieldvaluevalid_timetx_time
Fetching the newest rows live…
prov_log the audit ledger: every question, every verb call, permanently
prov_idactorverbquestionasked
Fetching the newest rows live…
The double clock why every row carries two timestamps, drawn from two real facts

Top track: when a fact became true in the world (valid_time). Bottom track: when the twin learned it (tx_time). The risk was real for ten days before the system knew. The due date was corrected without touching history: a second row, a later tx_time, the same valid_time. "What did we know on date X" filters on the bottom track only, which is why history can be reconstructed but never silently rewritten. Click any point for its raw row.

04 · Where the facts come from

Ingested feeds

The twin ingests these source systems as feeds, declared as named individuals in the ontology itself, so the claim of what the system has and has not seen is checkable in the same governed file as everything else. Any system of record maps into the twin the same way: a feed writing append-only events in the closed vocabulary. The vocabulary does not change when the source does.

05 · Under the hood

For the IT team

The anatomy of one event row, fetched live

The entire twin is one table. Every fact, every edge of the graph above, is one row shaped like this, a real row fetched from the database as you opened this section:


Fetching a live row…

Two clocks on every row is what makes time travel provable: valid_time is when a fact became true in the world, tx_time is when the system learned it. "What did we know on date X" filters on tx_time only, so history can be reconstructed but never silently rewritten. A correction is a second row, never an edit.

Why the graph cannot drift from the truth

There is no stored graph to go stale. Every render of this page re-derives nodes and edges from the events table at query time, the same discipline every answer engine follows: derived fields like an approval's idle days are computed from raw status events on demand and are forbidden from existing as stored state. The runtime database role holds SELECT on the events table and nothing else: no INSERT, no UPDATE, no DELETE. Append-only is a database grant, not a code review policy.

The closed vocabulary, enforced, not promised

Questions route against a fixed set of verbs by deterministic rules, no embeddings, so "no match" is a checkable statement. Status vocabularies are closed by SHACL shapes declared in the same ontology file, validated live by pyshacl on demand (the Prove SHACL button below runs it right now). When a question needs a class the ontology does not declare, the system names the missing class and the exact feeds it checked, and refuses. The refusal is parsed from the same file this page renders.