What it does
A buyside searcher gives Mark or Ewing their criteria (geography, EBITDA band, verticals). The routine produces a polished HTML letter with a 15 to 25 company shortlist in 8 minutes. Letter format. Operator to operator voice. PDF ready. Zero em dashes.
First customer: Jonathan, self funded searcher in Carmel Valley San Diego, 16 month search, $500,000 to $2,000,000 EBITDA, route based and equipment driven service shops inside 50 miles. 22 qualified targets across 5 verticals on the first run. Two verticals were swapped (septic and dumpster came back too thin). Final five: window cleaning, pressure washing, landscape, pest, pool.
Run KPIs
Per agent verdicts
| Agent | Phase 1 Verdict | Headline |
|---|---|---|
| architect | COHERENT_HOME | One BLOCKING flag: confirm Slack signing secret. No new repos or DBs. |
| data-architect | SCHEMA_DRAFT_NEEDED | Three new tables: buyers, buyside_runs, vertical_margin_bands. All canonical from day one. |
| quarterback | GAPS_EXIST | Five plumbing gaps, additive only. Lazy scaffold deal manager skill only after engagement signed. |
| audit-data | REWORK 58/100 | HQ false matches, cross vertical dupes, no DNC pre screen. All three fixed same day. |
| audit-skills | READY_TO_BUILD | Skill registered at ~/.claude/skills/buyside-hunt/. One trigger collision with writer's "buyer list" resolved. |
| audit-quality | CONCERNS 80/100 | Ten point checklist: high on copy + security + observability, low on reusability + production readiness. |
| writer | PASS | Banned phrases scan clean. Three Slack reply templates drafted. |
| storyteller | NEEDS_NARRATIVE_DESIGN | Mandatory human review gate before delivery. Buyer state continuity for run to run. |
Three fixes shipped same day
Backlog (7 items, ranked)
buyers table at >= 10 buyers. Schema in data architect Phase 1 verdict.buyside_runs table for audit trail. Every Slack invocation logs a row.vertical_margin_bands lookup table so margins are editable without code deploy.extract_owner regex to reject names with whitespace anomalies or company tokens.How to use
From CLI today:
doppler run --project clawdbot --config dev -- \
python3 engine/contacts/pipeline/buyside_hunt_v1.py \
--buyer <slug> \
[--per-query 20] \
[--push-supabase]
To onboard a new buyer: copy engine/contacts/configs/buyers/_template.json to <slug>.json, fill in geo / EBITDA band / verticals / preamble, run.
To iterate copy without re running Exa: add --rerender-only <run_dir>. Costs zero API calls.
Slash command (planned): /buyside-hunt <slug> in Slack hits an API route at next-chapter-os/api/slack/buyside-hunt, enqueues a job row in Supabase, Mac mini Hermes worker runs the pipeline, posts public URL back to channel.
Patterns banked
- Audit-data: if a signal is strong enough to trigger a warning, it's strong enough to drop the row. No middle ground.
- Writer: rules with carve outs become rules of permission, not rules of restraint. Tighten when in doubt.
- Storyteller: if the artifact's voice promises a human read every row, a human must read every row before delivery.
- Quarterback: every new Hermes pipeline ships as "the script runs" and stops there. The deal orchestration tax is the last 20% of the work.
- Architect: every "make it Slack callable" feature defaults to "stand up a new webhook receiver." The canonical answer is "use the existing next-chapter-os Next.js API surface."
Files
- Skill:
~/.claude/skills/buyside-hunt/SKILL.md - Pipeline:
engine/contacts/pipeline/buyside_hunt_v1.py - Runbook:
engine/contacts/pipeline/buyside_routine.md - Template:
engine/contacts/configs/buyers/_template.json - HTML template:
engine/contacts/templates/buyside_report.html.j2 - Banned phrases (W7 tightened):
skills/maxswarm/banned_phrases.md - Notebook entry:
skills/maxswarm/notebook/2026-05-05__009__buyside-hunt-routine-review.md - Per agent journals:
skills/maxswarm/notebook/journals/009__<agent>.html