Connect by JBRH Open Connect

Support that remembers the sale

Continuity is an identity problem before it is a memory problem. A Person is the canonical human; an Identity is one address on one channel, and a person may hold many. Once the address on an incoming message resolves to a Person, the sale, the promises, the calls and the open cases arrive with it — which is why the interesting failures are all resolution failures.

Status
Available What this means
Audience
both
Channels
emailphonewhatsapp
In the app
#/relationships, #/timeline, #/inbox
Last verified
Product version
6.3.2

The three records that make continuity work#

Person
The canonical human. Everything else hangs off this: lifecycle stage, deals, demos, follow-ups, cases, onboarding.
Identity
One address on one channel — a mailbox, a number, a WhatsApp handle — keyed by value_key(kind, value). A person who writes from a second address has a second identity, not a second history, once the two are joined.
Company
The organisation. Several people attach to one, which is how a colleague who was never part of the sale still reaches somebody who knows the account.

relationship_console answers one relationship for either audience over one implementation, with the customer surface renaming things: a customer people are the Owner relationships. The views are listing, detail, story — the written relationship summary, with names scrubbed on the way out — and by_handle.

From prospect to client to case#

  1. A prospect is researched and approached. Identity resolution stops an organisation you already deal with being treated as new.

    Result The evidence gathered in research stays on the record rather than being discarded at the point of sale.

  2. The relationship moves through lifecycle stages. move_stage is the action and stages() is the vocabulary.

    Result Stage is a property of the person, so support sees what sales knew.

  3. After the sale, onboarding_action carries the post-sale steps.

    Result The handover is a record rather than a conversation somebody has to remember having.

  4. A problem opens a case — open_case, act_on_case, resolve_case.

    Result The case sits on the same person as the deal that created it, and timeline.py assembles the whole history in one view.

Memory runs underneath all of it at four tiers — workspace, channel, endpoint, contact — resolved narrowest-first. Something recorded about one customer outranks a channel-wide direction, which is exactly the shape support needs: general policy, with exceptions that hold.

What breaks the thread#

SymptomCauseResolution
A long-standing customer is treated as a strangerThey wrote from an address that is not yet an identity on their PersonAdd the identity, or merge the duplicate the system proposes
Two records for one humanTwo identities that were never joinedduplicates proposes; merge_people is a human decision and preserves identities, stages, follow-ups, deals, demos, cases and onboarding from both sides
A phone conversation is missing from the historyThe call resolved to a number that is not an identity on that personAttach the number as an identity; the call record itself is never lost
Support does not know what was promised in the saleThe promise was made in conversation and never became a follow-up or a memoryA commitment needs a record; a transcript is evidence, not a reminder
Nothing from another workspace appearsIsolation working as designed, enforced three times overNothing to fix — continuity is per workspace by construction

The limits worth knowing#

  • Merging is a human decision. Duplicates are proposed, never merged automatically, because an incorrect merge is far harder to undo than a duplicate is to live with.
  • A call leaves a transcript, not a recording. Recording is foundation and is not enabled on the live carrier. For continuity purposes the transcript and summary are usually better — they are searchable — but they are not an audio archive.
  • Continuity does not cross a workspace boundary. Isolation is enforced by the tenant allowlist, the SQLAlchemy workspace kernel and PostgreSQL row-level security. A customer asking why an enquiry addressed to the platform operator is not in their workspace is seeing isolation working.
  • The relationship story scrubs names on the way out. That is deliberate; read the detail view when you need the specifics.

What it costs to keep#

Almost nothing per record. The cost of continuity is paid in query efficiency rather than tokens, and that was worth fixing: the Owner customer list once fetched the user, workspace and entitlement for every membership one at a time, so 1,857 accounts cost 5,574 statements. Three inner joins say the same thing in three. Relationship views are read constantly, and a page that grows its cost with the size of the account is the one that stops being opened.

Questions#

Does support automatically see what sales promised?

It sees what was recorded. A promise that became a follow-up with a reason, a memory against the contact, or a fact in Knowledge travels. A promise made aloud on a call exists in the transcript, which is evidence rather than a prompt — nothing acts on it unless it also became a commitment.

What happens when a customer emails from a personal address?

It arrives as an unrecognised identity and starts as its own thread. If it looks like an existing person, the duplicate proposal appears for somebody to confirm. Once merged, the two histories become one and every follow-up, deal, case and onboarding step from both sides is preserved.

Can I see one customer whole history in one place?

Yes. Customer 360 answers one person across every channel, and timeline.py assembles the chronological view behind it. Both are the same implementation for the Owner and for a customer workspace; only the naming differs.