A tool that looks for you on data broker sites has two halves. Fetching the pages is the boring one. The interesting one is what happens when a page comes back with a person on it and you have to decide whether that person is you.
Every result is a claim. Getting the claim wrong in one direction is much worse than getting it wrong in the other, and once you accept that, most of the design writes itself.
The asymmetry
A miss means you did not hear about a listing that exists. Annoying, and the next scan may catch it.
A false positive means the tool tells you that a stranger's age, address history and relatives are yours. That is worse. You might act on it. You might file a removal request against someone else's record. You might sit with a piece of information about your own life that is simply not true.
So the scorer is tuned to prefer the miss. Not as a slogan, as actual thresholds.
Two name metrics, on purpose
Name similarity is the first gate, and it uses two different string metrics depending on which part of the name it is looking at.
First names get Jaro-Winkler. Jaro-Winkler is plain Jaro similarity plus a bonus for a shared prefix, up to four characters. That bonus is the right behaviour for given names, where shortenings and variants tend to agree at the front and drift at the back.
Surnames get plain Jaro, no prefix bonus. This is the deliberate part. "Doe" and "Dorsey" share a start. On Jaro-Winkler that shared start buys real score, which is exactly wrong when the surname is the strongest identifying token in the name. Dropping the prefix boost makes a common beginning stop counting for anything special.
Same idea, opposite tuning, because the two fields fail in opposite ways.
Combine with min, not average
Once you have a first-name score and a last-name score, the temptation is to average them.
Don't. Averaging lets a perfect first name pay for a wrong surname. "John Smith" against "John Smythe" averages out to something respectable while being, in all likelihood, a different person.
Take the minimum instead:
similarity = min( jaroWinkler(first), jaro(last) )
Now the name is only as strong as its weakest half. A middle initial on one side and not the other still scores well, since the comparison is first token against first token and last token against last token. A near-miss surname cannot be rescued.
Hard gates before soft scores
Some things are not evidence to be weighed. They are disqualifiers.
Name similarity below 0.85 ends it. Age off by more than two years ends it. Neither of those goes into a weighted sum where a strong location match might drag it back over the line, because no amount of "lives in the right city" makes a different person into you.
Only records that survive both gates get scored at all.
Then, and only then, weigh
The confidence number is a weighted blend:
confidence = 0.5 × name + 0.25 × age + 0.25 × location
Name carries half. Age and location split the rest.
Two details in there are worth calling out.
Age missing on either side scores 0.4, not 0 and not 1. Absent data is not evidence of a match and it is not evidence against one, so it should pull toward the middle rather than push either way.
Location is graded rather than binary. Current city and state is full credit. A city and state that appear in the record's past addresses is most of the credit, because people move and brokers keep history. Right state, wrong city is partial. Nothing in common is nothing.
And after all of that, name alone still is not enough. A record has to agree on age or location as well, no matter how perfectly the name matches, because there are a lot of people and not that many names.
Why write it out like this
None of this is sophisticated. It is Jaro similarity, a couple of thresholds, and a weighted sum.
The reason to be explicit is that every one of those constants encodes a judgement about how wrong you are willing to be, and in which direction. A threshold at 0.85 rather than 0.75 is a decision to show fewer results and be more sure about them. Scoring unknown age at 0.4 is a decision about what silence means.
Bury those in a model somewhere and nobody can audit them, including you. Written down as numbers with reasons attached, every result the tool returns can explain itself: name similarity 0.94, age within one year, location match current. If that reasoning looks wrong, you can go change the number that caused it.