@sellable/mcp 0.1.151 → 0.1.152

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/README.md +4 -3
  2. package/agents/post-find-leads-filter-scout.md +5 -4
  3. package/agents/post-find-leads-message-scout.md +15 -14
  4. package/agents/source-scout-linkedin-engagement.md +6 -5
  5. package/agents/source-scout-prospeo-contact.md +4 -4
  6. package/agents/source-scout-sales-nav.md +4 -4
  7. package/dist/index-dev.js +0 -0
  8. package/dist/index.js +0 -0
  9. package/dist/tools/cells.js +1 -1
  10. package/dist/tools/leads.d.ts +36 -3
  11. package/dist/tools/leads.js +83 -71
  12. package/dist/tools/prompts.js +9 -9
  13. package/dist/tools/registry.d.ts +17 -0
  14. package/dist/tools/rubrics.js +23 -20
  15. package/package.json +1 -1
  16. package/skills/create-campaign/SKILL.md +59 -56
  17. package/skills/create-campaign-v2/SKILL.md +43 -42
  18. package/skills/create-campaign-v2/SOUL.md +16 -13
  19. package/skills/create-campaign-v2/core/auto-execute.README.md +16 -17
  20. package/skills/create-campaign-v2/core/auto-execute.yaml +8 -7
  21. package/skills/create-campaign-v2/core/flow.v2.json +81 -149
  22. package/skills/create-campaign-v2/core/policy.md +13 -12
  23. package/skills/create-campaign-v2/references/approval-gate-framing.md +4 -3
  24. package/skills/create-campaign-v2/references/filter-leads.md +5 -4
  25. package/skills/create-campaign-v2/references/lead-validation-preview.md +2 -2
  26. package/skills/create-campaign-v2/references/sample-validation-loop.md +32 -27
  27. package/skills/create-campaign-v2/references/step-13-import-leads.md +29 -28
  28. package/skills/create-campaign-v2/references/watch-guide-narration.md +27 -28
  29. package/skills/create-campaign-v2-tail/SKILL.md +44 -44
  30. package/skills/create-rubric/SKILL.md +5 -5
  31. package/skills/find-leads/SKILL.md +2 -2
  32. package/skills/generate-messages/SKILL.md +2 -1
  33. package/skills/providers/prospeo.md +3 -3
  34. package/skills/providers/sales-nav.md +7 -7
  35. package/skills/providers/signal-discovery.md +11 -11
@@ -95,16 +95,16 @@ async function fetchCampaignOffer(campaignOfferId) {
95
95
  leadScoringRubrics: v3.rubrics,
96
96
  };
97
97
  }
98
- const filterLeadsReadyWatchNarration = {
98
+ const filterRulesSavedForReviewWatchNarration = {
99
99
  stage: "fit-message",
100
- headline: "Filter rules saved",
101
- visibleState: "The browser is staying on Filter Leads with the fit rules saved.",
102
- agentIntent: "Codex is preparing the message template for approval before enrichment, filtering, or message cells run.",
103
- nextAction: "Review the message template in chat",
100
+ headline: "Filter rules saved for review",
101
+ visibleState: "The browser is showing Filter Rules with the saved criteria.",
102
+ agentIntent: "Codex is waiting for filter approval before the review batch is enriched or scored.",
103
+ nextAction: "Approve or revise the filters",
104
104
  progressLabel: "Fit + message",
105
- safety: "Template approval comes before row execution.",
105
+ safety: "Saved rules are ready to review; downstream row processing remains gated.",
106
106
  };
107
- function shouldMoveToFilterLeads(campaign) {
107
+ function shouldKeepFilterRulesVisible(campaign) {
108
108
  const currentStep = campaign.currentStep;
109
109
  if (!currentStep)
110
110
  return true;
@@ -116,16 +116,15 @@ function shouldMoveToFilterLeads(campaign) {
116
116
  "filter-choice",
117
117
  "create-icp-rubric",
118
118
  "filter-rules",
119
- "apply-icp-rubric",
120
119
  ].includes(currentStep);
121
120
  }
122
121
  function buildEnableIcpFiltersPayload(campaign) {
123
122
  const payload = {
124
123
  enableICPFilters: true,
125
124
  };
126
- if (shouldMoveToFilterLeads(campaign)) {
127
- payload.currentStep = "apply-icp-rubric";
128
- payload.watchNarration = filterLeadsReadyWatchNarration;
125
+ if (shouldKeepFilterRulesVisible(campaign)) {
126
+ payload.currentStep = "create-icp-rubric";
127
+ payload.watchNarration = filterRulesSavedForReviewWatchNarration;
129
128
  }
130
129
  return payload;
131
130
  }
@@ -245,7 +244,7 @@ export const rubricToolDefinitions = [
245
244
  },
246
245
  {
247
246
  name: "save_rubrics",
248
- description: "Persist rubric criteria to the campaign. Pass leadScoringRubrics directly to save without drafting. Saving active rubrics enables ICP filtering and moves the watched client to Filter Leads; it does not run filtering by itself.",
247
+ description: "Persist rubric criteria to the campaign. Pass leadScoringRubrics directly to save without drafting. Saving active rubrics enables ICP filtering and keeps the watched client on Filter Rules for user approval; it does not move to Filter Leads or run filtering by itself.",
249
248
  inputSchema: {
250
249
  type: "object",
251
250
  properties: {
@@ -580,12 +579,16 @@ export async function saveRubrics(input) {
580
579
  // cascade blocked.
581
580
  let enableICPFiltersSet = false;
582
581
  let currentStepSet = false;
582
+ let savedCurrentStep = null;
583
583
  try {
584
584
  const api = getApi();
585
585
  const payload = buildEnableIcpFiltersPayload(campaign);
586
586
  await api.put(`/api/v2/campaign-offers/${input.campaignOfferId}`, payload);
587
587
  enableICPFiltersSet = true;
588
- currentStepSet = payload.currentStep === "apply-icp-rubric";
588
+ if (typeof payload.currentStep === "string") {
589
+ savedCurrentStep = payload.currentStep;
590
+ currentStepSet = true;
591
+ }
589
592
  }
590
593
  catch (error) {
591
594
  // Non-fatal: the rubric save already succeeded. Retry the minimum
@@ -604,17 +607,17 @@ export async function saveRubrics(input) {
604
607
  }
605
608
  return {
606
609
  success: true,
607
- message: currentStepSet
608
- ? `Saved ${normalizedDraft.length} rubric criteria, ICP filtering is ON, and the campaign is on Filter Leads.`
609
- : enableICPFiltersSet || campaign.enableICPFilters === true
610
+ message: savedCurrentStep === "create-icp-rubric"
611
+ ? `Saved ${normalizedDraft.length} rubric criteria, ICP filtering is ON, and the campaign is waiting for filter approval.`
612
+ : currentStepSet
610
613
  ? `Saved ${normalizedDraft.length} rubric criteria and ICP filtering is ON.`
611
- : `Saved ${normalizedDraft.length} rubric criteria to the campaign. WARNING: could not auto-enable ICP filtering — call update_campaign({ campaignId, enableICPFilters: true }) to activate rubric-based filtering.`,
614
+ : enableICPFiltersSet || campaign.enableICPFilters === true
615
+ ? `Saved ${normalizedDraft.length} rubric criteria and ICP filtering is ON.`
616
+ : `Saved ${normalizedDraft.length} rubric criteria to the campaign. WARNING: could not auto-enable ICP filtering — call update_campaign({ campaignId, enableICPFilters: true }) to activate rubric-based filtering.`,
612
617
  criteriaCount: normalizedDraft.length,
613
618
  deletedCount: deletedRubricIds.length,
614
619
  enableICPFiltersSet,
615
- currentStep: currentStepSet
616
- ? "apply-icp-rubric"
617
- : (campaign.currentStep ?? null),
620
+ currentStep: savedCurrentStep ?? campaign.currentStep ?? null,
618
621
  currentStepSet,
619
622
  rubrics: result?.rubrics ?? normalizedDraft,
620
623
  activeRubrics: result?.rubrics ?? normalizedDraft,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.151",
3
+ "version": "0.1.152",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -72,10 +72,10 @@ not create, link, or surface local draft files unless the user explicitly asks
72
72
  for them. Resume, gating, and handoff read campaign state first. The
73
73
  watchable campaign exists after the short brief; lead import is bounded to the
74
74
  first review batch. After that, the user chooses whether to use filters or skip.
75
- When filters are chosen, save rubrics, then pause before queueing enrichment or
76
- filtering: tell the user the fit rules are saved, the message template needs
77
- approval next, and enrichment/filtering will start after that approval. Use
78
- Template is the default message path; AI Generated is only an explicit opt-out.
75
+ When filters are chosen, save rubrics, get filter approval, then wait for
76
+ message-template approval before enrichment/filtering or Generate Message cells.
77
+ Use Template is the default message path; AI Generated is only an explicit
78
+ opt-out.
79
79
 
80
80
  ## Opening Turn Contract
81
81
 
@@ -124,9 +124,10 @@ data, compare sources by source volume, sampled ICP fit, activity/warmth
124
124
  signals, cleanup risk, and confidence basis. If a user asks for a forecast,
125
125
  label it explicitly as not estimated from this run.
126
126
 
127
- Before any provider prompt, search, source scout, or signal-discovery call,
128
- show a short source-plan gate and ask for approval. This first approval
129
- authorizes scouting/search only. The gate should say:
127
+ Before any provider prompt, search, source scout, or signal-discovery call, show
128
+ one source-plan gate and ask for approval. The plan must be visible before the
129
+ question, and this first approval authorizes scouting/search only. The gate
130
+ should say:
130
131
 
131
132
  - given this campaign, the viable source options
132
133
  - the recommended first lane
@@ -143,6 +144,10 @@ why. Do not call `search_signals`, `search_sales_nav`, `search_prospeo`,
143
144
  `fetch_post_engagers`, or provider-scoped subagents until the user approves this
144
145
  source plan or explicitly chooses a different source.
145
146
 
147
+ If the user already answered a provider approval such as "Approve Prospeo plan",
148
+ that answer satisfies the source-plan gate. Persist the approved provider and
149
+ run the scouting/search next; do not ask a second source-plan approval question.
150
+
146
151
  For hiring-led campaigns, do not default to Sales Nav just because the target is
147
152
  a role search. Prospeo is the primary lane when the brief asks for companies
148
153
  actively hiring specific roles, open-role signals, account/contact coverage, or
@@ -153,41 +158,42 @@ are likely. Sales Nav is useful for recent LinkedIn activity, role/title
153
158
  precision, and referral paths, but it does not provide hiring-by-role filters;
154
159
  say that distinction plainly in the source-plan gate.
155
160
 
156
- After scouting, ask for a second approval on the concrete source action. For
157
- Signal Discovery, name how many selected posts will be scraped, the target
158
- engager/source-candidate volume, and the bounded review-batch size. For Sales
159
- Nav or Prospeo, name the specific approved import lane and source lead count.
161
+ After scouting, ask for a second approval on the concrete source action. For
162
+ Signal Discovery, name how many selected posts will be scraped, the target
163
+ engager/source-candidate volume, and the 15-row review/process sample size. For Sales
164
+ Nav or Prospeo, name the specific approved import lane and source lead count.
165
+
160
166
  Do not call `import_leads` or `confirm_lead_list` until this second approval is
161
167
  granted.
162
168
 
163
- For Sales Nav and Prospeo, the second gate approves materializing the source
164
- lead list, not importing only the review batch. Use the first-page/sample review
165
- to calculate projected good fits: sampled fit rate after conservative cleanup,
166
- raw pool size, source target, and expected good-fit count. If the projected
167
- good-fit pool is below the campaign target (normally about 150+ usable
168
- prospects unless source defaults say otherwise), keep refining/broadening
169
- filters before asking for import approval. Once it clears target, approve
170
- `import_leads` with the source-list `targetLeadCount` (up to the raw count or
171
- provider max). Only after the source list is ready should `confirm_lead_list`
172
- clone the bounded review batch into the campaign table.
169
+ For Sales Nav and Prospeo, the second gate approves materializing the source
170
+ lead list, not importing only the review batch. Use the first-page/sample review
171
+ to calculate projected good fits: sampled fit rate after conservative cleanup,
172
+ raw pool size, source target, and expected good-fit count. If the projected
173
+ good-fit pool is below the campaign target, keep refining/broadening filters
174
+ before asking for import approval. Once it clears target, approve `import_leads`
175
+ with a source-list `targetLeadCount` around 1,000 by default (provider cap is
176
+ internal when the raw pool is larger). Only after the source list is ready
177
+ should `confirm_lead_list({ reviewBatchLimit: 15 })` copy confirmed rows into
178
+ the campaign table and return the first 15 review/process rows.
173
179
 
174
180
  For Signal Discovery, the customer-facing approval card must use the exact
175
181
  action shape "Approve scraping N Signal Discovery posts?" and the chat summary
176
182
  should be a compact `## Source Recommendation` block with:
177
183
 
178
- - good-fit target: about 150 prospects after cleanup, enrichment, and filters
179
- - source-candidate plan: about 1,000 raw engagers using a conservative 15%
180
- fit-rate assumption unless sampled data supports a different number
184
+ - goal: about 300 good-fit prospects after cleanup, enrichment, and filters
185
+ - source-candidate plan: about 1,500 raw engagers using a 20% working fit-rate
186
+ assumption unless sampled data supports a different number
181
187
  - planning floor: continue with Signal Discovery only when sampled/projected
182
188
  fit is at least 10% after cleanup; below that, move to Sales Nav recent
183
189
  activity instead of scraping noisy engagers
184
- - review checkpoint: after the source list exists, clone only the bounded
185
- review batch into the campaign for fit and message review
190
+ - review checkpoint: after the source list exists, copy confirmed source rows
191
+ into the campaign and process only the first 15 for fit and message review
186
192
  - a selected-post table with post author/topic, why it fits, and visible
187
193
  engagement
188
194
  - total visible pool and estimated good-fit pool
189
- - first pass: build the source list at the approved source-candidate target,
190
- then clone only the bounded review batch into the campaign
195
+ - first pass: build the source list, copy it into the campaign, then process
196
+ only the first 15 leads before scaling
191
197
  - fallback: switch to Sales Nav recent activity if sampled/projected fit falls
192
198
  below 10%, or if the review batch is vendor-heavy, agency-heavy, or off-ICP
193
199
 
@@ -217,17 +223,19 @@ which posts are being sampled in the watched app. The watch guide should say
217
223
  that we are pulling sample engagers from these posts to confirm the ICP is
218
224
  actually engaging and the source is viable.
219
225
 
220
- After the bounded review batch exists, use the same registry pattern for
226
+ After confirmed source rows exist in the campaign table, use the same registry pattern for
227
+
221
228
  post-lead work, but do not load that registry or any deep filter/message prompt
222
229
  before the filter-choice question. After `confirm_lead_list`, ask add filters
223
230
  vs skip filters immediately. Once the user answers, launch the message scout
224
231
  from the same campaign/table basis. If the user chooses filters, also launch the
225
- filter-leads scout, move to Filter Rules, save rubrics, then keep the browser on
226
- Filter Leads while the message recommendation is reviewed. If the user skips
227
- filters, move to Messages/message review. Workflow cell execution still waits
228
- for filter and template approval. AI Generated is an explicit opt-out from the
229
- template path. If the post-lead agents are absent, the main thread still
230
- orchestrates the same branches from the compact context with MCP tools/assets.
232
+ filter-leads scout, move to Filter Rules, save rubrics, then ask for filter
233
+ approval. After approval, keep the browser on Filter Leads while the message
234
+ recommendation is reviewed. If the user skips filters, move to Messages/message
235
+ review. Enrichment/filtering and Generate Message cells wait for message
236
+ approval. AI Generated is an explicit opt-out from the template path. If the
237
+ post-lead agents are absent, the main thread still orchestrates the same
238
+ branches from compact MCP context.
231
239
 
232
240
  Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
233
241
  lines short, use indexed section labels and bullets, and translate internal
@@ -643,29 +651,23 @@ updates.
643
651
  until `hasMore=false`. Message review requires Message Draft Builder output:
644
652
  do not draft from a checklist, local markdown artifact, or parent-thread
645
653
  intuition. Use campaign state, campaign brief content, selected source state, and
646
- imported review-batch rows as the source of truth; do not read stale local
654
+ first review/process sample rows as the source of truth; do not read stale local
647
655
  markdown such as `message-validation.md`, inspect the database directly, or
648
656
  synthesize local validation artifacts from general knowledge.
649
657
  5. Create the campaign shell early with the v1 brief so the user can open the
650
- watch link and see useful setup state immediately. Import only the first
651
- bounded review batch after the source is attached to the campaign; do not
652
- queue workflow cells, attach a sequence, or start until the filter choice is
653
- resolved, rubrics are saved when filters are enabled, template/token rules
654
- are approved on the default Use Template path, and the approved message set
655
- is synced into the campaign brief. When filters are approved, immediately
658
+ watch link and see useful setup state immediately. Materialize the approved
659
+ source list, copy confirmed rows into the campaign, and process only the
660
+ first 15 review rows after the source is attached to the campaign; do not
661
+ queue workflow cells, attach a sequence, or start until saved filters and the
662
+ message template/token rules are approved. When filters are chosen, immediately
656
663
  call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
657
664
  so the watched app moves to Filter Rules while rubrics are drafted/saved.
658
- After rubrics save, move the watched app to `apply-icp-rubric` / Filter
659
- Leads and say the fit rules are saved; the background message scout is
660
- preparing the message recommendation and approval comes next while the
661
- browser stays on Filter Leads. If filters are skipped, move the watched app to
662
- Messages/message review and wait for message approval there. After approval,
663
- save the template to the campaign brief, then queue the bounded review-batch
664
- `enrichCellId` cells to kick off enrichment/filtering. Move to Messages only
665
- after at least one review row passes and Generate Message cells are running or
666
- ready.
667
- Product Generate Message cells must not run before that template/token
668
- approval.
665
+ After rubrics save, keep Filter Rules visible for approval; after approval,
666
+ move to Filter Leads and wait there for the background message recommendation.
667
+ If filters are skipped, move to Messages/message review. Queue the bounded
668
+ review-batch `enrichCellId` cells only after message approval. Move to
669
+ Messages only after at least one review row passes and one generated message
670
+ is ready.
669
671
  Do not ask the user to approve the brief before shell creation unless they
670
672
  explicitly requested a no-write draft; the shell itself is the review surface.
671
673
  6. The main thread owns watch navigation. Call
@@ -673,9 +675,10 @@ updates.
673
675
  visible work so the user can watch progress in the app: `create-offer` for
674
676
  the brief, `pick-provider` or the selected provider step while sourcing,
675
677
  `filter-choice` after the review batch, `create-icp-rubric` as soon
676
- as filters are approved, `apply-icp-rubric` after rubrics save and while
677
- waiting for message-template approval, `validate-sample` while the approved
678
- template unlocks bounded enrichment/filter scoring on Filter Leads,
678
+ as filters are chosen and while saved filters await approval,
679
+ `apply-icp-rubric` after filter approval and message approval while bounded
680
+ enrichment/filter scoring runs, `validate-sample` only as a recovery/legacy
681
+ observation state,
679
682
  `auto-execute-messaging` after at least one row passes and review-batch
680
683
  messages are being generated or reviewed, `awaiting-user-greenlight` only
681
684
  after generated review-batch messages are approved, `settings` for sender
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: create-campaign-v2
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.
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, copy the confirmed source list into the campaign, process the first 15 review rows, persist rubrics and approved message template, validate the first passing generated message, then hand off to Settings, sequence, and start.
4
4
  visibility: internal
5
5
  ---
6
6
 
@@ -40,19 +40,17 @@ for debug output.
40
40
  4. Create the watchable campaign shell with `create_campaign` and the v1 brief.
41
41
  5. Surface the direct watch link.
42
42
  6. Choose and approve the lead source.
43
- 7. Import and confirm only the bounded first review batch.
43
+ 7. Materialize the approved source list, confirm/copy it into the campaign, and
44
+ use only the first 15 rows as the initial review/process sample.
44
45
  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. After message approval, keep the watched app on Filter Leads while the
51
- bounded enrichment/filter cascade starts.
52
- 14. Move to Messages only after at least one review row passes and one generated
53
- message is ready for review. Do not wait for a stronger sample once that
54
- first passing message exists; review it, then hand off to Settings, sender,
55
- sequence, and explicit launch greenlight.
46
+ 9. Persist lead rubrics when filters are enabled, then ask approval while the
47
+ app remains on Filter Rules.
48
+ 10. Move to Filter Leads only after saved filters are approved.
49
+ 11. Review and approve/revise the message template.
50
+ 12. Sync the approved template into the brief, then queue bounded
51
+ enrichment/filtering.
52
+ 13. Move to Messages after one row passes and one generated message is ready;
53
+ review it, then hand off to Settings, sender, sequence, and launch.
56
54
 
57
55
  There is no normal approval-packet, commit-gate, atomic-mint, or local
58
56
  artifact-validation step. Those belong only to legacy validation/rehearsal
@@ -136,9 +134,9 @@ can be a conversation-signal check if relevant hiring posts are likely, and
136
134
  Sales Nav is a LinkedIn activity/referral fallback rather than the main hiring
137
135
  filter.
138
136
 
139
- Before any provider prompt, search, source scout, or signal-discovery call,
140
- show a short source-plan gate and ask for approval. This first approval
141
- authorizes source scouting/search only. The gate must say, in plain language:
137
+ Before any provider prompt, search, source scout, or signal-discovery call, show
138
+ one source-plan gate and ask for approval. The gate must include the plan before
139
+ the question, and this first approval authorizes source scouting/search only:
142
140
 
143
141
  - given this campaign, the viable source options
144
142
  - the recommended first lane
@@ -151,7 +149,9 @@ Do not surface blanket source heuristics as product copy. Make the recommendatio
151
149
  specific to the campaign. If Signal Discovery is recommended, name the exact
152
150
  post themes you will search. If the campaign looks unlikely to have relevant
153
151
  public conversations, recommend the specific Sales Nav or Prospeo lane instead
154
- and say why. Do not call `search_signals`, `search_sales_nav`, `search_prospeo`,
152
+ and say why. An approval like "Approve Prospeo plan" satisfies this gate; persist
153
+ the provider and search next. Do not ask a second source-plan question. Do not
154
+ call `search_signals`, `search_sales_nav`, `search_prospeo`,
155
155
  `fetch_post_engagers`, or provider-scoped subagents until the user approves this
156
156
  source plan or explicitly chooses a different source.
157
157
 
@@ -176,17 +176,17 @@ name the specific search/import lane and source lead count. Do not call
176
176
  `import_leads` or `confirm_lead_list` until this second source-action approval
177
177
  is granted.
178
178
 
179
- For Sales Nav and Prospeo, do not ask to import only the 25-row review batch at
179
+ For Sales Nav and Prospeo, do not ask to import only the 15-row review sample at
180
180
  the source-action gate. First-page samples are for source math: compute sampled
181
181
  fit after conservative cleanup, project how many good-fit prospects the raw
182
182
  pool can yield, and keep refining filters while the projected good-fit pool is
183
- below the campaign target (normally about 150+ usable prospects unless the
184
- campaign/source defaults say otherwise). Once the lane clears the target, ask
183
+ below the campaign target. Once the lane clears the target, ask
185
184
  approval to materialize the source list with
186
- `targetLeadCount = min(rawResultCount, providerMax, ceil(targetGoodFitLeads /
187
- projectedFitRateAfterCleanup))`. After that source list is ready,
188
- `confirm_lead_list` imports only the bounded review batch into the campaign
189
- table for fit and message review.
185
+ `targetLeadCount` around 1,000 source contacts by default (use the provider cap
186
+ internally when the raw pool is larger). After that source list is ready,
187
+ `confirm_lead_list({ reviewBatchLimit: 15 })` copies confirmed source rows into
188
+ the campaign table and returns the first 15 review/process row ids for fit and
189
+ message review.
190
190
 
191
191
  After the user approves this concrete source-action gate, do not show the
192
192
  Source Recommendation again and do not ask another source approval question.
@@ -205,10 +205,11 @@ selected posts exist:
205
205
 
206
206
  Use Signal Discovery first.
207
207
 
208
- **Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
209
- **Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
208
+ **Goal:** ~300 good-fit prospects after cleanup, enrichment, and filters<br>
209
+ **Working assumption:** ~20% of raw post engagers become good-fit prospects<br>
210
+ **Engagers needed:** ~1,500 raw engagers<br>
210
211
  **Planning floor:** continue only when sampled/projected fit is at least 10% after cleanup; below that, switch to Sales Nav recent activity<br>
211
- **Review checkpoint:** after the source list exists, clone only the bounded review batch into the campaign for fit and message review<br>
212
+ **Review checkpoint:** after the source list exists, copy the confirmed source list into the campaign and process only the first 15 leads for fit and message review<br>
212
213
 
213
214
  ### Selected posts
214
215
 
@@ -219,19 +220,18 @@ Use Signal Discovery first.
219
220
  | Divyanshi Sharma | LinkedIn lead-gen system built with Claude Code | ~508 |
220
221
 
221
222
  **Total visible pool:** ~2,813 engagers<br>
222
- **Estimated good-fit pool at 15%:** ~420 prospects before dedupe/risk cleanup
223
+ **Estimated good-fit pool at 20%:** ~560 prospects before dedupe/risk cleanup
223
224
 
224
225
  ### Recommendation
225
226
 
226
227
  Approve scraping these 3 posts.
227
228
 
228
- This gives enough volume to work toward ~150 good-fit prospects, while
229
+ This gives enough volume to target ~300 good-fit prospects after cleanup, while
229
230
  keeping the source tied to people already engaging with Claude Code outbound /
230
231
  AI-native sales workflows.
231
232
 
232
- **First pass:** build the source list at the approved source-candidate target,
233
- then clone only the bounded review batch into the campaign so we can inspect
234
- fit and messages before sending.
233
+ **First pass:** build the source list, copy it into the campaign, then process
234
+ only the first 15 leads so we can inspect quality before scaling.
235
235
 
236
236
  **Fallback:** if sampled/projected fit falls below 10%, or if the review batch
237
237
  is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent
@@ -245,7 +245,7 @@ authorizes. For Sales Nav/Prospeo it must also show source export math:
245
245
  `rawResultCount`, `sampledFitRate`, conservative projected fit rate,
246
246
  `targetLeadCount` for the source list, and projected good-fit count from that
247
247
  export. If projected good-fit count is below target, the recommendation is to
248
- refine or broaden filters, not to import a 25-row batch.
248
+ refine or broaden filters, not to run a 15-row review sample.
249
249
 
250
250
  Supplied profile CSVs, company/domain CSVs, pasted domains, and existing
251
251
  Sellable lead lists are supported, but keep provider mechanics out of the first
@@ -253,7 +253,7 @@ customer-facing source-choice labels.
253
253
 
254
254
  ## Post-Lead Workstreams
255
255
 
256
- After `confirm_lead_list` imports a non-empty bounded review batch and
256
+ After `confirm_lead_list` copies a non-empty confirmed source into the campaign and
257
257
  `get_rows_minimal({ tableId: workflowTableId })` proves rows exist, ask the
258
258
  filter-choice question immediately. Do not call
259
259
  `get_post_find_leads_scout_registry`, load filter/message subskill prompts, or
@@ -271,11 +271,12 @@ are optional only.
271
271
  When the user chooses filters, immediately call
272
272
  `update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
273
273
  before rubric thinking or branch work. The watched app should move to Filter
274
- Rules quickly. After `save_rubrics`, the watched app should move to
275
- `apply-icp-rubric` / Filter Leads so the user can see the saved filters are
276
- ready and wait there for the background message agent. Tell the user explicitly
277
- that a message agent is drafting the first-message template while enrichment,
278
- filtering, and Generate Message cells remain blocked.
274
+ Rules quickly. After `save_rubrics`, keep the app on Filter Rules so the user
275
+ can read and approve the saved criteria. Only after that approval should
276
+ `update_campaign` move to `apply-icp-rubric` / Filter Leads, where the run waits
277
+ for the message template approval before enrichment, filtering, or Generate
278
+ Message cells are queued. Tell the user the Message Draft Builder is preparing
279
+ the template in the background.
279
280
 
280
281
  Lead Fit Builder persists production rubrics with `save_rubrics` when filters
281
282
  are enabled. It must not require `brief.md`, `lead-review.md`, or
@@ -311,11 +312,11 @@ state before drafting. Do not render message review until
311
312
 
312
313
  Load references only when needed:
313
314
 
314
- - `references/watch-link-handoff.md` for watch-link recovery and handoff copy.
315
- - `references/watch-guide-narration.md` for watched-step narration.
315
+ - `references/watch-link-handoff.md` for watch-link handoff.
316
+ - `references/watch-guide-narration.md` for watch narration.
316
317
  - `references/lead-validation-preview.md` for legacy/debug preview shapes.
317
318
  - `references/filter-leads.md` for rubric design and `save_rubrics` rules.
318
- - `references/step-13-import-leads.md` before review-batch import.
319
+ - `references/step-13-import-leads.md` before source copy.
319
320
  - `references/sample-validation-loop.md` before review-batch validation.
320
321
  - `references/final-handoff-contract.md` for Settings, sender, sequence, and
321
322
  start.
@@ -51,9 +51,11 @@ turn anchored to that:
51
51
  3. Turn that into a campaign brief and create the watchable campaign shell.
52
52
  4. Ask for brief approval before any lead import or sending-adjacent work.
53
53
  5. Find likely responders and approve the source.
54
- 6. Import only the bounded review batch.
54
+ 6. Copy the confirmed source list into the campaign and use the first 15 rows as
55
+ the review/process sample.
55
56
  7. Filter for fit and draft the reusable message template from the same sample.
56
- 8. Ask for message approval before queueing the review-batch cascade.
57
+ 8. Queue the bounded fit cascade from saved rubrics/run conditions only after the
58
+ message template is approved.
57
59
  9. Use Settings for sender selection, sequence attach, and final launch handoff.
58
60
 
59
61
  Approvals only feel safe when the user can see what they are approving. Before
@@ -81,12 +83,13 @@ example, like `omit the noticed... line` or `use "operators"`. Missing data
81
83
  should never produce robotic or creepy copy.
82
84
 
83
85
  Approved token guidance is part of the campaign, not just the review. After the
84
- bounded review batch exists and message generation has a selected template, the
85
- campaign brief should carry forward the token fill rules and examples before any
86
+ first review/process sample exists and message generation has a selected
87
+ template, the campaign brief should carry forward the token fill rules and examples before any
86
88
  workflow-table cascade is queued: good fills, good omits, bad fills, fallback
87
89
  rules, and why the bad fills are blocked.
88
90
  The campaign brief must carry forward the token fill rules from review into the
89
- live campaign state before enrichment, filtering, or Generate Message cells run.
91
+ live campaign state before enrichment, filtering, Generate Message cells, sender
92
+ setup, sequence attach, or launch.
90
93
 
91
94
  ## Progress Updates
92
95
 
@@ -275,17 +278,17 @@ surface install status to the customer.
275
278
 
276
279
  For post-lead work, call `get_post_find_leads_scout_registry` after
277
280
  the user chooses filters, not before the filter-choice question. After
278
- `confirm_lead_list` imports a non-empty bounded review batch and
279
- `get_rows_minimal` proves rows exist, ask add-filters vs skip-filters
281
+ `confirm_lead_list` copies source rows and `get_rows_minimal` proves the first
282
+ review/process sample exists, ask add-filters vs skip-filters
280
283
  immediately. Once the user answers, start `post-find-leads-message-scout` /
281
284
  message generation from the same campaign/table basis. If the user chooses
282
285
  filters, also start `post-find-leads-filter-scout`, move the browser to Filter
283
- Rules, save rubrics, then keep the browser on Filter Leads while the message
284
- recommendation is reviewed. If the user skips filters, move the browser to
285
- Messages/message review. The join gate is live branch readiness: saved rubrics
286
- or a resolved skip-filter choice, plus a message recommendation grounded in the
287
- same campaign/table basis. Enrichment, filtering, and product Generate Message
288
- cells still wait for template approval.
286
+ Rules, save rubrics, then ask for filter approval. After approval, keep the
287
+ browser on Filter Leads while the message recommendation is reviewed. If the user
288
+ skips filters, move the browser to Messages/message review. The join gate is
289
+ saved-filter approval or a resolved skip-filter choice, plus a message
290
+ recommendation grounded in the same campaign/table basis. Enrichment, filtering,
291
+ and Generate Message cells wait for template approval on the Use Template path.
289
292
 
290
293
  Only promise parallel post-lead work when parallel work actually started. If the
291
294
  host cannot or should not launch background branches, say the real sequence:
@@ -11,19 +11,19 @@ autonomous tail (Step 13, `auto-execute-leads`). All subsequent steps (14
11
11
  validate-sample, 15 auto-execute-messaging, 16 awaiting-user-greenlight)
12
12
  read the already-parsed config; they do not re-load the YAML mid-run.
13
13
 
14
- Config values are NOT written to DB. They live on the skill side and
15
- influence tool arguments (e.g. `importLimit` flows into `import_leads`
16
- `targetLeadCount` arg, `sampleSize` flows into the first N rows pulled from
17
- the imported review batch for validation).
14
+ Config values are NOT written to DB. They live on the skill side and influence
15
+ tool arguments (e.g. `importLimit` / `sampleSize` controls the first N
16
+ review/process rows after `confirm_lead_list` copies the confirmed source rows
17
+ into the campaign).
18
18
 
19
19
  ## Sections
20
20
 
21
21
  ### `import`
22
22
 
23
- - **`importLimit`** — Review-batch size imported in Step 13. The tail MUST
24
- NOT exceed this cap before the user reviews the first batch and explicitly
25
- approves expansion. If the user wants 250 leads, run a later expansion step;
26
- do not spend credits on all 250 during the default approval tail.
23
+ - **`importLimit`** — Review/process sample size used after Step 13 copies the
24
+ confirmed source rows into the campaign. The tail MUST NOT exceed this cap
25
+ before the message template is approved and at least one generated passing
26
+ message is reviewed.
27
27
  - **`provider`** — Inherited from the Phase 84 commit decision (saved in
28
28
  the committed brief / campaign metadata). Present here so the tail can
29
29
  narrate which provider it's running against; it does NOT override the
@@ -31,19 +31,18 @@ the imported review batch for validation).
31
31
 
32
32
  ### `sample`
33
33
 
34
- - **`sampleSize`** — How many rows the validation loop pulls from the
35
- imported review batch. In v2 this matches the review-batch cap
36
- (default 25), so the user sees enough real rows to judge the campaign
37
- without spending credits on hundreds more.
34
+ - **`sampleSize`** — How many rows the validation loop pulls from the first
35
+ review/process sample. In v2 this matches the process cap (default 15), so the
36
+ user sees enough real rows to judge the campaign without spending credits on
37
+ hundreds more.
38
38
  - **`minProjectedPass`** — Passing-message floor required before handoff.
39
- The default requires 5 passing examples from the 25-row review batch.
39
+ The default requires one passing example from the 15-row review sample.
40
40
  Math:
41
41
  ```text
42
42
  projectedPass = round(passInSample / sampleSize * importLimit)
43
43
  ```
44
- With defaults (sampleSize=25, importLimit=25), `projectedPass` equals
45
- the actual review-batch pass count. 5 passing rows is exactly at the
46
- floor.
44
+ With defaults (sampleSize=15, importLimit=15), `projectedPass` equals the
45
+ actual review sample pass count. One passing row is exactly at the floor.
47
46
  - **`maxRevisionRounds`** — Hard cap before escalating to the user. A
48
47
  revision round is one full sample pass that triggered brief revision
49
48
  and retried. On stale resume the counter does NOT reset.
@@ -128,7 +127,7 @@ logs and adjust:
128
127
 
129
128
  - `importLimit` higher only if users consistently ask for larger review
130
129
  batches and credit spend is acceptable.
131
- - `sampleSize` higher if a 25-row review batch is not enough to judge
130
+ - `sampleSize` higher if a 15-row review sample is not enough to judge
132
131
  quality for a specific market.
133
132
  - `minProjectedPass` lower only if fewer than 3 passing examples is still
134
133
  enough for a confident user decision.