@sellable/mcp 0.1.557 → 0.1.559

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +2 -13
  2. package/agents/registry.json +2 -2
  3. package/dist/api.js +6 -3
  4. package/dist/auth.d.ts +6 -0
  5. package/dist/auth.js +44 -2
  6. package/dist/refill-contract.d.ts +157 -0
  7. package/dist/refill-contract.js +487 -0
  8. package/dist/refill-run-client.d.ts +10 -0
  9. package/dist/refill-run-client.js +22 -0
  10. package/dist/refill-run-loop.d.ts +14 -2
  11. package/dist/refill-run-loop.js +169 -18
  12. package/dist/server.js +0 -23
  13. package/dist/tools/auth.d.ts +5 -0
  14. package/dist/tools/auth.js +49 -12
  15. package/dist/tools/campaign-message-preparation.d.ts +62 -0
  16. package/dist/tools/campaign-message-preparation.js +41 -0
  17. package/dist/tools/campaigns.js +2 -2
  18. package/dist/tools/csv-dnc.js +2 -2
  19. package/dist/tools/evergreen-refill-plan.d.ts +3 -0
  20. package/dist/tools/evergreen-refill-plan.js +29 -7
  21. package/dist/tools/leads.d.ts +32 -317
  22. package/dist/tools/leads.js +10 -171
  23. package/dist/tools/model-quality.js +6 -4
  24. package/dist/tools/prompts.d.ts +3 -3
  25. package/dist/tools/prompts.js +15 -7
  26. package/dist/tools/provider-preflight.d.ts +2 -65
  27. package/dist/tools/provider-preflight.js +10 -97
  28. package/dist/tools/readiness.d.ts +5 -89
  29. package/dist/tools/readiness.js +0 -66
  30. package/dist/tools/refill-executors.d.ts +38 -0
  31. package/dist/tools/refill-executors.js +222 -3
  32. package/dist/tools/refill-sends-v2.d.ts +118 -1
  33. package/dist/tools/refill-sends-v2.js +312 -3
  34. package/dist/tools/refill-sends.d.ts +678 -32
  35. package/dist/tools/refill-sends.js +274 -13
  36. package/dist/tools/refill-target-plan.js +486 -14
  37. package/dist/tools/registry.d.ts +115 -330
  38. package/dist/tools/registry.js +1 -7
  39. package/dist/tools/scheduler-fill-capacity.js +1 -1
  40. package/dist/tools/scheduler-run.d.ts +71 -0
  41. package/dist/tools/scheduler-run.js +203 -1
  42. package/dist/tools/setup-evergreen-campaigns.js +1 -1
  43. package/dist/tools/workspace-context.d.ts +1 -1
  44. package/dist/tools/workspace-context.js +8 -3
  45. package/dist/tools/workspace-export.js +2 -2
  46. package/dist/tools/workspaces.d.ts +48 -2
  47. package/dist/tools/workspaces.js +48 -5
  48. package/package.json +1 -1
  49. package/skills/create-campaign/SKILL.md +3 -3
  50. package/skills/create-campaign-v2/SKILL.md +1 -1
  51. package/skills/create-evergreen-campaigns/SKILL.md +16 -16
  52. package/skills/find-leads/SKILL.md +630 -48
  53. package/skills/refill-sends/SKILL.md +94 -353
  54. package/skills/refill-sends-v2/SKILL.md +6 -6
  55. package/skills/refill-sends-v2-workflow/SKILL.md +5 -5
  56. package/skills/refill-sends-v2-workflow/core/flow.v1.json +8 -8
  57. package/skills/refill-sends-workflow/SKILL.md +100 -743
  58. package/skills/refill-sends-workflow/core/contract.v2.json +543 -0
  59. package/skills/refill-sends-workflow/core/flow.v1.json +185 -1
  60. package/dist/tools/find-leads-runs.d.ts +0 -151
  61. package/dist/tools/find-leads-runs.js +0 -98
  62. package/skills/find-leads-v2/SKILL.md +0 -70
  63. package/skills/find-leads-v2/core/flow.v1.json +0 -31
@@ -1,57 +1,639 @@
1
1
  ---
2
2
  name: find-leads
3
- description: Find or source prospects, build and watch a live Sellable lead list, and export the finished list without creating a campaign.
4
- visibility: public
5
- allowed-tools:
6
- - mcp__sellable__get_auth_status
7
- - mcp__sellable__start_cli_login
8
- - mcp__sellable__wait_for_cli_login
9
- - mcp__sellable__get_active_workspace
10
- - mcp__sellable__list_workspaces
11
- - mcp__sellable__set_active_workspace
12
- - mcp__sellable__get_subskill_prompt
13
- - mcp__sellable__get_subskill_asset
14
- - mcp__sellable__search_subskill_prompts
15
- - mcp__sellable__get_provider_prompt
16
- - mcp__sellable__bootstrap_find_leads
17
- - mcp__sellable__get_find_leads_run
18
- - mcp__sellable__update_find_leads_run
19
- - mcp__sellable__wait_for_find_leads_run
20
- - mcp__sellable__cancel_find_leads
21
- - mcp__sellable__reissue_find_leads_watch_link
22
- - mcp__sellable__preflight_find_leads_provider
23
- - mcp__sellable__lookup_sales_nav_filter
24
- - mcp__sellable__search_sales_nav
25
- - mcp__sellable__search_prospeo
26
- - mcp__sellable__search_signals
27
- - mcp__sellable__select_promising_posts
28
- - mcp__sellable__import_leads
29
- - mcp__sellable__wait_for_lead_list_ready
30
- - mcp__sellable__get_rows_minimal
31
- - mcp__sellable__export_table_csv
3
+ description: Lead-strategy orchestrator for new Sellable campaigns. Turns kickoff context into a kickoff doc, feasibility check, progressive discovery plan, and selective deep-exploration recommendation.
4
+ visibility: internal
32
5
  ---
33
6
 
34
- # Sellable Find Leads
7
+ # Find Leads
35
8
 
36
- Use this public command when the user asks to find or source prospects, build a lead list,
37
- watch the list fill in real time, review leads, or export the list.
38
- It works without an existing campaign.
9
+ You own lead sourcing strategy for new Sellable campaigns.
10
+ This subskill is a kickoff-doc builder first, a provider-discovery orchestrator second.
11
+ Narrate progress briefly, write findings into the kickoff doc as you go, and stop at the explicit approval gates.
39
12
 
40
- ## Load the canonical workflow
13
+ ## Scope Boundary
41
14
 
42
- 1. Call `mcp__sellable__get_auth_status({})` and complete login/workspace setup
43
- if required.
44
- 2. Load `mcp__sellable__get_subskill_prompt({ subskillName: "find-leads-v2" })`.
45
- Continue chunks until `hasMore` is false.
46
- 3. Load `mcp__sellable__get_subskill_asset({ subskillName: "find-leads-v2",
47
- assetPath: "core/flow.v1.json" })`.
48
- 4. Execute that prompt and flow as the operational source of truth.
15
+ In scope:
49
16
 
50
- Do not emulate the workflow from memory or local files. If prompt or asset
51
- loading fails, use `search_subskill_prompts({ query: "find-leads-v2",
52
- includePublic: true, includeInternal: true })`, retry once, then give the
53
- workflow's reinstall/reload guidance.
17
+ - WHO to target
18
+ - WHY NOW signals
19
+ - sender LinkedIn access and provider readiness
20
+ - DIRECT / PROXIED / UNSUPPORTED feasibility mapping
21
+ - progressive discovery and explorer recommendations
22
+ - kickoff doc creation and final lead strategy
54
23
 
55
- Keep approval questions in the current chat. A source-plan approval allows only
56
- the bounded provider search. A later import approval is required before rows
57
- are materialized. Export uses the source list directly.
24
+ Out of scope:
25
+
26
+ - offer framing
27
+ - messaging drafts
28
+ - voice calibration
29
+ - DNC / calendar logistics
30
+ - campaign launch or lead import confirmation
31
+
32
+ Leave out-of-scope topics in `## Deferred to Create Campaign`.
33
+
34
+ ## Required Inputs
35
+
36
+ Use as many of these as are available. Use `Unknown` rather than inventing facts.
37
+
38
+ - client legal entity and product / brand name
39
+ - sender LinkedIn URL(s)
40
+ - existing ICP doc / persona sheet / targeting list
41
+ - optional kickoff transcript or notes
42
+ - optional draft campaign context from the caller
43
+
44
+ If a transcript is provided, mine it before asking live questions.
45
+
46
+ ## Shared Artifact
47
+
48
+ Create or update:
49
+
50
+ `~/.sellable/gtm-kickoffs/{client-slug}-{date}.md`
51
+
52
+ Minimum sections:
53
+
54
+ - `Status`
55
+ - `Client Identity`
56
+ - `Sender Access`
57
+ - `Source Material`
58
+ - `ICP Draft`
59
+ - `Feasibility Check`
60
+ - `Progressive Discovery Notes`
61
+ - `Lead Strategy`
62
+ - `Deferred to Create Campaign`
63
+
64
+ The kickoff doc is the resume surface. Re-open it before repeating discovery work.
65
+
66
+ ## Execution Backend Routing
67
+
68
+ Run source work in the parent thread with MCP provider tools. The packaged
69
+ Sellable install exposes only one normal background agent, Message Drafting, so
70
+ do not dispatch custom source-scout subagents for source comparison.
71
+
72
+ When two or more source angles are viable, compare them with bounded provider
73
+ probes from the parent thread. Load only the provider prompt for the active
74
+ provider, run the relevant search/import-preview tool, inspect a small sample,
75
+ then synthesize `lead-review.md` from the tool evidence.
76
+
77
+ If `multi_tool_use.parallel` is available, independent provider reads/searches
78
+ may run in parallel as tool calls. Otherwise run sequentially. Do not claim
79
+ agent work or missing install status to the customer; customer-facing output
80
+ should stay focused on source evidence.
81
+
82
+ ## Core Tools
83
+
84
+ - `mcp__sellable__enrich_sender`
85
+ - `mcp__sellable__get_provider_prompt`
86
+ - `mcp__sellable__search_signals`
87
+ - `mcp__sellable__fetch_post_engagers`
88
+ - `mcp__sellable__lookup_sales_nav_filter`
89
+ - `mcp__sellable__search_sales_nav`
90
+ - `mcp__sellable__search_prospeo`
91
+ - `mcp__sellable__search_prospeo_companies`
92
+ - `mcp__sellable__confirm_prospeo_company_accounts`
93
+ - `mcp__sellable__list_dnc_entries`
94
+ - `mcp__sellable__load_csv_dnc_entries`
95
+ - `mcp__sellable__load_csv_domains`
96
+ - `mcp__sellable__load_csv_linkedin_leads`
97
+ - host-native question flow / AskUserQuestion
98
+ - host-native local-file read/search tools when transcript or kickoff docs are on disk
99
+
100
+ ## Operating Rules
101
+
102
+ - Do not hallucinate customer proof, ICP filters, or sender readiness.
103
+ - If the user provides a blocklist, DNC, do-not-contact list, suppression list,
104
+ or "do not import/message these" domains/profiles, route it to
105
+ `load_csv_dnc_entries`. That tool writes to Sellable's workspace-level DNC
106
+ list after confirming the exact active workspace. Keep the mechanism to
107
+ Sellable DNC and `DNC Check`, not provider search work or Prospeo domain
108
+ filters.
109
+ - If the user asks to see the current DNC count, list names, or first page
110
+ before import, call `list_dnc_entries`. Report the active workspace name and
111
+ ID from the tool response before any DNC write.
112
+ - Do not infer sender identities from meeting attendance alone. Only treat someone as a sender when the source material explicitly identifies them as a sender or supplies their LinkedIn URL.
113
+ - Do not ask Layer 1 questions already answered by a transcript, ICP doc, or Layer 0 research.
114
+ - Do not include Apollo in the explorer set for this phase.
115
+ - Do not move to deep exploration until Gate 0 is approved.
116
+ - Do not finalize `## Lead Strategy` until Gate 2 is approved.
117
+ - Provider choice must be intent-relative and evidence-relative.
118
+ - Default source order for reply-likelihood-first outbound is `Signals -> Sales Nav -> Prospeo` unless the ask explicitly points elsewhere.
119
+ - If the user is explicit about the goal, route from that goal first.
120
+ - If the user is not explicit, infer the first hypothesis from the brief, then validate it with sample probes before recommending a lane.
121
+ - Before the first provider prompt, search, or signal-discovery
122
+ call, show the user a compact source plan and get approval. Write it in plain
123
+ customer language: which buyer groups or places you could check, the best
124
+ place to start, why the right buyers are likely to be there, what signs the
125
+ next search will check, where you'll look next if the first place is too thin,
126
+ and that approval only lets you look for the best places to find buyers. No
127
+ one is added to the campaign yet. The approval must come after the visible
128
+ plan; do not reuse a prior brief approval or generic approval panel.
129
+ - When enough context exists, try 1-2 alternate hypotheses if the first lane is too weak or noisy.
130
+ - Directional preview does not require a sender, campaign, or selected lead list. Start with count/sample exploration first; only attach searches to a campaign when the user is ready to import.
131
+ - If the user already has a LinkedIn-profile CSV, treat that as a direct lead-list path and skip discovery.
132
+
133
+ Execution flow:
134
+
135
+ 1. Confirm lead source with the user.
136
+ 2. If the user has a DNC/blocklist/suppression CSV or pasted domains/profiles,
137
+ call `load_csv_dnc_entries` first.
138
+ - Preview must name the exact Sellable workspace name and ID.
139
+ - Confirm only after the user agrees that this workspace should receive the
140
+ DNC entries.
141
+ - Campaign creation already includes `DNC Check`, which checks domain/profile
142
+ before message generation.
143
+ - If the user wants the existing DNC count or first page first, call
144
+ `list_dnc_entries` before previewing the import.
145
+ 3. If the user has a CSV of LinkedIn profile URLs on disk, call `load_csv_linkedin_leads` first.
146
+ - Preview, confirm, then review the resulting lead list before `confirm_lead_list`.
147
+ - Confirmed execution uploads the raw CSV file, starts the server-owned import job, and waits on lead-list readiness before returning.
148
+ - This path creates/appends a real lead list directly and does not use provider search/import jobs.
149
+ 4. If the user has a CSV of company domains on disk for known-account targeting, call `load_csv_domains` first.
150
+ - Use the returned `domainFilterId` in a provider search, then continue with `import_leads`.
151
+ 5. Otherwise run the appropriate search tool and collect a `searchId` if relevant.
152
+ 6. Call `import_leads` with:
153
+ - `campaignOfferId`
154
+ - `currentStep`
155
+ - `sourceLeadListId` OR `searchId`
156
+ - On success, `import_leads` owns the watched move to `confirm-lead-list`
157
+ after a lead list/job exists. Do not call `update_campaign` to fix the
158
+ import step.
159
+ 7. Call `wait_for_lead_list_ready` only for provider-imported lead lists (pass jobId/targetLeadCount from `import_leads` if available).
160
+ 8. Ask the user to review and confirm the list looks good.
161
+ 9. When the user confirms, call `confirm_lead_list` with:
162
+ - `campaignOfferId`
163
+ - `sourceLeadListId` (or omit to use `selectedLeadListId`)
164
+ - `jobId` (from `import_leads` when available; omit for direct CSV lead lists)
165
+ - `reviewBatchLimit: 15` for the internal campaign-table execution slice
166
+ 10. For campaign-builder flows, `confirm_lead_list` owns the watched move to
167
+ `filter-choice` after the initial campaign-table execution slice exists. Then run:
168
+ - `wait_for_campaign_table_ready({ campaignId })`
169
+ - `get_campaign_context({ campaignId, refresh: true })`
170
+ - `get_rows_minimal({ tableId: workflowTableId, limit: 10, page: 1 })`
171
+ 11. Report campaign table results.
172
+
173
+ ## Layer 0: Pre-research intake
174
+
175
+ 1. Confirm client identity: legal entity plus product / brand name.
176
+ 2. Confirm sender LinkedIn URL(s).
177
+ 3. Ask for any existing ICP doc, persona sheet, or targeting list.
178
+ 4. If a transcript or kickoff notes are available, extract WHO, WHY NOW, signals, exclusions, and sender-access facts before asking more questions.
179
+ 5. If no strong ICP doc exists, run `enrich_sender` for the sender URL(s) and collect company context from the sender / company snapshot.
180
+ 6. Draft a first-pass ICP hypothesis inside the kickoff doc.
181
+ 7. Present the draft with a lightweight correction gate:
182
+ - `close enough`
183
+ - `needs tweaks`
184
+ - `start over`
185
+ 8. Route:
186
+ - `close enough` -> skip most of Layer 1
187
+ - `needs tweaks` -> ask only the weak sections
188
+ - `start over` -> run full Layer 1
189
+
190
+ ## Layer 1: Trimmed interview (max 9 questions)
191
+
192
+ Use only the questions still missing after Layer 0.
193
+
194
+ ### Block A: WHO
195
+
196
+ 1. Primary persona + decision layers
197
+ 2. Company shape: industry, size, geography
198
+ 3. Exclusions: competitors, partners, over- / under-senior titles, DNC sources
199
+ 4. Ten-minute rubric: what makes a lead a `yes` or `no`
200
+
201
+ ### Block B: WHY NOW
202
+
203
+ 5. Pain or urgency trigger
204
+ 6. Signals that indicate active need now
205
+ 7. ABM list or named-account bias
206
+ 8. Competitor / adjacent-tool presence worth using as a proxy
207
+
208
+ ### Block C: Sender access
209
+
210
+ 9. Sender LinkedIn access and provider readiness (Sales Nav state, domain lists, LinkedIn URL CSVs)
211
+
212
+ For each answer, mark one of:
213
+
214
+ - `confident`
215
+ - `guess`
216
+ - `missing`
217
+
218
+ ## Layer 1.5: Feasibility Check
219
+
220
+ Before discovery, classify each ask as:
221
+
222
+ - `DIRECT` = at least one provider supports it natively
223
+ - `PROXIED` = only achievable through a weaker proxy
224
+ - `UNSUPPORTED` = no provider can satisfy it reliably
225
+
226
+ Write the result into `## Feasibility Check`.
227
+
228
+ ### Provider Capability Matrix
229
+
230
+ | Need | Signals | Sales Nav | Prospeo | Notes |
231
+ | ----------------------------------------- | ----------- | ---------------------------- | ----------- | ----------------------------------------------------------------------------------- |
232
+ | Recent behavioral intent | DIRECT | PROXIED via activity filters | UNSUPPORTED | Signals is the true behavior-first path |
233
+ | Posted recently on LinkedIn | PROXIED | DIRECT | UNSUPPORTED | Sales Nav `POSTED_ON_LINKEDIN` is the canonical proxy |
234
+ | Tight title + seniority + company filters | PROXIED | DIRECT | DIRECT | Sales Nav wins for live activity, Prospeo wins for broad verified-contact expansion |
235
+ | Named-account or domain-list targeting | UNSUPPORTED | PROXIED | DIRECT | Build a domain filter before `search_prospeo` |
236
+ | Company/account lookalikes | UNSUPPORTED | PROXIED | DIRECT | Use account search, approval, `companySearchToken`, then people search |
237
+ | Broad persona expansion | PROXIED | PROXIED | DIRECT | Prospeo replaces Apollo for this phase |
238
+ | LinkedIn profile CSV on disk | DIRECT | UNSUPPORTED | UNSUPPORTED | Use `load_csv_linkedin_leads` as the direct path, skip provider discovery |
239
+ | Existing Sellable lead list | DIRECT | DIRECT | DIRECT | Sample existing rows; do not re-source or pretend the list was discovered in-run |
240
+
241
+ ### Gate 0
242
+
243
+ Stop and ask:
244
+
245
+ - which threads should be pulled first
246
+ - which asks require proxies
247
+ - which asks are unsupported
248
+
249
+ Proceed only after approval.
250
+
251
+ ## Layer 2: Hypothesis-driven progressive discovery
252
+
253
+ Run light-touch discovery before deep dispatch.
254
+
255
+ ### Step 1: Choose the first hypothesis from intent
256
+
257
+ Pick the first lane from the ask, not from a fixed default:
258
+
259
+ - explicit goal = "reach out to people most likely to reply" or similar, and the TAM plausibly uses LinkedIn -> start with `Signals`, then fall back to `Sales Nav`, then `Prospeo`
260
+ - explicit competitor engagers, topic engagers, community leaders, or conversation participants -> start with `Signals`
261
+ - explicit active practitioners, recently active LinkedIn users, recently changed jobs, or tight role/company filters -> start with `Sales Nav`
262
+ - explicit ABM/domain targeting, hiring-led targeting, or broad verified-contact expansion -> start with `Prospeo`
263
+ - no explicit routing -> infer the most plausible first lane from the brief and why-now context
264
+
265
+ ### Step 2: Validate the first hypothesis with sample probes
266
+
267
+ Use the existing provider tools to run a small, directional probe:
268
+
269
+ - capture counts
270
+ - inspect first-page / top samples
271
+ - note false positives
272
+ - keep only one plain-English search link label when available, such as `Search link I'd use:`, so the user can open the recommended search directly; describe discarded searches in prose without additional links and avoid internal phrases like `chosen lane`
273
+ - decide whether the lane looks viable
274
+ - For function-specific lanes, do not trust generic seniority labels (`Head`, `Director`, `VP`) by themselves. Pair them with explicit function keywords in `person_job_title`, then inspect the sample for `Head of X` leakage before widening.
275
+
276
+ If the first probe is weak or noisy and enough context exists, try 1-2 alternate hypotheses before returning.
277
+ If the first probe has good quality but insufficient scale, iterate 1-2 times to widen intelligently before returning.
278
+ When two or more source angles are viable, run bounded parent-thread probes for
279
+ each credible lane. Examples: LinkedIn Engagement + Sales Nav, LinkedIn
280
+ Engagement + Prospeo Contact, or Sales Nav + Prospeo Contact. Compare the live
281
+ provider evidence and recommend the best source.
282
+
283
+ Treat refinement as a measured loop:
284
+
285
+ 1. start with a reasonable baseline
286
+ 2. judge quality and projected scale
287
+ 3. if quality is weak, tighten
288
+ 4. if quality is good but scale is below threshold, widen
289
+ 5. keep the best recipe found and explain why it won
290
+
291
+ ### Provider playbooks
292
+
293
+ #### `Signals`
294
+
295
+ Use first when the value is in conversation opportunity, competitor engagers, community participants, or visible why-now behavior.
296
+
297
+ - For reply-likelihood-first outbound, Signals is the preferred first pass whenever the TAM plausibly posts, comments, or engages on LinkedIn.
298
+ - Treat Signals as the highest-upside source for first-send quality because active posters and engagers usually reply at materially higher rates than the cold full-TAM pool.
299
+ - The downside is scale and activeness: there may not be enough fresh posts, enough ICP-fit engagers, or enough TAM activity on LinkedIn to sustain the campaign. Measure that directly before committing.
300
+
301
+ - Treat Signals inside `find-leads` as a spot check for lane viability, not a full discovery project.
302
+ - Prefer 2 strong hypotheses over broad search spam.
303
+ - Start with one batch of 5 keywords or equivalent competitor/community probes.
304
+ - If the first batch is ambiguous but still promising, run one second batch of 5 new keywords.
305
+ - Stop after that spot check unless the user explicitly wants deeper Signals work.
306
+ - Favor ICP-fit conversation density over raw post volume.
307
+ - Capture counts, false-positive patterns, and notable examples.
308
+ - If Signals is materially in the running, do not stop at post-level quality alone.
309
+ - Pick a few promising posts by default so the user can see real post-level
310
+ evidence. Start with 3-5 fresh, high-density posts when available; if only
311
+ 1-2 genuinely strong posts exist, sample those and say the lane needs more
312
+ inventory. If the sampled pass rate is good but the projected pool is below
313
+ target, recommend adding/scraping more similar posts as the expansion lever
314
+ before discarding Signals.
315
+ - Use `select_promising_posts` before the first `fetch_post_engagers` call when
316
+ Signals returns multiple candidate posts. That selection shows the
317
+ promoted posts, why they were chosen, and the post-level math the parent
318
+ thread will use for the Start Import recommendation.
319
+ - Sample a representative first page only, scoring the first 25-40 engagers across the chosen posts against a rough yes/no headline rubric or `headlineICPCriteria`.
320
+ - Use headline and display-name cues only for the spot-check sample; do not enrich people during this phase.
321
+ - Base `estimatedReachableLeads` on the sampled engager pass rate, not only on a guessed discount from post themes.
322
+ - Use a 10% planning floor after conservative cleanup. If the sampled/projected
323
+ fit rate is below 10%, do not scale Signals; move to Sales Nav recent activity
324
+ instead.
325
+ - A Signals lane with ~150+ estimated ICP-fit reachable engagers from selected
326
+ posts is viable for a focused warm campaign, even if Sales Nav is more
327
+ scalable. Do not discard that lane solely for being smaller. If post-level
328
+ filtering likely reduces 150 good fits to ~100 after stricter cleanup, say so
329
+ plainly and treat it as a viable-but-smaller option.
330
+ - When Signals and Sales Nav/Prospeo are both viable, present the tradeoff and
331
+ ask for the user's source preference if the decision changes campaign
332
+ strategy: Signals = warmer, smaller, higher reply upside; Sales Nav/Prospeo =
333
+ more scalable, usually colder or less signal-rich. Recommend the source you
334
+ believe is better, but keep the viable alternate as a real option.
335
+ - When Signals was searched or considered, do not recommend skipping or
336
+ discarding it until the user can see the post-level math. Show a compact
337
+ LinkedIn posts table with the keyword lane, selected/finalist post URL or
338
+ title, post age, engager count, sampled engagers, good fits as `n/N`,
339
+ estimated usable prospects per post, and use/discard decision. This table is
340
+ the evidence for how many posts to scrape; raw post count alone is not enough.
341
+ If the first few posts look good but do not produce enough volume, say how
342
+ many more posts to add/scrape next instead of treating the lane as failed.
343
+ - If you cannot fetch engagers in the current runtime, say the estimate is inferred and lower confidence.
344
+ - If Signals is too sparse, too noisy, or clearly below campaign scale after the spot check, fall back to `Sales Nav` rather than forcing a weak conversation-led lane.
345
+
346
+ #### `Sales Nav`
347
+
348
+ Use first when LinkedIn activity plus tighter role / company filters matter.
349
+
350
+ - Always call `lookup_sales_nav_filter` before dynamic filters.
351
+ - Start with a broad-but-reasonable baseline: company size + core roles + core industries.
352
+ - If the campaign gives specific target role names, preserve them with
353
+ `CURRENT_TITLE` lookups. Seniority filters are supporting constraints, not a
354
+ substitute for target roles. Example: VP Sales / VP Revenue / Head of Growth
355
+ should use title filters, not only `SENIORITY_LEVEL: Vice President`.
356
+ - When a title lookup returns multiple options, choose the option that most
357
+ closely matches the intended role, not the first option by position. If
358
+ `Head of Growth` appears after `Head of Marketing`, use `Head of Growth`.
359
+ - For reply-likelihood-first outbound, Sales Nav is the second choice after Signals: use it when the TAM is not active enough on LinkedIn, when Signals cannot sustain enough good fits, or when the targeting thesis depends on tighter role/company control than Signals can provide.
360
+ - For InMail or LinkedIn-send motions, establish the baseline TAM first, then test a `POSTED_ON_LINKEDIN` slice when the pool can still sustain a campaign.
361
+ - Treat recent posters as a preferred first-send slice, not just a nice-to-have proxy. When the recently-posted slice still yields enough projected good fits, prefer it because reply / acceptance performance is usually materially better than the cold full-TAM pool.
362
+ - When explaining a LinkedIn source decision, make the buying logic obvious:
363
+ pick people who are good fits and active enough to be worth a LinkedIn test.
364
+ Compare source paths by expected volume, sampled ICP fit, activity/warmth
365
+ signal, cleanup risk, and tradeoffs.
366
+ - Do not forecast connection acceptance rates, reply rates, meetings, pipeline,
367
+ revenue, or ROI unless the user supplied verified benchmark data for this
368
+ exact workspace/sender. Without that data, say performance is not estimated
369
+ from the source review.
370
+ - Use these rough planning bands only as directional defaults when better
371
+ workspace/founder data is not available: Signals/recent engagers = lower
372
+ volume, higher reply upside; Sales Nav with recent LinkedIn activity = medium
373
+ volume and stronger acceptance/reply odds; broad Sales Nav = higher volume
374
+ with weaker reply odds; Prospeo/domain expansion = scale/account coverage but
375
+ usually weaker LinkedIn reply odds unless paired with strong signals.
376
+ - If the recently-posted slice becomes too small, remove the `POSTED_ON_LINKEDIN` filter and continue refining the non-posted baseline with the other role / company / industry filters.
377
+ - When you fall back from the recently-posted slice, say clearly that the posted filter was tested, explain why it was dropped, and keep the best non-posted lane as the source of truth.
378
+ - Use `RECENTLY_CHANGED_JOBS` when job-change activity is part of the targeting thesis.
379
+ - If quality is poor, tighten the lane with role, industry, seniority, geography, or activity filters.
380
+ - After each Sales Nav preview, sanity-check the result before using it in the
381
+ decision: the returned `searchUrl` should include filters, the first page
382
+ should visibly match the intended roles and companies, and the count should
383
+ be plausible. If filters did not apply, the search errors, or the total looks
384
+ obviously unfiltered, retry once with clean filter objects. If it still fails,
385
+ mark Sales Nav as a provider/tool issue and do not include it as a winning
386
+ source.
387
+ - If quality is good but scale is too small, widen the lane by adding/removing roles, expanding industries, widening headcount bands, or relaxing activity constraints.
388
+ - Use the same 10% planning floor after cleanup. If the final Sales Nav lane is
389
+ projected below 10% good-fit after reasonable refinement, move to Prospeo
390
+ rather than importing a noisy Sales Nav list.
391
+ - Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
392
+ - If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
393
+ - If you can name a specific next Sales Nav refinement that is still allowed by the probe budget, execute it before returning instead of listing it only as a recommendation.
394
+ - Only leave an obvious next Sales Nav refinement unexecuted when you already hit the search cap, the tool/runtime blocked it, or the previous refinement already showed quality breaking down.
395
+ - Keep widening until the lane is clearly scalable, quality breaks down, or no reasonable expansion remains.
396
+ - Stop when the lane is clearly scalable, clearly exhausted, or no longer improves.
397
+
398
+ #### `Prospeo`
399
+
400
+ Use first for broad persona expansion, ABM/domain targeting, hiring-led targeting, or scale once the lane is known.
401
+
402
+ - Never pass raw domains to `search_prospeo`.
403
+ - Create a `domainFilterId` first.
404
+ - Use Prospeo instead of Apollo for broad verified-contact expansion.
405
+ - For reply-likelihood-first outbound, Prospeo is the fallback path after Signals and Sales Nav. Use it when LinkedIn-native sources cannot produce enough good fits, when the TAM is not active enough on LinkedIn, or when domain/account expansion is the clearest remaining move.
406
+ - Start with the most likely person + company baseline for the ask.
407
+ - For security, AppSec, SOC, RevOps, Demand Gen, and similar function-specific lanes, prefer explicit function-title anchors first (`Head of Security`, `Director of Security Operations`, `VP of Demand Gen`) instead of generic seniority plus a department guess.
408
+ - If you widen with seniority labels such as `Head` or `Director`, keep a matching department/function constraint and inspect the sample for off-function leakage such as `Head of Social Media`, `Head of IT`, or `Director of Finance`.
409
+ - If quality is poor, tighten titles, company shape, seniority, geography, or hiring filters.
410
+ - If quality is good but scale is too small, widen titles, industries, company-size bands, or account scope.
411
+ - For companies like X, our best customers, lookalike accounts, companies that use AI, companies with API/SSO/Chrome extension, or
412
+ news/award/integration/key-customer account filters, use
413
+ `search_prospeo_companies` before people search.
414
+ - For lookalike seed selection, route by campaign intent. In outbound/sales
415
+ prospecting campaigns, treat "best customer", "top customer", "target
416
+ domains", "approved accounts", "customer domains", and similar wording as
417
+ target account/customer seed asks. Use explicit user-provided
418
+ target/account/customer domains or company names first, then verified
419
+ past-customer/account evidence from research, CRM, or proof. Never substitute
420
+ the sender's current company/domain or employer history as a lookalike seed for
421
+ outbound unless the user explicitly confirms that domain is a target/customer
422
+ seed or asks for sender-company peers. In job-search/application campaigns,
423
+ lookalike seeds may be existing companies from the candidate's current or past
424
+ employers because those companies define the candidate-fit lane. If campaign
425
+ intent or seed source is ambiguous, ask whether the seed should be
426
+ target/customer domains or current/past employers; if YOLO requires moving
427
+ without a seed, switch to non-lookalike company filters instead of inventing a
428
+ seed. If the user asks for a geography like Germany, preserve it in account
429
+ discovery where supported (`company_location_search` or
430
+ `company_icp.geographic_markets`) and in follow-on people search
431
+ (`person_location_search`); do not drop geography when moving from lookalike
432
+ accounts to people leads.
433
+ - Use Prospeo company/account search when the ask depends on website traffic
434
+ (`company_website_traffic`), confirmed AI Attributes including `pricing`,
435
+ `uses_ai`, `has_api`, `has_chrome_extension`, `has_sso`, `has_open_source`,
436
+ `has_marketplace`, `has_blog`, `has_knowledge_base`, `has_soc2`,
437
+ `data_residency: "EU"`, website pages, products, integrations, key
438
+ customers, Google discovery, location headcount, or structured ICP.
439
+ - When using `company_icp.company_sizes` for micro/SMB/midmarket or enterprise
440
+ sizing, pair it with `company_headcount_range` or rely on MCP normalization
441
+ that derives the range; inspect the account sample for size drift before
442
+ approving accounts.
443
+ - For lookalike seeds passed as `seedCompanies` or `seedDomains`, omit
444
+ `company_oids`; the MCP backend resolves real Prospeo company IDs. Do not
445
+ invent company_oids.
446
+ - For company ICP geography, `geographic_scope` only accepts `single_country`
447
+ or `multi_country`; put North America style regions in `geographic_markets`
448
+ as specific markets such as United States and Canada.
449
+ - Product is not a company_icp.departments value; use `titles_include` for
450
+ product roles. Allowed company ICP departments include Consumers, Customer
451
+ Success, Data, Design, Engineering, Finance, HR, IT, Legal, Marketing,
452
+ Operations, Procurement, SMB Owners, Sales, and Security.
453
+ - `company_keywords.include/exclude` values must be at least 3 characters; use
454
+ `artificial intelligence` instead of `AI`, or use confirmed attributes such
455
+ as `uses_ai` when that is the actual signal.
456
+ - Use `company_key_customers` as a standalone first-pass account filter; in
457
+ short, run company_key_customers as a standalone first-pass. Do not
458
+ combine `company_key_customers` with `company_website_search`, `company_icp`,
459
+ `company_keywords`, or broad AI Attributes in the first call.
460
+ - Do not combine `company_key_customers` with ICP, website-search, keyword,
461
+ attribute, industry, or headcount filters until the standalone pass proves
462
+ useful.
463
+ - Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms; use
464
+ confirmed attributes or spell out artificial intelligence, application
465
+ programming interface, go to market, and software as a service.
466
+ - Do not send `company_keywords.exclude` unless at least one include keyword is
467
+ present. Do not duplicate `company_industry` when `company_icp.industries`
468
+ already carries the industry.
469
+ - For seeded company lookalikes, keep the first call simple: resolved seed
470
+ company/domain plus `company_lookalike.minimum_tier` and simple confirmed
471
+ attributes, headcount, or industry. Do not add `company_website_search`,
472
+ `company_keywords`, or `company_icp` until the account sample proves the seed
473
+ works. Do not send placeholder seed names like `another approved best-customer seed`,
474
+ and only use concrete companies or domains you actually resolved. If another approved seed is referenced but not named, ask for it or run one seed without `match_all`; do not invent a second seed from examples, competitors, or exclusions. Prefer `seedDomains`
475
+ for single-seed lookalikes. For multi-seed `match_all` lookalikes, use concrete company names unless you already know the exact canonical Prospeo domains; do not mix both in one seeded lookalike call. Do not combine `has_api` and `has_sso` in the first seeded lookalike call; start with
476
+ `has_api` and refine after a valid account sample if SSO still matters. Do not send `company_website_search.exclude_keywords` without a positive website include signal.
477
+ - Do not use `company_intent`. Do not invent unsupported support-channel filters
478
+ or AI Attribute guesses like phone/email/chat/ticket/social.
479
+ - Company/account search returns an account sample only; account rows are not people leads yet. Ask the user to approve the account sample.
480
+ - After approval, call `confirm_prospeo_company_accounts` with the
481
+ `companySearchToken` and selected Prospeo company IDs from
482
+ `search_prospeo_companies`; do not reconstruct account rows or domains
483
+ manually. Always copy the `companySearchToken` exactly; package-backed MCP may
484
+ return a short `mcp-prospeo-company-search-token:*` reference to avoid
485
+ long-token copy errors.
486
+ - Use the returned `domainFilterId` in the follow-on `search_prospeo` people
487
+ search.
488
+ - For post-confirm people search, prefer `person_job_title.boolean_search` for
489
+ long role synonym lists instead of many `person_job_title.include` values plus
490
+ broad department/seniority filters.
491
+ - Prospeo is the terminal fallback for this chain. If projected fit is still
492
+ below the 10% planning floor after reasonable Prospeo refinement, stop and ask
493
+ for a tighter ICP/source direction instead of inventing another provider.
494
+ - When ABM/domain targeting exists, prefer refining around the account set before broadening away from it.
495
+ - Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
496
+ - If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
497
+ - If you can name a specific next Prospeo refinement that is still allowed by the probe budget, execute it before returning instead of listing it only as a recommendation.
498
+ - Only leave an obvious next Prospeo refinement unexecuted when you already hit the search cap, the tool/runtime blocked it, or the previous refinement already showed quality breaking down.
499
+ - Keep widening until the lane is clearly scalable, quality breaks down, or no reasonable expansion remains.
500
+ - Stop when the lane is clearly scalable, clearly exhausted, or no longer improves.
501
+
502
+ Document for each tested path:
503
+
504
+ - why it was chosen
505
+ - what was tested
506
+ - rough TAM / result quality
507
+ - sample size used for quality estimation
508
+ - sampled pass rate for the rough ICP rubric when available
509
+ - `sampledCount` when a lane used a sampled people review
510
+ - `passCount` when a lane used a sampled people review
511
+ - `passRate` when a lane used a sampled people review
512
+ - `projectedRange` for the projected usable or reachable pool that follows from the sample
513
+ - `recentStrongPostCount` when Signals is involved
514
+ - `freshEnoughPostCount` when Signals is involved
515
+ - `avgUsableEngagersPerStrongPost` when Signals is involved
516
+ - estimated usable conversations after sample-quality filtering
517
+ - estimated reachable leads if the team later scrapes or engages the usable lane
518
+ - notable false positives
519
+ - keep / discard decision
520
+ - what to deepen vs discard next
521
+
522
+ When the lane is intended for scalable outbound, classify the projected pool:
523
+
524
+ - `< 500` good fits -> below minimum for a scalable lane; say so explicitly
525
+ - `500-2499` good fits -> workable but may need supplementation or tighter sequencing
526
+ - `2500+` good fits -> ideal scalable lane
527
+
528
+ Do not treat a lane as "good enough" for scale if it does not clear the minimum threshold.
529
+ If a lane is below minimum but clearly promising, return it as "below minimum unless expanded" and include the exact next refinement steps that should be tried.
530
+ Do not claim a percent discount or projected-good-fit estimate unless it comes from a visible sample or you explicitly label it as a weak inference.
531
+
532
+ ### Gate 1
533
+
534
+ Show the light-touch results and ask whether to deep-dispatch or iterate.
535
+
536
+ ## Layer 3: Selective deep exploration
537
+
538
+ Run only the validated paths from Gate 1 with parent-thread provider probes.
539
+ Each explored lane must return:
540
+
541
+ - hypothesis tested
542
+ - search recipe / filters
543
+ - counts
544
+ - best-fit examples
545
+ - failure modes / false positives
546
+ - recommended next move
547
+
548
+ Synthesize the results into `## Lead Strategy`:
549
+
550
+ - ranked personas
551
+ - best source order
552
+ - why each lane won or lost based on evidence, not just totals
553
+ - estimated count range or usable-yield range for the winning lane
554
+ - whether the estimate came from sampled people or only inferred pass-through
555
+ - explicit scale judgment for the winning lane:
556
+ - below minimum
557
+ - workable
558
+ - ideal
559
+ - exclusion rules
560
+ - recommended explorer set
561
+ - WHY NOW signals to bias toward
562
+ - fallback path when the first source underperforms
563
+ - why the non-winning lanes were deprioritized
564
+
565
+ ### Gate 2
566
+
567
+ Ask for approval before freezing the lead strategy.
568
+ After approval:
569
+
570
+ - set kickoff doc status to `FINALIZED`
571
+ - leave offer / messaging / logistics inside `## Deferred to Create Campaign`
572
+ - return the kickoff doc path and summary
573
+
574
+ ## Use Case Playbook
575
+
576
+ - Competitor engagers / topic engagers / community leaders -> `Signals` first, then `Sales Nav` if title/company tightening is needed
577
+ - Behavior or intent heavy ICP with enough ICP-fit conversation density -> `Signals` first; if too noisy, fall back to `Sales Nav`
578
+ - Tight role / company list with strong LinkedIn access -> `Sales Nav` first, then `Prospeo` if the pool is too small
579
+ - Broad persona expansion, named-account targeting, or hiring-led targeting -> `Prospeo` first when it is the clearest lane, else use `Sales Nav` to validate before scaling
580
+ - Existing LinkedIn URL CSV -> bypass discovery and use `load_csv_linkedin_leads`
581
+ in preview mode before approval; do not pass `confirmed: true`,
582
+ `campaignOfferId`, `currentStep`, `leadListId`, or `sourceLeadListId`.
583
+ - Existing Sellable lead list -> bypass discovery and sample from the existing
584
+ rows before approval. The review must say the list was supplied/reused, not
585
+ discovered during this run.
586
+ - Existing domain CSV -> use `load_csv_domains` to create a standalone
587
+ `domainFilterId`, then run a campaignless Prospeo people sample constrained
588
+ by that filter. If the sample is empty or too small, ask whether to widen role
589
+ filters, add domains, or abort; never remove the domain constraint silently.
590
+
591
+ For supplied sources, produce `lead-review.md` and `lead-sample.json` with
592
+ source type, source row/account counts, invalid/duplicate counts, sample method,
593
+ likely-good message handoff rows, and next action. Avoid generic TAM language
594
+ for supplied profile rows and existing lead lists.
595
+
596
+ ## Output Contract
597
+
598
+ Return:
599
+
600
+ - `kickoffDocPath`
601
+ - `status`
602
+ - `recommendedSearchOrder`
603
+ - `validationSummary`
604
+ - `sampledCount`
605
+ - `passCount`
606
+ - `passRate`
607
+ - `projectedRange`
608
+ - `recentStrongPostCount`
609
+ - `freshEnoughPostCount`
610
+ - `avgUsableEngagersPerStrongPost`
611
+ - `estimatedUsefulConversations`
612
+ - `estimatedReachableLeads`
613
+ - `scaleAssessment`
614
+ - `recommendedExplorerSet`
615
+ - `feasibilitySummary`
616
+ - `topPersonas`
617
+ - `deferredTopics`
618
+ - `nextAction`
619
+
620
+ ## Acceptance Rehearsal
621
+
622
+ Before calling this prompt ready, rehearse it against:
623
+
624
+ - `./.planning/phases/02-lead-list-building-automation/02-AMPLIFY-KICKOFF-TRANSCRIPT.md`
625
+
626
+ Compare the resulting kickoff doc outline against:
627
+
628
+ - `./.planning/phases/02-lead-list-building-automation/02-DRYRUN-AMPLIFY-GTM-KICKOFF.md`
629
+
630
+ Passing rehearsal means the prompt can:
631
+
632
+ - extract the ICP / persona layers from the Amplify call
633
+ - write a feasibility check
634
+ - recommend source order from brief quality plus sample evidence instead of one fixed default
635
+ - try alternate hypotheses when the first lane is too weak or noisy
636
+ - estimate recent usable conversation volume instead of only saying keep/discard
637
+ - say clearly when a lane is below the minimum scalable threshold instead of over-recommending it
638
+ - widen and retest a promising but under-scaled lane before returning
639
+ - produce a kickoff doc shape that matches the dry-run sections closely enough for human review