00-gtm-router
Plan and run the full API-first GTM chain - the orchestrator (step 00) that turns an ICP description plus optional budget, volume, and urgency into the right…
Rank a prospect's outbound signals and pick the campaign approach (Pain-led / Value-led / Segment fallback) - the judgment layer (step 05) of the API-first GTM chain. Takes scraped website markdown (03-firecrawl-research), vendor signals like funding / headcount / recent hires
$ npx -y skills add Zevenue/headless-gtm --skill 05-signal-builder --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/05-signal-builderContext preview
The summary Claude sees to decide when to auto-load this skill.
Rank a prospect's outbound signals and pick the campaign approach (Pain-led / Value-led / Segment fallback) - the judgment layer (step 05) of the API-first GTM chain. Takes scraped website markdown (03-firecrawl-research), vendor signals like funding / headcount / recent hires
name: 05-signal-builder description: > Rank a prospect's outbound signals and pick the campaign approach (Pain-led / Value-led / Segment fallback) - the judgment layer (step 05) of the API-first GTM chain. Takes scraped website markdown (03-firecrawl-research), vendor signals like funding / headcount / recent hires (04-crustdata-signals), or just a URL or pasted content, and emits ranked provenance-backed signals: the exact quotable sentence, source URL, 1-10 score, and recommended approach. Use whenever the user wants to score, rank, or prioritize prospects or accounts, decide outreach angles, or asks "which of these should we email first", "what's the angle for this account", "rank these signals", or "turn this scrape into campaign angles" - and whenever a records.jsonl or enrichment output is ready for judgment before writing copy. Scoring lives here; scraping belongs to firecrawl-research, vendor pulls to crustdata-signals, email finding to resolution.
Signal vendors sell facts ("company X raised", "company Y is hiring"). Scrapers sell pages. Neither tells you whether a fact is a Pain-led trigger, a Value-led opening, or noise for this particular client. That call - which finding matters, how much, and what to do with it - is this skill. It runs on model judgment alone: no API key, no credits spent.
Two ways in:
| You have | Mode | |---|---| | One prospect - a URL, pasted content, or a content file | A - Single prospect | | Chain output - records.jsonl and run folders from 01/02/03/04 | B - Batch over records |
Both modes need `icp_context`, and both produce the same two outputs: a human report and chain records.
`icp_context` (required): what the client sells, who they sell to, and what pain it removes. 2-4 sentences is enough. If it's missing, ask once - accept a pasted description or a file path. A signal only exists relative to this context: a hiring spree is a 9 for one client and noise for another.
`icp_shape` picks the calibration catalog:
| Shape | Prospects look like | Catalog | |---|---|---| | `b2b-saas` | funded companies, title-based orgs, tech stacks, exec moves | `references/signal-types-b2b-saas.md` | | `vertical-smb` | local or owner-operated - studios, venues, clinics, restaurants, trades | `references/signal-types-vertical-smb.md` |
If the user doesn't pass a shape, infer it from icp_context (end-customers that are local, Maps-addressable businesses → `vertical-smb`; otherwise `b2b-saas`) and state which one you picked. Read the catalog before scanning - it carries the per-shape scoring adjustments, not just examples. For a vertical neither catalog fits, see `references/calibration-guide.md`.
1. Get content. Pasted or file content: use as-is. URL only: if the 03-firecrawl-research skill is installed, run its standard mode and use the scan output; otherwise fetch the high-signal pages directly (homepage, /about, /careers, /pricing, /blog) with whatever fetch tool is available. List any page you couldn't get - a missing careers page is a coverage gap to report, not a zero signal. 2. Judge (method below) and write the report. If this prospect is part of a chain run, also emit a record (Mode B, step 3).
`scripts/signal_io.py` is stdlib-only Python - no installs. Paths below are relative to this skill's directory.
1. **Collect** - assemble one evidence bundle per domain from upstream outputs:
python3 scripts/signal_io.py collect \
--records path/to/03-run/records.jsonl \
--records path/to/04-run/records.jsonl \
--scrape-run path/to/03-run \
--crustdata-run path/to/04-run \
--out runs/2026-07-21-acme-batch`--records` takes any chain `records.jsonl` - 01, 02 (Maps), and 04 run folders all emit one.
Every flag except `--out` is optional and repeatable; pass whatever upstream artifacts exist. Records merge by domain (upstream fields are kept, never overwritten). Output: `inputs/<domain>.md` bundles, `records_in.jsonl`, `tracker.json`, `meta.json`. Re-running collect is safe - done domains stay done.
Bundles with no page content and no structured signals are flagged `thin` in the tracker. For a thin batch, run 03-firecrawl-research first; for 10 or fewer domains it's fine to fetch pages yourself as in Mode A and judge from that.
2. **Judge** each pending domain: read `inputs/<domain>.md`, apply the method below, write the signal JSON to a temp file, then:
3. **Emit** - validate and append to the chain output:
python3 scripts/signal_io.py emit --run runs/2026-07-21-acme-batch \
--domain acme.com --signals-json /tmp/acme-signals.jsonEmit enforces the record contract (fields, score range, approach enum, non-empty sentence and source), merges signals into the upstream record, appends to `records.jsonl`, and marks the domain done. On a validation failure it names the bad signal and rule - fix the JSON and re-emit. Re-emitting a domain replaces its record instead of duplicating it.
4. **Resume / finish**: `python3 scripts/signal_io.py status --run runs/<id>` shows done/pending. When all domains are done, write `runs/<id>/report.md` (per-domain report sections plus segment-level patterns you noticed) and point the user at `records.jsonl` - that file is what 06-resolution and the router consume.
For batches over ~100 domains, judge in passes of 25 and re-check score distribution between passes (see the honesty threshold below) so drift doesn't compound.
Work one domain at a time with the shape catalog open.
1. **Pull candidates from every source.** Page content: careers/jobs, blog/news, pricing, integrations, footer tech clues. Structured blocks: funding rounds, headcount and department growth, recent hires, job postings. Enri
GTM without the SaaS layer. An outbound pipeline built as agent skills for Claude Code and Codex: describe an ICP in plain English and the chain takes it from company discovery to verified, signal-ranked contacts - every step running on raw vendor APIs, not
Plan and run the full API-first GTM chain - the orchestrator (step 00) that turns an ICP description plus optional budget, volume, and urgency into the right…
The qualification gate of the GTM chain - judges every discovered company against the client's ICP before any paid enrichment, so credits are spent only on…
B2B company discovery and list building via the Prospeo search API. Use when the user wants to find companies from an ICP, build a prospect or TAM list, search…
Seed-based B2B company discovery via the Prospeo company-lookalike API. Use when the user has example companies and wants more like them - "find companies…
Find local-business (SMB) prospects via Google Maps using the Apify Compass actor. Use for Zevenue Step-2 Discovery (Vertical) when the ICP is Maps-addressable…
Scrapes a company website into clean, page-typed markdown using Firecrawl map + scrape + extract. Triggers on: "scrape this company", "read their website",…