# Contact Enrichment

<!-- BEGIN GENERATED: guide-map -->
## Guide map

Read only the section needed for the next decision. Line ranges are exact
for this generated runtime target.

| Section | What it covers | Lines |
| --- | --- | --- |
| [Purpose](#purpose) | Scope, ownership, and the central operating question. | 27-31 |
| [Use This When](#use-this-when) | Tasks and conditions that belong in this guide. | 32-36 |
| [Do Not Use This For](#do-not-use-this-for) | Boundaries and the correct routes for excluded work. | 37-46 |
| [Choose A Path](#choose-a-path) | Decision hierarchy for selecting the right capability or provider. | 47-66 |
| [Primary SDK Paths](#primary-sdk-paths) | Operating guidance and contracts for this section. | 67-78 |
| [Supporting References](#supporting-references) | Capability, provider, policy, and runtime guides for this outcome. | 79-89 |
| [Mental Model](#mental-model) | Concepts and state boundaries needed for correct operation. | 90-106 |
| [Preflight](#preflight) | State, authority, inputs, and readiness to verify before execution. | 107-116 |
| [Risk And Side Effects](#risk-and-side-effects) | Effects, approvals, cost, privacy, and retry boundaries. | 117-126 |
| [Canonical Operating Pattern](#canonical-operating-pattern) | The normal end-to-end execution sequence. | 127-139 |
| [Data Contracts](#data-contracts) | Required identities, fields, evidence, handles, and durable shapes. | 140-153 |
| [Verification](#verification) | Evidence required before reporting success. | 154-161 |
| [Troubleshooting](#troubleshooting) | Failure diagnosis and corrective routes. | 162-171 |
| [Related References](#related-references) | Adjacent boundaries and when to cross them. | 172-181 |
<!-- END GENERATED: guide-map -->

## Purpose

Resolve trustworthy identity, role, profile, email, phone, and evidence for
people who are already known.

## Use This When

Use this guide after a person has been identified. Use `contact-search.md` when
the people themselves still need to be discovered.

## Do Not Use This For

| Need | Owning Guide |
| --- | --- |
| Discover people who are not already identified | `contact-search.md` |
| Discover or qualify companies | `company-search.md` |
| Inspect conversations, relationships, or perform LinkedIn actions | `linkedin-outreach.md`, then `linkedin.md` |
| Treat a candidate email or phone as verified | Preserve its actual verification state |
| Stage enriched contacts into outbound | `outbound-campaigns.md` and `safety.md` |

## Choose A Path

1. Preserve the input person and company identity plus the requested fields.
2. Choose the narrowest first path below. Do not run every resolver as a
   waterfall unless the deliverable explicitly requires those fields and the
   owning guide defines that fallback order.
3. Run one or a small sample before scaling provider-backed work, then preserve
   per-field evidence and unresolved values.
4. Never convert an unverified candidate into a verified contact.

| Requested fact | First path | Boundary |
| --- | --- | --- |
| Work email discovery | `enrichment.md` email resolver with every known person and company identity field | Discovery is not validation. Keep unresolved candidates unresolved. |
| Existing email validity or recipient-domain ESP | The dedicated validation or ESP helper in `enrichment.md` | Do not rerun email discovery for a known address. |
| Current profile fields or recent authored posts from a known LinkedIn URL | `enrichment.md` person profile or recent-post resolver | Use artifact-backed execution for large or durable outputs. |
| Phone, address, partial identity, or typed person attributes | The narrow corresponding helper in `enrichment.md` | Preserve job ids, status, confidence, and missing results. |
| Relationship, conversation, connection, or live LinkedIn action state | `linkedin.md` | Those are channel facts, not generic profile enrichment. |
| Explicit public page or a fact no typed resolver owns | `web-research.md` | Preserve source URL and observation time; do not infer identity from name alone. |
| CRM-owned lifecycle, ownership, association, or suppression facts | `crm.md` | CRM is authoritative only for facts stored in that workspace. |

## Primary SDK Paths

<!-- BEGIN GENERATED: primary-sdk-paths -->
| Primary function | Choose it when | Required inputs | Returns | Exact contract |
| --- | --- | --- | --- | --- |
| `vf.enrichment.deanonymize_contacts` | Use partial person and company hints to resolve the likely identity or LinkedIn profile before further enrichment. | `contacts` | `deanonymize_job` | [`enrichment.md`](enrichment.md) · installed SDK: `verbiflow/enrichment.py:771-829` |
| `vf.enrichment.emails` | Use when known people and companies need work-email resolution. | `rows` | `resolver_rows` | [`enrichment.md`](enrichment.md) · installed SDK: `verbiflow/enrichment.py:308-334` |
| `vf.enrichment.person_profiles` | Use when known contacts need canonical profile, role, or optional recent-post fields. | `linkedin_urls` | `resolver_rows_or_artifact_job` | [`enrichment.md`](enrichment.md) · installed SDK: `verbiflow/enrichment.py:437-495` |
| `vf.enrichment.phone_lookup_start` | Use after sufficient person identity is known and phone discovery is explicitly required. | None | `phone_lookup` | [`enrichment.md`](enrichment.md) · installed SDK: `verbiflow/enrichment.py:708-752` |
| `vf.enrichment.validate_emails` | Use to verify supplied email addresses. It validates existing values and does not discover new ones. | `rows` | `email_validation_rows` | [`enrichment.md`](enrichment.md) · installed SDK: `verbiflow/enrichment.py:336-361` |
<!-- END GENERATED: primary-sdk-paths -->

## Supporting References

Open only the child that resolves the next material decision.

| Reference | Use it for | Kind |
| --- | --- | --- |
| [`enrichment.md`](enrichment.md) | Canonical company and person enrichment contracts, identity boundaries, and evidence confidence. | capability |
| [`web.md`](web.md) | Public web search, page extraction, screenshots, Markdown, and browser evidence. | capability |
| [`linkedin.md`](linkedin.md) | LinkedIn reads, search, activity, conversations, messages, connections, and posts. | provider |
| [`parallelism.md`](parallelism.md) | Bounded consolidation, concurrency, retries, deadlines, and no-progress guards. | policy |

## Mental Model

Contact enrichment attaches field-level observations to a known person. Person
identity, current-company relationship, contact-point discovery, and contact-point
verification are different claims. Do not let success in one claim imply success
in another.

| Object | Meaning |
| --- | --- |
| Input identity | The known person plus company and profile hints supplied before enrichment. |
| Resolved person | The canonical person identity supported by stable evidence. |
| Candidate contact point | An email or phone discovered but not necessarily verified. |
| Verified contact point | A candidate carrying the explicit verification result and observation time. |

Not found, ambiguous, unverified, invalid, provider failure, and not requested
must remain distinguishable states.

## Preflight

1. Freeze the input person set and preserve every company/profile identity hint.
2. List the exact requested fields and whether each requires discovery,
   verification, or both.
3. Define person resolution, current-company evidence, field freshness, merge
   precedence, and acceptable verification states.
4. Run one row or a small diverse sample before scaling. Inspect evidence,
   output states, cost, latency, and failure behavior.

## Risk And Side Effects

| Stage | Risk | Rule |
| --- | --- | --- |
| Typed resolution or bounded sample | Read or bounded provider work | Preserve input identity and per-field receipts. |
| Large contact enrichment | Provider work, credits, sensitive contact data, and artifact writes | Bound rows, requested fields, concurrency, deadline, and retention. |
| Merge identity or contact points | False person merge or stale data overwrite | Resolve person and company identity before merging; preserve conflicts. |
| Inspect live relationship or conversation state | Channel-specific provider work | Leave for `linkedin.md` or inbox owners. |
| Stage, message, or send | Customer-visible mutation | Leave for outbound and safety owners. |

## Canonical Operating Pattern

1. Preserve the input person row and requested-field contract.
2. Resolve person identity and current-company relationship before contact-point
   enrichment.
3. Choose the narrowest field owner and test a representative sample.
4. Run bounded discovery and verification, retaining per-field evidence and
   explicit status.
5. Merge only on resolved person identity, preserve conflicts, and never upgrade
   a candidate to verified without a verification result.
6. Calculate field and verification-state coverage and materialize the exact
   enriched artifact.

## Data Contracts

Every output row should preserve:

- original person and company identity plus the source row key;
- canonical person/profile and company identity when resolved;
- each requested value with field-level source, observation time, confidence,
  and resolution or verification state;
- current-company evidence and ambiguity status;
- invalid, unverified, not found, provider failure, and not-requested states
  without fabricated placeholders.

Report coverage separately for discovered and verified email or phone fields.

## Verification

Verify identity, current-company relationship, per-field provenance,
verification state, observation time, and requested-field coverage.

Inspect successful, unresolved, ambiguous, unverified, and invalid rows and
verify the exact final artifact bytes.

## Troubleshooting

| Symptom | Likely Cause | Next Step |
| --- | --- | --- |
| Contact data belongs to another person | Name-only matching or company context was ignored. | Re-resolve person identity using profile, company, and stable provider evidence. |
| Candidate emails appear verified | Discovery and validation states were collapsed. | Restore the actual verification result and downgrade unsupported claims. |
| Current title or company is stale | Profile evidence lacks a current observation or conflicts with another source. | Preserve both observations, resolve recency, and mark ambiguity when unresolved. |
| Coverage looks high but usable contacts are low | Any discovered field was counted as success. | Report requested-field and verification-state coverage separately. |
| Row count changed after enrichment | Provider results replaced the frozen input universe. | Rejoin to the original row key and report unmatched results separately. |

## Related References

| Next Decision | Read |
| --- | --- |
| Discover people first | `contact-search.md` |
| Use canonical contact and identity resolvers | `enrichment.md` |
| Inspect LinkedIn relationship or activity | `linkedin.md` |
| Use CRM-owned lifecycle or association facts | `crm.md` |
| Research an explicit public page | `web-research.md` |
| Transform and publish enriched rows | `row_operations.md` and `artifacts.md` |
