# Telling a new prospect from an existing customer

Before anything is written to a prospect, `prospect_identity_resolution` asks whether it is already a relationship. Getting it wrong in one direction sends a cold opening to an existing customer; getting it wrong in the other suppresses a genuine prospect that happens to share an address. Identity is one address on one channel, a person may hold several, and a proposed duplicate is never merged without a person.

- **Status:** Available
- **Audience:** both
- **In the app:** #/prospects, #/relationships
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/research/prospect-identity-resolution/

## The question asked before outreach

Discovery produces organisations and people who match a description. Some of them are already in the workspace — as a customer, as an open support case, as a deal on the pipeline, as somebody who asked not to be contacted. Sending the standard first-contact message to any of those is the single most expensive mistake in outbound, because it is visible to the person best placed to be offended by it.

`prospect_identity_resolution.py` is the stage that stops it. It runs before outreach and independently of the compliance check, which handles a different question — whether writing is permitted — rather than who this is.

## The model it resolves against

****Person**** — The canonical human. One row, however many ways they can be reached.
****Identity**** — One address on one channel — an email address, a phone number, a WhatsApp handle — created by `people.add_identity` and keyed by `value_key(kind, value)`. A person may hold many.
****Company**** — The organisation. Several people attach to one.

Resolution therefore is not string matching against a contacts list. It is asking whether any identity on the candidate resolves to a Person the workspace already has, and separately whether the organisation resolves to a Company. The two can disagree — a new person at an existing customer is genuinely a new person, and should be approached as a colleague of somebody known rather than as a stranger or as a duplicate.

## The two failures, which need different medicine

| Failure | What it looks like | What reduces it |
|---|---|---|
| **False negative** — an existing relationship treated as new | A cold introduction to somebody with an open case; a pitch to a current customer | Every identity resolved, not just the primary email; company-level resolution as well as person-level |
| **False positive** — a genuine prospect treated as known | A real opportunity silently never contacted, which nobody notices because nothing happened | Matching on identities rather than on organisation names; a shared address such as a general enquiries inbox is weak evidence of a person |

The asymmetry matters. A false negative is loud and lands on a customer; a false positive is silent and lands on revenue. A resolver tuned only to avoid embarrassment drifts towards suppressing everything, so both directions have to be kept in view.

## What makes resolution work in practice

- **Identities have to be written at creation.** A contact created by voice lead capture now carries `phone_key` from the start; before that, **23 of 25** contacts on the host had none, so no phone-based resolution could succeed at all. A resolver is only as good as the keys it has to match on.
- **Ties are broken deterministically.** `identify_caller` resolves a number that matches two rows to the **oldest**, so the same call resolves the same way twice rather than depending on row order.
- **Duplicates are proposed, not merged.** `duplicates` suggests; `merge_people` is a human decision, and when a person takes it the merge preserves identities, stages, follow-ups, deals, demos, cases and onboarding from both sides.
- **A block travels with the person, not the channel.** Blocking is a `connect_memory` row tagged `block:<channel>` in `tags`, so it holds across channels and across future conversations rather than living on one thread.

## Where it is still weak

Shared mailboxes and shared phone numbers are the hard case in both directions: a general enquiries address genuinely belongs to an organisation rather than a person, and treating it as a person's identity creates a record that merges strangers. A person changing employer is the mirror problem — the same human, a new organisation, and an old identity that now reaches somebody else entirely.

No accuracy figure for resolution is measured here, in either direction: UNKNOWN. What is countable today is the input — how many contacts carry a key on each channel — which is where the 23-of-25 finding came from and is the first thing to check on a workspace where resolution seems not to be working.

## Questions

### Why not merge duplicates automatically when confidence is high?

Because a merge is the least reversible operation in a relationship store. It combines two histories, and unpicking them afterwards means deciding which follow-up, deal and case belonged to which side. Proposing costs a click; merging wrongly costs a record nobody trusts again.

### What happens to a prospect that turns out to be an existing customer?

It stops being a prospect. The research is not wasted — it attaches to the relationship you already have — but the outbound sequence does not run, because the correct next action for a customer is never a first-contact message.

### Does a shared enquiries address block the whole organisation?

It should not, and that is the reason resolution works on identities rather than on domains. A general address is one identity; a named person at the same organisation is another, and the two are resolved separately.

## Related

- [Relationships in Connect](https://connectbyjbrh.com/docs/relationships/)
- [Why the machine proposes a merge and a person disposes](https://connectbyjbrh.com/research/one-person-many-channels/)
- [Evidence-first prospecting without guessed emails](https://connectbyjbrh.com/research/evidence-first-prospecting/)
- [Prospecting in Connect](https://connectbyjbrh.com/docs/prospects/)
- [Spending research budget where it changes a decision](https://connectbyjbrh.com/research/research-cost-routing/)

## What this page is based on

- `docs-source/sources/CHANNELS.md` §4 — identity resolution and freshness in prospecting
- `docs-source/sources/CHANNELS.md` §5 — Person, Identity, Company and `merge_people`
- `docs-source/sources/PHONE.md` §10 — `phone_key` on lead capture and `identify_caller`
- `docs-source/sources/GENERAL.md` §3 — blocking as a tagged memory row
