← All craftbooks

Bulk CRM Update from Notes

Comms and ops automationevalv1.0.0released 2026-06-05workflow: build-loop

Turn unstructured notes (call logs, meeting recaps, email threads) into a batch of structured CRM updates: per-contact field changes, activity logs, and next-step tasks as a validated import file. Scopes the CRM field schema and extraction rules FIRST (which objects/fields, allowed picklist values, the match-or-create key, required fields), then a developer extracts and maps every note into rows against that schema, then a reviewer validates the batch for schema-conformance and that no update mutates a field without evidence in the source. Scoping the schema before extraction is what makes the import load cleanly and prevents fabricated field values. Use for CRM data entry, bulk contact updates, importing notes into Salesforce/HubSpot, activity logging, and turning call notes into pipeline updates.

Steps

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

  1. Scope the schemaplannerentry

    lock the CRM fields, picklists, match key, and rules

    Show working prompt
    Define the import contract before extracting. (1) Identify the CRM objects to touch (Contact, Account, Opportunity, Activity) and the EXACT fields per object you will update, with their types. (2) Lock allowed values for any picklist/enum field (stage, status, lead source) — extractions must map to these, never free text. (3) Define the match-or-create key (e.g. match Contact by email; if absent, flag for review rather than create blindly). (4) List required fields per row and the output format (CSV with a header, or the CRM's import schema). (5) Lock the evidence rule: every field change must be justified by a quote from the source note. Write an acceptance-criteria checklist ('every row conforms to the field schema and types', 'picklist fields use only allowed values', 'each changed field cites a source quote', 'unmatched contacts flagged not silently created', 'required fields populated', 'file parses as valid CSV/import format') plus the schema + picklists to notes/scope.md via write_task_note AND the produces path.
  2. Build the batchdeveloper

    extract and map notes into schema-conformant rows

    Show working prompt
    Produce updates.csv (or the locked import format) by mapping the notes to the schema. (1) Read each note and identify the contact/account it concerns; resolve via the match key, flagging UNMATCHED in a status column rather than fabricating an ID. (2) Extract field updates ONLY where the note gives evidence; normalize every picklist value to an allowed option from scope (drop, don't invent, if no clean mapping). (3) Emit an Activity/log row per note capturing the interaction (type, date, summary) and a next-step task row if the note implies one. (4) Add a source-quote column on each row pointing at the justifying text. (5) Ensure required fields are present and the file parses cleanly (proper header, consistent column count, quoting/escaping). Touch no field the notes don't support. On a loop-back fix only the flagged rows. Write the path and row counts (updates, activities, tasks, unmatched) to notes via write_task_note.
  3. Evaluatereviewer

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

    Show working prompt
    Validate updates.csv against every locked criterion. (1) Parse the CSV — malformed structure, a missing header, or ragged rows (inconsistent column count) is an immediate FAIL. (2) Confirm every field value conforms to its type and that picklist columns contain only allowed values from notes/scope.md. (3) Confirm required fields are populated on every row and that unmatched contacts are flagged in the status column, not given fabricated IDs. (4) Trace 4-5 field changes to their source-quote column — any change with no supporting quote is a FAIL for fabrication. (5) Confirm Activity/task rows exist where the notes implied them. Write PASS/FAIL per criterion with the specific offending rows.
    
    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: "build" })` 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.
  4. 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