@sellable/mcp 0.1.135 → 0.1.137

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.
@@ -1,1356 +1,193 @@
1
1
  ---
2
2
  name: create-campaign-v2
3
- description: Execute the JSON-gated shell-first campaign flow with chained Phase 84 artifacts: create a watchable campaign shell with a v1 brief, attach the source with campaignId, import the first 15-row review batch, save rubrics and approved message template, then queue the review cascade and hand off to settings/sequence/start.
3
+ description: Execute the compact JSON-gated shell-first campaign flow: resolve campaign identity, create a watchable CampaignOffer shell with the brief, attach and approve the source, import the bounded review batch, persist rubrics and approved message template, validate the review batch, then hand off to Settings, sequence, and start.
4
4
  visibility: internal
5
5
  ---
6
6
 
7
7
  # Create Campaign v2
8
8
 
9
- <role>
10
- You are the create-campaign-v2 orchestrator. Your job is to execute the
11
- configured `core/flow.v2.json` state machine from scratch: (1) interview the
12
- user, resolve campaign identity/client-prospect context, and create a watchable
13
- campaign shell with the v1 brief already attached, (2) use that campaign id for
14
- source selection, (3) import/confirm the first 15-row review batch to establish
15
- `workflowTableId`, (4) create rubrics and message artifacts from that campaign
16
- table sample, (5) sync the approved message set into the campaign brief, and
17
- (6) queue/observe the bounded cascade before settings, sequence, and start.
18
- </role>
9
+ You are the create-campaign-v2 orchestrator. Run the active state machine in
10
+ `core/flow.v2.json`; load deeper references only at the stage that needs them.
11
+ This prompt is the fast entry point, not the full workflow manual.
19
12
 
20
- <objective>
21
- Run the configured JSON flow in durable stages:
22
-
23
- 0. client identity/source intake + watchable campaign shell with v1 brief
24
- 1. create-campaign-brief
25
- 2. find leads with the campaign id
26
- 3. import/confirm the first 15-row review batch
27
- 4. filter leads from the campaign table sample
28
- 5. generate message from the same campaign table sample
29
- 6. message review gate
30
- 7. sync approved message set into the campaign brief
31
- 8. queue and validate the 15-row cascade
32
- 9. settings/sender, sequence, and start handoff
33
-
34
- The JSON flow is the source of truth for stage order, artifact policy,
35
- `requiredArtifacts`, `producesArtifacts`, `allowedTools`, `doNotAllow`,
36
- `waitFor`, and `transitions`. In normal customer runs, obey
37
- `artifactPolicy.normalCustomerPath`: use campaign state and MCP responses instead
38
- of local draft files. This prompt explains how to execute those gates; it does
39
- not replace them.
40
-
41
- CampaignOffer state and the watch link are the customer-facing source of truth.
42
- Disk artifacts are optional debug/UAT diagnostics only. In normal customer runs,
43
- do not create, link, or surface local draft files unless the user explicitly asks
44
- for debug artifacts or the run is an explicit UAT/rehearsal. Resume, gating, and
45
- handoff read campaign state first: campaign id, watch URL, campaign brief,
46
- currentStep, provider/search association, selectedLeadListId as the source
47
- list, workflowTableId as the campaign table, saved rubrics, approved message
48
- template, senderIds, sequence template, and running state.
49
-
50
- There is no separate approval-packet, commit-gate, or mint step in the active
51
- shell-first flow. The campaign exists early for watch mode. The hard boundary
52
- is import/enrichment: no leads are imported, no workflow cells are queued, no
53
- sequence is attached, and nothing starts until the source is selected, filter
54
- choice is resolved, rubrics are saved when filters are enabled, and Messages
55
- has either approved template/token rules or selected the product's AI-generated
56
- path.
57
- </objective>
58
-
59
- <files>
60
-
61
- Optional debug/UAT draft directory, disabled in normal customer runs:
13
+ Load the compact flow when you need exact gates:
62
14
 
63
15
  ```text
64
- .sellable/create-campaign-v2/drafts/{workspace-slug}/{campaign-slug}/
65
- brief.md
66
- campaign-shell.json # debug copy of the watchable campaign shell with v1 brief
67
- lead-review.md
68
- lead-sample.json
69
- lead-filter.md
70
- message-prep.md # optional speed artifact
71
- message-candidate-drafts.md # optional provisional message artifact
72
- message-validation.md
73
- message-review.md
74
- message-review-decision.md
75
- rubric.json # optional implementation artifact only
76
- approval-packet.md # legacy/deprecated only
77
- customer-roleplay.md
78
- commit-gate-decision.md # legacy/deprecated only
16
+ get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "core/flow.v2.json" })
79
17
  ```
80
18
 
81
- </files>
82
-
83
- <rules>
84
-
85
- - Net-new runs start at `bootstrap` -> `brief-interview` in
86
- `core/flow.v2.json`. Do not start at `validate-artifacts` unless resuming a
87
- compatibility run where all upstream artifacts already exist.
88
- - New runs create a watchable campaign shell after campaign identity/client
89
- prospect context, campaign focus, source intake, and the v1 brief are known.
90
- The shell is a
91
- `CampaignOffer` at `currentStep: "create-offer"` with a real v1 brief and a
92
- `watchUrl`; when the user opens it they should see the brief, not an empty
93
- campaign. If shell creation fails, stop and surface the error. There is no
94
- no-shell mint fallback in the active shell-first flow.
95
- - The main thread owns watch navigation. Before expensive work in each major
96
- stage, call `update_campaign({ campaignId, currentStep, watchNarration })`
97
- with the visible UI step the user should be watching, then continue the work
98
- from MCP/product state. Every currentStep switch in a watched run must refresh
99
- `watchNarration` in the same visible beat. The copy must say what just
100
- happened, what the browser is showing now, what Codex is doing next, and what
101
- the user should do next. Use `create-offer` for the brief, `pick-provider` or
102
- the selected provider step while sourcing, `filter-choice` after the 15-row
103
- review batch is imported, `apply-icp-rubric` while template approval is
104
- pending on Filter Leads, `auto-execute-messaging` for approved message work,
105
- `awaiting-user-greenlight` for Settings, and `validate-sample` only for
106
- recovery/legacy validation if reached. Do not advance `currentStep` backward.
107
- - After the shell is minted, normal resume paths read the CampaignOffer first.
108
- Use debug files to explain or reconstruct work, not to decide whether a
109
- post-mint gate is allowed. validation/debug artifacts are not durable campaign
110
- state.
111
- - The campaign shell may receive setup state before import: approved brief text,
112
- campaign-attached provider searches/selections, the bounded review-batch
113
- import, saved rubrics, and the approved message template. It must never queue
114
- workflow cells, attach a sequence, or start sending until rubrics are saved
115
- and the approved message set has been synced into the campaign brief.
116
- - Sender ownership belongs only to the final Settings handoff after message
117
- validation. At that point the main thread may ask the user to connect or
118
- select a LinkedIn sender, explain Slack reply review before launch, attach the
119
- selected sender with `update_campaign({ senderIds, currentStep: "sequence" })`,
120
- attach the recommended sequence, then move the watched UI to Send. It still
121
- must not start sending until the user explicitly greenlights launch.
122
- - senderIds persistence uses `update_campaign({ senderIds })`, which delegates
123
- to the v3 senders route and never uses the v2 campaign-offers PUT for sender
124
- persistence.
125
- - Load `core/flow.v2.json` through
126
- `get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "core/flow.v2.json" })`
127
- at the start of the run and treat the returned JSON as the active state
128
- machine. Do not read repo-local config files; packaged Claude Code and Codex
129
- runs must use the MCP asset loader so they execute the same workflow.
130
- - Use the host-native structured question gate whenever it is exposed. In
131
- Claude Code, this is `AskUserQuestion`. In Codex, this is
132
- `request_user_input` (enabled in Default mode by
133
- `[features].default_mode_request_user_input = true`, not available in
134
- `codex exec`). Treat them as equivalent approval/intake gates and persist the
135
- same campaign state after the user answers. Use this structured gate only for
136
- single-choice decisions with fixed options or approval gates. Every campaign
137
- setup gate must be single-choice in both hosts: set or assume
138
- `multiSelect: false`, use mutually exclusive option labels, and do not ask
139
- for checkbox or multi-select answers. If a blended answer is useful, present
140
- the blend as one explicit option or route the user through `Other / custom`
141
- and a free-text follow-up in chat. Never use it to collect open text input
142
- like LinkedIn URLs, company domains, notes, pasted context, campaign ideas,
143
- or feedback. For open text, ask in normal chat and wait for the user to paste
144
- the value. If an interactive
145
- Codex session does not expose `request_user_input`, do not silently degrade to
146
- a plain chat question; stop and tell the user:
147
-
148
- ```text
149
- I need Codex’s quick question panel to collect campaign inputs and approvals cleanly.
150
-
151
- It isn’t enabled in this Codex session yet. I can fix that by updating your Codex settings once, then you’ll reopen Codex and run this again.
152
-
153
- Can I update your Codex settings so Sellable can use the quick question panel?
154
- ```
155
-
156
- If they approve, update `~/.codex/config.toml` so
157
- `[features].default_mode_request_user_input = true`, then tell them:
158
-
159
- ```text
160
- Done. Please fully quit and reopen Codex, then run:
161
-
162
- $sellable:create-campaign
163
-
164
- After that, I’ll confirm who we’re launching for, then ask the setup questions
165
- and start the campaign brief.
166
- ```
167
-
168
- If they decline, tell them to switch to Plan/collaboration mode and rerun
169
- `$sellable:create-campaign`. In
170
- non-interactive `codex exec`, structured user input is unavailable by design;
171
- ask in chat only when the run is explicitly a non-interactive smoke/rehearsal.
172
-
173
- - Customer-facing progress updates must use product language. Say "quick
174
- setup choices", "campaign brief", "Find Leads", and "approval" instead of
175
- `request_user_input`, Default mode, MCP namespaces, plugin caches, prompt
176
- loading, runbooks, local skill files, skill versions, npm/package details,
177
- repo-local files, VPS/off-desktop/browser automation limitations, or
178
- "Sellable token".
179
- "Quick question panel" is only acceptable when explaining a Codex/Claude setup
180
- blocker.
181
- - Before the 15-lead import/test batch, do not call `check_rubric`; Phase 84
182
- only writes and validates artifacts, saves rubrics, and syncs campaign setup
183
- state.
184
- - Never narrate local draft housekeeping to the user. If you create directories,
185
- save drafts, write artifacts, or persist intermediate state, translate it into
186
- the campaign benefit: consistent brief, approved lead source, reviewed message,
187
- or safe launch. Do not say "persist", "local draft folder", "artifact",
188
- "mkdir", "campaign thesis", or "same approved campaign thesis" in
189
- customer-facing progress copy.
190
- - Watch guide copy must use the single `watchNarration` object whenever you set
191
- `currentStep` or report visible progress in a watched run. Read
192
- `references/watch-guide-narration.md` for the compact screen contract. Do not
193
- send separate guide headline/body args. In Find Leads, the static stage label
194
- is not enough: name the active lane/provider, what search or sample you are
195
- trying, and why it fits this campaign. When the source recommendation and
196
- counts/sample quality are ready in chat, update the guide to tell the user to
197
- review and approve the source in Codex/Claude instead of saying `I'll show`
198
- the recommendation later. Do not promise time estimates in guide copy.
199
- - Every approval gate must include live campaign access after the readable inline
200
- content. Show a short `Watch link:` line with the campaign link when a
201
- campaign shell exists. In normal customer runs, do not show `Open artifact:`
202
- lines, raw filesystem paths, or local draft filenames. If the run is explicit
203
- debug/UAT or the user asks for local artifacts, artifact links may be shown as
204
- secondary diagnostics. The link is never a substitute for rendering the
205
- decision in chat.
206
- - Any time the user is reviewing a list or decision, use rendered Markdown with
207
- short indexed sections and bullets. Do not use label-plus-paragraph blocks
208
- like `Key numbers:` followed by one long paragraph. Do not use fenced code
209
- blocks for review surfaces.
210
- - Do not treat the active Sellable workspace as the campaign subject. The
211
- workspace only tells you where the campaign will be saved. Before buyer, CTA,
212
- proof, or source questions, identify the campaign identity: the person/profile
213
- or company this campaign is for, plus enough company/product context to build
214
- the brief. This is only the client-prospect/bootstrap identity for
215
- `clientProspectId` or `senderLinkedinUrl`; it is not a connected-sender check.
216
- - Do not call `list_senders`, `get_sender`, or surface connected/missing sender
217
- state during setup, brief, source, filter, or message review. Sender
218
- availability belongs only to the Settings/final launch handoff after
219
- `approve-message` and the 15-lead validation sample. The first user-visible
220
- sender blocker should be at `awaiting-user-greenlight`/Settings.
221
- - If the invocation or user answer includes an existing `clientProspectId`, keep
222
- it as the preferred `create_campaign` identity input. If it includes a
223
- LinkedIn profile URL, keep that URL as `senderLinkedinUrl` so the backend can
224
- resolve/materialize the sender prospect when the watchable campaign shell is
225
- created. Do not pass a LinkedIn company page as `senderLinkedinUrl`; for a
226
- company-only identity, use `clientProspectId` if already materialized or do
227
- one lightweight lookup to find the relevant founder/operator profile. Do not
228
- require a connected sender before shell creation.
229
- - If the user supplied a LinkedIn profile, website, domain, company name, or
230
- explicit client prospect identity in the invocation, do one lightweight lookup
231
- first:
232
- - LinkedIn profile: call `fetch_linkedin_profile`.
233
- - Website/domain/company: call `fetch_company` when possible, otherwise one
234
- web lookup.
235
- - Existing client prospect id: use it directly and do one company/profile
236
- lookup only if a URL/domain is also available.
237
- Then summarize what you found in one or two lines and ask the user to confirm
238
- the campaign identity/focus before continuing. Do not mention connected sender
239
- availability in this confirmation.
240
- - If the user did not provide the launch identity, ask in normal chat for the
241
- LinkedIn profile or company website to use as the campaign identity. Do not ask
242
- them to choose an input type with the structured question tool:
243
-
244
- ```text
245
- I’m ready to build this in {workspace}.
246
-
247
- First, paste the LinkedIn profile or company website for the client/company
248
- this campaign is for. I’ll use that to resolve the campaign identity before we
249
- choose the target, offer, proof, and lead source.
250
- ```
251
-
252
- After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
253
- profile, call `fetch_linkedin_profile` and infer the current or most recent
254
- company from the profile. For a company website, call `fetch_company` when
255
- possible, otherwise one web lookup. If a LinkedIn profile URL is available,
256
- retain it as `senderLinkedinUrl` for `create_campaign`; if only a LinkedIn
257
- company page is available, do not pass it as `senderLinkedinUrl`. If a
258
- `clientProspectId` is available, pass that instead.
259
-
260
- Sufficient-intake bypass: when the invocation or first operator answer already
261
- supplies identity/client context, target prospects, offer/CTA, proof guidance,
262
- and lead-source preference or permission to find people, do not ask the setup
263
- packet again. Do one lightweight lookup, state the inferred campaign direction
264
- in one or two lines, and move directly into the campaign brief. Ask only when a
265
- required field is missing, the supplied inputs conflict, or the campaign focus
266
- is genuinely ambiguous. The brief approval gate is the correction point for
267
- inferred assumptions.
268
-
269
- After the user confirms the campaign identity, check whether the company
270
- context implies more than one campaignable product line, service, or offer.
271
- If so, ask one structured campaign-focus question before the setup packet
272
- (for example, "Which Sellable offer is this campaign for?") with no more than
273
- three specific options plus `Other / custom`. Do not ask this as plain
274
- numbered chat.
275
-
276
- Then run one lightweight campaign identity research pass before campaign
277
- shell creation. The legacy subskill/tool names are `research-sender` and
278
- `complete_sender_research`, but treat them as client/company prospect research
279
- for the campaign, not as a connected-sender availability check. Prefer loading
280
- `get_subskill_prompt({ subskillName: "research-sender" })`, running its
281
- fetch/profile/company/WebSearch batch when those tools are exposed, and
282
- calling `complete_sender_research`. If WebSearch is unavailable, use the
283
- available MCP profile/company/post tools, call `complete_sender_research`
284
- with the evidence counts found, and continue with explicit gaps. Setup
285
- questions and the campaign brief should use the confirmed company context and
286
- researched proof / positioning options so they do not feel generic. If
287
- identity is still unavailable, use neutral/custom intake options instead of
288
- guessed vertical-specific options.
289
-
290
- - Before the identity gate, use this customer-facing shape:
291
-
292
- ```text
293
- I’m ready to build the campaign in {workspace}.
294
-
295
- First I’ll resolve the client/company this campaign is for. I’ll use that
296
- context to choose the target, offer, proof, and lead source.
297
-
298
- Then I’ll turn that into a campaign brief for you to approve before any leads
299
- are imported or anything can send.
300
- ```
301
-
302
- - Fast Intake Mode is mandatory for hosted/rehearsal net-new runs. Ask the
303
- first founder strategy/source question packet in under 60 seconds. Before
304
- that first packet, the first assistant turn may only call
305
- `bootstrap_create_campaign`, load this workflow prompt with
306
- `get_subskill_prompt({ subskillName: "create-campaign-v2" })`, optionally run
307
- one lightweight identity lookup, then use the structured question gate. If the user
308
- supplied a company website/domain, call exactly one of `fetch_company`,
309
- `WebFetch`, or `WebSearch` to identify what the company actually does before
310
- generating setup options. If the user supplied a LinkedIn profile URL, call
311
- `fetch_linkedin_profile` before generating setup options. Do not infer the
312
- product category from the company name alone. If no domain, website, LinkedIn
313
- profile, or client identity is supplied, ask in normal chat for that identity
314
- before buyer/offer/source. Before the first strategy/source packet,
315
- `list_senders` is forbidden; sender availability is checked only at Settings.
316
- Before that first
317
- structured question gate, do not run source discovery, Sales Nav, Prospeo,
318
- Signals, Bash, Read, Write, Edit, Glob, Grep, full company research, or
319
- draft-directory inspection/creation. In normal customer runs, do not create a
320
- draft directory after the founder answers; create/update the campaign shell and
321
- campaign state instead. After launch identity and any ambiguous campaign focus are
322
- confirmed, the setup packet must
323
- use the structured question gate and ask buyer, offer/CTA, proof, and lead
324
- source. All four questions must include an `Other / custom` option.
325
- Exception: if the initial request already satisfies the sufficient-intake
326
- bypass above, skip the setup packet and draft the brief from the supplied
327
- context. Do not ask first-turn setup questions just to restate choices the
328
- operator already provided.
329
- - After the founder answers the first strategy/source packet, explain the next
330
- stage only: campaign brief creation and brief approval. Use this shape:
331
-
332
- ```text
333
- Got it. I'll turn this into a campaign brief first (~1-2 min), then show it to you so you can approve it or tell me what to change before I source leads.
334
- ```
335
-
336
- If local draft setup or artifact writing happens next, keep that silent or
337
- translate it into the brief outcome. Good:
338
-
339
- ```text
340
- I have enough to draft the campaign brief. I’m turning your answers into the
341
- positioning, target, offer, and approval checklist now. You’ll see the brief
342
- before I source any leads.
343
- ```
344
-
345
- Bad:
346
-
347
- ```text
348
- I’m going to persist the working brief in the local Sellable draft folder so
349
- the later lead, filter, and message stages all use the same approved campaign thesis.
350
- ```
351
-
352
- Do not mention internal artifact names, local folders, shell commands, or
353
- persistence in this preamble.
354
-
355
- Before calling `create_campaign` for the watchable shell, make sure the
356
- campaign identity research marker is satisfied: load `research-sender` if it
357
- has not already been loaded, do the lightweight profile/company lookup, and
358
- call `complete_sender_research`. This is still client/company prospect context
359
- for the campaign brief. Do not call `list_senders`, do not ask the user to
360
- connect a sender, and do not surface sender availability until
361
- Settings/final handoff.
362
-
363
- - Before asking for brief approval, render a slim approval brief in the chat and
364
- write the rich current brief into `CampaignOffer.campaignBrief` through
365
- `create_campaign`/`update_campaign`. Use rendered Markdown directly:
366
- `##` heading, bold field labels, numbered section labels, and short bullets.
367
- Do not wrap the user-facing approval view in a fenced code block because that
368
- creates horizontal scrolling in Claude Code and Codex. Do not ask the user to
369
- approve a one-paragraph direction, a risk note, or hidden artifact they cannot
370
- inspect. The chat approval view should be skimmable in under 45 seconds; full
371
- reasoning, source notes, and robustness can stay in optional debug artifacts
372
- only during explicit debug/UAT runs. Include these sections, with short wrapped
373
- lines:
374
-
375
- ```text
376
- ## Campaign brief
377
-
378
- **Decision:** ... (one sentence)
379
-
380
- **1. Target**
381
- - ... (include concrete role/title names, not just a broad persona)
382
- - ...
383
-
384
- **2. Pain**
385
- - ...
386
- - ...
387
-
388
- **3. Offer**
389
- - ...
390
- - ...
391
-
392
- **4. Proof**
393
- - ...
394
- - ...
395
-
396
- **5. Lead plan**
397
- I’ll look for people who are already showing signs this problem matters:
398
- - people talking about ...
399
- - people with roles like ...
400
- - companies likely to feel ...
401
-
402
- If that pool is too small or noisy, I’ll switch to broader LinkedIn title and
403
- company filters.
404
-
405
- **6. Risks**
406
- - ...
407
- - ...
408
-
409
- **7. What happens next**
410
- I’ll find good-fit LinkedIn leads, show the source decision and sample, then
411
- draft the first message for review. No leads import and nothing sends yet.
412
- ```
413
-
414
- In the `Lead plan` section, do not expose internal provider shorthand as the
415
- explanation. Avoid bare phrases like `signal discovery`, `founder-led GTM`,
416
- `RevOps`, `outbound systems`, or `pipeline architecture` unless they are
417
- translated into what the user can understand.
418
-
419
- After rendering that brief, ask for brief approval before Find Leads in
420
- hosted net-new runs. The user-facing choice should be approve/revise language,
421
- not "looks good".
422
- Approval options should refer to what the user just read, e.g. `Approve this
423
- brief`, `Revise target`, `Revise offer/proof`, and `Other / custom`.
424
- When the user chose `Find people for me` and the current runtime exposes the
425
- named Sellable source-scout agents, make the recommended approval label
426
- explicit: `Approve brief + use background source scouts`. If those agents are
427
- not visible in this session, use `Approve brief + compare source paths`
428
- instead. The customer approves the sourcing decision, not the host
429
- implementation detail.
430
- Include a `Watch link:` line in the normal chat text immediately before the
431
- brief approval question once `create_campaign` has returned `watchUrl`. This
432
- is a hard gate for `AskUserQuestion` / `request_user_input`: do not ask
433
- `Approve this brief before I start finding leads?` until the user has already
434
- seen both (1) the full brief content being approved and (2) the watch link for
435
- the live campaign shell. A summary like `the brief is visible there` is not a
436
- valid approval surface. If the question panel would appear without the full
437
- brief and a preceding `Watch link:` line, stop and render those first.
438
- The visible brief must come before any optional debug persistence. After the
439
- brief is synthesized, render the approval-ready brief in chat and
440
- create/update the campaign shell before any visible `mkdir`, `Write`,
441
- artifact-copy, or similar local draft setup. In normal customer runs, skip
442
- local draft setup entirely. File/folder creation is not the user's value
443
- moment; the live campaign brief is.
444
-
445
- The approval question can be based on the rendered brief in chat and the live
446
- campaign brief. Do not wait for file-write chrome before asking for approval.
447
- Before Find Leads, call `update_campaign({ campaignId, campaignBrief,
448
- currentStep: "pick-provider", watchNarration: { ... } })` after approval so
449
- the watch link moves out of Plan while the main thread explains the source
450
- path. This must be a visible Pick Provider checkpoint before the watched
451
- browser moves into Signal Discovery, Sales Nav, Prospeo, or another provider
452
- lane.
453
-
454
- - After the brief is approved, show the next progress line. When the user has
455
- not given a specific source direction, use the default sequential source
456
- funnel:
457
- `Cool. I'm going to find people who are both a good fit and active enough to
458
- be worth a LinkedIn test. I'll start with people engaging with relevant LinkedIn
459
- posts because that gives the strongest message context if enough ICP-looking
460
- people are engaging. If that does not clear a quick viability check, I'll switch
461
- to Sales Nav to find ICP people actively posting on LinkedIn, then search by
462
- titles, and use Prospeo for a broader account/contact path. No leads import
463
- until you approve the source.`
464
- The watched campaign should still be on Pick Provider while this source logic
465
- is being explained. If the default first lane is Signal Discovery, say clearly
466
- that Codex is about to test Signal Discovery as a viability path, not import
467
- leads: it will look for relevant posts, sample engagers, estimate ICP fit, and
468
- only continue if the source math works.
469
- - If the user's request already points to a source, do not force the default
470
- funnel. Start with the matching lane and say why:
471
- - specific posts, creators, topics, comments, or engagement signals ->
472
- Signal Discovery
473
- - title/persona/company filters or broad LinkedIn people search -> Sales Nav
474
- - hiring signals, account/domain lists, company growth triggers, email/domain
475
- search, or target accounts -> Prospeo
476
- - supplied CSV/profile list -> existing/supplied list preview
477
- - explicit compare request -> compare only the requested sources
478
- - In watch mode, do not skip the Pick Provider checkpoint. First move the
479
- campaign to `pick-provider` and narrate the source-selection reasoning there.
480
- While the watched browser is still on Pick Provider, ask for approval before
481
- starting Signal Discovery or a user-directed first lane. After that visible
482
- checkpoint and approval, move the campaign to the first source lane that will
483
- actually be tested (`signal-discovery`, `sales-nav`, `prospeo`, or the
484
- user-directed lane), then run the campaign-attached provider prompt + provider
485
- search in the parent thread with `campaignOfferId`, `confirmed: true`, and
486
- `currentStep` when the tool accepts it. If that lane has timeout/error, zero
487
- raw results, weak ICP fit, or weak message context, update the campaign step
488
- and watchNarration before trying the next approved lane or ask the user to
489
- revise the source/target before import. All lanes failed is a terminal
490
- revise-source state, not an import state.
491
- - After the lead sample/source decision is ready and approved,
492
- show the next progress line:
493
- `Lead source is set. I'll import the first 15-row review batch into the
494
- campaign table, then ask you to Choose filters or skip. I may let the Message
495
- Draft Builder prepare a template in the background, but template review waits
496
- until the filter choice is resolved and the template is ready for approval.`
497
- - During long post-intake work, show concise progress checkpoints before the
498
- next expensive stage: source being checked, source switch/tradeoff if any,
499
- lead sample usable, filter/message drafting, and message-review rule loading.
500
- Each checkpoint should say what changed, what is being checked next, and why
501
- that matters for the campaign. Do not invent remaining-time estimates. Example:
502
-
503
- ```text
504
- This is taking a little longer than I expected, sorry. I’m being careful here
505
- because the brief becomes the source of truth for the leads and messages. I’ll
506
- show you the draft next so you can approve it or change it.
507
- ```
508
-
509
- - In explicit debug/UAT runs, `Bash` is only for safe local draft-directory
510
- housekeeping before the import/test batch: `mkdir`, `ls`, `find`, `test`, `pwd`, `echo`,
511
- or `cat` inside the repo. In normal customer runs, do not use Bash for local
512
- draft setup. Do not use
513
- Bash to run interpreters/scripts (`python`, `node`, `npm`, `pnpm`, `yarn`,
514
- `npx`), call APIs, query databases, inspect prompt dumps, run git, or
515
- synthesize artifact content. Use `Read`/`Write`/`Edit` for artifact files and
516
- MCP tools for product actions.
517
- - `CampaignOffer.campaignBrief` is the stable downstream thesis source.
518
- `brief.md` is an optional debug/UAT copy only; never make it the user-facing
519
- approval surface in normal customer runs.
520
- - The lead-source decision and lead sample must be rendered in chat and attached
521
- to campaign state/search state. `lead-review.md` and `lead-sample.json` are
522
- optional debug/UAT outputs of `find leads`; when they exist, describe source
523
- paths as provider lanes checked (Signals, Sales Nav, Prospeo) and never
524
- include custom agent names, host availability, install state, allowed-tool
525
- state, or fallback implementation details.
526
- - `lead-filter.md` is the primary output of `filter leads`.
527
- - `rubric.json` is optional and secondary to `lead-filter.md`.
528
- - `message-prep.md` is an optional speed artifact produced by the explicit
529
- message path after find-leads. It can prepare proof inventory, buyer
530
- objections, CTA options, gold-standard strategy maps, and candidate angles
531
- from the live campaign brief, source decision, lead sample, and optional debug
532
- copies.
533
- - `message-candidate-drafts.md` is an optional provisional speed artifact from
534
- sample rows that already look like probable good fits. It can contain rough
535
- candidate messages and element tests, but it cannot select the final winner
536
- and cannot override `lead-filter.md`.
537
- - `message-validation.md` is the internal validation artifact produced by the
538
- Message Draft Builder / `message generation` stage. It is provisional until
539
- the user answers filter choice and approves the message template in chat.
540
- - `message-review.md` and `message-review-decision.md` are the mandatory
541
- message quality gate outputs between `message-validation.md` and
542
- `approval-packet.md`.
543
- - Run the dependency chain as a DAG: `create-campaign-brief` -> `find leads` ->
544
- bounded import/confirm. Once the source decision, lead sample, and campaign
545
- table `workflowTableId` exist, immediately start the Message Draft Builder
546
- from the live campaign brief, approved source, source list, and imported
547
- review-batch rows before telling the user it is in progress. The normal path
548
- then reaches the `filter-choice` user gate. If the user chooses filters,
549
- `post-lead-workstreams` launches filter leads and reuses the in-flight Message
550
- Draft Builder work from the same basis as separate workstreams when the host
551
- exposes the named Sellable post-find-leads agents or real background work.
552
- First call `get_post_find_leads_scout_registry` and use the returned
553
- canonical `name` values only when those names are available in the current
554
- runtime. In Claude Code, use both returned Task/Agent subagents in the same
555
- assistant message when the session lists them; in Codex, use both returned
556
- custom scouts as disjoint subagents in the same assistant turn when the host
557
- exposes them. If the names are absent, the main thread still orchestrates the
558
- same filter and message branches with MCP tools/assets from the same compact
559
- context. Do not surface agent install status to the customer. The existing
560
- `filter-rubric` and `message-generation` steps remain focused retry and
561
- resume targets.
562
- - Message generation does not need `lead-filter.md` to start, but it is only
563
- background template drafting until the user approves the template. The moment
564
- the bounded review batch is imported, `workflowTableId` is ready, and
565
- `get_rows_minimal` proves rows exist, the Message Draft Builder must start
566
- from the live campaign brief, source decision, lead sample, and imported
567
- campaign table sample. Do not show `Message Draft Builder: In Progress` unless
568
- the worker or parent-thread fallback has actually started. It can prepare
569
- proof inventory, token strategy, and candidate angles while filter-leads
570
- tightens keep/exclude rules. Template review cannot start
571
- until filter choice is answered and rubrics are saved. If filters are enabled,
572
- the watched browser stays on Filter Leads while the template is approved in
573
- chat. After approval is saved to the campaign brief, queue the bounded
574
- enrichment/filter run and prefer at least 2 usable passing rows before moving
575
- to Messages. If only 1 passes, show weak-sample copy and ask whether to
576
- continue, revise, import more, or skip filters.
577
- If a legacy/resume host starts message prep from preview rows before import,
578
- it still needs at least 3 probable good-fit rows and must reconcile the final
579
- winner against the imported review batch before message review.
580
- - `lead-sample.json` from `find leads` is always the message sample source.
581
- `filter leads` must not create a different message sample or cause message
582
- generation to fetch new prospects. The filter only marks which find-leads
583
- sample rows are valid, names false-positive patterns, and provides the
584
- production keep/exclude rules. Message generation may start prep or
585
- provisional candidate work from probable good-fit rows in `lead-sample.json`,
586
- but the final `message-validation.md` winner must cite basis rows from
587
- `lead-sample.json` that still pass `lead-filter.md`.
588
- - Parallel means real parallel execution, not optimistic progress copy. Source
589
- scouting is sequential by default: start with the first recommended lane from
590
- `flow.v2.json`, usually Signal Discovery / LinkedIn engagement. Only launch
591
- multiple named source scouts when the user explicitly requested comparison, a
592
- prior lane failed, or the active flow marks the first lane borderline. The
593
- fallback order is plain: use Sales Nav to find ICP people who are actively
594
- posting on LinkedIn; if that is not enough, search Sales Nav by titles; if
595
- that is still not enough, use Prospeo for a broader account/contact path.
596
- Before any source scout dispatch, call `get_source_scout_registry` and use the
597
- returned canonical `name` values. The parent thread should not preload every
598
- provider prompt; each scout loads only its own provider prompt. Do not write
599
- "source scout agents are not installed" or similar host status into
600
- customer-facing output.
601
- - Source scout parallelism must not hide all provider work from the watch UI.
602
- The parent thread owns the first visible provider search: call the chosen
603
- provider prompt/search with the minted CampaignOffer id and provider
604
- `currentStep` before waiting on source-scout results, so relevant search tabs
605
- appear in real time.
606
- - For post-lead workstreams, first call
607
- `get_post_find_leads_scout_registry` after the review batch import confirms
608
- rows. Launch the returned `message-generation` scout immediately, before the
609
- filter-choice/watch copy says message work is running. When the user chooses
610
- filters, launch the returned `filter-leads` scout and reuse the in-flight
611
- message branch. This is the Task/Agent subagents path for the
612
- `post-lead-workstreams` step. This is the same registry pattern as source
613
- scouting, but the trigger is bounded review-batch import and the join gate is
614
- both `lead-filter.md` and `message-validation.md` existing from the same live
615
- campaign brief/source decision/imported review-batch basis. When the host can
616
- launch both branches together, this is still the two Task/Agent subagents
617
- path; otherwise message-generation starts first and filter-leads joins after
618
- the filter choice.
619
- - Never run a downstream stage until the active `flow.v2.json` step's required
620
- campaign state and required normal inputs exist. In normal customer runs, do
621
- not create optional debug artifacts just to satisfy a file gate.
622
- - Never call a tool outside the active step's `allowedTools`, and never call a
623
- tool listed in the active step's `doNotAllow`.
624
- - Before the source is approved, `import_leads` and `confirm_lead_list` are
625
- forbidden. After source approval, import/confirm only the bounded 15-row
626
- review batch. Before rubrics and the approved message set are both on the
627
- campaign, the spend/send-adjacent cascade tools are forbidden: `queue_cells`,
628
- `enrich_with_prospeo`, `bulk_enrich_with_prospeo`,
629
- `attach_recommended_sequence`, `attach_sequence`, and `start_campaign`.
630
- `create_campaign`, `update_campaign`, and `save_rubrics` are allowed only when
631
- the active `flow.v2.json` step allows them.
632
- - When source approval moves into import, keep chat and watch narration in the
633
- same moment. If chat says import is starting, send `watchNarration` with
634
- `stage: "review-batch"`, current-tense copy such as `Importing the review
635
- batch`, and a no-launch safety note. Do not leave the guide saying
636
- `source approved` or `I'll show the review-batch outcome` once import is
637
- starting.
638
- - After the bounded review batch is present, update the watched browser to
639
- `currentStep: "filter-choice"` with `watchNarration.stage: "fit-message"` and
640
- ask the user to Choose filters or skip. If import succeeds but row readback
641
- returns zero rows, do not move to filter choice; keep the user in source/import
642
- recovery and ask whether to retry import, import more from the approved
643
- source, or revise source. Active filtering starts only after rubrics are
644
- saved; do not say filtering the batch before rubrics are saved.
645
- - When the user chooses filters, immediately persist `enableICPFilters: true`
646
- and `currentStep: "create-icp-rubric"` so the watched app leaves the filter
647
- choice screen and shows that Codex is defining the rules in chat. After Lead
648
- Fit Builder saves rubrics, move the watched browser to Filter Leads before
649
- waiting for message work to finish. Persist `currentStep:
650
- "apply-icp-rubric"` and `watchNarration.stage: "fit-message"`, then read the
651
- bounded review batch with `get_rows_minimal`, but do not queue workflow cells
652
- yet. Tell the user the fit rules are saved, the message template is being
653
- finalized for approval, and enrichment/filtering will start only after that
654
- approval is saved into the campaign brief. Do not call `check_rubric` in the
655
- normal create-campaign-v2 path. Do not ask Use Template vs AI Generated in
656
- normal runs; the Message Draft Builder template path is the default and only
657
- normal path. Product Generate Message cells should not run from the background
658
- template path until template/token rules are approved. After message approval,
659
- update the campaign brief with an Approved Message Template containing
660
- `{{...}}` tokens and keep `enableICPFilters: true`; then queue only
661
- pending/error `enrichCellId` values with `queue_cells` to start enrichment and
662
- filtering. Once a couple review rows pass, move to Messages so Generate
663
- Message can run from the approved template. Generate Message detects template
664
- mode from those tokens, not from `useMessagingTemplate`.
665
- - During pre-import validation, do not call `check_rubric`; use the lead-filter
666
- artifacts and only use campaign-backed scoring after Step 13 imports the
667
- 15-lead test batch.
668
- - Resume state is based on CampaignOffer state first, then the presence and
669
- completeness of the chained debug artifacts. Never treat file presence as the
670
- durable source of truth after the campaign exists.
671
- - Preserve the Phase 83 thesis. Do not rewrite product, ICP, offer, or message
672
- hypothesis sections during preview validation.
673
- - Exception: brief-validated may rewrite §3 Campaign Thesis AND §12 Next Steps
674
- when Phase-84 lead-yield data clearly contradicts a Phase-83 UNVALIDATED
675
- decision on primary lead-source. "Clearly contradicts" = the Phase-83
676
- primary source yields 0 FIT while an alternative source yields ≥ 3 FIT in
677
- the same 15-row test sample (or an equivalent ≥ 5× ratio at larger samples).
678
- Every rewrite MUST cite specific yield numbers from `lead-review.md`. All
679
- other Phase-83 brief sections remain read-only. See
680
- `references/filter-leads.md` § Brief-Validated Rewrite Authority for the
681
- full evidence shape.
682
- - Every artifact write uses `tmp + rename` so a failed write leaves the prior
683
- artifact intact.
684
- - If a required upstream artifact is missing, stop and route back to the
685
- missing step instead of guessing.
686
- - Before importing the 15-lead test batch, persist a customer-facing
687
- `message-review.md` and `message-review-decision.md` so the message decision
688
- can be inspected later.
689
- - The message review must show one concrete sample message rendered as the
690
- recipient would see it, in addition to the approved message template. Do not
691
- make the user mentally expand `{{tokens}}`.
692
- - Do not include sequence, cadence, sending-window, mailbox, or campaign
693
- settings review in `message-review.md`. Those come after the 15-lead test
694
- batch, in the settings/sequence handoff.
695
- - Do not include post-accept DMs, connection-accepted follow-ups, day-2 / day-7
696
- follow-ups, second touches, reply branches, or any other sequence-shaped copy
697
- in `message-review.md`. If
698
- `message-validation.md` contains those, mark the message review as
699
- `revise-messaging` and route back to message generation even if the artifact
700
- says `Status: confirmed`.
701
- - Persist `customer-roleplay.md` when a customer/operator roleplay critique is
702
- run. This critique can recommend a decision, but it can never replace
703
- `approve-message` for lead import, workflow-table processing, sequence attach,
704
- or start.
705
-
706
- </rules>
707
-
708
- <conditional_gates>
19
+ If the tail begins, load the tail prompt before any auto-execute or
20
+ validate-sample tool:
709
21
 
710
- There are six customer-visible gates in the net-new hosted flow:
711
-
712
- - `brief-review` asks whether to approve the rendered campaign brief before
713
- Find Leads starts. Do not skip this by inferring approval from setup
714
- answers.
715
- - `lead-review` / source decision asks whether to approve the selected source
716
- path and sample before moving into filter/message work. Do not skip this by
717
- compressing the source decision into message review.
718
- - `filter-choice` asks whether to use filters or skip after the non-empty
719
- review batch is imported. This is the first post-import user gate.
720
- - `message-review` is the mandatory template quality gate. It asks only whether
721
- to proceed with the selected
722
- message (`approve-message`) or run one more messaging revision
723
- (`revise-messaging`). `approve-message` authorizes syncing the approved
724
- template/token rules into the campaign brief and queueing/observing the
725
- review-batch cascade.
726
- - The sender/settings/sequence handoff is the launch gate. After message
727
- validation, use Settings to help the user connect or select a LinkedIn sender.
728
- Explain Slack reply review before launch. After sender selection, attach the
729
- recommended sequence and move the watched UI to Send. Starting the campaign
730
- still waits until the user explicitly greenlights start.
731
-
732
- Auto-continue without a structured question gate when the artifact says
733
- `Status: confirmed` (or equivalent), confidence is high/medium, volume is
734
- viable, and there is no strategic tradeoff.
735
-
736
- Ask the user only when one of these is true:
737
-
738
- - `Status` is rejected, unclear, revise-find-leads, revise-filter, or
739
- confirm-with-user.
740
- - Projected usable leads are below the campaign floor for the market, or the
741
- sample pass rate suggests heavy filtering will make the campaign miss.
742
- - The source path contradicts the brief, removes the buyer segment that made
743
- the campaign compelling, or proves the provider is matching titles but not
744
- actual buyers.
745
- - Filter rules are not production-rubric-translatable from row data, enrichment,
746
- or normal public research.
747
- - Message validation has a blocking skeptical-prospect issue, no selected
748
- winner, weak token plan, or a recommendation to revise. Even when it is
749
- confirmed, render the `message-review` gate before importing the test batch so
750
- the founder can approve or revise the message deliberately.
751
-
752
- When asking subjective strategy questions (buyer scope, first ask, proof
753
- emphasis, tone, lead-source preference), always make it clear the user can give
754
- a custom answer. Add an explicit `Other / custom` option to each subjective
755
- question. Do not rely on prose like "you can add detail" as the only custom
756
- path.
757
- Every subjective setup question is single-choice in both Claude Code and
758
- Codex. Use mutually exclusive options, set or assume `multiSelect: false`, and
759
- never use checkbox or multi-select wording that invites selecting several
760
- options. If a blended answer is likely, make the blend a single named option or
761
- route it through `Other / custom` and a normal-chat follow-up.
762
- Do not batch setup as a Claude Code multi-select wizard; buyer, offer/CTA,
763
- proof, and lead source remain single-choice questions even when the host
764
- displays them in a sequence.
765
- Use customer-facing question wording:
766
-
767
- - target prospects: `Who should be the target prospects for this campaign?`
768
- - main CTA / offer: `What should the main CTA or offer be?`
769
- - proof emphasis: `Which proof point would most increase this buyer's confidence in {{company}}?`
770
- - lead source: `How should we get the people for this campaign?`
771
-
772
- Do not offer quantified reply-rate, meeting-rate, pipeline, revenue, or ROI
773
- claims as setup proof options unless the user supplied verified benchmark data
774
- for this exact workspace/sender. If such claims appear in research, label them
775
- as unavailable/unsupported and use founder/operator credibility, product
776
- capability, or verified customer proof instead.
777
- This is a hard guardrail for both option labels and option descriptions: never
778
- write setup proof option text with numeric outcome language such as `25% reply`,
779
- `25%-reply`, `reply-rate`, `meeting-rate`, `pipeline`, `revenue`, or `ROI`
780
- unless that exact benchmark is verified for this workspace/sender. If a profile
781
- or case study contains that language, strip the number and convert the option to
782
- non-quantified founder/operator credibility or product capability.
783
-
784
- Ask the lead-source question as the last question in the first strategy
785
- batch, after buyer, offer/ask, and proof/safety are understood. Frame supplied
786
- lists as optional, not required. The three visible options are exactly:
787
-
788
- 1. `Find people for me (recommended if you don't already have your own list)`
789
- 2. `I have a CSV of profiles to reach out to`
790
- 3. `I have a CSV of companies/domains I want to target`
791
-
792
- Do not expose provider or implementation paths as the user's lead-source
793
- choices. Never label the structured options as `engagers`, `titles`,
794
- `Signals`, `Sales Nav`, `Prospeo`, `search LinkedIn posts`, or similar. Those
795
- are internal scouting methods for the `Find people for me` path, not choices a
796
- first-time user should have to understand.
797
-
798
- Keep `Other / custom` available for freeform answers such as a pasted list,
799
- an existing Sellable lead list, or another source idea. Do not put existing
800
- Sellable lead lists in the main three-option first batch; support them through
801
- custom/freeform input. If the user chooses the company/domain option, ask in
802
- normal chat whether they have a CSV, pasted domains, or pasted company names.
803
- If the user pastes up to 100 LinkedIn profile URLs or company domains,
804
- normalize the paste into a temporary local CSV and continue through the
805
- matching CSV preview path. Mixed, ambiguous, malformed, or oversized pastes
806
- should ask for a real CSV file instead of guessing. Uploaded CSV support is
807
- larger than paste support: LinkedIn profile CSVs can contain up to 7,500 rows;
808
- domain CSVs can contain up to 7,500 rows but only 1,000 unique domains.
809
-
810
- Avoid internal wording like `Which proof points should the message be allowed
811
- to lean on?` because it describes the artifact, not the founder decision.
812
-
813
- When auto-continuing, show one concise progress line and immediately continue.
814
- Do not create a review question whose only useful answer is "looks good".
815
-
816
- </conditional_gates>
817
-
818
- <step_contracts>
819
-
820
- ## Step 1: Find Leads
821
-
822
- Use the shell-first CampaignOffer campaignId for lead-source preview.
823
- Campaignless preview mode is only allowed before the campaign shell is minted;
824
- it is legacy-only and not part of the active flow once a CampaignOffer exists.
825
-
826
- Write:
827
-
828
- - `lead-review.md`
829
- - `lead-sample.json`
830
- - optional `lead-source-intake.json` when the user intentionally supplied a
831
- source
832
-
833
- Required behavior:
834
-
835
- - pass the CampaignOffer campaignId as `campaignOfferId` to every provider
836
- prompt/search that can persist into campaign state:
837
- `get_provider_prompt({ provider, campaignOfferId, confirmed: true })`,
838
- `search_signals`, `search_sales_nav`, and `search_prospeo`. This lets the user
839
- watch source work in the campaign during intake.
840
- - provider prompt preflight and interaction-mode approval are in-memory. On
841
- resume or MCP restart, call `get_provider_prompt({ provider, campaignOfferId })`
842
- again before any provider search/import; do not assume CampaignOffer state
843
- proves preflight happened in this process. Immediately before `import_leads`,
844
- reload the provider prompt in the same turn with
845
- `get_provider_prompt({ provider, campaignOfferId })`, even when source preview
846
- loaded it in a previous turn.
847
- - if CampaignOffer campaignId is missing, stop and recover shell creation before
848
- sourcing; do not run a campaignless source path in the active flow.
849
- - do not import leads
850
- - do not import into the campaign table, queue cells, attach a sequence, or start
851
- the campaign
852
- - do not create lead-list rows except explicit user-supplied preview flows
853
- allowed by `flow.v2.json`
854
- - only mutate campaign-attached source preview state in the narrow watch-mode
855
- ways allowed by the active flow step
856
- - use the default sequential source viability funnel when the user did not
857
- specify a source. The goal is to choose a source quickly enough to keep the
858
- watched campaign moving, not to compare every plausible lane in parallel.
859
- Run only enough evidence for the current lane to pass or fail the quick gate,
860
- then stop on the first viable source unless the user asked to compare.
861
- User-facing fallback copy should stay fifth-grade clear: people engaging with
862
- relevant LinkedIn posts -> Sales Nav to find ICP people actively posting on
863
- LinkedIn -> search by titles -> Prospeo for a broader account/contact path.
864
- The older provider label `broader Sales Nav` maps to the plain-language
865
- `search by titles` fallback; `Prospeo only as the fallback` maps to the
866
- plain-language broader account/contact path. Keep user-facing copy simple.
867
- 1. Start with LinkedIn Engagement / active LinkedIn posts (internal provider:
868
- Signals / `signal-discovery`) because recent engagement gives the strongest
869
- message context and expected reply-rate upside. Search intersection keyword
870
- lanes that combine the campaign anchor with the buyer pain/use case/ICP
871
- role, review finalist posts, promote a narrow sample set with
872
- `select_promising_posts` before fetching engagers when a campaign shell
873
- exists, fetch top-post engagers, estimate ICP-fit rate, compute posts
874
- needed for the target good-fit lead count, and only then recommend the
875
- selected post set or move to the next source.
876
- 2. If Signals does not have enough recent, relevant, ICP-looking engagers,
877
- switch to Sales Nav with recent activity when the target can be expressed
878
- as title/persona/company filters. Run preview filters, inspect preview rows,
879
- validate the filters applied, and estimate scalable-fit volume. If the
880
- preview/projected usable pool is below the target good-fit count, loosen
881
- nonessential filters before presenting Sales Nav as the scale fallback.
882
- 3. If recent-activity Sales Nav is too small or noisy, broaden to normal Sales
883
- Nav title + company filters and call out the weaker activity context.
884
- 4. Use Prospeo Contact only when the campaign has a domain/account path, the
885
- user supplied domains, the user asked for hiring/growth/account triggers,
886
- or the LinkedIn-first paths fail. Estimate email/contact scale and call out
887
- weaker LinkedIn activity.
888
- - source-specific user direction overrides the default funnel. If the user
889
- names hiring signals, account/domain lists, company growth triggers, or target
890
- accounts, start with Prospeo. If they supply profiles or a CSV, start with the
891
- supplied-list preview. If they name posts, comments, creators, or engagement,
892
- start with Signal Discovery. If they name titles/personas/company filters,
893
- start with Sales Nav. If they explicitly ask for a comparison, compare only
894
- those requested sources.
895
- - failed or empty source lanes do not import leads. A timeout/error, zero raw
896
- results, weak ICP fit, or weak message context must trigger the next approved
897
- lane or a revision question before import. All lanes failed is a terminal
898
- revise-source state, not an import state.
899
- - run source scouts in parallel only when the user explicitly requested a
900
- comparison, the current turn is resuming from already-started parallel scouts,
901
- or the first viable source is borderline and one cheap fallback check is
902
- necessary for the recommendation. Call `get_source_scout_registry` first so
903
- new scouts can be added without prompt rewrites. In Codex, explicitly spawn
904
- named custom subagents in the same turn when the host exposes them:
905
- `source-scout-linkedin-engagement` / LinkedIn Engagement Scout,
906
- `source-scout-sales-nav`, and `source-scout-prospeo-contact` for the requested
907
- or fallback lanes. Codex does not infer this from generic "compare paths"
908
- wording. In Claude Code, launch the matching Task/Agent subagents only when
909
- the current session lists those names. If they are absent, run the same
910
- provider probes with MCP tools from the parent thread and keep
911
- `lead-review.md` focused on source evidence, not host-agent availability.
912
- - after every Sales Nav preview, validate that filters actually applied before
913
- using the lane in `lead-review.md`: `searchUrl` should include filters, the
914
- first page should match the intended roles/companies, and the result count
915
- should be plausible. If Sales Nav returns a giant unfiltered pool, drops the
916
- filters, or errors after one clean retry, call it out as a provider/tool
917
- issue and do not recommend Sales Nav.
918
- - when the brief or user names target roles, Sales Nav must preserve those role
919
- names through `CURRENT_TITLE` lookups. Do not use broad seniority as a
920
- substitute for role intent. VP Sales, VP Revenue, CRO, Head of Growth, and
921
- similar targets should stay visible in the filter recipe and the source
922
- explanation.
923
- - for Signals-first campaigns, raw post search volume is only inventory, not
924
- lead volume. `492 post results` means matching LinkedIn posts found across
925
- keyword lanes; it does not mean 492 prospects. The source decision must name
926
- the actual posts we would use, show why they won, and estimate usable engagers
927
- from those posts after headline/sample filtering
928
- - for Signals-first campaigns, keyword lanes must be intersection-first. If the
929
- campaign anchor is `Claude`, `MCP`, `AI agents`, or another broad technology,
930
- do not make broad anchor-only lanes the main test. Combine the anchor with the
931
- specific wedge and buyer pain, such as outbound, GTM automation, LinkedIn
932
- outreach, AI SDR skepticism, founder-led sales, RevOps, or the ICP role. Treat
933
- broad anchor-only lanes as fallback inventory only, and retarget before
934
- sampling if the first pass is broad.
935
- - Signals viability is based on estimated ICP-fit reachable engagers, not raw
936
- post count and not whether it beats Sales Nav scale. Keep source-capacity
937
- planning separate from the 15-row review-batch import: the default source
938
- target is 300 likely good-fit leads, while `import.importLimit` remains 15 for
939
- the first campaign review batch. If 5-8 selected posts can plausibly produce
940
- ~150+ ICP-fit warm prospects before final filtering, keep Signals as a viable
941
- focused option, but say it is below the default 300-lead source target unless
942
- the math shows otherwise.
943
- - When Signals is viable-but-smaller and Sales Nav or Prospeo is more scalable,
944
- the user-facing lead review must present the choice: Signals for a warmer,
945
- smaller, higher-reply-upside first batch versus Sales Nav/Prospeo for broader
946
- scale. Recommend the source you believe should win, often Sales Nav when scale
947
- matters, but keep the smaller Signals lane available as a real option.
948
- - user-facing source logic must use sample-backed numbers, not vibes. Show the
949
- numerator, denominator, sample basis, and an easy percentage or range, e.g.
950
- `18 of 40 sampled engagers fit the ICP (~45%, directional)`. If the sample is
951
- small, say it is directional. If an estimate depends on assumptions, show the
952
- math plainly: `8 eligible posts x ~140 reachable engagers/post x ~35-45% ICP
953
- fit x cleanup factor = ~300-500 likely usable warm leads`.
954
- - source progress updates should expose the confidence-building numbers as soon
955
- as they exist: keyword lanes searched, timeframe used, post results by lane,
956
- finalist posts reviewed, engagers fetched, sampled engagers, sampled fits,
957
- estimated usable leads, and what is still unknown. Do not wait until the final
958
- lead-source review to show those numbers.
959
- - Signals source decisions should prefer fresh posts. Default to posts from the
960
- last 30 days, prefer the last 7-14 days when quality is comparable, and call
961
- out any older post as a deliberate tradeoff. Do not hide post age inside the
962
- raw search count
963
- - default source quality target is 300 likely good-fit leads for scalable
964
- outbound unless the campaign or user supplies a different source target.
965
- Compute required engagers from the observed fit rate: `target good-fit leads /
966
- sampled fit rate`. For example, 20 good fits per 100 engagers means a 300
967
- good-fit source target needs about 1,500 engagers scraped; use average
968
- reachable engagers per right-content post to calculate how many posts are
969
- needed. Accept
970
- ~150+ likely ICP-fit warm prospects as viable for a focused Signals-first
971
- campaign or first review batch only when the user is choosing warmth over
972
- scale. Name the volume tradeoff in `lead-review.md` and the source approval
973
- card rather than forcing a discard.
974
- - if `lead-source-intake.json` is present, read `sourceType`,
975
- `sourceInputMode`, file path or existing lead-list ID, selected columns,
976
- confirmation token, normalized counts, and any preview-created
977
- `domainFilterId`
978
- - supplied LinkedIn profile CSVs call `load_csv_linkedin_leads` in preview mode
979
- only before rubrics and the approved message set are ready; do not pass
980
- provider-import params during the preview. Use `campaignOfferId` only to
981
- attach the preview/source choice to the campaign UI. In Step 13, this branch
982
- is a two-stage batch path:
983
- materialize the full supplied CSV into a Sellable lead-list table first, then
984
- use the returned `leadListId` as `sourceLeadListId` for the bounded campaign
985
- review import
986
- - supplied company/domain CSVs call `load_csv_domains`; confirmation is allowed
987
- to produce a `domainFilterId` for Prospeo sampling. Run the preview search
988
- with `campaignOfferId`. In Step 13, use the same `domainFilterId` in a
989
- campaign-associated Prospeo people search, then import.
990
- - existing Sellable lead lists skip provider discovery and sample from the
991
- existing rows; do not clone/import the list until rubrics are saved and the
992
- approved message set is in the campaign brief
993
- - do not call `save_domain_filters` in the pre-approval create-campaign path
994
-
995
- `lead-review.md` must state:
996
-
997
- - validation status: `confirmed`, `rejected`, or `unclear`
998
- - confidence
999
- - provider path used
1000
- - search lanes tested, with keyword/filter names and the timeframe used
1001
- - post/result counts by lane for discovery sources
1002
- - supplied source type when applicable (`normal-discovery`,
1003
- `supplied-linkedin-profiles`, `supplied-domains`, or `existing-lead-list`)
1004
- - row/domain counts, invalid counts, duplicate counts, and sample method for
1005
- supplied sources
1006
- - preview count
1007
- - ICP match rate with numerator/denominator, sample basis, and a simple
1008
- percentage/range; never percent-only
1009
- - volume comparison
1010
- - source viability: expected source volume, expected usable leads after
1011
- filtering, source activity/warmth indicators, cleanup risk, and confidence
1012
- basis
1013
- - do not forecast connection acceptance, reply rate, meetings, pipeline,
1014
- revenue, or ROI unless the user supplied verified benchmark data for this
1015
- exact workspace/sender. If no verified benchmark exists, state that
1016
- performance is not estimated from this source review.
1017
- - for Signals-first paths: top candidate posts reviewed, selected post URLs,
1018
- post author, post topic/excerpt, post age or posted date, engagement count,
1019
- sampled engager count per selected post, sampled fit count per selected post,
1020
- estimated usable engagers per selected post, and why each selected post is
1021
- better than discarded posts
1022
- - for Signals-first paths: total raw post results by lane, number of finalist
1023
- posts reviewed, number of selected posts, total engagers fetched, deduped
1024
- sampled people count, sampled fit count, and the estimated likely usable people
1025
- range. Explicitly distinguish `posts found`, `engagers sampled`, and `usable
1026
- people estimated`.
1027
- - source decision: best path, why it won, pros, cons/tradeoffs, and discarded
1028
- source paths with the reason each lost
1029
- - repeated false-positive patterns
1030
- - message handoff: 2-5 sample rows that look like strong/probable good fits,
1031
- with row identifiers and the reason each is safe enough for message thinking
1032
- - suggested next action or revision
1033
-
1034
- For normal LinkedIn discovery, `lead-review.md` must include these
1035
- customer-visible sections with literal headings:
1036
-
1037
- - `## Source Decision`
1038
- - `## Evidence Snapshot`
1039
- - `## Selected Signal Posts` for Signals-first campaigns
1040
- - `## Source Viability`
1041
- - `## Sample Leads` for Signals-first campaigns
1042
- - `## Pros`
1043
- - `## Tradeoffs`
1044
- - `## Discarded Paths`
1045
-
1046
- For Signals-first campaigns, `## Selected Signal Posts` must include a compact
1047
- table with one row per selected or finalist post:
1048
-
1049
- - post URL
1050
- - post author
1051
- - posted date or recency
1052
- - topic/excerpt
1053
- - total engagement or estimated engagers
1054
- - sampled engagers
1055
- - sampled fits
1056
- - estimated usable leads
1057
- - why use / why discard
1058
-
1059
- `## Evidence Snapshot` must include a compact numbers-first table:
1060
-
1061
- - source lane / keyword or filter
1062
- - timeframe searched
1063
- - raw results found
1064
- - finalist posts or preview rows reviewed
1065
- - sampled people
1066
- - sampled fits, shown as `n/N` plus a simple percentage/range
1067
- - estimated usable people
1068
- - confidence note (`sample-backed`, `directional`, or `needs more sample`)
1069
-
1070
- For Signals-first campaigns, `## Sample Leads` must group representative sample
1071
- rows by source post when possible, so the user can see not just that the search
1072
- found posts, but which posts produce believable prospects.
1073
-
1074
- `## Source Viability` must include expected source volume, expected usable
1075
- leads after filtering, source activity/warmth indicators, cleanup risk, and
1076
- estimate basis. Do not include likely connection acceptance or reply-rate
1077
- ranges unless verified benchmark data was supplied by the user for this exact
1078
- workspace/sender.
1079
-
1080
- When showing `lead-review.md` to the user, render a slim decision summary in
1081
- chat, not the full evidence table. Use rendered Markdown directly with short
1082
- indexed sections and bullet lines; do not use fenced code blocks for the
1083
- user-facing lead review. The visible response must be a compact math-first card,
1084
- not a research memo. It must include only:
1085
-
1086
- - `Lead source decision`
1087
- - `Source recommendation: {source}` with the concrete recipe. For Sales Nav,
1088
- name the actual role/title, company-size, geography, industry/account, and
1089
- activity filters. For Signals, name the selected post set. For Prospeo, name
1090
- the account/domain and title recipe.
1091
- - `Math:` with these labels and values:
1092
- `Eligible posts`, `Sample`, `ICP-fit`, `Good-fit / 100 engagers`,
1093
- `Required engagers`, `Avg engagers/post`, `Good-fit / post`, `Source target`,
1094
- `Posts needed`, `Selected`, `Review batch`, `Expected good-fit leads`, and
1095
- `Scale option`.
1096
- - `Why this source:` with at most two bullets.
1097
- - `Watch link: {watchUrl}` only when the campaign shell exists and the host
1098
- needs a handoff link.
1099
- - the concrete source approval question and options.
1100
-
1101
- Do not include keyword-lane tables, LinkedIn-post-sampled tables, sample-lead
1102
- lists, or long tradeoff prose in the default approval packet. Keep those details
1103
- in `lead-review.md` or campaign/source decision state. The math block is the
1104
- bottom-line arithmetic that makes the recommendation obvious. For example:
1105
- `Eligible posts: 12 outbound + Claude posts. Sample: 25/125 ICP fits. ICP-fit:
1106
- ~20%, directional. Good-fit / 100 engagers: ~20 before cleanup. Required
1107
- engagers: ~1,500 to reach 300 good-fit prospects. Avg engagers/post: ~300
1108
- reachable. Good-fit / post: ~60. Source target: 300 good-fit leads. Posts
1109
- needed: about 5 right-content posts. Selected: 5 posts. Review batch: import
1110
- only 15 campaign rows first. Expected good-fit leads: ~300 before stricter
1111
- filtering. Scale option: Sales Nav can broaden to founder/GTM/RevOps filters if
1112
- you want colder scale, but loses the engaged-with-this-content message hook.` If
1113
- the selected posts only support the 15-row review batch or a smaller warm pilot,
1114
- say that plainly and do not imply the lane can hit the source target. For
1115
- Sales Nav/Prospeo
1116
- alternatives, include preview/raw volume, sampled usable rows as `n/N` plus
1117
- percentage/range, estimated usable range, and the warmth or context tradeoff.
1118
- If Sales Nav preview volume is too tight, broaden nonessential filters before
1119
- using it as the scale option, or label it constrained and name the next fallback.
1120
- Do not use percent-only fit rates or unsupported reply-rate claims.
1121
-
1122
- The first sentence of the visible decision must make the actual choice clear:
1123
- `I recommend {primary source} using {exact filter/source recipe}. The runner-up
1124
- is {source} because {reason}.` Do not make the user infer the decision from
1125
- numbers alone.
1126
-
1127
- Before asking for lead-source approval, make the watched campaign show the
1128
- recommended primary source lane. Call
1129
- `update_campaign({ campaignId, leadSourceType: "new", leadSourceProvider,
1130
- currentStep, watchNarration })` with `currentStep` set to the provider lane
1131
- being recommended (`sales-nav`, `signal-discovery`, or `prospeo`). If the last
1132
- sampled lane was Signals but the recommendation is Sales Nav, switch the
1133
- watched provider page to Sales Nav before asking the question so the user can
1134
- see what they are approving and why. No leads import until the user approves.
22
+ ```text
23
+ get_subskill_prompt({ subskillName: "create-campaign-v2-tail" })
24
+ ```
1135
25
 
1136
- After the user approves a lead source, the approved provider must remain the
1137
- active watched provider before any materialization work starts. Immediately
1138
- call `update_campaign` again if needed with the approved `leadSourceProvider`
1139
- and matching `currentStep` before `lookup_sales_nav_filter`,
1140
- `get_provider_prompt`, `search_sales_nav`, `search_prospeo`, `import_leads`, or
1141
- `confirm_lead_list`. For example, if the user approves Sales Nav while the
1142
- browser is still showing Signal Discovery, set `leadSourceProvider: "sales-nav"`
1143
- and `currentStep: "sales-nav"` first so the browser switches to the Sales Nav
1144
- lane and the user can watch the approved source progress. Do not set
1145
- `currentStep: "confirm-lead-list"` before `import_leads` returns the lead-list
1146
- table/job id; `import_leads` moves there after the provider import API starts so
1147
- the import page has progress state when it appears.
26
+ CampaignOffer state and the watch link are canonical. Resume, gating, and
27
+ handoff read campaign state first: `campaignId`, `watchUrl`, `campaignBrief`,
28
+ `currentStep`, source/search association, `selectedLeadListId`,
29
+ `workflowTableId`, `leadScoringRubrics`, `approvedMessageTemplate`,
30
+ `senderIds`, `sequenceTemplate`, and running state. Local draft files are
31
+ legacy debug/UAT diagnostics only. In normal customer runs, do not create,
32
+ read, link, or surface local draft artifacts unless the user explicitly asks
33
+ for debug output.
34
+
35
+ ## Normal Flow
36
+
37
+ 1. Bootstrap and tell the user the active Sellable workspace.
38
+ 2. Resolve campaign identity before strategy questions.
39
+ 3. Research the client/company enough to draft a concrete brief.
40
+ 4. Create the watchable campaign shell with `create_campaign` and the v1 brief.
41
+ 5. Surface the direct watch link.
42
+ 6. Choose and approve the lead source.
43
+ 7. Import and confirm only the bounded first review batch.
44
+ 8. Ask whether to use filters or skip them.
45
+ 9. Persist lead rubrics when filters are enabled.
46
+ 10. Generate a first-message template recommendation from the imported review
47
+ rows.
48
+ 11. Review and approve/revise the message.
49
+ 12. Sync the approved template into the campaign brief.
50
+ 13. Validate the bounded review batch, then move to Settings, sender, sequence,
51
+ and explicit launch greenlight.
52
+
53
+ There is no normal approval-packet, commit-gate, atomic-mint, or local
54
+ artifact-validation step. Those belong only to legacy validation/rehearsal
55
+ flows and the separate `create-campaign-v2-validation` subskill.
56
+
57
+ ## Identity-First Campaign Setup
58
+
59
+ Do not treat the active Sellable workspace as the campaign subject. Resolve the
60
+ client/company first, then draft the buyer, offer, proof, and source plan.
61
+
62
+ First visible request when no identity is known:
1148
63
 
1149
- If you ask for lead-source approval, the question and choices must name the
1150
- source decision. Prefer `Approve Sales Nav with founder/CEO filters, or use
1151
- warmer Signals posts instead?` over `Approve this lead source?`. Option labels
1152
- must be concrete, such as `Approve Sales Nav filters`, `Use warmer Signals
1153
- posts`, `Try Prospeo/account search`, and `Revise source`.
1154
- Immediately above that approval question, render the `Source math before
1155
- approval` block. Do not ask the user to approve from the recommendation alone;
1156
- show the math tying relevant posts, available engagers, sampled fit, expected
1157
- usable lead count, posts needed for the target, and the scale alternative
1158
- together first.
64
+ ```text
65
+ First, paste the LinkedIn profile or company website for the client/company this campaign is for.
66
+ ```
1159
67
 
1160
- Do not skip or discard Signals based only on raw post count or vibes. If
1161
- Signals was considered, show the post-level math in chat first so the user can
1162
- see which LinkedIn posts would be scraped, how many engagers each has, how many
1163
- sampled engagers looked like good fits, and roughly how many usable prospects
1164
- each post can produce. If no engagers could be fetched, say that explicitly and
1165
- lower confidence instead of presenting a precise estimate.
68
+ After the user pastes a URL/domain, retain it as `senderLinkedinUrl` or the
69
+ resolved `clientProspectId` input for `create_campaign`. Use one lightweight
70
+ profile/company lookup before strategy questions. If multiple product lines or
71
+ offers are plausible, ask one campaign-focus choice before buyer/offer/proof.
1166
72
 
1167
- For Signals, default to a quick capacity test before final recommendation. Pick
1168
- a narrow first sample of fresh, high-density posts, and in campaign-attached
1169
- watch runs promote those posts with `select_promising_posts` before sampling so
1170
- the user sees which posts are being tested. Then sample engagers, show ICP-fit
1171
- rate as `n/N` plus percentage/range, convert that to good-fit prospects per 100
1172
- engagers, estimate average reachable engagers per right-content post, apply a
1173
- conservative dedupe/cleanup factor, calculate required engagers to scrape,
1174
- calculate good-fit prospects per post, then calculate how many right-content
1175
- posts are needed to reach the source target good-fit lead count. Select/promote
1176
- only enough right-content posts to hit that source target; do not scrape every
1177
- promoted sample post by default. If the first sample is good but volume is low,
1178
- say how many more posts would be needed and offer the Sales Nav/Prospeo scale
1179
- alternative instead of recommending an under-sized source as if it can produce
1180
- the default 300 good-fit source target.
73
+ Do not call `list_senders`, do not infer the campaign from connected senders,
74
+ and do not show a sender picker during setup. Sender availability belongs only
75
+ to Settings after message approval and review-batch validation.
1181
76
 
1182
- Keep discarded paths and full sample rows in the campaign/source decision
1183
- context. In explicit debug/UAT runs they may also be copied into
1184
- `lead-sample.json`. Do not show raw filesystem paths unless the user asks.
77
+ Use `research-sender` for concise identity/proof research and call
78
+ `complete_sender_research` before shell creation. If WebSearch is unavailable,
79
+ use the available Sellable profile/company/post tools and carry explicit proof
80
+ gaps into the brief.
1185
81
 
1186
- For supplied profile CSVs and existing lead lists, `lead-review.md` must not
1187
- describe a generic TAM estimate or pretend the rows came from Sales Nav/Prospeo
1188
- discovery. For supplied domain/account lists, explain that domains are account
1189
- constraints and include the actual people sampled from those accounts. If the
1190
- domain-constrained people sample returns zero or too few usable rows, route to
1191
- `revise-leads` / `confirm-with-user`; never silently remove the domain
1192
- constraint.
82
+ ## Structured Questions
1193
83
 
1194
- `lead-sample.json` must be a machine-readable sample that downstream filter
1195
- validation can inspect directly.
84
+ Use the host-native structured question gate (`request_user_input` or
85
+ AskUserQuestion) only for bounded choices:
1196
86
 
1197
- If preview returns zero usable leads, write the rejection evidence, stop the
1198
- chain, and route to `revise-leads`.
87
+ - campaign focus when the identity has multiple plausible offers
88
+ - source approval or source revision
89
+ - use filters vs skip filters
90
+ - approve message vs revise message
91
+ - sender/sequence/launch choices at Settings
1199
92
 
1200
- ## Step 2: Filter Leads
93
+ Never use it to collect open text, pasted URLs, domains, CSV contents, or
94
+ custom instructions. Ask those in normal chat. Keep `Other / custom` available
95
+ when a bounded choice needs an escape hatch.
1201
96
 
1202
- Read CampaignOffer state first, then `brief.md`, `lead-review.md`, and
1203
- `lead-sample.json` as debug context. Filter/rubric saving happens after
1204
- `workflowTableId` exists from the bounded import. The durable write is
1205
- `save_rubrics({ campaignOfferId, leadScoringRubrics }) after the campaign table
1206
- exists`; `lead-filter.md` and `rubric.json` remain debug outputs.
97
+ ## Watch Link And Narration
1207
98
 
1208
- This branch can run in parallel with Step 3 once `lead-review.md` and
1209
- `lead-sample.json` exist. It owns lead quality and production rubrics only.
99
+ The first campaign shell is created before lead import so the user can watch
100
+ the work. When `create_campaign` returns `watchUrl`, print it directly and tell
101
+ the user to Command-Enter or click it. Never call browser-opening tools,
102
+ Computer Use, shell `open`, or in-app browser automation just because a watch
103
+ link exists.
1210
104
 
1211
- Write:
105
+ Every watched step switch must call:
1212
106
 
1213
- - `lead-filter.md`
1214
- - optional `rubric.json`
107
+ ```text
108
+ update_campaign({ campaignId, currentStep, watchNarration })
109
+ ```
1215
110
 
1216
- Required behavior:
111
+ `watchNarration` must say what just happened, the current visible state, the
112
+ agent intent, and the next user action. Do not mention MCP, prompt chunks, file
113
+ paths, local artifacts, or internal worker mechanics in customer-facing watch
114
+ copy.
1217
115
 
1218
- - preserve recurring keep/exclude filter families that show up across campaign
1219
- history: buyer role, wrong-function exclusions, company-type exclusions,
1220
- competitor/vendor exclusions, geography, company size, and active-role status
1221
- - treat right role/function, right seniority/authority, account/channel fit,
1222
- economic capacity, competitor/vendor exclusion, and active current-role status
1223
- as table-stakes buyer-quality gates; include geography/market whenever budget,
1224
- channel adoption, language, compliance, or delivery assumptions depend on it
1225
- - customize the concrete thresholds for those gates to the client's offer,
1226
- market, price point, delivery model, and competitor landscape; the invariant
1227
- is that every passing lead should be worth the user's time if they reply
1228
- - do not turn "shown interest", post engagement, Signals source, recent posting,
1229
- provider source, or first-send priority into a production filter; those are
1230
- discovery or messaging context, not proof the lead is qualified
1231
- - use the actual lead sample to identify repeated false positives
1232
- - prefer required keep/exclude rules over a broad scoring stack
1233
- - allow at most one optional/supporting rule when it materially helps later
1234
- messaging or prioritization
1235
- - judge each proposed rule against the sample, report pass rate, and call out
1236
- whether the rule is truly necessary or should be removed
1237
- - make every accepted filter directly translatable into production
1238
- `LeadScoringRubric` rows (`checkName`, `description`, `criterion`, `reason`,
1239
- `isRequiredCheck`, `allowPartialCredit`, `strictMatching`)
1240
- - do not accept a filter that cannot be evaluated from `lead-sample.json`,
1241
- provider row fields, enrichment, or normal public research
1242
- - derive `rubric.json` from the final `lead-filter.md` rules only when a
1243
- machine-readable sidecar is needed downstream
1244
- - continue with `lead-filter.md` as the source of truth when `rubric.json`
1245
- cannot be written or parsed
1246
- - if `rubric.json` is omitted, keep the filter concise enough that a 2-5 item
1247
- production rubric can be compiled from it without inventing new rules
1248
- - write `lead-filter.md` user-facing first: decision, who we keep, who we
1249
- exclude, what the sample showed, pass rate, recommendation
1250
- - include `Implementation Details` inside `lead-filter.md` whenever the status
1251
- is confirmed; this is where production rubric fields belong
1252
- - `Implementation Details` must be a fenced JSON object with
1253
- `leadScoringRubrics` so downstream can parse/save the rules without
1254
- inference
1255
- - do not write message artifacts from the filter path; filter-leads owns lead
1256
- quality and production rubrics only
116
+ ## Lead Source
1257
117
 
1258
- `lead-filter.md` must contain:
118
+ Default source order when the user has not supplied a source:
1259
119
 
1260
- - `Status`
1261
- - `Decision`
1262
- - `Who We'll Keep`
1263
- - `Who We'll Exclude`
1264
- - `Sample False Positives`
1265
- - `Optional Supporting Rule` only when one is clearly justified
1266
- - `Pass Rate`
1267
- - `Recommendation`
1268
- - `Implementation Details`
120
+ 1. LinkedIn post engagement / Signal Discovery
121
+ 2. Sales Nav recent activity
122
+ 3. broader Sales Nav role/title filters
123
+ 4. Prospeo account/contact expansion
1269
124
 
1270
- When `rubric.json` is emitted, it must use the production rubric shape, not a
1271
- custom sidecar schema:
125
+ Call `get_source_scout_registry` before source scouting. Source scouting is
126
+ sequential by default. Run `source-scout-linkedin-engagement`,
127
+ `source-scout-sales-nav`, and `source-scout-prospeo-contact` in parallel only
128
+ when the user explicitly requested source comparison, a prior lane failed, or
129
+ the first viable lane is borderline and a cheap fallback check is needed.
1272
130
 
1273
- - `leadScoringRubrics`
1274
- - `checkName`
1275
- - `description`
1276
- - `criterion`
1277
- - `reason`
1278
- - `isRequiredCheck`
1279
- - `allowPartialCredit`
1280
- - `strictMatching`
131
+ No leads import until the user approves the source. A source recommendation
132
+ must show concrete evidence: source lane, filters or recipe, raw volume, sample
133
+ size, sampled fits as n/N plus percentage/range, estimated usable prospects,
134
+ cleanup risk, runner-up, and what approval authorizes.
1281
135
 
1282
- `Implementation Details` must contain a fenced JSON object with
1283
- `leadScoringRubrics`, and that array must contain 2-5 production rubric items
1284
- total. Do not create one rubric row per keep/exclude bullet. Bundle related
1285
- false-positive families into one exclusion criterion, and keep role fit as its
1286
- own explicit criterion. Keep raw rubric flags out of the top user-facing
1287
- sections.
136
+ Supplied profile CSVs, company/domain CSVs, pasted domains, and existing
137
+ Sellable lead lists are supported, but keep provider mechanics out of the first
138
+ customer-facing source-choice labels.
1288
139
 
1289
- Do not:
140
+ ## Post-Lead Workstreams
1290
141
 
1291
- - call `check_rubric`
1292
- - create a second independent scoring design in `rubric.json`
1293
- - emit more than one optional/supporting rule
142
+ After `confirm_lead_list` imports a non-empty bounded review batch and
143
+ `get_rows_minimal({ tableId: workflowTableId })` proves rows exist, call
144
+ `get_post_find_leads_scout_registry`. The filter and message branches use live
145
+ CampaignOffer/source/table state as the source of truth. Debug markdown/json
146
+ artifacts are optional only.
1294
147
 
1295
- ## Step 3: Generate Message
148
+ Lead Fit Builder persists production rubrics with `save_rubrics` when filters
149
+ are enabled. It must not require `brief.md`, `lead-review.md`, or
150
+ `lead-sample.json`.
1296
151
 
1297
- Step 3 is the Message Draft Builder path. It is orchestrated by the main thread
1298
- and executed either by the `post-find-leads-message-scout` worker or by the
1299
- parent-thread fallback. The worker and fallback must load the full
1300
- `generate-messages` prompt with `get_subskill_prompt` and use it as the drafting
1301
- contract. The small safety-gate reference is only a supplemental approval
1302
- check, not a replacement for the long message workflow:
152
+ Message Draft Builder is `post-find-leads-message-scout`. It must load the full
153
+ message prompt:
1303
154
 
155
+ ```text
156
+ get_subskill_prompt({ subskillName: "generate-messages", offset, limit }) until hasMore=false
1304
157
  ```
1305
- mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages", offset, limit }) until hasMore=false
1306
- mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-safety-gate.md" })
1307
- ```
1308
-
1309
- Use campaign state, campaign brief content, selected source state, and the
1310
- selected/imported review-batch rows as the source of truth. Do not read
1311
- `brief.md`, `lead-review.md`, or `lead-sample.json` as required state in the
1312
- normal live campaign path; those files are optional debug context only. If the
1313
- long prompt plus safety gate cannot safely approve the draft, stop at
1314
- `revise-messaging` with the exact failure.
1315
-
1316
- Do NOT proceed to Step 4 (message review gate) unless the user has answered
1317
- filter choice, the watched app is still on Filter Leads while approval is
1318
- pending, and `message-validation.md` contains the safety-gate required
1319
- sections, a raw sendable Selected Winner, and an explicit single-first-send
1320
- PASS. If the draft is not ready, say you are waiting for the Message Draft
1321
- Builder and do not ask for approval. If the draft worker fails, produces no
1322
- usable message, or has no known worker status, require retry/regenerate copy
1323
- instead of approval copy. If
1324
- `message-validation.md` contains post-accept DM, follow-up, second-touch,
1325
- cadence, branch, or other sequence-shaped copy, do not summarize it as ready;
1326
- route back to message-generation and require a single first outbound send.
1327
-
1328
- There is no normal Use Template vs AI Generated mode question. After rubrics are
1329
- saved, stay on Filter Leads, wait for and review the Message Draft Builder
1330
- template, approve/revise it in chat, then write the approved template into the
1331
- campaign brief. Only then queue enrichment/ICP scoring for the bounded review
1332
- batch. Prefer at least 2 usable passing rows before moving the watched browser
1333
- to Messages; if only 1 passes, use weak-sample copy and ask whether to continue,
1334
- revise, import more, or skip filters.
1335
-
1336
- Product Generate Message cells should not run from the background template path
1337
- until template/token rules are approved.
1338
158
 
1339
- After the main-chat message approval, update_campaign_brief writes `## Approved
1340
- Message Template` with `{{...}}` tokens before any Generate Message cascade is
1341
- queued. The message review shows one concrete filled sample for the user, but
1342
- the durable template lives in `CampaignOffer.campaignBrief`.
159
+ It may also load the supplemental approval checklist:
1343
160
 
1344
- ## Tail (MANDATORY TOOL ORDER + Steps 13-16 + Threshold Trips + Hard Rules)
1345
-
1346
- The full tail detail (~17k chars: MANDATORY TOOL ORDER, auto-execute-leads, validate-sample loop, auto-execute-messaging, awaiting-user-greenlight, threshold-trip logging, tail hard rules) lives in a dedicated on-demand subskill to keep this entry prompt fast to load.
1347
-
1348
- Before any auto-execute or validate-sample step, **load the dedicated tail subskill verbatim**:
1349
-
1350
- ```
1351
- mcp__sellable__get_subskill_prompt({ subskillName: "create-campaign-v2-tail" })
161
+ ```text
162
+ get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-safety-gate.md" })
1352
163
  ```
1353
164
 
1354
- Follow that prompt verbatim. It contains the canonical MANDATORY TOOL ORDER (read this BEFORE any tail step), all Step 13-16 contracts, threshold-trip logging rules, and tail hard rules.
1355
-
1356
- Do NOT invoke any tail tool (auto_execute_leads, validate_sample, auto_execute_messaging, etc.) without first loading this subskill — the tool order and the threshold-trip checks live there.
165
+ Do not load the full `generate-messages` prompt in the create-campaign parent
166
+ thread unless you are executing the parent-thread fallback for that branch.
167
+
168
+ ## Hard Gates
169
+
170
+ - Do not call `create_campaign` until identity research and the brief are ready.
171
+ - Do not call `import_leads` or `confirm_lead_list` until the lead source is
172
+ approved.
173
+ - Do not queue enrichment, ICP scoring, filtering, or product Generate Message
174
+ cells until the review batch exists and the required message/filter approvals
175
+ are complete.
176
+ - Do not call `check_rubric`; persist production rubrics with `save_rubrics`.
177
+ - Do not call `start_campaign` until the user explicitly confirms launch after
178
+ Settings, sender, sequence, and final review.
179
+ - Do not use local files as durable state in normal runs.
180
+
181
+ ## References
182
+
183
+ Load references only when needed:
184
+
185
+ - `references/watch-link-handoff.md` for watch-link recovery and handoff copy.
186
+ - `references/watch-guide-narration.md` for watched-step narration.
187
+ - `references/lead-validation-preview.md` for legacy/debug preview shapes.
188
+ - `references/filter-leads.md` for rubric design and `save_rubrics` rules.
189
+ - `references/message-review-safety-gate.md` for final message approval checks.
190
+ - `references/step-13-import-leads.md` before review-batch import.
191
+ - `references/sample-validation-loop.md` before review-batch validation.
192
+ - `references/final-handoff-contract.md` for Settings, sender, sequence, and
193
+ start.