Leads: project-scoped lead generation and cold outreach - #122
Merged
Merged
Conversation
Finds businesses, scans their sites, and pitches the fix — grounded in what
the scan actually found rather than in a merge field.
Modelled on two paid MCP servers, neither of which is the design. Velvet
Forge is seven LLM prompt wrappers whose "personalisation" never looks at
the prospect's website. Signal Found sells thousands of Reddit DMs a day
through a browser extension replaying your session or a farm of managed
accounts, which is against Reddit's User Agreement and ends with the domain
banned sitewide. CrawlProof already runs the scanner, so it can open with a
defect verifiably on their site, linked to a report they can check.
The funnel — discover, scan, research, draft, send, follow up — runs
unattended from a 15-minute cron tick, or step by step from the Leads tab
or the MCP toolset. All three share one code path so the guardrails cannot
differ between what the robot does and what the button does.
Leads belong to a project: the same agency runs different outreach for
different clients. Send caps stay per person — one operator with five
projects still has one sending reputation.
Guardrails, which are the design and not a bolt-on:
- dry run by default everywhere that touches the outside world
- auto_send defaults false; a new campaign builds and drafts, then stops
- global do-not-contact list; one-click unsubscribe scoped to an address
or a whole domain, with its own token so a cold recipient is never
enrolled in the newsletter to be given an opt-out
- CAN-SPAM postal address required before any live send
- generated drafts are rejected if they cite a score or report that does
not exist, or imply a prior relationship
- sites that already score well are skipped rather than pitched a rescue
- Reddit: live subreddit rules are a hard stop, public replies preferred,
one cold DM per person ever, disclosure required
Lead sources cost nothing by default (DuckDuckGo, Mojeek, the prospect's own
pages) and use ValueSERP when its key is set. No purchased contact data.
Tests cover the decisions that carry risk: suppression ordering, contact
discovery and ranking, grounding checks, thread scoring, reply validation.
Three bugs they caught are fixed here — logo@2x.png passing as an address,
shared inboxes outranking named humans, and phone extraction returning
dates and postal codes.
Migration applied to production.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Engagements are now ~$12k and run two to three weeks at $100/hour, so "< 24h turnaround" and "live the same business day" were promises the delivery model can no longer keep. A timeline claim a buyer discovers is false during onboarding costs more than the urgency it bought. Replaces it with what is actually true: work is scoped from the findings in their own report, billed at $100/hour, typically two to three weeks. That also matches lib/audit/quote.ts, which already prices remediation at $100/hour and caps at 120 hours before asking for manual scoping. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a Leads tab to every project: find businesses, scan their sites, and pitch the fix — grounded in what the scan actually found.
Where it is
/projects/<id>/leads— tab row, between Uptime and Autoblog. Not in the top nav (project-scoped by design).What it does
discover → scan → research → draft → send → follow up, drivable three ways off one code path: the Leads UI, an MCP toolset (7 tools), and a 15-minute cron tick.Lead sources cost nothing by default (DuckDuckGo → Mojeek, plus the prospect's own pages); ValueSERP is used when its key is set. No purchased contact data.
Guardrails
auto_senddefaults false — a new campaign builds and drafts, then stopsAlso
Drops the "under 24 hours" turnaround promise from
/hire— engagements now run 2–3 weeks at $100/hour.State
Before it fully works
OUTREACH_POSTAL_ADDRESSon Railway — live sending is refused without it (dry runs work)pg_cronjob for/api/cron/outreachyet, so campaigns won't self-run until one is scheduledread+privatemessages)🤖 Generated with Claude Code