Two people file the same finding six weeks apart. One writes “login endpoint accepts unlimited attempts”, the other “no throttling on the authentication API”. Same problem, zero words in common, and keyword search cannot help you: it is looking for shared text and there isn't any. The connections go unrecorded too. This finding makes that one far more dangerous, and nobody links them, because nobody holds the whole register in their head. Here's how we solve both in one pass at creation time, over findings we've encrypted so thoroughly the database can't read them either.
A register full of near-misses
A duplicate isn't just clutter. It splits the history of one issue across two rows, so remediation work on one is invisible from the other, and your open-findings count is wrong in a way nobody can explain. The fix people reach for, telling everyone to search before filing, fails on exactly the cases that matter: you can't search for a phrasing you didn't think of.
The mirror image of a duplicate is a relation. Take “backups are written to a NAS in the server room, attached to the corporate LAN” and “no policy requirement for offline or immutable copies of recovery media”. One is a technical finding, one is a governance gap, and they share no words at all. Together they are your ransomware recovery plan failing twice over: the copy is reachable from the network that gets encrypted, and nothing in your policy set requires one that isn't. Nobody links them, because the two live in different parts of the register and were probably filed by different people months apart.
So the target is one pass, at creation, that answers two questions. Is this the same finding as something already here? And does it connect to anything already here?
Keyword matching, over hashes
The keyword index finds shared terms such as a hostname, CVE or port using per-organisation hashes. It is useful for exact references but cannot reliably connect two descriptions with different vocabulary. The encrypted-search article explains that index and its trade-offs.
A second index, for meaning
With semantic matching enabled, we also compare mathematical representations of meaning, called embeddings. That can bring “unlimited login attempts” close to “no authentication throttling” even without shared words. Keyword matching remains useful for exact references.
The two indexes serve different purposes. Keywords preserve identifiers from the original text. Semantic comparison uses the enriched narrative where available, so a short note and a long assessment can be compared in a more consistent form.
Embeddings are encrypted under the organisation's key. Creating them uses our platform-managed Mistral account, independently of the generative provider. See where your AI data goes for processing terms and the BYOK setting.
Two agents make the call
Retrieval only produces suspects. The top candidates get decrypted once, then two AI agents run concurrently over that same set, asking different questions:
- Is this the same finding? Sameness is about scope and identity, not similarity of wording. Two unpatched hosts in the same subnet read almost identically and are two findings.
- Is it connected to any of them? Shared root cause, same asset, one issue amplifying another, same trust chain, a remediation dependency. The question is whether the relationship helps explain or treat the findings.
Two jobs, two agents, on purpose. Each is tuned for its own question, and each fails alone: a relations failure still leaves you a duplicate verdict, and a duplicate failure still leaves you the candidates to judge by hand.
Directional links, with the reasoning kept
“Related” on its own is nearly useless, so the vocabulary is small and directional. Each link is stored once and read from both ends, so the reverse phrasing is always derived rather than kept as a second row that can drift.
| On this finding | On the other one | What it says |
|---|---|---|
| Related to | Related to | Worth reading together, with no dependency either way |
| Is part of | Contains | One finding is a piece of a larger one |
| Worsens | Worsened by | One finding makes the other more dangerous or harder to recover from |
| Depends on | Enables | Fixing one is a prerequisite for fixing the other |
- Related to / Related to from the other sideWorth reading together, with no dependency either way
- Is part of / Contains from the other sideOne finding is a piece of a larger one
- Worsens / Worsened by from the other sideOne finding makes the other more dangerous or harder to recover from
- Depends on / Enables from the other sideFixing one is a prerequisite for fixing the other
Suggestions arrive on the review step as pre-ticked checkboxes, each with the model's one-line reason for the link. Review each suggestion before saving. Similar language is not enough: check the affected systems, scope and proposed relationship. Clear any link that the evidence does not support. When you accept, the reasoning is saved with the link, so six months later it explains itself instead of sitting there as an unexplained arrow. Bulk imports get the same treatment per row.
For the record, the pair from the top of this article lands as “worsens”: the LAN-attached backup target worsens the missing offline-media policy, and reads as “worsened by” from the policy gap's side.
