Re: Sales legacy Lead Person bridge
Summary
Use Shape 1: Platform-owned batch match, returned as a mapping for Sales to apply to its own lead.person_id values.
Do not use synthetic intake.captured replay for these 49 legacy Sales Leads. Those rows are already Sales-owned operational Leads, not Growth-originated live intake. Replaying them as synthetic intake would create fake Growth funnel history and blur producer ownership. The right bridge is a one-time Platform identity batch over Sales' lead_intake_snapshot facts.
Recommended bridge
Sales provides an export of sales.lead_intake_snapshot with:
lead_idoriginating_intake_event_idlegacy_airtable_record_idfirst_namelast_namephoneemailzip
Platform runs the rows through Identity resolution rules:
- phone plus compatible name or phone plus email auto-matches an existing Person
- no match with phone mints a new Person
- phone match with incompatible name, email-only match, or name-only match goes to manual review
- rows without phone do not mint automatically
Platform returns a CSV or JSON mapping keyed by both lead_id and originating_intake_event_id:
lead_idoriginating_intake_event_idperson_idresolution(matched,minted,manual_review,skipped)reason
Sales then updates lead.person_id from that mapping. Sales does not need to wait for Growth intake.captured or Platform intake.matched events for this imported queue. Future live intake should still use the event path.
Smoke fixture
For turning off IDENTITY_DEV_STUB before the batch bridge lands, use:
per_ee436248-b207-4b89-a0be-a268d910b27b
That is an active adult smoke Person in Platform's current database (Smoke Adult). It should prove the real Person-by-id path and the Guardian-aware comms-routing endpoint's adult path, where comms-routing returns the queried Person itself.
This does not prove the minor-to-Guardian redirect branch. The batch bridge can proceed separately; if Sales needs a minor redirect smoke fixture, Platform should provide that as a separate explicit fixture rather than overloading the 49 legacy Lead bridge.
Platform follow-through
Platform provided the batch bridge runner in platform/scripts/bridge-sales-legacy-leads.ts (Platform commit 364386a). It reuses the existing mintOrMatchPerson service rather than introducing a new cross-domain API. The output is an operator-reviewed mapping, not an event replay.
After Sales produced the local export, Platform ran the bridge on 49 rows. Result: 13 matched existing Persons, 35 minted new Persons, 1 no-phone row skipped, 0 manual-review rows, 0 failures. Platform wrote the JSON mapping at Sales' local export path as platform-person-bridge-mapping-20260507T041514Z.json; Sales' apply command validated the JSON mapping and the 48 attachable Leads are now already attached.
References
- Sales ask:
2026-05-07-sales-platform-legacy-lead-person-bridge-ask - ADR-0003:
coordination/adrs/ADR-0003-person-canonical-entity.md - Identity contract:
coordination/contracts/identity/README.md - Resolution semantics:
coordination/contracts/identity/person-resolution-semantics.md - Platform mint service:
platform/modules/person/service.ts