Merging duplicate people, end to end
A pair is proposed or found, a person reads both records and accepts, and merge_people folds them into one — carrying identities, stages, follow-ups, deals, demos, cases and onboarding across. No provider takes part, nothing is sent, and the customer sees nothing. The only irreversible step is the one a human takes deliberately.
The chain#
- TRIGGER — two records describe one human.
duplicatesproposes the pair with the reason it looks that way, or somebody finds it while searching. - USER / EXTERNAL EVENT — a person opens the pair. Nothing external has happened and nothing external will: this flow never touches a provider.
- AUTH / WORKSPACE RESOLUTION — both records belong to one workspace. The kernel scopes the query and row-level security backs it; there is no cross-workspace merge to attempt.
- INGEST / REQUEST — the request names the record to keep and the record to merge. Missing either is refused with a 422 and a plain message rather than a guess about which was meant.
- CANONICAL RECORD — one Person survives. Every identity from the other re-points to it, so
by_handlesends the next message from any of those addresses to one place. - CLASSIFICATION / RESEARCH / REASONING — detection contributes the reason a pair looked alike. It does not contribute a verdict; two colleagues at one customer look alike too.
- KNOWLEDGE + MEMORY + RULES — memory is held at the contact tier and a block lives as a
block:<channel>tag, so the surviving record's memory is worth reading before Connect answers on that channel again. - AUTONOMY / APPROVAL — no autonomy mode authorises this. A merge is only ever a person's decision, which is why the Assistant's rights stop short of it.
- ACTION / PROVIDER — none. Nothing is sent, no message goes out, and no customer is notified that their records were tidied.
- RESULT — one record, immediately. There is no clean undo: separating the two again means working through the underlying rows by hand.
- RELATIONSHIP / TIMELINE / MEMORY — stages, follow-ups, deals, demos, cases and onboarding are carried from each side; the timeline now assembles both histories in one order, which is why entries appear to arrive all at once.
- AUDIT / USAGE / NEEDS YOU — the decision is recorded with who made it, because 'who joined these two customers, and when' is a question that gets asked months later.
- NEXT — verify the survivor, tidy anything the merge deliberately did not resolve, and treat a wrong merge as manual repair work rather than a second merge.
Stage by stage#
| Stage | What you see | What changes | What can fail |
|---|---|---|---|
| Proposal | A pair, with a reason | Nothing | No proposal for an obvious pair — detection suggests, it does not guarantee |
| Reading both | Two records side by side | Nothing | Reading only one side is how two colleagues get merged |
| Request | A confirmation | Nothing yet | A request naming only one record is refused with a 422 |
| Merge | One record | Identities re-point; seven kinds of record carry across | Accepting the wrong pair — and there is no clean undo |
| After | A longer timeline | Nothing further | Two lifecycle positions and duplicate follow-ups may need tidying by hand |
The tidying is deliberate. A merge preserves rather than resolves, because choosing which of two lifecycle positions survives is a business decision dressed as a data one — what a merge preserves is the itemised list.
Doing it well#
Read the identities on both records first.
Result Complementary addresses — a work address on one, a mobile on the other — are the strongest ordinary evidence that this is one human.
Read the most recent conversation on each.
Result Two records discussing the same order or the same visit are usually one person. Two people discussing different things at one customer are not.
Choose the survivor by what colleagues will search for.
Result Material from each side is kept either way, so the choice is about the name and addresses people will type months from now.
Accept, then verify.
Result Count identities, check the pipeline and the follow-up queue for that person, confirm open cases are still open, and read the recomposed summary.
What this flow deliberately does not do#
- No bulk acceptance. A queue of proposals is for reading. Accepting a list unread is how a workspace loses the ability to tell two customers apart.
- No background merging. Nothing joins records while nobody is watching, at any confidence.
- No notification. The customer is unaffected — except that the next reply is written with the whole relationship in view.
- No deletion. Nothing is dropped to make the survivor tidier; the untidiness afterwards is visible work, which is the point.
Questions#
Can the Assistant run this for me?
No. The Assistant reads relationships, cases, follow-ups and opportunities, and its rights are deliberately narrower than a person's. A merge belongs with clearing a do-not-contact entry: something a person decides with both records in front of them.
What if I merge the wrong pair?
There is no clean undo, so the repair is manual work over the underlying rows. That asymmetry is why an unmerged duplicate — visible and harmless — is preferred to a wrong merge, which is invisible and harmful.
Do the customer's messages move?
Messages and calls live in their own canonical tables and reach a person through identities. Since every identity attaches to the survivor, both histories read on one timeline without anything being rewritten.