M
Made Scientific
Commercial AI-OS · built with BioCreative

CRM Mapping — Salesforce & HubSpot → MADE-ID → Accounts & Contacts

Both CRMs are one-way inbound: nine master objects arrive, and none of it means anything to the engine until it resolves to a MADE-ID. This page reads left to right as what arrives → how it resolves → what it becomes — the nine objects and which of their fields survive the sync, the account and contact identity ladders plus the human gate they pass through, and finally the two kinds of value the ID unlocks: a contact's lifecycle status (MQL / SQL) and an account's science (modality, cell type, indication, phase). Live-read from Transfer (jrfcfayphcmaxsixxupu) and Reporting (xyopyttkhoxvnyeyijzb). Click any node to jump to its full reference card.

Live-verified 2026-07-29 — object counts, identity-map coverage, lifecycle distributions and crosswalk contents are live SELECTs on both databases, not doc claims. Updated later the same day: Salesforce contact identity went 9.3% → 97.7% (K4 closed), HubSpot accounts got their first 822 proposals (K5), and the ceiling moved from matching to review throughput.
Live & running Built · partially filled or stale Gap · built but not run, or blocking Designed, not built Free — SQL, deterministic Paid — Claude adjudication
Swimlane P · What arrives

Nine master objects, two systems, one direction

Everything lands first on the Reporting DB — Made's CRM landing zone — then a second daily hop copies a deliberately selective subset into Transfer, where the engine reads. The two starred objects carry the payload this page is about: P3 holds the science, P8 holds the contact lifecycle. Nothing here ever writes back to Salesforce or HubSpot.
Swimlane R · Account identity

Resolving a CRM account to one MADE-ID

The disciplined ladder, and the rule that governs it: exact domain → exact normalized name → trigram candidates plus mandatory LLM adjudication. Fuzzy similarity alone is never a match decision, and nothing the agents propose applies itself. er_identity_map holds 9,261 confirmed links across four systems — bc_hub 3,302 · lifesci 2,661 · salesforce 1,917 · hubspot 1,381.
Swimlane K · Contact identity

Resolving a CRM contact to one contact MADE-ID

The same idea for people. er_contact_identity_map reads as 112,576 rows — but 102,529 of those are self-links (the engine's own leads pointing at themselves), so 10,047 are genuine cross-system matches, up from 5,886 on 2026-07-29. The jump did not come from building the richer matcher this page previously called for: Reporting's persons dimension already held both CRM ids on one row for 16,886 people, and nobody had synced it. The crosswalk existed upstream the whole time.

Exhibit A — one real contact, traced end to end

A live row, read 2026-07-29. Every value below comes from the database; none is illustrative. Read it as the answer to “what does MADE-ID actually do for me?” — two orphan CRM facts become a person with a status, sitting at an account with a science profile.

CRM
HubSpot Contact · arrives 06:15 UTCjonathan.terrett@crisprtx.com, HubSpot id 114483217552, lifecycle_stage salesqualifiedlead. On its own this row knows nothing about Made's account universe.
ID · P
Contact resolution — email_exactThe email matches a known person, so the row binds to MADE-CTC-11448321-jonathan-terrett. Until 2026-07-29 this was the only rung available — had the email differed by one character, no link would have existed. A contact like this one would now also be caught by the reporting_person_bridge rung (K3), which needs no email at all.
ID · A
Account resolution — er_identity_mapThe person's company resolves to MADE-19B654F5-crispr-therapeutics-agCRISPR Therapeutics AG. One canonical account that the Salesforce, HubSpot and Hub records now all agree on.
VAL 1
Contact status landsBecause the person ID exists, the HubSpot stage projects onto the engine's own row: leads.hs_lifecycle_stage = 'salesqualifiedlead', alongside job title Head Of Research. That is what turns “show me every SQL at a CGT account” into a query instead of a CRM export.
VAL 2
Account science landsThe same account ID pulls Salesforce's opportunity science: modality Stem Cell: Pluripotent, cell type Stem Cells: Induced pluripotent stem cells (iPSCs), phase Develop/Non-Clinical, service category Consultancy — from one opportunity line.
VAL 3
The gold sheet renders it, with provenancemodality_canonical = 'Stem Cell: Pluripotent' with modality_base_source = 'sfdc' (indigo dot), cell_type_base_source = 'sfdc' — but clinical_stage_value = 'Commercial' and indication_value = 'oncology_solid_tumor' both resolve to 'pipeline' (amber dot), because Salesforce left those two blank.

An honest wrinkle this single account exposes. Salesforce holds two disagreeing science answers here: the opportunity line says Stem Cell: Pluripotent / iPSC, while the account picklist account_modalities says T Cell - CAR-T. v_account_sfdc_science surfaces both, and the gold sheet resolves to the opportunity value — because deal-line science describes the work actually quoted. That precedence is a real decision, correctly made, but it is documented nowhere outside this page.

Swimlane V · What the ID unlocks

The two kinds of value mapped onto accounts and contacts

These are different in kind and must never be conflated. Contact status (V1–V3) is a commercial state that HubSpot owns and Salesforce expresses on a different object entirely. Account science (V4–V6) is a scientific fact that Salesforce owns and that the system treats as source of truth — normalized into one vocabulary, then rendered with a provenance dot proving where each field really came from.

Exhibit B — how far the CRM payload actually travels

Two separate journeys, each measured against its own base and labelled as such. First: of the 17,630 HubSpot contacts that arrive carrying a lifecycle stage, how many end up as a status on an engine person? Second: of the 4,595 accounts, how many get a science field whose true source is Salesforce? Both answer the same underlying question — the payload only travels as far as the identity link carries it.

HubSpot contacts arriving — 100% carry a lifecycle_stage: lead 16,680 · MQL 453 · SQL 275 · opportunity 138 · other 45 · customer 25 · subscriber 14.
17,630
…resolved to a company — 12,254 by email domain. The other 5,376 hold a stage that belongs to no account.
12,254
…and linked to an engine person — 5,446 via email_exact. This one number caps everything downstream of it.
5,446
…so this many engine persons carry a CRM stage — 5,577 of 102,529. Of those, 38 are MQL and 64 are SQL — the entire marketing-qualified population the engine can currently see, against 453 + 275 sitting in HubSpot.
5,577
Second journey — account science, measured against the 4,595 accounts
Accounts with any Salesforce science at all v_account_sfdc_science returns a row for 1,872 (40.7%): those with at least one MADE-ID-linked SFDC account or opportunity.
1,872
…where the gold sheet's cell type resolves to SFDC — 144 accounts. Another 2,174 show a cell type from a weaker source, so the field looks full while only 6% of it is rep-curated truth.
144
…where modality resolves to SFDC — 87 accounts, against 107 from pipeline and 9 from registry. Salesforce is the highest-trust source and also the thinnest.
87
…where indication resolves to SFDC — 45 accounts, out of 1,960 showing an indication from somewhere. The starkest ratio on the page.
45
The one thing to understand about this map

Salesforce is the designated source of truth, and it is the least-connected source.

The architecture is right. Salesforce picklists are GlobalData-derived, so they should outrank AI inference — and the gold sheet correctly resolves SFDC → native → AI with a visible provenance dot on every field. The vocabulary crosswalk exists precisely so that a Salesforce label and a pipeline label collapse into one clean value instead of two competing ones on the same screen.

What limits it is reach, in two places. Accounts: 1,922 of 3,060 Salesforce accounts are MADE-ID-linked, and the science only travels for those — which is why indication resolves to SFDC for 45 accounts while showing some value for 1,960. Contacts: the person-level bridge has exactly one rung, email_exact, so 440 of 4,711 Salesforce contacts carry a person ID even though 3,233 of them already sit at a resolved account.

So the highest-leverage work here is not another field or another source. It is extending the account ladder's discipline down to contacts — name plus company, then trigram plus adjudication, propose-only through the same human gate — and seeding the crosswalk for the five science fields it does not yet cover. Both are joins against data already in the building.

Full reference

Every object, ladder rung and mapped field — named, counted, located

Each card names the actual table, view, Postgres function or cron job, with live counts read on 2026-07-29. Where a number contradicts an existing internal doc, the card says so and gives both.

Swimlane P — What arrives from Salesforce & HubSpot
Swimlane R — Account identity resolution
Swimlane K — Contact identity resolution
Swimlane V — Values mapped onto accounts & contacts