# Why the machine proposes a merge and a person disposes

A **Person** is the canonical human, an **Identity** is one address on one channel, and a Person may hold many. That split is what lets a WhatsApp message, an email thread and an inbound call land on the same record without any of them being the record. Merging two Persons stays a human decision, because it is the least reversible operation a relationship store has.

- **Status:** Available
- **Audience:** both
- **In the app:** #/relationships, #/timeline
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/research/one-person-many-channels/

## Three records rather than one

**Person** — The human. Created once, kept whatever changes around them.
**Identity** — One address on one channel, keyed by `value_key(kind, value)` and attached with `people.add_identity`. An email address, a phone number, a messaging handle.
**Company** — The organisation. Several people attach to one, and a person can move between them.

The temptation is to skip the middle record and put the email address on the person. It works until the second channel arrives, at which point either the phone number becomes a second person or one channel becomes the *real* one and the others become attributes of it. Both outcomes make the history unreadable, which is the only thing a relationship record is for.

## What an inbound message actually does

The shape is the same everywhere, which is what makes cross-channel continuity possible at all: inbound event, workspace resolution, person resolution, canonical conversation, then a reply governed by the same autonomy rule as any other channel.

- **Email** arrives into provider-shaped `tenant_*` tables and is bridged into canonical `threads`, `messages` and `contacts`. The engine never reads the provider tables, so adding a provider changes nothing downstream and a bug in one adapter cannot corrupt a workspace's history.
- **Phone** resolves the caller by number. A contact created by lead capture carries `phone_key` from the start, and a number matching two rows resolves to the oldest so the same call resolves the same way twice.
- **WhatsApp** resolves the handle to a person and continues the same conversation, under provider session-window rules that Connect exposes rather than simulates.

## What follows the person, not the conversation

Once identity is a first-class record, several things stop being per-channel settings and become properties of a relationship.

| Thing | Where it lives | Consequence |
|---|---|---|
| A block | A `connect_memory` row tagged `block:<channel>` in `tags` | It holds across channels and across future conversations, because `directives()` reads only the tag list |
| Memory | Four tiers: workspace → channel → endpoint → contact | The narrowest applicable tier wins, the same hierarchy autonomy uses |
| Autonomy | Scopes: contact, endpoint, channel, workspace | One customer can need approval while everything else runs |
| History | Customer 360 and the timeline | One person's whole history, every channel, in one view |
| Follow-ups | Any channel, plus `any` and `task` | A commitment belongs to the person, not to the thread it was made on |

## Merging is proposed by the machine and decided by a person

`duplicates` proposes candidates. `merge_people` executes one, and it is deliberately a human decision. When it runs it preserves identities, stages, follow-ups, deals, demos, cases and onboarding **from both sides** — a merge that quietly drops the losing record's open case is worse than no merge.

The reason for the human is reversibility. Almost everything else in a relationship store can be undone by editing a field. A merge combines two histories, and separating them afterwards means deciding which follow-up and which deal belonged to which side — a judgement nobody can make from the merged record.

> **Note** One `relationship_console` answers a relationship for both audiences over one implementation; the customer surface only renames things, so a customer's *people* are the operator's *relationships*. There is no second resolution path to disagree with the first.

## Where a shared identity breaks the model

- A general enquiries address or a shop counter phone belongs to an organisation, not a person. Treating it as a person's identity merges strangers into one record.
- A person who changes employer keeps their mobile and loses their work address, which now reaches somebody else. The identity is stale rather than wrong, and nothing detects that automatically.
- Names are the other leak. `identity.PROTECTED_MARKERS` with `name_rejected`, `clean_name` and `scrub_names` guard every door a name passes through — summariser output, lead capture, person upsert, memory — and every door it is read back through. A form of address is never a name, and `fact_rejected` refuses a name-keyed fact that is a suffix, a pronoun or *the caller*.
- Resolution accuracy is not measured here in either direction: UNKNOWN. What is countable is how many contacts carry a key per channel, which is the first thing to look at when continuity is failing.

## Questions

### Why keep a separate Identity record instead of columns for email and phone?

Because people have more than one of each, and the count changes. Columns force a primary, and a primary forces every later channel to be secondary — which is exactly backwards when the customer's next message arrives on the channel you called secondary.

### If two people share a phone number, whose call is it?

Deterministically the older record, so the resolution is stable and reviewable, and then a duplicate proposal if the two look like one person. A stable wrong answer can be corrected; an unstable one cannot even be described.

### Does a block on WhatsApp stop email as well?

It depends on the tag. The directive is `block:<channel>`, so blocking a channel blocks that channel — but because the row lives against the person rather than the conversation, it survives the thread ending and applies to future conversations too.

## Related

- [Relationships in Connect](https://connectbyjbrh.com/docs/relationships/)
- [Relationship memory versus chat history](https://connectbyjbrh.com/research/relationship-memory/)
- [Telling a new prospect from an existing customer](https://connectbyjbrh.com/research/prospect-identity-resolution/)
- [WhatsApp in Connect](https://connectbyjbrh.com/docs/whatsapp/)
- [Memory in Connect](https://connectbyjbrh.com/docs/memory/)

## What this page is based on

- `docs-source/sources/CHANNELS.md` §5 — Person, Identity, Company and the relationship console
- `docs-source/sources/GENERAL.md` §3 and §6 — canonical records, memory tiers and the block directive
- `docs-source/sources/PHONE.md` §10 — caller identification and the name guards
- `docs-source/sources/CHANNELS.md` §2 — WhatsApp resolution and provider limits
