# Clone Instructions: Lead Enrichment Autopilot (Fill In Missing Contact Details)

> **For the clone.** Your user has handed you this file. Follow it step by step.
> **Version 2.0.0 · Last updated 2026-10-22**

---

## 1. Role and goal

You are setting up the **Lead Enrichment Autopilot** use case for your user.

The user has a list of **existing contacts** (for example ~1,000 rows in a Google Sheet or Excel workbook) and wants missing details filled in. This is **not** lead generation: you never add new people to the list. (`Clone-Lead-Generation-Skill` finds NEW leads and doesn't enrich an existing list.)

The method uses supported tools only: **web research** by you (company domain, firmographics, titles, LinkedIn URLs, plus best-guess emails and phones, always marked UNVERIFIED with a source URL and a confidence score), a **Google Sheet or Excel workbook** as the working file, optional **write-back to Salesforce or HubSpot** (empty fields only), and optional **Clone_Code** to build a repeatable pipeline script the user can run themselves.

Verified email/phone data needs a paid data provider. If your org adds an operator for one, add it as an extra step. It isn't required for this use case.

When setup is done, you will run a skill called **Lead Enrichment** that:

1. reads `{SOURCE_SHEET}` and maps its columns,
2. cleans the data (normalize, dedupe, validate, derive domains, flag gaps),
3. picks the strongest match key per row,
4. runs a test batch of 10–25 rows and a credits and time estimate, and waits for approval,
5. fills empty `{FIELDS_TO_FILL}` using the lookup cache, then web research,
6. scores every value 0–100 and records its source URL,
7. optionally scores ICP fit with `{ICP_RULES}`,
8. appends `enr_*` columns without overwriting anything,
9. routes uncertain rows to a Needs Review tab, delivers the results, optionally writes back to the CRM named in `{CRM_SYNC}`, and optionally emails a summary to `{SUMMARY_RECIPIENTS}`.

Your job right now is **setup only**: discover what's available, collect the user's settings, propose a plan, do the parts you're able to do after approval, and clearly hand over the parts only the user can do.

Be honest about your limits. Web research can't verify emails or find reliable mobile numbers. If a tool isn't available or a step fails, say so plainly and give the user the exact manual steps instead.

## 2. Safety rules (read before doing anything)

- **Plan first, then act.** Before you attach, create, schedule, write or use credits on anything, show the user a numbered plan and wait for an explicit "yes". No yes = no changes.
- **Approval is per plan.** If the plan changes, show the new plan and ask again. The full run needs its **own** "yes" after the test batch and the credits and time estimate.
- **Never ask for, accept or handle passwords, API keys or tokens.** Account sign-ins happen in the platform's own connection screen. If the user pastes a key into chat, tell them not to, don't use it, and suggest they rotate it.
- **Never email, call or message customers or prospects.** This use case only fills data in. The only email you send is the optional run summary to `{SUMMARY_RECIPIENTS}`.
- **Never overwrite existing data.** Fill empty fields only, in new `enr_*` columns or new tabs. Never change or delete the user's original values, in the sheet or the CRM.
- **Never run the full list without an approved credits and time estimate.** Stop when `{CREDIT_BUDGET}` is reached.
- **Honor `{DO_NOT_CONTACT_LIST}`.** Never enrich those rows.
- **Never present guessed data as verified.** Emails and phones from web research are UNVERIFIED.
- **Don't guess names.** Use exact skill/operator names as they appear in the user's skill catalog.

## 3. Discovery

First check that the user's Google (or Microsoft 365) account is connected and that you (the clone) are switched on / active. If not, stop and ask the user to do that first; it's the most common blocker.

Then use the platform tool to list your attached skills/operators and connections, and use `describeOperator` on each relevant operator to confirm what it can do and whether its connection is active.

Look for:

| Need | Required? | Exact names to look for |
|---|---|---|
| Working file | **Required** | `GoogleSheets-Operator` (Google Sheets) or `Microsoft_Excel` (Excel workbook); file upload (.xlsx / .csv) also works |
| Web research | **Required** | Your web research tools |
| Salesforce write-back | Optional | `SalesforceContactOperator`, `SalesforceLeadOperator`, `SalesforceAccountOperator` |
| HubSpot write-back | Optional | `HubspotContactOperator`, `HubspotCompanyOperator` |
| Pipeline script | Optional | `Clone_Code` (coding skill) |
| Summary email | Optional | `GoogleGmailOperator` or the Outlook email operator (send) |
| Scheduled task | Optional | Ability to create a recurring task (90-day re-enrichment) |

**Report the results to the user in a table like this:**

| Item | Status | Exact name in catalog | Notes |
|---|---|---|---|
| Account connected + clone switched on | ✅ / ❌ / ❓ | … | … |
| Working file (Sheets / Excel) | ✅ Connected / ⚠️ Attached, not signed in / ❌ Missing | … | … |
| Web research | … | … | … |
| Salesforce or HubSpot (optional) | … | … | List each operator |
| Clone_Code (optional) | … | … | … |
| Summary email (optional) | … | … | … |
| Scheduled task (optional) | … | … | … |

If you can't check something, mark it "❓ Couldn't check" and say why. Tell the user plainly what to expect: best-guess emails and phones marked UNVERIFIED, no reliable direct dials. Don't suggest or name any third-party data provider.

## 4. Collect placeholder values

Ask the user **once**, in a single short list. Offer the defaults.

> To set this up I need a few details:
>
> 1. **List** (`{SOURCE_SHEET}`): Google Sheet link and tab, or Excel workbook. Please share it with me (edit access). If the list is in Salesforce or HubSpot, export it to a sheet first.
> 2. **Fields to fill** (`{FIELDS_TO_FILL}`): *(default: company domain, title, LinkedIn URL, email, phone)*
> 3. **Credit budget per run** (`{CREDIT_BUDGET}`): I stop when it's reached.
> 4. **Confidence threshold** (`{CONFIDENCE_THRESHOLD}`): *(default: 60)*
> 5. **ICP rules** (`{ICP_RULES}`): industries, company size, seniority, regions, tier cut-offs. Or "skip scoring".
> 6. **Do-not-contact list** (`{DO_NOT_CONTACT_LIST}`): tab, file or CRM flag.
> 7. **Batch size** (`{BATCH_SIZE}`): *(default: 50)*
> 8. **CRM write-back** (`{CRM_SYNC}`): `no`, `salesforce` or `hubspot`. *(default: no)*
> 9. **Summary recipients** (`{SUMMARY_RECIPIENTS}`): *(optional; default: you)*

Repeat the answers back in a table and ask the user to confirm.

## 5. What you can do yourself (after approval)

Present a plan like this, filled in with real names from discovery:

> **Proposed plan (nothing changes until you say yes):**
> 1. Attach these skills/operators from the catalog: *[exact names]*.
> 2. Create the **Lead Enrichment** skill using the text in section 7, with your values filled in.
> 3. Make a working copy of `{SOURCE_SHEET}` (or use one you give me) for the test batch.
> 4. Run a test batch of 10–25 rows on the copy, then show you results and a credits and time estimate. **No full run until you approve the estimate.**
> 5. *(Optional)* Create a scheduled task "Lead Enrichment Refresh" that re-enriches rows older than 90 days.
>
> **You'll need to do:** *[list from section 6]*.
>
> Reply **yes** to proceed, or tell me what to change.

After a clear "yes":

1. **Attach skills/operators.** Search the catalog and attach each approved item. Confirm each with `describeOperator`. If one needs a sign-in, it goes on the user's list.
2. **Create the Lead Enrichment skill.** Fill in the confirmed values and save it.
   - **If you can't create a custom skill directly**, give the user the complete skill markdown in one copy-paste block, plus exact steps:
     1. Open your clone's settings → **Skills** (or **Custom skills**).
     2. Click **New skill** / **Add skill**.
     3. Name it exactly **Lead Enrichment**.
     4. Paste the full block into the skill instructions field.
     5. Read it through, then **Save**.
     6. Tell me "saved" so I can verify it's attached.
     (Menu names may differ slightly in your workspace.)
3. **Optional scheduled task.** Name: "Lead Enrichment Refresh". Schedule: weekly or monthly (user's choice). Action: "Run Lead Enrichment on rows of `{SOURCE_SHEET}` where enr_date is older than 90 days, within `{CREDIT_BUDGET}`." Every scheduled run must still respect the budget and stop on it. If you can't create scheduled tasks, give the user these values to create it manually.
4. **Optional `Clone_Code` pipeline.** If the user wants a repeatable pipeline, offer to build a small script with **Clone_Code** as a separate project: it reads a list, applies the same hygiene, match key and confidence rules, and writes the same output columns, and the user runs it themselves. No keys go in code or chat.
5. **Report back** what succeeded and what failed, honestly.

## 6. What the user must do

Give the user this list, with the how-to steps, and track which ones are done.

1. **Connect your Google (or Microsoft 365) account and make sure I'm switched on.** Clone settings → **Connections** → Google / Microsoft → **Connect** → approve Sheets/Drive (or Excel/OneDrive) permissions. Then check that the clone is switched on / active. *Without this I can't open your sheet.*
2. **Share the sheet with me** (edit access), or upload the file. Make a copy for the test batch if you'd rather I don't touch the original at all.
3. **Confirm the do-not-contact list.** Share the tab/file or tell me the CRM field that marks opt-outs. Make sure it's current.
4. **(If `{CRM_SYNC}` is `salesforce` or `hubspot`)** Connect that CRM via Connections → **Connect** → sign in. Ask your CRM admin to grant write access to the fields to be filled only, and to create custom fields for source, confidence and enrichment date.
5. **(Optional) Connect email** (Gmail or Outlook) if you want the summary email.
6. **Check your legal basis.** Confirm with your privacy lead that you can process this personal data (GDPR/CCPA).

## 7. The Lead Enrichment skill (save this in full)

Fill in the placeholders, then save as a skill named **Lead Enrichment**. Don't shorten it.

~~~~markdown
# Lead Enrichment

## Purpose
Fill in missing details (default: company domain, title, LinkedIn URL, email, phone)
for contacts that ALREADY exist in a list. Clean the list, choose the best match key
per row, research the gaps on the public web, score confidence, append results
without overwriting anything, route uncertain rows to review, optionally write empty
CRM fields, and report. Never add new people. Never present a guess as verified.

## Settings
- Source list: {SOURCE_SHEET}
- Fields to fill (only when empty): {FIELDS_TO_FILL}
- Credit budget per run: {CREDIT_BUDGET}
- Confidence threshold: {CONFIDENCE_THRESHOLD}   (default 60)
- ICP rules (optional): {ICP_RULES}
- Do-not-contact list: {DO_NOT_CONTACT_LIST}
- Batch size: {BATCH_SIZE}   (default 50)
- CRM write-back: {CRM_SYNC}   (no | salesforce | hubspot)
- Summary recipients (optional): {SUMMARY_RECIPIENTS}
- Confidence caps: guessed email 40; email or phone published on an official page 60; company main line 70
- Re-enrich after: 90 days

## Tools
Use the exact names from my skill catalog. Use whatever is connected; skip what isn't.

| Purpose | Tool (exact catalog name) | Required | Access |
|---|---|---|---|
| Read the list; write new tabs/columns and cache | GoogleSheets-Operator or Microsoft_Excel | Yes | Read; write ONLY new tabs or new enr_* columns |
| Domains, firmographics, public titles, LinkedIn URLs, email patterns, company phones | Web research | Yes | Read public web |
| Salesforce write-back (if {CRM_SYNC} = salesforce) | SalesforceContactOperator, SalesforceLeadOperator, SalesforceAccountOperator | Optional | Read; write empty fields only |
| HubSpot write-back (if {CRM_SYNC} = hubspot) | HubspotContactOperator, HubspotCompanyOperator | Optional | Read; write empty properties only |
| Repeatable pipeline script | Clone_Code | Optional | Create a script for the user to run |
| Send the run summary | GoogleGmailOperator or Outlook email operator | Optional | Send ONLY to {SUMMARY_RECIPIENTS} |

Verified email/phone data needs a paid data provider. If your org adds an operator for one, add it as an extra step. It isn't required for this use case.

## Guardrails
- Enrich existing rows only. Never add new contacts. (Clone-Lead-Generation-Skill finds NEW leads; this skill does not.)
- Never overwrite: fill empty fields only, in enr_* columns or new tabs. Never edit or delete original values in the sheet or CRM.
- Never email, call or message anyone on the list.
- Skip every row matching {DO_NOT_CONTACT_LIST} (email or domain). Mark enr_status = do_not_contact.
- Collect only the fields in {FIELDS_TO_FILL}. Don't gather personal details beyond what is needed.
- No full run until the user has approved a credits and time estimate for this run. Track credits after every batch; stop before exceeding {CREDIT_BUDGET} and mark remaining rows skipped_budget.
- Check the Lookup Cache before every lookup. Write every result to the cache.
- Every web-derived value needs a source URL. If there is no source, leave the field empty. Never invent values.
- Emails and phones from web research are UNVERIFIED. A pattern-guessed email is never labeled verified and is capped at confidence 40.
- Retry rule: if a tool call fails, retry ONCE. If it fails again, mark that tool "unavailable" for this run, continue with the other rows, and report it.
- Never ask for, accept or handle passwords, API keys or tokens.

## Step 1: Intake
- Open {SOURCE_SHEET}. Do not modify the source tab.
- Map headers to canonical fields: first_name, last_name, full_name, email, company, company_domain (website/URL), title, linkedin_url, phone, country/location. Keep unmapped columns as they are.
- If a needed header is unclear, ask the user once with your best guess.
- Load {DO_NOT_CONTACT_LIST}.
- Count rows. Over 5,000 rows: warn the user and plan more batches.

## Step 2: Data hygiene
In memory (or in clean_* helper columns on the output tab, never the source):
1. Trim whitespace; Title Case names; lowercase emails and domains; strip https://, www. and paths from websites.
2. Validate email format. Malformed emails are treated as missing and flagged.
3. Normalize phones to E.164 (+country code). If no country, use the list's default country if the user gave one; otherwise flag "phone_no_country".
4. Derive company_domain: website column, then email domain (unless free-mail such as gmail.com, outlook.com, yahoo.com), otherwise leave empty for web research to find. Flag guessed domains.
5. Dedupe: same email, or same full name + domain. Keep the first row; mark others enr_status = duplicate with the row they duplicate. Don't enrich duplicates.
6. Mark do-not-contact rows.
7. Flag gaps: which {FIELDS_TO_FILL} are empty per row. Rows with nothing missing are marked "already complete" and skipped.

## Step 3: Match key strategy
For each remaining row pick the strongest identifier available:
1. Work email (best)
2. LinkedIn URL
3. Full name + company domain
4. Full name + company name (weakest; firmographics may match, people often won't)
5. None: enr_status = unmatched, send to review.
Record match_key_type per row. A free-mail email ranks below name + domain.

## Step 4: Test batch and credits and time estimate (approval gate)
1. Pick 10–25 representative rows (mix of match key types). Work on the user's copy.
2. Run Steps 5–8 on them.
3. Report: fields filled per field, confidence distribution, credits used, time taken, and 3–5 sample rows with their source URLs.
4. Estimate the full run (these are estimates, based on the test batch):
   rows_to_look_up = unique rows − already complete − do-not-contact − cache hits
   credits = rows_to_look_up × fields per row × credits per field lookup (use the test batch's real numbers)
   time = rows_to_look_up ÷ rows researched per minute (from the test batch)
   batches = rows_to_look_up ÷ {BATCH_SIZE}, rounded up
   Show estimated credits, estimated time and number of batches. Compare with {CREDIT_BUDGET}. Point the user to the "Credits & time estimator" linked on the library card to try other inputs.
5. Ask: "Proceed with the full run within {CREDIT_BUDGET}? (yes / change settings / stop)". Do nothing more until the user says yes.

## Step 5: Web research
For each row, for each empty field in {FIELDS_TO_FILL}:
1. Lookup Cache: reuse any result for the same email, LinkedIn URL or name + domain that is less than 90 days old (no new research).
2. Web research: company domain, industry, size, HQ, company main phone, public title, LinkedIn URL. For email, look for one published on an official page; otherwise infer the company's email pattern from public examples and build a candidate (guess). For phone, use the company main line unless a direct number is published on an official page.
3. Record each value with its source URL and mark emails and phones UNVERIFIED.
4. If two sources disagree, keep the value with the stronger source and note the conflict.
5. After each batch add its credits to the running total. If the next batch would exceed {CREDIT_BUDGET}, stop.
6. Write each result to the Lookup Cache with the date.

## Step 6: Confidence scoring (0–100)
- Firmographics and titles from an official company page: 80–90. From a third-party page: 60–75.
- LinkedIn URL matching name + company: 70–85. Name-only match: max 50.
- Email published on an official page: max 60. Pattern-guessed email: max 40. Label "UNVERIFIED".
- Phone: company main line from the official site up to 70; direct number published on an official page max 60; otherwise leave empty.
- Add 10 when a second independent source agrees; max 90 for any web value.
- Row status: all filled key fields at or above {CONFIDENCE_THRESHOLD} → enriched; some filled → partial; any filled key field below threshold → needs_review; nothing found → unmatched.

## Step 7: Lead scoring / ICP fit (optional)
- Apply {ICP_RULES} to enriched and original data (industry, size, seniority, region).
- Missing inputs score 0 points; never guess them.
- Output fit_score (0–100), fit_tier (A / B / C) and a short fit_reasons note. Skip unmatched rows. Skip this step if the user said "skip scoring".

## Step 8: Write to the file
Write to a tab named "Enriched Leads" (new tab or the user's copy). Never touch the source tab.
- Original columns first, unchanged, then for each field in {FIELDS_TO_FILL}: enr_<field>, enr_<field>_source (include the source URL; say UNVERIFIED for emails and phones), enr_<field>_conf.
- Then: enr_status, match_key_type, fit_score, fit_tier, fit_reasons (last three only if scoring is on), enr_date (YYYY-MM-DD).
- If a header already exists, keep the enr_ prefix so nothing collides.
- If the user asked for in-place columns, add them to the right of existing data only.

## Step 9: Review and exceptions
Copy to a "Needs Review" tab every row with status needs_review, unmatched or partial below threshold, with: the original data, review_reason (no match / low confidence / guessed email / guessed domain / phone_no_country / conflicting sources), source URLs, and empty reviewer_decision (approve / fix / reject) and notes columns.

## Step 10: Batching, progress and delivery
- Full run: process remaining rows in batches of {BATCH_SIZE}. After each batch send the user a one-line update: batch n/N, rows done, fill rate per field, credits used / {CREDIT_BUDGET}.
- If the budget is reached: stop, mark remaining rows enr_status = skipped_budget, and report how many are left and the estimated credits to finish.
- "Run Summary" tab: rows in, duplicates, do-not-contact, already complete, enriched / partial / needs review / unmatched / skipped_budget, fill rate per field, credits and time used, cache hits, tools unavailable.
- CRM write-back (only if {CRM_SYNC} is salesforce or hubspot and the user approved it): Salesforce uses SalesforceContactOperator, SalesforceLeadOperator and SalesforceAccountOperator; HubSpot uses HubspotContactOperator and HubspotCompanyOperator. Match by email (then by record ID); fill EMPTY fields only; never replace a CRM value; never write do-not-contact rows or values below {CONFIDENCE_THRESHOLD}; never write UNVERIFIED emails or phones unless the user explicitly asked for that; never create new CRM records unless the user explicitly asked; log failed writes.
- If {SUMMARY_RECIPIENTS} is set, send ONE summary email there. Subject: "Lead Enrichment: {list name}: {enriched}/{total} rows enriched". Body: the Run Summary numbers, link to the sheet, Needs Review count, tools unavailable, and next refresh date.
~~~~

## 8. Test plan

Run this before any full run. Ask the user to approve the test first.

1. **User prepares a COPY of the list** (or a small sample tab) with 10–25 rows, including:
   - a few rows with work emails, a few with only name + company,
   - one deliberate duplicate,
   - one row whose email is on `{DO_NOT_CONTACT_LIST}`,
   - one row that already has every field filled.
2. **Run Lead Enrichment** on the copy ("Run the test batch").
3. **Verify the checklist together:**

| Check | Pass? |
|---|---|
| Columns were mapped correctly and the source tab is unchanged | ☐ |
| Original values were **not** overwritten anywhere | ☐ |
| Duplicate marked `duplicate`, not enriched or paid for | ☐ |
| Do-not-contact row marked `do_not_contact`, not enriched | ☐ |
| Already-complete row was skipped (no credits used) | ☐ |
| Every new value has `_source` (with a URL), `_conf` and `enr_date` | ☐ |
| Guessed emails and phones say UNVERIFIED with confidence ≤ 40 (60 if published on an official page) | ☐ |
| Phones are in E.164 format | ☐ |
| Low-confidence / unmatched rows appear in Needs Review with a reason | ☐ |
| Lookup Cache tab was written; re-running a row uses no new credits | ☐ |
| Credits used in the report are plausible for the rows processed | ☐ |
| Credits and time estimate for the full list was shown and **no full run started** without a yes | ☐ |
| (If set) Summary went to `{SUMMARY_RECIPIENTS}` only; **no email to any contact** | ☐ |
| (If `{CRM_SYNC}` is on) Only empty CRM fields were filled, on one test record the user approved | ☐ |

4. The user spot-checks 3–5 enriched values by hand. Fix anything that failed, re-run, then ask for approval of the full run.

## 9. Final status checklist

When you finish, send the user a status summary in this format:

**✅ Done by me**
- [ ] Account connection and clone status checked
- [ ] Discovery table shared
- [ ] Placeholder values confirmed
- [ ] Skills/operators attached: …
- [ ] Lead Enrichment skill created (or full text handed over for copy-paste)
- [ ] Test batch completed on a copy; results: …
- [ ] Full-run credits and time estimate shared: … credits / … estimated time
- [ ] (If approved) Full run completed: … enriched, … needs review, … credits used

**⏳ Waiting on you**
- [ ] Connect Google/Microsoft 365 account and switch the clone on (if not done)
- [ ] Share the sheet with edit access
- [ ] Confirm do-not-contact list
- [ ] Save the Lead Enrichment skill (if I handed it over)
- [ ] Approve the full-run credits and time estimate
- [ ] Work through the Needs Review tab

**💡 Optional next steps**
- [ ] Schedule a 90-day refresh
- [ ] Turn on Salesforce or HubSpot write-back after reviewing results
- [ ] Build a repeatable pipeline script with Clone_Code
- [ ] Tune `{ICP_RULES}` after looking at the tier distribution
