Skip to content

Facts corroborate an identity when the profile cannot - #342

Merged
WaylandYang merged 1 commit into
devfrom
feat/facts-corroborate-an-identity
Sep 5, 2026
Merged

WaylandYang merged 1 commit into
devfrom
feat/facts-corroborate-an-identity

Conversation

@WaylandYang

Copy link
Copy Markdown
Contributor

Closes #331.

resolve_mention decided who a mention was from one signal: the cosine between the mention's chunk vector and each candidate's profile centroid. When that vector cannot separate two people — and after #221 it routinely cannot, because both namesakes were seeded from the same chunk — the code gave up and asked a person. The Review card it then rendered showed the two works_for facts. The code was looking at the answer and handing it to a human.

Now it reads them. The mention's chunk text is threaded down to resolve_mention, and where the profile is inconclusive the facts get a turn.

The evidence only runs one way

Agreement is weak evidence of same. Disagreement is evidence of nothing: someone who works at Acme and moonlights at Zenith has two works_for values and is one person, and two different people can share an employer. So corroborating_candidate only ever answers "which candidate did the text name" — it has no way to express "this candidate is excluded", and a mismatch never demotes anyone or pushes a pair apart.

Three rules keep it from over-reaching:

  • Exactly one candidate may hit. Two hits mean the clue does not separate them either, so the old behaviour stands.
  • Objects the namesakes share are excluded in SQL. Two Zhang Weis at the same holding company make that company the single most likely string to appear in any document about either of them, and the least useful for telling them apart.
  • It can turn a new entity into an attach, never the reverse. SIM_ATTACH and SIM_NEW are untouched, as Two namesakes with identical profiles attach a later mention by candidate order #270 asked; this adds a question asked outside the thresholds, not a change to them.

Objects are picked the way refresh_disambiguators picks them after #299 — ordered by whether the ontology declares a range, then state, then functional — so the disambiguator a person sees and the clue the code uses come from the same judgement.

Where it fires

Both places the profile gives up: the namesake tie #329 added, and the grey zone between SIM_NEW and SIM_ATTACH. Below SIM_NEW it stays out — those candidates do not even earn a review pair, and letting one string pull them in would be bypassing the threshold rather than supplementing it.

Verified

Five database-backed tests in facts_corroborate_an_identity.rs, and two of them exist to stop this feature rather than to prove it:

Text names one department Attaches to that Zhang Wei, no review pair
Text names both Still creates an entity, still files two review pairs
Text names the employer they share Still creates an entity — a shared object is not a clue
Text names neither Unchanged from #329, which is the gate against reading a mismatch as a difference
Grey zone, text names one Attaches, thresholds untouched

The full suite passes against a real database, plus cargo fmt --check, cargo clippy -D warnings and pnpm build.

Not in this cut

The other half of #331 — a person split in two who is never reviewed again, because a best candidate below SIM_NEW files no pair at all. That wants a queue that does not exist yet ("same name, same type, never reviewed"), and it is a different change from this one.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: WaylandYang <wayland0916@gmail.com>
@WaylandYang
WaylandYang merged commit 5e51d3c into dev Sep 5, 2026
@WaylandYang
WaylandYang deleted the feat/facts-corroborate-an-identity branch September 5, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The facts that would settle a namesake take no part in settling it

1 participant