Contractor Call Sheet
What this produces
Two deliverables that turn a vetted directory into same-day outreach:
- A one-page call sheet (printable HTML): the top picks grouped by trade, each with phone, the one-line reason it's the pick, what to confirm on the call, and empty Status / Notes / Next-step columns to work down. Call-first (cross-validated) providers are flagged at the top.
- Personalized first-contact messages: a short, human text or voicemail for each top pick, varied so they don't read like a mass blast, plus the vetting-call question script for when someone picks up.
The call sheet is generated by scripts/build_call_sheet.py (deterministic). The messages
are drafted by you (the model) from references/outreach-templates.md, personalized per
provider. That part shouldn't be a template mail-merge; it should sound like a real person.
Why it's split this way
The sheet is mechanical (same columns every time), so a script does it perfectly and free. The outreach is the opposite: a message that lands is specific ("saw you do a lot of investor work in Maryville") and varied, which is a judgment task, not a merge. Doing the merge in a script would produce the exact spammy sameness we're trying to avoid.
Workflow
1. Get the input
Ideally the Excel from vendor-directory-builder (it has the columns this expects:
Category, Company, Phone, Serves, Why, Cautions, Source, Confidence, Top Pick). Any
spreadsheet or pasted list with company names + phones also works: map the columns
mentally and pass what you have.
2. Build the call sheet
python scripts/build_call_sheet.py <directory.xlsx> <call_sheet.html> [--all]
By default it includes only the top picks (starred rows), the people to call first.
Pass --all to include every provider. It groups by trade, puts cross-validated
"call-first" providers in a banner at the top, and leaves Status / Notes / Next-step
columns blank to work down. Open or deliver the HTML (it prints cleanly to one or two
pages). The script's header shows the market and date if present in the file.
3. Draft the outreach
Read references/outreach-templates.md. For each top pick, write a short first-contact
text and a voicemail line, personalized from that provider's own row: pull a
specific hook from the Why field (what they're good at / who recommended them) and, for
any "Confirm [area]" provider, lead with the coverage question. Vary the wording across
providers. Keep them short, plainly worded, and investor-to-pro (not salesy). Include the
vetting-call script so whoever dials knows what to ask when someone answers.
4. Deliver
Hand over the call sheet (HTML) + the outreach messages (grouped by provider). Offer to drop the messages into the directory or a tracker if the team wants them stored.
Guardrails
- Don't invent contact info. If a row's phone is "not found," carry that through: say "no number yet, get it from the group/site first." Never fill in a plausible number.
- Respect the confidence + cautions. Low-confidence or "confirm license/insurance" rows should surface that in the notes, not get a glowing intro that overstates them.
- Messaging is a draft for a human to send. This skill writes the outreach; it does not send it. Sending is the user's call.
Files
scripts/build_call_sheet.py: builds the printable call sheet from a directory file.references/outreach-templates.md: first-contact text/voicemail templates, the vetting-call script, and how to personalize per provider without sounding mass-sent.