Entity Resolution for OSINT, One Node per Real Actor

Pull-quote: “A knowledge graph has one invariant worth defending: one node, one real-world actor. Everything useful about the graph is downstream of that.”
Why this matters
Open sources do not agree on names. The same official appears under three transliterations, a nickname, a former title, and a misspelling, sometimes within a single week of reporting. The same company surfaces as a legal name, a trading name, an abbreviation, and a subsidiary. Feed those mentions into a graph without resolution and you get a diagram that looks like intelligence: thousands of nodes, dense edges, impressive at a distance. Query it and it falls apart, because the actor you are asking about is scattered across nine nodes that do not know they are the same person. In a layered analytical stack, the knowledge graph of actors and connections sits directly above monitoring, and entity resolution is what makes that layer real rather than decorative.
From mentions to actors
raw mentions resolution graph
──────────── ────────── ─────
"A. Karimov" ──► candidate generation ──► ● one actor node
"Karimov, Anvar" (names, aliases, │ aliases kept
"Анвар Каримов" context blocking) │ sources kept
"the minister" │ │ merge evidence
▼ │ kept
match evidence ──► edges to other
(attributes, co- resolved actors
occurrence, time)
The pipeline shape is standard; the discipline is in what gets kept. Every merge decision carries its evidence and its sources. The aliases are not discarded after resolution, they become part of the node, so tomorrow’s mention in a fourth script has something to match against. And because merges are recorded rather than silently applied, a wrong merge can be found and unwound instead of quietly poisoning every query that ever touched the node.
Context does most of the matching work that names cannot. Two mentions sharing a name is weak evidence; two mentions sharing a name, a role, a set of associates, and a window of activity is strong evidence. That is why resolution runs against the graph rather than against a name list: the connections already resolved become the context that decides the next case.
The two ways resolution fails
| Failure | What it looks like | What it does downstream |
|---|---|---|
| Under-merge | One actor split across many nodes | Connections invisible, centrality diluted, questions return fragments |
| Over-merge | Two actors fused into one node | False connections asserted with confidence, trust destroyed retroactively |
The failures are not symmetric. Under-merging hides truth and costs recall. Over-merging manufactures falsehood: it takes two people who share a common name and welds their networks together, and every multi-hop query that crosses the welded node inherits the error. This asymmetry sets the policy: merge on evidence, not on string similarity alone, and record enough provenance that any merge can be interrogated later. When in doubt, leave nodes apart and let accumulating evidence make the case.
Why multi-hop analysis depends on this
The questions worth asking a graph are multi-hop: which actors connect this company to that ministry, what paths run between two organizations, who recurs across these events. Every hop compounds the resolution quality. A path of three hops across a graph with a merge error in the middle is not analysis. It is fiction with good graph aesthetics. Resolution with provenance is what makes multi-hop answers mean something, which is why it sits so early in the stack: the analysis, prediction, and simulation layers above all inherit whatever the graph gets wrong.
Closing
An OSINT knowledge graph is a claim: these nodes are real actors, and these edges are real connections. Entity resolution is where the claim is earned. Hold the invariant of one node per real-world actor, keep aliases and merge evidence on the node, treat over-merging as the expensive failure, and the graph becomes what it should be: a queryable model of who is involved and how, with an audit trail from every node back to the mentions that built it.
