Connect by JBRH Open Connect

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 What this means
Audience
both
In the app
#/prospects, #/relationships
Last verified
Product version
6.3.2

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#

FailureWhat it looks likeWhat reduces it
False negative — an existing relationship treated as newA cold introduction to somebody with an open case; a pitch to a current customerEvery identity resolved, not just the primary email; company-level resolution as well as person-level
False positive — a genuine prospect treated as knownA real opportunity silently never contacted, which nobody notices because nothing happenedMatching 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.