← All craftbooks

Enrich a Leads List

Personal and business workflowsevalv1.0.0released 2026-06-05workflow: build-loop

Take a raw leads or contacts list and enrich each row with derived and looked-up attributes — company domain, industry, size band, role seniority, normalized location, and a quality/score flag — into a clean CRM-ready file. Scopes the enrichment fields, their sources, and the dedup/normalization rules FIRST, then enriches each lead row-by-row, then verifies coverage, that nothing was fabricated when a source had no data, and that duplicates are merged. Defining 'what each field means and where it comes from' before enriching is what stops a small model from inventing plausible-but-false company data.

Steps

Entry step: scope. Each step names the specialist role it wants; the full working prompt is expandable.

  1. Scope the enrichmentplannerentry

    fields, sources, dedup + normalization rules

    Show working prompt
    Define enrichment before touching the list. Step 1: load the input leads file and list its existing columns. Step 2: define each enrichment field to add (e.g. company_domain, industry, employee_band, seniority, normalized_country, lead_score) with its type, its source (derive from email domain, look up via an available tool, or normalize an existing value), and an allowed-value set where applicable (industry list, seniority levels, size bands). Step 3: define the dedup key (e.g. lowercased email, or name+company) and the merge rule for duplicates. Step 4: state the no-fabrication rule explicitly — if a field cannot be sourced, leave it blank and mark a confidence/flag, never guess. Step 5: write an acceptance-criteria checklist ('every input lead present in output', 'enriched fields use only allowed values', 'unsourced fields are blank+flagged, not invented', 'duplicates merged by the dedup key', 'output is CRM-ready in the chosen format'). Call write_task_note with fields + sources + rules + checklist and write notes/scope.md. No enrichment yet.
  2. Enrich each leaddeveloper

    derive, look up, normalize, and flag each row

    Show working prompt
    Enrich the list to the locked field spec. Step 1: dedup the input by the chosen key first, merging duplicate rows per the merge rule. Step 2: for each lead, derive the deterministic fields (e.g. company_domain from a work email, normalized_country from a location string). Step 3: for lookup fields, use the available capability and constrain outputs to the allowed-value set; when a lookup returns nothing, set the field blank and flag low confidence — do not fabricate. Step 4: compute the lead_score from the agreed signals. Step 5: write the enriched, deduped dataset to the output file in the chosen format and confirm it parses. Call write_task_note with the output path, input vs output row counts, and a per-field fill-rate.
  3. Verify the enrichmentreviewer

    coverage, allowed values, no fabrication, dedup

    Show working prompt
    Verify the enriched dataset against scope. Step 1: confirm the file parses and every input lead survived (counting merges) — no rows silently dropped. Step 2: confirm enriched fields contain only allowed values (industries, seniority, size bands are in-set). Step 3: confirm unsourced fields are blank-and-flagged rather than guessed — spot-check 5 leads against their evidence (e.g. does the company_domain actually match the email?). Step 4: confirm duplicates were merged by the dedup key and none remain. Step 5: sanity-check the lead_score distribution is plausible. Write PASS/FAIL per criterion to notes/verify.md and task notes; on failure, name the rows/fields and loop back to enrich.
  4. Evaluatereviewer

    Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.

    Show working prompt
    Open leads_enriched.json and verify every criterion from notes/scope.md. Confirm it parses, every input lead is represented (accounting for merges), enriched fields use only allowed values, unsourced fields are blank+flagged rather than fabricated (spot-check 5 against evidence such as email→domain), duplicates are merged by the dedup key, and the score distribution is plausible. Write PASS/FAIL per criterion; on any failure, name the rows/fields and loop back to enrich.
    
    Then route — this is the whole point of the loop:
    
    - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`.
    - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "enrich" })` to loop back. The builder fixes exactly those gaps.
    
    Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in.
  5. Finishdeveloper

    All acceptance criteria met. Stamp a short summary and report DONE.

    Show working prompt
    Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.

Triggers

Phrases that suggest this craftbook to a crew.

Source

View this craftbook on GitHub · MIT license