Ask the graph
- Link namesto entity IDs, or ask which one when a name is ambiguous
- Generate SPARQLgrounded on a schema card built from the ontology
- Validateevery term and value against the ontology, before running
- Executeon the graph
- Citeeach row to the assertions and sources behind it
The ontology and its taxonomies
Two kinds of structure, kept apart on purpose. Ontological relationships say how things act on each other: a firm participated in a deal, a fund is managed by a firm, a person held a role at an organisation. Taxonomies are controlled vocabularies you filter and roll up by: stage, sector, geography, deal type, asset class. A thing becomes a class when it carries its own properties or rules (a family office is a kind of investor firm). A value you group by becomes a SKOS concept.
Versioned vocabulary, with a deprecation path
v1.0 had a sector concept called Cleantech. It overlapped two others, so v1.1 deprecates it: the concept keeps its IRI, gets owl:deprecated true and dcterms:isReplacedBy pmv:sector-climate-tech. Loaders migrate records that declare vocabulary v1.0. Records with no version are not migrated silently; the integrity rules flag them instead. The query validator refuses a deprecated concept and names the replacement.
Files: ontology (OWL, Turtle), vocabularies (SKOS), integrity rules (SHACL-SPARQL).
Entity resolution, biased toward precision
Four invented sources (a CRM import, deal documents, a third-party data feed, web profiles) describe the same people with nicknames, initials, transliterations (Mohammed, Muhammad, Mohamed; Chen and Chan), diacritics, swapped name order, firm renames and people who changed firms. Distinct people who share a name, and relatives at the same family office, are planted on purpose as traps.
Blocking keeps candidate pairs small, a logistic model scores each pair, and a merge is refused when a cluster would hold conflicting evidence: two different emails at one firm, or two clearly different given names. That guard stops one "J. Reed" record from chaining Joseph Reed and James Reed into a single person.
One person, several records, every assertion sourced
Score a pair yourself
Edit either record. The trained model scores the pair and shows which signals moved the score.
Integrity rules, run live
Ontology-level rules written as SHACL-SPARQL shapes. Ten violations were planted in the source data: deals with no company, a stage outside the vocabulary, a zero deal size, legacy Cleantech rows, and affiliations that end before they start. Each one should be caught, and nothing else.
The benchmark, with its failures
Query the graph directly
Read-only SPARQL 1.1 against the same store. Prefixes pm:, pmv:, id:, skos:, rdfs: and prov: are declared for you, and the same validator runs first.
What this does not show yet
- Production scale and operations. The graph (about 110,000 quads) is rebuilt in memory on each cold start; a real deployment needs a persistent store, incremental loads from PostgreSQL and orchestration.
- External standards. No FIBO, GICS or NAICS identifiers are used. FIBO alignment is a v2 step, and NAICS codes would be added only after checking each one against the Census source.
- An independent question set. The prompt rules were written while looking at failures on this same benchmark, so the accuracy here is optimistic. The honest measure is a question set your deal team writes.
- Global rate limiting. Limits are per function instance, not shared across instances.
- Query timeouts. The store has no per-query timeout; the function's time limit is the backstop.