@sellable/mcp 0.1.154 → 0.1.156

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/agents/post-find-leads-filter-scout.md +6 -6
  2. package/agents/post-find-leads-message-scout.md +12 -11
  3. package/agents/source-scout-linkedin-engagement.md +29 -24
  4. package/agents/source-scout-prospeo-contact.md +3 -3
  5. package/agents/source-scout-sales-nav.md +3 -3
  6. package/dist/index-dev.js +0 -0
  7. package/dist/index.js +0 -0
  8. package/dist/tools/cells.js +1 -1
  9. package/dist/tools/leads.d.ts +1 -0
  10. package/dist/tools/leads.js +43 -25
  11. package/dist/tools/navigation.js +2 -2
  12. package/dist/tools/prompts.js +7 -7
  13. package/dist/tools/readiness.js +2 -2
  14. package/dist/tools/rubrics.js +1 -1
  15. package/package.json +1 -1
  16. package/skills/create-campaign/SKILL.md +37 -28
  17. package/skills/create-campaign-v2/SKILL.md +39 -50
  18. package/skills/create-campaign-v2/SOUL.md +4 -4
  19. package/skills/create-campaign-v2/core/auto-execute.README.md +9 -9
  20. package/skills/create-campaign-v2/core/flow.v2.json +7 -7
  21. package/skills/create-campaign-v2/core/policy.md +1 -1
  22. package/skills/create-campaign-v2/references/approval-gate-framing.md +2 -2
  23. package/skills/create-campaign-v2/references/filter-leads.md +11 -11
  24. package/skills/create-campaign-v2/references/final-handoff-contract.md +4 -4
  25. package/skills/create-campaign-v2/references/sample-validation-loop.md +8 -8
  26. package/skills/create-campaign-v2/references/step-13-import-leads.md +19 -18
  27. package/skills/create-campaign-v2/references/step-15-re-cascade.md +2 -2
  28. package/skills/create-campaign-v2/references/watch-guide-narration.md +15 -15
  29. package/skills/create-campaign-v2-tail/SKILL.md +27 -27
  30. package/skills/create-rubric/SKILL.md +1 -1
  31. package/skills/find-leads/SKILL.md +2 -2
  32. package/skills/providers/prospeo.md +1 -1
  33. package/skills/providers/sales-nav.md +1 -1
  34. package/skills/providers/signal-discovery.md +31 -27
  35. package/skills/research/config.json +9 -0
@@ -7,13 +7,13 @@ on every revision round.
7
7
  ## Principle
8
8
 
9
9
  We spend a bounded review/process sample (default 15 rows) to prove fit before
10
- the user spends credits on the rest of the confirmed source list. The sample loop has one job:
10
+ the user spends credits on the rest of the confirmed source list. The setup loop has one job:
11
11
  answer the question "do we have enough real passing examples for the user to
12
12
  judge this campaign?" Message generation starts earlier: the first row that
13
13
  passes filters is enough to begin observing or queueing Generate Message for
14
14
  that passing row.
15
15
 
16
- If the answer is yes, proceed to Step 15 messaging for the review sample. If
16
+ If the answer is yes, proceed to Step 15 messaging for the initial campaign rows. If
17
17
  the answer is no, diagnose whether the brief is wrong or the list is wrong,
18
18
  and either revise brief autonomously OR escalate to the user — never
19
19
  auto-revise leads.
@@ -25,7 +25,7 @@ auto-revise leads.
25
25
  not a visible route)
26
26
  - Approved message template/token rules exist in the campaign brief before any
27
27
  enrichment or scoring cells are queued
28
- - Confirmed campaign rows from Step 13, with first review/process sample from
28
+ - Confirmed campaign rows from Step 13, with the internal execution slice from
29
29
  `reviewBatchRowIds` (size: `importLimit`, default 15)
30
30
  - Config from `auto-execute.yaml`: `sample.sampleSize`,
31
31
  `sample.minProjectedPass`, `sample.maxRevisionRounds`
@@ -57,9 +57,9 @@ auto-revise leads.
57
57
  scoring from the queued Enrich Prospect cells
58
58
 
59
59
  6. wait_for_rubric_results(sample, targetCount = <cohortSize>, minPassedCount = 1)
60
- - cohortSize = stats.totalRows of the enrichment batch, or the review sample
60
+ - cohortSize = stats.totalRows of the enrichment batch, or the execution slice
61
61
  count
62
- - default targetCount=15 matches the default review sample, but pass the
62
+ - default targetCount=15 matches the default execution slice, but pass the
63
63
  explicit batch count anyway so future larger expansion batches do not
64
64
  accidentally stop early
65
65
  (see §Known Tool Behaviors #3)
@@ -179,7 +179,7 @@ company, enrichCellId, enrichStatus) over the default shape.
179
179
 
180
180
  ### 5. `wait_for_rubric_results` can timeout with enough signal to decide
181
181
 
182
- Observed: a 15-row review sample may return `ready=false`, `reason="timeout"`,
182
+ Observed: a 15-row internal execution slice may return `ready=false`, `reason="timeout"`,
183
183
  and partial stats such as 12/15 scored, 4 passing, 4 messages generated. That is
184
184
  enough to diagnose an underperforming sample. Waiting again without active
185
185
  processing makes the experience feel frozen.
@@ -211,8 +211,8 @@ Worked examples with defaults (sampleSize=15, importLimit=15):
211
211
  | 15 | 15 | Yes |
212
212
 
213
213
  When non-default importLimit/sampleSize are configured, the math scales
214
- the same way. In the default review-batch mode, the sample size equals the
215
- import limit, so the projection is the actual review-batch pass count.
214
+ the same way. In the default internal-slice mode, the slice size equals the
215
+ import limit, so the projection is the actual pass count.
216
216
 
217
217
  ## Brief-vs-List Diagnosis
218
218
 
@@ -55,7 +55,7 @@ Supported branches:
55
55
  `import_leads({ campaignOfferId })` for Signal Discovery unless selected posts
56
56
  already exist on the campaign. Provider import materializes the source lead
57
57
  list from the approved source-capacity plan; it is not the same target as the
58
- default 15-row campaign review/process sample.
58
+ default internal campaign-table execution slice.
59
59
  - **Supplied LinkedIn profile CSV** — confirm `load_csv_linkedin_leads` only
60
60
  after the user approves that supplied-list source. Batch/materialize the
61
61
  uploaded CSV into a Sellable lead-list table. Persist the returned
@@ -74,7 +74,7 @@ Supported branches:
74
74
  its `domainFilterId`, run a campaign-associated Prospeo people search with
75
75
  `campaignOfferId`, provider prompt preflight, and `domainFilterId`, then
76
76
  materialize the source list from that search before copying the confirmed
77
- list into the campaign table and processing the first 15 rows.
77
+ list into the campaign table and processing the first internal execution slice.
78
78
 
79
79
  ## Campaign-Attached Source Contract
80
80
 
@@ -107,14 +107,14 @@ import_leads({
107
107
  campaignOfferId,
108
108
  targetLeadCount: <sourceCandidateTarget from approved good-fit math>,
109
109
  // Signal Discovery only:
110
- targetEngagerCount: <ceil(targetGoodFitLeads / sampledFitRateAfterCleanup)>,
110
+ targetEngagerCount: <ceil(targetHeadlineFitProspects / sampledHeadlinePassRate)>,
111
111
  maxPostsToScrape: <postsNeeded from approved math>
112
112
  })
113
113
  ```
114
114
 
115
115
  Provider is inherited from the selected source decision (not re-selected here)
116
116
  and should already be saved on the campaign before import. For Sales Nav and
117
- Prospeo, `<sourceCandidateTarget>` is not the 15-row review/process sample. It is
117
+ Prospeo, `<sourceCandidateTarget>` is not the internal campaign-table execution slice. It is
118
118
  the source-list export/materialization count from the approved source math. Aim
119
119
  for about 1,000 source contacts by default and use the provider cap internally
120
120
  when the raw pool is larger. If projected good fits remain below the target,
@@ -124,20 +124,21 @@ escalation logic so dedup ratios are visible.
124
124
 
125
125
  For Signal Discovery, do not scrape every currently selected/promoted sample
126
126
  post by default. Before `import_leads`, reconcile selected posts with the
127
- approved source math. The default good-fit target is 300 and the planning
128
- fit-rate assumption is 20%, so the default source-candidate plan is about 1,500
129
- raw engagers. If the sampled fit rate is stronger or weaker, use the sampled
130
- rate with a conservative cleanup factor, cap the source candidates at the
131
- approved provider limit, and select only enough posts to reach that engager
132
- count. The planning floor is 10% projected fit after cleanup; if Signal
133
- Discovery falls below that floor during the pre-scrape sample, revise the source
134
- plan before importing. After an approved scrape starts, do not discard a nonempty
127
+ approved source math. The default headline-fit target is 300 and the planning
128
+ headline-pass assumption is 20%, so the default source-candidate plan is about
129
+ 1,500 raw engagers. If the sampled headline-fit rate is stronger or weaker, use
130
+ that sampled rate for `ceil(targetHeadlineFitProspects / sampledHeadlinePassRate)`,
131
+ cap the source candidates at the approved provider limit, and select only
132
+ enough posts to reach that engager count. The planning floor is 10% projected
133
+ headline-fit rate; if Signal Discovery falls below that floor during the
134
+ pre-scrape sample, revise the source plan before importing. After an approved
135
+ scrape starts, do not discard a nonempty
135
136
  completed source list just because it lands below the source-candidate target:
136
- confirm/copy the completed list for the first review sample, then add more posts
137
- or switch provider if the sample quality or scale is not enough. The subsequent
137
+ confirm/copy the completed list for campaign setup, then add more posts
138
+ or switch provider if the source quality or scale is not enough. The subsequent
138
139
  `confirm_lead_list` call uses `reviewBatchLimit: 15`. It copies the confirmed
139
140
  source rows into the campaign table and returns only the first 15 rows as the
140
- review/process sample.
141
+ internal campaign-table execution slice.
141
142
 
142
143
  Harvest-specific interpretation: Signal Discovery post comments and reactions
143
144
  are paged from Harvest at about 100 records per page, with production caps of
@@ -145,12 +146,12 @@ are paged from Harvest at about 100 records per page, with production caps of
145
146
  headline-passing candidates after that scrape. Therefore `71 source rows` means
146
147
  71 candidates passed headline/list filtering and were inserted; it does not
147
148
  mean the post scrape stopped after 71 raw engagers. Treat raw visible engagement,
148
- raw fetched pages, inserted source rows, and the 15-row review/process sample as
149
+ raw fetched pages, inserted source rows, and the internal campaign-table execution slice as
149
150
  separate numbers.
150
151
 
151
152
  For supplied direct lists, `confirm_lead_list` should receive
152
153
  `reviewBatchLimit: 15` so the campaign table can hold the confirmed list while
153
- the first 15 rows drive the initial approval flow.
154
+ the first 15 rows drive the internal setup flow.
154
155
 
155
156
  ## `mode=add` Two-Step Handshake
156
157
 
@@ -241,7 +242,7 @@ cannot scale further without a new source lane.
241
242
  - `import_leads` is allowed immediately after the concrete source-action
242
243
  approval. It materializes the source list and then `confirm_lead_list` copies
243
244
  the confirmed source rows into the campaign table while returning only the
244
- first 15 rows for the initial review/process sample. Enrichment and fit
245
+ first 15 rows for the internal campaign-table execution slice. Enrichment and fit
245
246
  scoring wait for saved rubrics/run conditions; message cells wait for the
246
247
  approved message set.
247
248
  - Step 13 MUST reuse an approved source already attached with `campaignOfferId`
@@ -10,7 +10,7 @@ to `awaiting-user-greenlight`, and on every resume into Step 15.
10
10
  ## Principle
11
11
 
12
12
  Generate Message cells are cascade-scoped. If Step 14's rubric flips rows from
13
- pending → passed AFTER Step 15 first observes messages for the review batch, the
13
+ pending → passed AFTER Step 15 first observes messages for the initial campaign rows, the
14
14
  new rows can sit pending with no message. That must not block the first review
15
15
  handoff. Step 15 opens review as soon as one passing generated message exists;
16
16
  late-passed rows can be re-cascaded after explicit user continuation or resume.
@@ -24,7 +24,7 @@ flat at 257. The new rows never got messages.
24
24
  Re-cascade runs whenever ALL of the following are true:
25
25
 
26
26
  1. The user has already approved the first generated message or explicitly asked
27
- to continue processing more review-batch rows.
27
+ to continue processing more campaign rows.
28
28
  2. A subsequent check of rubric state shows rows that were pending at
29
29
  first message-generation pass are now passed.
30
30
  3. Those newly-passed rows do NOT yet have generated messages
@@ -49,13 +49,13 @@ states.
49
49
 
50
50
  ## Stages
51
51
 
52
- | stage | UI label | Next |
53
- | -------------- | ------------- | ------------- |
54
- | `brief-review` | Brief review | Find Leads |
55
- | `find-leads` | Find Leads | Review batch |
56
- | `review-batch` | Review batch | Fit + message |
57
- | `fit-message` | Fit + message | Review ready |
58
- | `review-ready` | Review ready | Validation |
52
+ | stage | UI label | Next |
53
+ | -------------- | -------------- | -------------- |
54
+ | `brief-review` | Brief review | Find Leads |
55
+ | `find-leads` | Find Leads | Campaign setup |
56
+ | `review-batch` | Campaign setup | Fit + message |
57
+ | `fit-message` | Fit + message | Review ready |
58
+ | `review-ready` | Review ready | Validation |
59
59
 
60
60
  ## Examples
61
61
 
@@ -138,7 +138,7 @@ Search iteration:
138
138
  "stage": "find-leads",
139
139
  "headline": "Tightening the search",
140
140
  "visibleState": "The first Signal Discovery search was broad, so Codex is trying a narrower Claude Code founder lane.",
141
- "agentIntent": "It is sampling a few engagers before scraping so the first review sample stays on-brief.",
141
+ "agentIntent": "It is sampling a few engagers before scraping so the source quality stays on-brief.",
142
142
  "nextAction": "Review source math"
143
143
  }
144
144
  ```
@@ -165,9 +165,9 @@ Review/process sample:
165
165
  ```json
166
166
  {
167
167
  "stage": "review-batch",
168
- "headline": "Preparing your first sample",
169
- "visibleState": "This page shows the confirmed source leads. Codex will process the first 15 for review.",
170
- "agentIntent": "Codex is preparing the first campaign sample from those leads.",
168
+ "headline": "Preparing campaign setup",
169
+ "visibleState": "This page shows the confirmed source leads. Codex will process the initial campaign rows for setup.",
170
+ "agentIntent": "Codex is preparing filters and messages from those leads.",
171
171
  "nextAction": "Fit + message"
172
172
  }
173
173
  ```
@@ -179,8 +179,8 @@ Source approved and import starting:
179
179
  "stage": "review-batch",
180
180
  "headline": "Copying source leads",
181
181
  "visibleState": "The browser is still showing the approved LinkedIn Engagement source candidates.",
182
- "agentIntent": "Codex is copying the confirmed source into the campaign and will process only the first 15 for review.",
183
- "nextAction": "Review sample ready"
182
+ "agentIntent": "Codex is copying the confirmed source into the campaign and will process only the internal execution slice for setup.",
183
+ "nextAction": "Campaign setup ready"
184
184
  }
185
185
  ```
186
186
 
@@ -282,8 +282,8 @@ Blocked/recovering:
282
282
  ```json
283
283
  {
284
284
  "stage": "review-batch",
285
- "headline": "Fixing the review batch",
286
- "visibleState": "The browser is not showing the campaign batch yet.",
285
+ "headline": "Fixing campaign setup",
286
+ "visibleState": "The browser is not showing campaign rows yet.",
287
287
  "agentIntent": "Codex is reconnecting the campaign state before moving forward.",
288
288
  "nextAction": "Fit + message",
289
289
  "blockedReason": "Campaign batch is not ready yet."
@@ -17,8 +17,8 @@ table.
17
17
  ## MANDATORY TOOL ORDER (read this BEFORE any tail step)
18
18
 
19
19
  Every tail run MUST call these tools in this exact order. The tail is
20
- **first-sample cascade-driven**: you kick off Enrich Prospect only for
21
- the first review/process sample, and the workflow engine chains DNC Check →
20
+ **initial-slice cascade-driven**: you kick off Enrich Prospect only for
21
+ the initial campaign-table execution slice, and the workflow engine chains DNC Check →
22
22
  ICP Score → Passes Rubric → Generate Message automatically. Your job is
23
23
  to START the bounded cascade, WAIT until filter results land, OBSERVE message
24
24
  generation as soon as one row passes, and stop for review.
@@ -26,13 +26,13 @@ Do NOT manually run rubric-check, enrich, or message-generation
26
26
  tools — the cascade already does them.
27
27
 
28
28
  ```text
29
- Step 13 — materialize source list + confirm first sample
29
+ Step 13 — materialize source list + confirm initial campaign slice
30
30
  materialize/reuse approved source with campaignOfferId
31
31
  import_leads(source-list target; SalesNav/Prospeo default ~1000, Signal Discovery default ~1500 engagers)
32
32
  wait_for_lead_list_ready
33
33
  confirm_lead_list(reviewBatchLimit=15)
34
34
  wait_for_campaign_table_ready # campaign table exists
35
- get_rows_minimal # read first review/process sample
35
+ get_rows_minimal # read initial campaign-table execution slice
36
36
  update_campaign(currentStep=filter-choice)
37
37
 
38
38
  Post-import main thread
@@ -42,10 +42,10 @@ Post-import main thread
42
42
  keep the watched app on Filter Leads after rubrics are saved
43
43
  while on Filter Leads, show the message template recommendation from the background Message Draft Builder
44
44
  after approve-message, update_campaign_brief writes `## Approved Message Template` with `{{...}}` tokens
45
- only then start the first-sample cascade
45
+ only then start the initial-slice cascade
46
46
 
47
- Step 14 — kick first-sample cascade + observe sample
48
- queue_cells(cellIds=<first 15 review/process Enrich Prospect cells only>) <-- starts bounded chain
47
+ Step 14 — kick initial-slice cascade + observe campaign rows
48
+ queue_cells(cellIds=<first 15 campaign-table execution-slice Enrich Prospect cells only>) <-- starts bounded chain
49
49
  wait_for_campaign_table_ready # wait until sample cascade starts returning filter results
50
50
  get_rows_minimal # read passesRubric + message cell status per row
51
51
  wait_for_rubric_results(minPassedCount=1, includeRows=false)
@@ -75,7 +75,7 @@ Step 16 — awaiting-user-greenlight
75
75
  update_campaign(senderIds=[selectedSenderId], currentStep=sequence)
76
76
  attach_recommended_sequence({ campaignId, currentStep: "send" }) # tier-aware: premium/SN -> If Open Profile->INMAIL_OPEN, else INVITE->accepted->DM
77
77
  if the attach response did not move the UI: update_campaign(currentStep=send)
78
- re-surface watchUrl + review-batch orientation + final launch choices
78
+ re-surface watchUrl + campaign setup orientation + final launch choices
79
79
  STOP. DO NOT call start_campaign. DO NOT move to running without explicit launch greenlight.
80
80
  ```
81
81
 
@@ -128,10 +128,10 @@ Message` column's http_request writes those cells via the cascade.
128
128
  any are pending, call `queue_cells` on those generateMessageCellIds
129
129
  and wait. If rows truly won't message, ESCALATE.
130
130
  - You MAY NOT advance past Step 13 without calling `queue_cells` on
131
- the review-batch Enrich Prospect cells. Without it, every downstream
131
+ the initial-slice Enrich Prospect cells. Without it, every downstream
132
132
  cell stays `pending` and the campaign ships empty.
133
- - You MAY NOT queue enrichment for rows outside the configured review
134
- batch before the user approves expansion. Full-list enrichment/message
133
+ - You MAY NOT queue enrichment for rows outside the configured internal
134
+ execution slice before the user approves expansion. Full-list enrichment/message
135
135
  generation is a credit-spend decision and must happen after the user
136
136
  has reviewed the sample.
137
137
 
@@ -165,8 +165,8 @@ Entered from the lead-source confirmation path, with
165
165
  import milestone.
166
166
 
167
167
  > Reminder: every provider search you run from this point forward — the
168
- > review-batch source rerun in Step 13, any expansion search after the
169
- > review batch, alternate-lane probes, account-based reruns, and operator
168
+ > campaign setup source rerun in Step 13, any expansion search after the
169
+ > initial slice, alternate-lane probes, account-based reruns, and operator
170
170
  > follow-ups — MUST include `campaignOfferId`. This applies to
171
171
  > `search_prospeo`, `search_sales_nav`, `search_apollo`,
172
172
  > `search_signals`, and any other provider search tool added later.
@@ -220,9 +220,9 @@ reviewBatchLimit: 15 })`. Do not call `import_leads` for this
220
220
  `domainFilterId`; run a campaign-associated Prospeo people search with
221
221
  `campaignOfferId`, provider prompt preflight, and that `domainFilterId`;
222
222
  then import with `targetLeadCount` set to the approved source-list target
223
- (default about 1,000). The first 15 copied campaign rows are the
224
- review/process sample; the full confirmed source list is copied into the
225
- campaign for later expansion.
223
+ (default about 1,000). The first copied campaign rows are the internal
224
+ execution slice; the full confirmed source list is copied into the campaign
225
+ for later expansion.
226
226
  Persist or recover materialized IDs on resume: `leadListId`,
227
227
  `domainFilterId`, `searchId`, `selectedLeadListId`, `workflowTableId`, and
228
228
  imported row IDs. If the source file changed after preview, or an existing lead list
@@ -263,10 +263,10 @@ searchId, targetLeadCount: 1000 })`.
263
263
  3. `wait_for_lead_list_ready` when a provider import job exists, then
264
264
  `confirm_lead_list`. Persist both identifiers: `selectedLeadListId` remains
265
265
  the source list and `workflowTableId` is the campaign table.
266
- 4. `wait_for_campaign_table_ready` until the first review/process sample rows are
266
+ 4. `wait_for_campaign_table_ready` until the initial campaign-table execution slice rows are
267
267
  available in the campaign table.
268
- 5. Call `get_rows_minimal({ tableId: workflowTableId })` and confirm the first
269
- 15-row review/process sample is present. Do not queue cells in Step 13.
268
+ 5. Call `get_rows_minimal({ tableId: workflowTableId })` and confirm the
269
+ 15-row internal execution slice is present. Do not queue cells in Step 13.
270
270
  6. If the import returns zero usable leads, ESCALATE per
271
271
  `references/escalation-ladder.md` (hard fail).
272
272
  7. `update_campaign({ campaignId, currentStep: "filter-choice" })`.
@@ -288,7 +288,7 @@ Do not route to a visible `validate-sample` step. Full decision tree lives in
288
288
  `references/sample-validation-loop.md`.
289
289
 
290
290
  **Step 14 starts the bounded fit cascade, then observes it.** Step 13 imported
291
- the review batch only. After `save_rubrics`, Step 14 queues the review-batch
291
+ the internal execution slice only. After `save_rubrics`, Step 14 queues the initial-slice
292
292
  Enrich Prospect cells, waits until filter results start landing, then moves to
293
293
  message observation as soon as one row passes and approved-template message
294
294
  generation is ready. Step 15 opens review as soon as one passing generated message
@@ -351,9 +351,9 @@ Signals underfloor results), then offer revise-filter only if the imported rows
351
351
  look close to ICP but the rubric is too strict. This prevents customer-visible
352
352
  loops where the agent keeps asking to retry the same weak source.
353
353
 
354
- When the sample passes the projected-pass floor, call
354
+ When the internal slice passes the projected-pass floor, call
355
355
  `update_campaign({ campaignId, currentStep: "auto-execute-messaging" })`
356
- and orient the user that messaging will complete for the review batch only.
356
+ and orient the user that messaging will complete for the initial campaign rows only.
357
357
 
358
358
  ## Step 15: auto-execute-messaging
359
359
 
@@ -367,7 +367,7 @@ flow through the column pipeline: `Enrich Prospect` →
367
367
  `DNC Check` → `ICP Score` → `Passes Rubric` → `Generate Message`.
368
368
  Each column's http_request auto-fires when its upstream dependency
369
369
  completes AND passes gate (e.g. `Passes Rubric === true` before
370
- `Generate Message`). Your job in Step 15 is to WAIT for the review-batch
370
+ `Generate Message`). Your job in Step 15 is to WAIT for the initial-slice
371
371
  cascade to reach `Generate Message` for rows that passed ICP, and verify
372
372
  the output — not to generate messages manually.
373
373
 
@@ -536,14 +536,14 @@ runs.
536
536
 
537
537
  ## Tail Hard Rules
538
538
 
539
- - Source-list materialization and first-sample confirmation happen in Step 13,
539
+ - Source-list materialization and initial-slice confirmation happen in Step 13,
540
540
  not during atomic mint.
541
541
  - Step 13 materializes/reuses the approved source with `campaignOfferId` before
542
542
  import. Do not import a legacy campaignless Signal source until selected posts
543
543
  exist on the campaign.
544
- - Full-list expansion happens only after the first review flow proves out. The
545
- first enrichment/scoring pass must stay capped to the 15-row review/process
546
- sample.
544
+ - Full-list expansion happens only after the initial campaign setup proves out.
545
+ The first enrichment/scoring pass must stay capped to the internal
546
+ campaign-table execution slice.
547
547
  - The tail NEVER calls `start_campaign` on its own.
548
548
  - The tail NEVER auto-revises leads. Brief revision is autonomous; lead
549
549
  revision is always operator-gated.
@@ -51,7 +51,7 @@ Create and save a comprehensive lead scoring rubric that:
51
51
 
52
52
  ## Rubric Validation + Results
53
53
 
54
- - `mcp__sellable__get_rows_minimal` - Read first review/process sample cell IDs
54
+ - `mcp__sellable__get_rows_minimal` - Read initial campaign-table execution-slice cell IDs
55
55
  - `mcp__sellable__queue_cells` - Queue only bounded sample `enrichCellId` values
56
56
  - `mcp__sellable__wait_for_rubric_results` - Poll pass-rate results
57
57
 
@@ -162,9 +162,9 @@ Execution flow:
162
162
  - `campaignOfferId`
163
163
  - `sourceLeadListId` (or omit to use `selectedLeadListId`)
164
164
  - `jobId` (from `import_leads` when available; omit for direct CSV lead lists)
165
- - `reviewBatchLimit: 15` for the first review/process sample
165
+ - `reviewBatchLimit: 15` for the internal campaign-table execution slice
166
166
  9. For campaign-builder flows, `confirm_lead_list` owns the watched move to
167
- `filter-choice` after the first review/process sample exists. Then run:
167
+ `filter-choice` after the initial campaign-table execution slice exists. Then run:
168
168
  - `wait_for_campaign_table_ready({ campaignId })`
169
169
  - `get_campaign_context({ campaignId, refresh: true })`
170
170
  - `get_rows_minimal({ tableId: workflowTableId, limit: 10, page: 1 })`
@@ -67,7 +67,7 @@ search_prospeo({
67
67
  after cleanup should be at least 10%. Prospeo is the terminal fallback; if the
68
68
  best reasonable Prospeo lane is still below 10%, tighten the ICP/source
69
69
  direction instead of switching to another provider.
70
- - After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and `reviewBatchLimit: 15` to copy confirmed rows into the campaign table and use the first 15 as the review/process sample.
70
+ - After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and `reviewBatchLimit: 15` to copy confirmed rows into the campaign table and use the first 15 as the internal campaign-table execution slice.
71
71
  - `import_leads` owns the watched move to `confirm-lead-list` after a lead list/job exists.
72
72
  - `confirm_lead_list` owns the watched move to `filter-choice` after confirmed campaign rows exist.
73
73
  - Post-confirm readback order is required:
@@ -381,7 +381,7 @@ User: "Save it"
381
381
  - `confirm_lead_list` - Copy confirmed lead list into campaign table
382
382
  Parameters: campaignOfferId, sourceLeadListId (optional), reviewBatchLimit (optional, default 15), currentStep (optional)
383
383
  Only call after user confirms the list looks good
384
- Owns the filter-choice beat after campaign rows exist; process only the first 15 review rows until later approvals
384
+ Owns the filter-choice beat after campaign rows exist; process only the internal campaign-table execution slice until later approvals
385
385
  </mcp_tools>
386
386
 
387
387
  <limits>
@@ -24,10 +24,12 @@ When the user asks to find posts or start searching, **IMMEDIATELY begin Round 1
24
24
 
25
25
  <lead_target>
26
26
 
27
- - **Default create-campaign target: ~300 good-fit prospects after cleanup,
28
- enrichment, and fit filtering.**
29
- - **Working assumption when no stronger sample exists: ~20% of raw post
30
- engagers become good-fit prospects, so plan around ~1,500 raw engagers.**
27
+ - **Default create-campaign target: ~300 headline-fit prospects that pass the
28
+ Signal Discovery headline criteria for now.**
29
+ - **Use sample math first: required raw engagers =
30
+ `ceil(targetHeadlineFitProspects / sampledHeadlinePassRate)`. When no
31
+ stronger sample exists, assume ~20% of raw post engagers pass headline
32
+ filtering, so plan around ~1,500 raw engagers.**
31
33
  - Provider/import caps are internal execution limits, not customer-facing
32
34
  promises. Do not tell the user the internal provider cap.
33
35
  - Quality > Quantity: a few hundred active users > 1000 potentially inactive profiles
@@ -47,8 +49,8 @@ number of engagers fetched. If a selected post has 1,200 visible engagers and
47
49
  the source list lands at 71 rows, read that as 71 headline-passing inserted
48
50
  rows, not as "only 71 engagers were scraped." Do not reject a completed
49
51
  non-empty source list solely because inserted rows are below the raw engager
50
- target; confirm/copy it for the 15-row review sample, then decide whether to add
51
- more posts or switch lanes based on sample quality and scale.
52
+ target; confirm/copy it for campaign setup, then decide whether to add more
53
+ posts or switch lanes based on source quality and scale.
52
54
 
53
55
  </harvest_scrape_contract>
54
56
 
@@ -112,23 +114,24 @@ You must estimate:
112
114
  - `passRate`
113
115
  - sampled pass rate used for extrapolation
114
116
  - `goodFitPer100Engagers`
115
- - normalized fit rate as good-fit prospects per 100 engagers, before and
116
- after a conservative dedupe/cleanup factor
117
+ - normalized headline-pass rate as headline-fit prospects per 100 engagers
117
118
  - `avgReachableEngagersPerPost`
118
119
  - average reachable engagers per right-content post used for capacity math
119
120
  - `goodFitProspectsPerPost`
120
- - expected good-fit prospects per right-content post after dedupe/cleanup
121
+ - expected headline-fit prospects per right-content post
121
122
  - `postsNeededForTarget`
122
123
  - number of right-content posts needed to reach the target good-fit lead
123
124
  count, defaulting to 300 for Signal Discovery unless the campaign says
124
125
  otherwise
125
126
  - `requiredEngagersToScrape`
126
- - `ceil(targetGoodFitLeads / sampledFitRate)`; for example the default
127
- planning assumption of 20 good-fit prospects per 100 engagers means a
128
- 300-good-fit source target needs about 1,500 raw engagers scraped
127
+ - `ceil(targetHeadlineFitProspects / sampledHeadlinePassRate)`; for example
128
+ a 35/60 sample is ~58%, so a 300 headline-fit target needs about 515 raw
129
+ engagers before adding a practical coverage buffer, not 3,000. The 10%
130
+ floor is a viability reject threshold, not the denominator when the sample
131
+ rate is higher.
129
132
  - `planningFloor`
130
- - minimum acceptable sampled/projected fit rate after conservative cleanup;
131
- default 10%. Below this, do not scale Signal Discovery.
133
+ - minimum acceptable sampled/projected headline-fit rate; default 10%.
134
+ Below this, do not scale Signal Discovery.
132
135
  - `projectedRange`
133
136
  - the conservative range implied by the observed sample
134
137
 
@@ -152,10 +155,10 @@ Use conservative logic:
152
155
  - stale posts
153
156
  - adjacent communities that are not actual buyers
154
157
  4. Explain the pass-through briefly and explicitly:
155
- - preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 before cleanup / ~13-16 after cleanup, `requiredEngagersToScrape`: ~1,875-2,300 for a 300-good-fit target after cleanup, `avgReachableEngagersPerPost`: 240, `goodFitProspectsPerPost`: ~31-38, `postsNeededForTarget`: ~8-10, `recentStrongPostCount`: 15-25, `freshEnoughPostCount`: 8-12, `projectedRange`: 300-380 from selected posts"
158
+ - preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 headline-fit prospects, `requiredEngagersToScrape`: ~1,365 raw engagers for a 300 headline-fit target before a practical coverage buffer, `avgReachableEngagersPerPost`: 240, `goodFitProspectsPerPost`: ~53, `postsNeededForTarget`: ~6, `recentStrongPostCount`: 15-25, `freshEnoughPostCount`: 8-12, `projectedRange`: 300-380 from selected posts"
156
159
  - fallback: "I could not fetch engagers, so this is inferred from post and author quality only"
157
160
  5. If the evidence is too weak, say so and return a low-confidence estimate instead of pretending precision.
158
- 6. If sampled/projected fit after cleanup is below the 10% planning floor,
161
+ 6. If sampled/projected headline-fit rate is below the 10% planning floor,
159
162
  reject the Signal Discovery scrape path and recommend Sales Nav recent
160
163
  activity as the next source.
161
164
  7. Do not manually enumerate dozens of engagers in the final answer. Summarize the sample by `sampledCount`, `passCount`, `passRate`, `projectedRange`, and 3-6 representative examples.
@@ -411,20 +414,21 @@ recommendation, estimate source capacity from real sample math:
411
414
  campaign says otherwise)
412
415
  - eligible right-content posts by lane/content type
413
416
  - reachable engagers from those posts
414
- - sampled ICP-fit rate as `n/N` plus an easy percentage/range
415
- - good-fit prospects per 100 engagers before and after conservative cleanup
416
- - required engagers to scrape for the source target
417
+ - sampled headline-fit rate as `n/N` plus an easy percentage/range
418
+ - headline-fit prospects per 100 engagers
419
+ - required engagers to scrape for the source target using the sampled
420
+ headline-fit rate
417
421
  - average reachable engagers per right-content post
418
- - expected good-fit leads per selected post after dedupe/cleanup
422
+ - expected headline-fit leads per selected post
419
423
  - posts needed to reach the target
420
- - whether sampled/projected fit clears the 10% planning floor
424
+ - whether sampled/projected headline-fit rate clears the 10% planning floor
421
425
 
422
426
  Then select the smallest right-content post set that plausibly hits the source
423
427
  target. Do not scrape every promoted sample post by default; promoted sampling
424
428
  state and final scrape plan are separate. If the math says the warm post lane
425
429
  only supports a smaller first batch, say that and name the Sales Nav or Prospeo
426
430
  scale fallback rather than padding the selection with noisy posts. If the
427
- sampled/projected fit rate is below 10% after cleanup, do not call
431
+ sampled/projected headline-fit rate is below 10%, do not call
428
432
  `import_leads`; move to Sales Nav recent activity.
429
433
 
430
434
  ```json
@@ -480,13 +484,13 @@ selections, headlineICPCriteria })`, then call
480
484
  targetEngagerCount, maxPostsToScrape })` for the approved
481
485
  source-capacity plan without asking for another yes/no gate. Then
482
486
  `confirm_lead_list({ reviewBatchLimit: 15 })` copies confirmed source rows into
483
- the campaign table and returns the first 15 review/process rows. Do not confuse
484
- the source-candidate target with the review sample size.
487
+ the campaign table and returns the internal campaign-table execution slice. Do not confuse
488
+ the source-candidate target with the execution-slice size.
485
489
  If the completed source scrape comes back below the approved source-candidate
486
490
  target but has usable rows, still call `confirm_lead_list` so the completed
487
- source list is copied into the campaign and the first 15 rows can be reviewed.
491
+ source list is copied into the campaign and the initial setup slice can run.
488
492
  Treat the shortfall as a scale warning: add more approved posts or move to Sales
489
- Nav only after the first sample proves the lane is too thin or off-ICP.
493
+ Nav only after source quality proves the lane is too thin or off-ICP.
490
494
 
491
495
  The promotion/select step is required campaign state. Use post IDs from the
492
496
  current campaign-scoped search result, not stale IDs copied from a source review
@@ -541,7 +545,7 @@ Then run post-confirm routing in this order:
541
545
  leads (e.g., "Does this look right? Should I import leads now?").
542
546
  `create-campaign-v2` tail flow: if the user already approved the source
543
547
  decision, that approval is the import confirmation for the source list and
544
- first review sample; do not ask again.
548
+ internal campaign setup slice; do not ask again.
545
549
  6. If confirmation exists, call `import_leads`. If not, refine
546
550
  selections/criteria and ask again.
547
551
  7. When the lead list finishes and the user confirms it looks good, call
@@ -0,0 +1,9 @@
1
+ {
2
+ "parallelMode": "wide",
3
+ "agentCount": 6,
4
+ "maxToolCallsPerAgent": 2,
5
+ "senderMaxAgents": 2,
6
+ "senderMaxToolCallsPerAgent": 3,
7
+ "progressMode": true,
8
+ "debugMode": true
9
+ }