Skip to content
~/robynrocha.io
cd /home
Case studyData / Enrichment / AI

From a raw vertical to a verified contact

The pipeline underneath everything else: grade the market once, source wide and keep the receipts, crawl cheaply and escalate only when needed, turn pages into a decision, and verify every address three times before it is allowed near a mailbox.

Everything else on this site sits on top of this pipeline. If the targeting data is wrong, better copy just means arguing more persuasively with the wrong people.

[ The Substrate ] Grade the market once, look it up forever

What it is: before any sourcing happens, the vertical itself gets mapped — its sub-segment types, the buyer profiles that sit inside them, the pairs that actually transact, and the economics of each. A fit filter scores every sub-segment on a weighted blend of follow-up potential, reach, lifetime value, sales-cycle length, and order frequency, then cuts the result into A through F bands.

Why it's built this way: the expensive mistake in outbound is deciding who is worth contacting one account at a time, inconsistently, forever. Doing it once at the segment level means that later — when a crawled site is classified — the grade is a lookup, not a judgement call. Thousands of downstream decisions inherit one deliberate decision instead of re-litigating it under time pressure.

$render targeting-store.mmd

No diagram code provided

rendering diagram…

[ Sourcing ] Over-source, then clean — and keep the receipts

What it is: a locked query plan runs in waves against the store's in-scope sub-segments. Every wave keeps per-seed telemetry and a map from each seed query back to the businesses it produced. Results are combined across queries, deduplicated on a stable identity, tagged with the query that found them, lightly normalized, and preserved raw in an append-only layer.

Why it's built this way: sourcing wide and filtering later beats sourcing narrow and hoping, but only if you can still answer "where did this row come from?" three steps downstream. The raw layer is never overwritten, so any later mistake is recoverable rather than baked in — and a row that turns out to be junk can be traced back to the query pattern that produced it, which fixes the next run instead of just this one.

[ The Crawl ] Cheap first, expensive only when it has to be

What it is: before anything gets crawled, each domain gets a fast screen — a DNS check, a parked-nameserver check, and one classified request. The screen is deliberately biased toward keeping: it drops what is provably dead, not what merely looks unusual. Survivors go through a two-pass fetch. Plain HTTP handles the large majority. Only when a content gate says the response is not real content does the request escalate to a full browser, with fingerprinting and a session pool behind it. Pages are chosen from the site's own sitemap rather than crawled blindly.

Why it's built this way: a browser costs orders of magnitude more than an HTTP request, so running one by default makes wide coverage unaffordable. Deciding on content rather than status code is the important part — a site can return a perfectly healthy 200 alongside a challenge page or a stub, and a status check will happily record that as success.

$render crawl-engine.mmd

No diagram code provided

rendering diagram…

[ From Pages to a Decision ] Read once, decide many times

What it is: the crawled pages become a written business summary — model, reach, history, context — which then becomes the evidence every later step reads. Classification works from that summary against the graded reference table and returns scope, sub-segment match, confidence, and reach. Routing off that decision is fully deterministic with no model involved. Entity resolution then works out corporate structure — who owns whom, what is a branch, what is a parent — with a tier estimate attached.

Why it's built this way: the summary is written once and becomes the durable record, so no later step needs to re-read raw pages and quietly form its own contradictory opinion. Keeping the routing deterministic matters just as much: once the decision exists, acting on it is arithmetic. Reserving inference for the steps that genuinely need judgement is what makes the pipeline both cheap and predictable.

$render understanding.mmd

No diagram code provided

rendering diagram…

[ Contacts, Verified ] Three verifiers, five verdicts, two lanes

What it is: contact extraction re-reads the raw crawl — not the summary — for roles, phone numbers, and addresses, with search filling the gaps. Every address then runs a multi-vendor waterfall with a deliberate order: a general verifier opens the flow — MillionVerifier or LeadMagic, interchangeably, with Findymail in the same slot — the middle flexes, and the anchor is always catch-all-capable: the BounceBan and DeBounce class, with OrbiSearch, Reoon, and TryKitt in the same family, there to resolve the unknowns. The verdicts collapse into tags and, from there, into two send lanes: addresses safe for the main fleet, and catch-all addresses routed to isolated infrastructure.

Why it's built this way: a single verifier is a single point of failure with a commercial incentive to say yes. Verifiers in sequence mean each one's blind spot is covered by the next, and disagreement is itself information. The last slot belongs to the most dependable vendor in the flow, and keeping catch-alls tagged rather than merged is the part that protects the program — they are worth contacting, but not with the reputation that everything else depends on.

Phone numbers come out of the same pass, which is why the calling step never needs a vendor lookup for a contact that has already been through the pipeline.

$render verification-waterfall.mmd

No diagram code provided

rendering diagram…

The pipeline is the substrate. These are the evergreen systems that stand on it — the ones that keep producing after you stop touching them.

[ The Lead Magnet ] The AI search readiness scorecard

What it is: a public "get your free scorecard" product. A prospect enters their domain; the engine digests their homepage positioning, picks a competitor set, fans out across Moz and other SEO and authority APIs, and produces a personalized scorecard — stored once, served twice: a public page for the prospect, a deeper handoff view for the rep.

Why it's built this way: a slow, expensive multi-API engine can't sit raw on the public internet, so a deliberately small connector owns intake, queueing, storage, and projection. It revives stuck analyses, gives up on lost causes, meters the flow, and never pays twice for the same company. Even abandonment is a signal — an unfinished demo booking becomes a Slack alert, because an almost-customer is a sales signal, not silence.

$render scorecard.mmd

No diagram code provided

rendering diagram…

[ Attribution ] From a review queue to company-wide multi-touch

What it is: campaign recipients matched to deal contacts by email address, with every possible match landing in a review queue rather than a live report — the contact, the source campaign, the matched deal, an AI-drafted rationale, and call-transcript evidence for the person who never replied but booked inbound after a forward. A human approves or denies every match before it enters any number.

Why it's built this way: the work happens across too many systems, and "did outbound source this?" answered by memory changes depending on who is asked. It evolved into company-wide linear multi-touch through HubSpot — credit split across every recorded touch, with synced properties making outbound available to lists, workflows, and reports.

$render attribution-queue.mmd

No diagram code provided

rendering diagram…

[ Warm Audiences ] Warm ad audiences via Clay

What it is: an engagement-plus-ICP membership list Clay keeps current — replied to a sequence, warm lifecycle stage, closed-lost but still ICP — synced live to LinkedIn and Meta retargeting, with people leaving the moment they stop qualifying. You're not uploading a scraped list; you're uploading people already proven worth the spend.

Why it's built this way: membership alone isn't a GTM motion. Senior titles landing in the audience also kick a second path — a human-activated sequence routed to the right rep, with the paid impression as air cover while a human works the account.

$render warm-ads.mmd

No diagram code provided

rendering diagram…

[ Scoring ] Lead scoring with living weights

What it is: HubSpot stays the operational CRM, Clay stays the hands, and a simple scoring model lives in a mirrored database you control. Engagement and firmographic change signals land in Supabase against the same account keys, and a scoring pass produces a living shortlist — who should the team be working right now, given everything we know.

Why it's built this way: account scoring usually happens once a year while the product and persona keep moving. With the data in your own database, the interface is a weight dashboard: persona drifts, you slide the weights, and the shortlist reshuffles. No six-week scoring project.

$render lead-scoring.mmd

No diagram code provided

rendering diagram…

[ The Compounding CRM ] A CRM that gets better every week

What it is: conventions built into every workflow so the database compounds instead of decaying. Verification results written back as standardized statuses, every enrichment stamped with when and where it came from so no lookup is paid for twice, legacy fields consolidated to one source of truth, and every bulk write snapshotted to a rollback file first.

Why it's built this way: across tens of thousands of accounts, data quality improves as a side effect of normal work. New campaigns start smarter than the last one, and nobody ever runs a "data cleanup quarter."

$render data-scaffolding.mmd

No diagram code provided

rendering diagram…

[ The Multiplier ] The operating system all of it is built with

Every system on this site was designed and built inside Claude Code, against a context architecture I maintain deliberately: an always-on contract that carries judgement rules and routes to the right knowledge, a navigation map, ledgers that hold each area's real state, a single file recording what every step consumes and produces, and a memory that is an index rather than a transcript.

The reason it matters is not that the assistant remembers more. It is that failures become infrastructure. When a vendor's API behaves differently than documented, the immediate task gets fixed and the reference gets corrected. When a process reveals a missing check, the check goes into the shared procedure. The next piece of work inherits the correction for free.

The full picture — what it consumes, what it produces, and how the layers stay separate — is on its own page.


The rest of the system: Running the Seat · Cold Email at Scale