# Resolving a sender to a person

An address is an **identity**: one address on one channel. An identity resolves to a **person**, and a person may belong to a **company**. An unknown sender is resolved into a new person rather than left as an anonymous string, which is what lets their second message, their phone call and their WhatsApp reply all arrive at the same history.

- **Status:** Available
- **Audience:** both
- **Channels:** email
- **In the app:** #/inbox, #/relationships
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/email/contact-resolution/

## Three records, not one

**Identity** — One address on one channel. A person's work address and their mobile number are two identities.
**Person** — The human. Everything a workspace remembers about someone hangs here, not on an address.
**Company** — The organisation, where one applies. A person can be attached to one without the company being a customer.

Keeping them separate is what makes cross-channel continuity possible at all. If memory, history and relationship state lived on the address, the same customer writing from their phone would be a stranger. Because they live on the person, adding an identity is an ordinary act rather than a merge — [One person across phone, email and WhatsApp](/research/one-person-many-channels/) is the longer version of that argument.

## What happens on a first message

1. The bridge canonicalises the message and produces a contact for the sender.
   - Result: There is now a canonical record of who wrote, not just a header string in a provider table.
2. The address is matched against existing identities in the workspace.
   - Result: A match attaches the message to an existing person, with their whole history and everything the workspace remembers about them.
3. With no match, a new person is created and the address becomes their first identity.
   - Result: The next message from that address lands on this person rather than creating another one.
4. Company attachment follows from what is known, not from a guess about the domain alone.
   - Result: A person can exist without a company, and that is a normal state rather than an incomplete record.

> **Note** Resolution runs after canonicalisation and does not care which mailbox the message arrived through. Two of your addresses receiving from the same person produce one person, not two.

## Where resolution is genuinely hard

| Case | What Connect can do | What it will not do |
|---|---|---|
| The same human, a second address | Attach the new address as another identity on that person, once it is known to be them | Assume two addresses are one person because the names look similar |
| A shared mailbox writing on behalf of several people | Hold it as an identity like any other | Invent people who have not written |
| A person who has changed employer | Keep the person and their history; the company attachment is a separate fact | Silently rewrite history to the new company |
| Two records that turn out to be one person | Merge them — `relationship_console` owns duplicate handling | Merge on a guess |
| A prospect whose address is unknown | Work from evidence found in public sources | Guess an address from a pattern — this is a documented refusal, see [Evidence-first prospecting without guessed emails](/research/evidence-first-prospecting/) |

The last row is the one that shows the principle most clearly. Guessing `firstname.lastname@` at a company domain would raise contactability numbers and produce mail to addresses nobody verified. It is refused, and the refusal is a capability rather than an omission.

## What resolution unlocks

- **Customer 360** — one person's whole history, every channel, in one view, which is only assemblable because the history hangs off the person.
- **Memory at the contact tier** — the narrowest of the four tiers, so what you tell Connect about one person survives beyond the thread that prompted it.
- **Autonomy at the contact scope** — the narrowest scope wins, so one account can always ask before sending while the mailbox runs autonomously.
- **Blocking that holds** — a `connect_memory` row tagged `block:<channel>` is against the contact, which is why it survives across channels and future conversations.
- **Compliance** — suppression, unsubscribe, complaints and do-not-contact are checked in one place before any outreach, and they are about the person rather than about one message.

The Assistant can read and change a great deal of this — it has tools for recall, for `customer_360` and for editing memory — but its rights are deliberately narrower than a person's. It cannot clear a do-not-contact entry. [Do not contact](/docs/email/dnc/) explains why that particular door is closed to it.

## Questions

### A customer wrote from a personal address. Will Connect know it is them?

Not from the address alone, and it will not assume. A new address becomes a new identity and, absent a match, a new person; attaching it to the existing person is something that happens once it is known to be them, and the two records can be merged.

### Does everyone who emails become a contact record?

Yes — a sender is resolved into a person rather than left as a string, which is what makes their next message continue rather than restart. That is also why duplicate handling exists in `relationship_console`.

### Where does the company on a person come from?

From what is actually known about them, held as a company record in its own right. A person without a company is an ordinary state, and a domain on its own is not treated as proof of employment.

## Related

- [Relationships in Connect](https://connectbyjbrh.com/docs/relationships/)
- [Conversation threads](https://connectbyjbrh.com/docs/email/threads/)
- [From a provider message to a canonical one](https://connectbyjbrh.com/docs/email/message-canonicalisation/)
- [Do not contact](https://connectbyjbrh.com/docs/email/dnc/)
- [Telling a new prospect from an existing customer](https://connectbyjbrh.com/research/prospect-identity-resolution/)

## What this page is based on

- Connect source pack — canonical `contacts`, identity and people modules (`docs-source/sources/GENERAL.md` §3–4)
- Connect source pack — memory tiers, autonomy scopes and the tagged block row (`docs-source/sources/GENERAL.md` §5–6)
- Connect capability registry (`docs-source/facts.py`) — `cross_channel_identity`, `duplicate_merge`, `customer_360`, `no_guessed_email`
