@sellable/mcp 0.1.149 → 0.1.151
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.
- package/README.md +8 -4
- package/agents/post-find-leads-message-scout.md +2 -2
- package/agents/source-scout-prospeo-contact.md +12 -5
- package/agents/source-scout-sales-nav.md +13 -3
- package/dist/tools/leads.d.ts +2 -1
- package/dist/tools/leads.js +162 -15
- package/dist/tools/prompts.d.ts +1 -0
- package/dist/tools/prompts.js +4 -3
- package/dist/tools/registry.d.ts +9 -1
- package/dist/tools/rows.d.ts +1 -0
- package/dist/tools/rows.js +2 -0
- package/dist/tools/rubrics.d.ts +55 -23
- package/dist/tools/rubrics.js +95 -10
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +57 -29
- package/skills/create-campaign/core/providers/apollo.json +4 -2
- package/skills/create-campaign/core/providers/prospeo.json +3 -2
- package/skills/create-campaign/references/provider-selection-strategy.md +66 -25
- package/skills/create-campaign-v2/SKILL.md +67 -37
- package/skills/create-campaign-v2/SOUL.md +11 -7
- package/skills/create-campaign-v2/core/flow.v2.json +70 -47
- package/skills/create-campaign-v2/references/approval-gate-framing.md +7 -8
- package/skills/create-campaign-v2/references/sample-validation-loop.md +9 -5
- package/skills/create-campaign-v2/references/step-13-import-leads.md +10 -4
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +12 -7
- package/skills/create-campaign-v2/references/watch-guide-narration.md +16 -13
- package/skills/create-campaign-v2-tail/SKILL.md +24 -16
- package/skills/providers/apollo.md +8 -1
- package/skills/providers/prospeo.md +11 -1
- package/skills/providers/sales-nav.md +1 -1
- package/skills/research/config.json +9 -0
- package/skills/create-campaign-v2/references/message-review-safety-gate.md +0 -162
|
@@ -53,7 +53,29 @@ Activity Filters (use one or both):
|
|
|
53
53
|
|
|
54
54
|
Sales Nav works without these filters too -- just expect lower reply rates.
|
|
55
55
|
|
|
56
|
-
### 3.
|
|
56
|
+
### 3. Prospeo (HIRING / ACCOUNT / VERIFIED-CONTACT EXPANSION)
|
|
57
|
+
|
|
58
|
+
Prospeo is the main lane when the user's direction points to database filters
|
|
59
|
+
that LinkedIn sources do not expose.
|
|
60
|
+
|
|
61
|
+
USE WHEN:
|
|
62
|
+
|
|
63
|
+
- Hiring-led targeting: companies actively hiring specific roles
|
|
64
|
+
- Named-account or domain-list targeting
|
|
65
|
+
- Broad persona expansion where verified contact coverage matters
|
|
66
|
+
- You need `company_job_posting_hiring_for`,
|
|
67
|
+
`company_job_posting_quantity`, funding, headcount, or domain filters
|
|
68
|
+
|
|
69
|
+
SKIP WHEN:
|
|
70
|
+
|
|
71
|
+
- The campaign is mainly about fresh LinkedIn activity or engagement warmth
|
|
72
|
+
- Signal Discovery can clearly produce enough ICP-fit engagers
|
|
73
|
+
|
|
74
|
+
WHY: Prospeo is the only current provider with company job-posting filters by
|
|
75
|
+
role. Sales Nav is stronger for recent LinkedIn activity, but not for
|
|
76
|
+
hiring-by-role filtering.
|
|
77
|
+
|
|
78
|
+
### 4. Apollo (LAST RESORT FOR VOLUME)
|
|
57
79
|
|
|
58
80
|
Large database but leads may not be active on LinkedIn.
|
|
59
81
|
|
|
@@ -74,25 +96,30 @@ Is your ICP LinkedIn-active (founders, sales, marketing, GTM, engineers)?
|
|
|
74
96
|
NO -> Sales Navigator + POSTED_ON_LINKEDIN (4x reply rates)
|
|
75
97
|
NO -> Sales Navigator (with or without POSTED_ON_LINKEDIN)
|
|
76
98
|
|
|
99
|
+
Need hiring-by-role filters? -> Prospeo (has company job-posting filters)
|
|
77
100
|
Need tech stack targeting? -> Apollo (has technology filters)
|
|
78
|
-
Have specific company names? -> Sales Navigator or
|
|
101
|
+
Have specific company names/domains? -> Sales Navigator for small lists or Prospeo with domainFilterId
|
|
79
102
|
```
|
|
80
103
|
|
|
81
104
|
## ICP-to-Provider Quick Reference
|
|
82
105
|
|
|
83
|
-
| ICP Type | Recommended | Why
|
|
84
|
-
| ------------------------- | ---------------- |
|
|
85
|
-
| Founders, CEOs | Signal Discovery | Highly active on LinkedIn, lots of founder content
|
|
86
|
-
| Sales/GTM leaders | Signal Discovery | Very active, tons of sales content
|
|
87
|
-
| Marketing leaders | Signal Discovery | Active, lots of marketing content
|
|
88
|
-
| Engineers/DevOps | Signal Discovery | Active on tech discussions, open source
|
|
89
|
-
| Enterprise CTOs | Sales Navigator | Less public engagement, use POSTED_ON_LINKEDIN
|
|
90
|
-
| Procurement/Ops | Sales Navigator | Rarely engage publicly
|
|
91
|
-
| Few specific companies | Sales Navigator | Use CURRENT_COMPANY filter (lookup each company)
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
| ICP Type | Recommended | Why |
|
|
107
|
+
| ------------------------- | ---------------- | -------------------------------------------------- |
|
|
108
|
+
| Founders, CEOs | Signal Discovery | Highly active on LinkedIn, lots of founder content |
|
|
109
|
+
| Sales/GTM leaders | Signal Discovery | Very active, tons of sales content |
|
|
110
|
+
| Marketing leaders | Signal Discovery | Active, lots of marketing content |
|
|
111
|
+
| Engineers/DevOps | Signal Discovery | Active on tech discussions, open source |
|
|
112
|
+
| Enterprise CTOs | Sales Navigator | Less public engagement, use POSTED_ON_LINKEDIN |
|
|
113
|
+
| Procurement/Ops | Sales Navigator | Rarely engage publicly |
|
|
114
|
+
| Few specific companies | Sales Navigator | Use CURRENT_COMPANY filter (lookup each company) |
|
|
115
|
+
| Hiring-led targeting | Prospeo | Has company job-posting filters by role |
|
|
116
|
+
| Company domain list (ABM) | Prospeo | Uses `domainFilterId` for domain targeting |
|
|
117
|
+
| Tech stack users | Apollo | Has technology filters |
|
|
118
|
+
|
|
119
|
+
**Default:** Try Signal Discovery first only when there is no stronger source
|
|
120
|
+
direction and the ICP is plausibly active in public LinkedIn conversations. Fall
|
|
121
|
+
back to Sales Navigator if ICP is too niche. Use Prospeo first when the ask is
|
|
122
|
+
hiring-led, account/domain-led, or broad verified-contact expansion.
|
|
96
123
|
|
|
97
124
|
## ABM / Account-Based Targeting
|
|
98
125
|
|
|
@@ -103,10 +130,10 @@ When user has a list of target companies:
|
|
|
103
130
|
- Requires looking up each company individually
|
|
104
131
|
- Can combine with POSTED_ON_LINKEDIN for active users
|
|
105
132
|
|
|
106
|
-
- **Many companies (domain list):** Use
|
|
107
|
-
- Supports
|
|
108
|
-
- Example:
|
|
109
|
-
- Trade-off: No POSTED_ON_LINKEDIN equivalent, so
|
|
133
|
+
- **Many companies (domain list):** Use Prospeo with `domainFilterId`
|
|
134
|
+
- Supports large domain filters through `load_csv_domains` or `save_domain_filters`
|
|
135
|
+
- Example: create a domain filter for `stripe.com`, `notion.so`, and `figma.com`, then pass `domainFilterId` into `search_prospeo`
|
|
136
|
+
- Trade-off: No POSTED_ON_LINKEDIN equivalent, so LinkedIn activity warmth may be lower
|
|
110
137
|
|
|
111
138
|
## Recommendation Templates
|
|
112
139
|
|
|
@@ -141,6 +168,19 @@ Here's why:
|
|
|
141
168
|
Should I search for active {icp} on Sales Navigator?
|
|
142
169
|
```
|
|
143
170
|
|
|
171
|
+
**Prospeo (hiring-led ICP):**
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
Since this campaign depends on companies actively hiring for **{roleThemes}**, I'd recommend **Prospeo** first.
|
|
175
|
+
|
|
176
|
+
Here's why:
|
|
177
|
+
- Prospeo can filter companies by open-role themes using job-posting filters
|
|
178
|
+
- We can pair those hiring signals with founder, GTM, recruiting, or revenue-owner contacts
|
|
179
|
+
- Sales Nav is useful for LinkedIn activity and referrals, but it cannot filter companies by hiring role
|
|
180
|
+
|
|
181
|
+
Should I search Prospeo for companies hiring {roleThemes} and the right hiring-owner contacts?
|
|
182
|
+
```
|
|
183
|
+
|
|
144
184
|
**Apollo (tech stack targeting):**
|
|
145
185
|
|
|
146
186
|
```
|
|
@@ -154,17 +194,17 @@ Here's why:
|
|
|
154
194
|
Should I search Apollo for {techStack} users?
|
|
155
195
|
```
|
|
156
196
|
|
|
157
|
-
**
|
|
197
|
+
**Prospeo ABM (company domains):**
|
|
158
198
|
|
|
159
199
|
```
|
|
160
|
-
Since you have a **list of target
|
|
200
|
+
Since you have a **list of target company domains**, I'd recommend **Prospeo** with a domain filter.
|
|
161
201
|
|
|
162
202
|
Here's why:
|
|
163
|
-
-
|
|
203
|
+
- Prospeo is the campaign-default path for supplied company-domain lists
|
|
204
|
+
- We'll create a `domainFilterId` from the CSV or pasted domains before searching
|
|
164
205
|
- We can find decision-makers at your exact target accounts
|
|
165
|
-
- Just share the domains (e.g., stripe.com, notion.so) and I'll find your ICP at those companies
|
|
166
206
|
|
|
167
|
-
Note:
|
|
207
|
+
Note: LinkedIn activity warmth may be lower than Signal Discovery or Sales Nav with POSTED_ON_LINKEDIN, so we should inspect the first review batch before scaling.
|
|
168
208
|
|
|
169
209
|
Can you share your target company domains?
|
|
170
210
|
```
|
|
@@ -179,7 +219,8 @@ Do not hardcode provider options. Build them from the framework:
|
|
|
179
219
|
- If user already has some other list shape that does not fit those CSV paths -> proceed with provider selection
|
|
180
220
|
- If the user specifies a provider or research plan -> treat that as a hard override
|
|
181
221
|
- Else if `providerPreference` override exists -> recommend that provider
|
|
182
|
-
- Else use the decision hierarchy above
|
|
222
|
+
- Else use the decision hierarchy above only when there is no stronger source
|
|
223
|
+
direction (Signal Discovery -> Sales Nav -> Prospeo -> Apollo)
|
|
183
224
|
2. Build options from `providerOrder` and `framework.providers[providerId].askOption`
|
|
184
225
|
3. Mark the recommended option by appending " (Recommended)" if needed
|
|
185
226
|
|
|
@@ -49,9 +49,10 @@ for debug output.
|
|
|
49
49
|
12. Sync the approved template into the campaign brief.
|
|
50
50
|
13. After message approval, keep the watched app on Filter Leads while the
|
|
51
51
|
bounded enrichment/filter cascade starts.
|
|
52
|
-
14. Move to Messages only after at least one review row passes
|
|
53
|
-
review
|
|
54
|
-
|
|
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.
|
|
55
56
|
|
|
56
57
|
There is no normal approval-packet, commit-gate, atomic-mint, or local
|
|
57
58
|
artifact-validation step. Those belong only to legacy validation/rehearsal
|
|
@@ -125,6 +126,16 @@ Default source order when the user has not supplied a source:
|
|
|
125
126
|
3. broader Sales Nav role/title filters
|
|
126
127
|
4. Prospeo account/contact expansion
|
|
127
128
|
|
|
129
|
+
Use that order only when the brief has no stronger sourcing constraint. If the
|
|
130
|
+
campaign is hiring-led, asks for companies actively hiring specific roles, asks
|
|
131
|
+
for open-role/job-posting signals, or needs verified contacts at companies with
|
|
132
|
+
those hiring signals, start with Prospeo. Prospeo supports
|
|
133
|
+
`company_job_posting_hiring_for` and `company_job_posting_quantity`; Sales Nav
|
|
134
|
+
does not provide hiring-by-role filters. For those campaigns, Signal Discovery
|
|
135
|
+
can be a conversation-signal check if relevant hiring posts are likely, and
|
|
136
|
+
Sales Nav is a LinkedIn activity/referral fallback rather than the main hiring
|
|
137
|
+
filter.
|
|
138
|
+
|
|
128
139
|
Before any provider prompt, search, source scout, or signal-discovery call,
|
|
129
140
|
show a short source-plan gate and ask for approval. This first approval
|
|
130
141
|
authorizes source scouting/search only. The gate must say, in plain language:
|
|
@@ -161,14 +172,30 @@ the target engager/source-candidate volume, the bounded campaign review-batch
|
|
|
161
172
|
size, the cleanup risk, and the fallback if the selected posts look wrong. The
|
|
162
173
|
approval label must describe the action with the count, such as "Approve
|
|
163
174
|
scraping 3 Signal Discovery posts?" For Sales Nav or Prospeo, the label should
|
|
164
|
-
name the specific search/import lane. Do not call
|
|
165
|
-
`confirm_lead_list` until this second source-action approval
|
|
175
|
+
name the specific search/import lane and source lead count. Do not call
|
|
176
|
+
`import_leads` or `confirm_lead_list` until this second source-action approval
|
|
177
|
+
is granted.
|
|
178
|
+
|
|
179
|
+
For Sales Nav and Prospeo, do not ask to import only the 25-row review batch at
|
|
180
|
+
the source-action gate. First-page samples are for source math: compute sampled
|
|
181
|
+
fit after conservative cleanup, project how many good-fit prospects the raw
|
|
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
|
|
185
|
+
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.
|
|
190
|
+
|
|
166
191
|
After the user approves this concrete source-action gate, do not show the
|
|
167
192
|
Source Recommendation again and do not ask another source approval question.
|
|
168
193
|
Acknowledge once, then call `import_leads` immediately with the approved source
|
|
169
|
-
math. For
|
|
170
|
-
|
|
171
|
-
|
|
194
|
+
math. For Sales Nav/Prospeo, pass `targetLeadCount` as the approved source-list
|
|
195
|
+
export count, not the review-batch size. For Signal Discovery, pass
|
|
196
|
+
`provider: "signal-discovery"`, `targetEngagerCount`, `maxPostsToScrape`, and
|
|
197
|
+
`confirmed: true`; the tool owns moving the watch UI to source-list progress
|
|
198
|
+
after a lead-list/job id exists.
|
|
172
199
|
|
|
173
200
|
For Signal Discovery, use this compact source-action approval shape after
|
|
174
201
|
selected posts exist:
|
|
@@ -181,7 +208,7 @@ Use Signal Discovery first.
|
|
|
181
208
|
**Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
|
|
182
209
|
**Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
|
|
183
210
|
**Planning floor:** continue only when sampled/projected fit is at least 10% after cleanup; below that, switch to Sales Nav recent activity<br>
|
|
184
|
-
**Review checkpoint:**
|
|
211
|
+
**Review checkpoint:** after the source list exists, clone only the bounded review batch into the campaign for fit and message review<br>
|
|
185
212
|
|
|
186
213
|
### Selected posts
|
|
187
214
|
|
|
@@ -202,8 +229,9 @@ This gives enough volume to work toward ~150 good-fit prospects, while
|
|
|
202
229
|
keeping the source tied to people already engaging with Claude Code outbound /
|
|
203
230
|
AI-native sales workflows.
|
|
204
231
|
|
|
205
|
-
**First pass:** build the source list
|
|
206
|
-
batch so we can inspect
|
|
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.
|
|
207
235
|
|
|
208
236
|
**Fallback:** if sampled/projected fit falls below 10%, or if the review batch
|
|
209
237
|
is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent
|
|
@@ -213,7 +241,11 @@ activity.
|
|
|
213
241
|
A source recommendation must show concrete evidence: source lane, filters or
|
|
214
242
|
recipe, raw volume, sample size, sampled fits as n/N plus percentage/range,
|
|
215
243
|
estimated usable prospects, cleanup risk, runner-up, and what approval
|
|
216
|
-
authorizes.
|
|
244
|
+
authorizes. For Sales Nav/Prospeo it must also show source export math:
|
|
245
|
+
`rawResultCount`, `sampledFitRate`, conservative projected fit rate,
|
|
246
|
+
`targetLeadCount` for the source list, and projected good-fit count from that
|
|
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.
|
|
217
249
|
|
|
218
250
|
Supplied profile CSVs, company/domain CSVs, pasted domains, and existing
|
|
219
251
|
Sellable lead lists are supported, but keep provider mechanics out of the first
|
|
@@ -222,46 +254,45 @@ customer-facing source-choice labels.
|
|
|
222
254
|
## Post-Lead Workstreams
|
|
223
255
|
|
|
224
256
|
After `confirm_lead_list` imports a non-empty bounded review batch and
|
|
225
|
-
`get_rows_minimal({ tableId: workflowTableId })` proves rows exist,
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
the
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
Builder
|
|
235
|
-
|
|
257
|
+
`get_rows_minimal({ tableId: workflowTableId })` proves rows exist, ask the
|
|
258
|
+
filter-choice question immediately. Do not call
|
|
259
|
+
`get_post_find_leads_scout_registry`, load filter/message subskill prompts, or
|
|
260
|
+
spawn post-lead workers before that question. The only customer-facing work
|
|
261
|
+
before the question should be a short review-batch summary and the choice:
|
|
262
|
+
add filters, skip filters, or revise source.
|
|
263
|
+
|
|
264
|
+
If the user chooses filters, then load the post-lead registry/reference needed
|
|
265
|
+
for filtering and start the Lead Fit Builder. Also start the Message Draft
|
|
266
|
+
Builder in the background from the same campaign/table basis as soon as the
|
|
267
|
+
filter-choice answer is known. If the user skips filters, move the watched app to
|
|
268
|
+
Messages and run the Message Draft Builder there. Debug markdown/json artifacts
|
|
269
|
+
are optional only.
|
|
236
270
|
|
|
237
271
|
When the user chooses filters, immediately call
|
|
238
272
|
`update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
|
|
239
273
|
before rubric thinking or branch work. The watched app should move to Filter
|
|
240
274
|
Rules quickly. After `save_rubrics`, the watched app should move to
|
|
241
275
|
`apply-icp-rubric` / Filter Leads so the user can see the saved filters are
|
|
242
|
-
ready
|
|
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.
|
|
243
279
|
|
|
244
280
|
Lead Fit Builder persists production rubrics with `save_rubrics` when filters
|
|
245
281
|
are enabled. It must not require `brief.md`, `lead-review.md`, or
|
|
246
282
|
`lead-sample.json`.
|
|
247
283
|
|
|
248
|
-
|
|
249
|
-
|
|
284
|
+
Run `post-find-leads-message-scout` as the background Message Draft Builder
|
|
285
|
+
whenever the host exposes it. It must load:
|
|
250
286
|
|
|
251
287
|
```text
|
|
252
288
|
get_subskill_prompt({ subskillName: "generate-messages", offset, limit }) until hasMore=false
|
|
253
289
|
```
|
|
254
290
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
Do not load the full `generate-messages` prompt in the create-campaign parent
|
|
262
|
-
thread unless you are executing the parent-thread fallback for the actual
|
|
263
|
-
message-draft branch. Parent-thread template approval uses only the compact
|
|
264
|
-
message-review safety gate.
|
|
291
|
+
No shortcut message instructions are valid. If the host cannot launch the
|
|
292
|
+
agent, the parent fallback must run the same full prompt from live campaign
|
|
293
|
+
state before drafting. Do not render message review until
|
|
294
|
+
`messageDraftRecommendation` proves current campaign/table/review-batch
|
|
295
|
+
`generate-messages` basis.
|
|
265
296
|
|
|
266
297
|
## Hard Gates
|
|
267
298
|
|
|
@@ -284,7 +315,6 @@ Load references only when needed:
|
|
|
284
315
|
- `references/watch-guide-narration.md` for watched-step narration.
|
|
285
316
|
- `references/lead-validation-preview.md` for legacy/debug preview shapes.
|
|
286
317
|
- `references/filter-leads.md` for rubric design and `save_rubrics` rules.
|
|
287
|
-
- `references/message-review-safety-gate.md` for final message approval checks.
|
|
288
318
|
- `references/step-13-import-leads.md` before review-batch import.
|
|
289
319
|
- `references/sample-validation-loop.md` before review-batch validation.
|
|
290
320
|
- `references/final-handoff-contract.md` for Settings, sender, sequence, and
|
|
@@ -274,14 +274,18 @@ keep the output numeric but do not claim the source scout was parallel or
|
|
|
274
274
|
surface install status to the customer.
|
|
275
275
|
|
|
276
276
|
For post-lead work, call `get_post_find_leads_scout_registry` after
|
|
277
|
+
the user chooses filters, not before the filter-choice question. After
|
|
277
278
|
`confirm_lead_list` imports a non-empty bounded review batch and
|
|
278
|
-
`get_rows_minimal` proves rows exist
|
|
279
|
-
immediately
|
|
280
|
-
|
|
281
|
-
filters
|
|
282
|
-
|
|
283
|
-
is
|
|
284
|
-
message
|
|
279
|
+
`get_rows_minimal` proves rows exist, ask add-filters vs skip-filters
|
|
280
|
+
immediately. Once the user answers, start `post-find-leads-message-scout` /
|
|
281
|
+
message generation from the same campaign/table basis. If the user chooses
|
|
282
|
+
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.
|
|
285
289
|
|
|
286
290
|
Only promise parallel post-lead work when parallel work actually started. If the
|
|
287
291
|
host cannot or should not launch background branches, say the real sequence:
|
|
@@ -66,9 +66,7 @@
|
|
|
66
66
|
"filter": [
|
|
67
67
|
"references/filter-leads.md"
|
|
68
68
|
],
|
|
69
|
-
"message": [
|
|
70
|
-
"references/message-review-safety-gate.md"
|
|
71
|
-
],
|
|
69
|
+
"message": [],
|
|
72
70
|
"tail": [
|
|
73
71
|
"references/sample-validation-loop.md",
|
|
74
72
|
"references/step-15-re-cascade.md",
|
|
@@ -588,20 +586,9 @@
|
|
|
588
586
|
]
|
|
589
587
|
},
|
|
590
588
|
{
|
|
591
|
-
"action": "
|
|
592
|
-
"
|
|
593
|
-
"
|
|
594
|
-
"requiresNonEmptyRows": true,
|
|
595
|
-
"mustRunBefore": [
|
|
596
|
-
"filter-choice question",
|
|
597
|
-
"filter approval",
|
|
598
|
-
"save_rubrics"
|
|
599
|
-
],
|
|
600
|
-
"mode": "background_when_host_supports_subagents",
|
|
601
|
-
"fallback": "if no real background branch can start, say the real sequence and do not claim background drafting is running",
|
|
602
|
-
"toolCallRequiredInBranch": "get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false",
|
|
603
|
-
"runtimeProofTransport": "CampaignOffer.watchNarration.workerDetails.messageDraftBuilder",
|
|
604
|
-
"purpose": "start the provisional message draft from the imported review batch immediately; do not defer this to filter approval"
|
|
589
|
+
"action": "summarize_review_batch_and_advance_to_filter_choice",
|
|
590
|
+
"purpose": "ask filter choice immediately; no post-lead registries, filter refs, or message prompts first",
|
|
591
|
+
"maxCustomerCopyLines": 4
|
|
605
592
|
}
|
|
606
593
|
],
|
|
607
594
|
"requiredCampaignState": [
|
|
@@ -611,8 +598,6 @@
|
|
|
611
598
|
],
|
|
612
599
|
"allowedTools": [
|
|
613
600
|
"get_subskill_prompt",
|
|
614
|
-
"get_subskill_asset",
|
|
615
|
-
"get_post_find_leads_scout_registry",
|
|
616
601
|
"import_leads",
|
|
617
602
|
"wait_for_lead_list_ready",
|
|
618
603
|
"confirm_lead_list",
|
|
@@ -620,16 +605,18 @@
|
|
|
620
605
|
"get_rows_minimal",
|
|
621
606
|
"update_campaign",
|
|
622
607
|
"AskUserQuestion",
|
|
623
|
-
"request_user_input"
|
|
624
|
-
"Task",
|
|
625
|
-
"spawn_agent"
|
|
608
|
+
"request_user_input"
|
|
626
609
|
],
|
|
627
610
|
"doNotAllow": [
|
|
611
|
+
"get_post_find_leads_scout_registry",
|
|
612
|
+
"Task",
|
|
613
|
+
"spawn_agent",
|
|
628
614
|
"list_senders",
|
|
629
615
|
"queue_cells",
|
|
630
616
|
"start_campaign",
|
|
631
617
|
"enrich_with_prospeo",
|
|
632
|
-
"bulk_enrich_with_prospeo"
|
|
618
|
+
"bulk_enrich_with_prospeo",
|
|
619
|
+
"save_rubrics"
|
|
633
620
|
],
|
|
634
621
|
"waitFor": "review_batch_imported",
|
|
635
622
|
"transitions": {
|
|
@@ -659,6 +646,13 @@
|
|
|
659
646
|
]
|
|
660
647
|
}
|
|
661
648
|
],
|
|
649
|
+
"hardRules": [
|
|
650
|
+
"ask_filter_choice_immediately_after_review_batch_import",
|
|
651
|
+
"do_not_call_get_subskill_prompt_before_filter_choice",
|
|
652
|
+
"do_not_call_get_subskill_asset_before_filter_choice",
|
|
653
|
+
"do_not_call_get_post_find_leads_scout_registry_before_filter_choice",
|
|
654
|
+
"do_not_spawn_post_lead_agents_before_filter_choice"
|
|
655
|
+
],
|
|
662
656
|
"requiredCampaignState": [
|
|
663
657
|
"campaignId",
|
|
664
658
|
"campaignBrief",
|
|
@@ -672,6 +666,11 @@
|
|
|
672
666
|
"get_campaign_navigation_state"
|
|
673
667
|
],
|
|
674
668
|
"doNotAllow": [
|
|
669
|
+
"get_subskill_prompt",
|
|
670
|
+
"get_subskill_asset",
|
|
671
|
+
"get_post_find_leads_scout_registry",
|
|
672
|
+
"Task",
|
|
673
|
+
"spawn_agent",
|
|
675
674
|
"create_campaign",
|
|
676
675
|
"list_senders",
|
|
677
676
|
"import_leads",
|
|
@@ -693,7 +692,7 @@
|
|
|
693
692
|
},
|
|
694
693
|
{
|
|
695
694
|
"id": "post-lead-workstreams",
|
|
696
|
-
"label": "Filter
|
|
695
|
+
"label": "Filter workstream",
|
|
697
696
|
"onEnter": [
|
|
698
697
|
{
|
|
699
698
|
"action": "persist_add_filters_approval",
|
|
@@ -715,17 +714,18 @@
|
|
|
715
714
|
},
|
|
716
715
|
"mustRunBefore": [
|
|
717
716
|
"get_post_find_leads_scout_registry",
|
|
718
|
-
"
|
|
717
|
+
"launch_lead_fit_builder_after_filter_choice",
|
|
719
718
|
"save_rubrics"
|
|
720
719
|
]
|
|
721
720
|
},
|
|
722
721
|
{
|
|
723
722
|
"tool": "get_post_find_leads_scout_registry",
|
|
724
|
-
"purpose": "load canonical post-lead worker names"
|
|
723
|
+
"purpose": "load canonical post-lead worker names only after the user has chosen filters"
|
|
725
724
|
},
|
|
726
725
|
{
|
|
727
|
-
"action": "
|
|
726
|
+
"action": "launch_lead_fit_builder_after_filter_choice",
|
|
728
727
|
"mode": "parallel_when_host_supports_subagents",
|
|
728
|
+
"target": "post-find-leads-filter-scout",
|
|
729
729
|
"inputs": [
|
|
730
730
|
"campaignId",
|
|
731
731
|
"campaignBrief",
|
|
@@ -734,9 +734,16 @@
|
|
|
734
734
|
"reviewBatchRowIds/hash",
|
|
735
735
|
"filterChoice"
|
|
736
736
|
],
|
|
737
|
-
"stateSource": "
|
|
738
|
-
"debugFilesOptionalOnly": true
|
|
739
|
-
|
|
737
|
+
"stateSource": "live campaign/table",
|
|
738
|
+
"debugFilesOptionalOnly": true
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
"action": "launch_message_draft_builder_after_filter_decision",
|
|
742
|
+
"mode": "parallel_when_host_supports_subagents",
|
|
743
|
+
"target": "post-find-leads-message-scout",
|
|
744
|
+
"when": "filters_enabled",
|
|
745
|
+
"doesNotQueueCells": true,
|
|
746
|
+
"customerNarration": "Say message agent is drafting."
|
|
740
747
|
},
|
|
741
748
|
{
|
|
742
749
|
"action": "save_filter_rubrics_to_campaign",
|
|
@@ -793,10 +800,13 @@
|
|
|
793
800
|
"hardRules": [
|
|
794
801
|
"after_save_rubrics_currentStep_must_be_apply-icp-rubric",
|
|
795
802
|
"do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped",
|
|
796
|
-
"
|
|
803
|
+
"no_post_lead_worker_or_deep_prompt_before_filter_choice",
|
|
804
|
+
"lead_fit_builder_starts_only_after_filters_enabled",
|
|
805
|
+
"msg_draft_after_filter_choice",
|
|
806
|
+
"msg_draft_no_cells"
|
|
797
807
|
],
|
|
798
808
|
"transitions": {
|
|
799
|
-
"post_lead_workstreams_ready": "message-
|
|
809
|
+
"post_lead_workstreams_ready": "message-generation",
|
|
800
810
|
"revise_leads": "find-leads",
|
|
801
811
|
"revise_rubric": "filter-rubric",
|
|
802
812
|
"revise_messaging": "message-generation",
|
|
@@ -865,14 +875,23 @@
|
|
|
865
875
|
"id": "message-generation",
|
|
866
876
|
"label": "Message generation",
|
|
867
877
|
"onEnter": [
|
|
878
|
+
{
|
|
879
|
+
"action": "set_message_review_visible_step_by_filter_choice",
|
|
880
|
+
"tool": "update_campaign",
|
|
881
|
+
"branchRules": [
|
|
882
|
+
"yes: currentStep=apply-icp-rubric; wait on Filter Leads",
|
|
883
|
+
"no: currentStep=messages; message review"
|
|
884
|
+
],
|
|
885
|
+
"watchNarration.stage": "fit-message"
|
|
886
|
+
},
|
|
868
887
|
{
|
|
869
888
|
"action": "run_or_reconcile_message_draft_builder",
|
|
870
889
|
"target": "post-find-leads-message-scout",
|
|
871
890
|
"toolCallRequiredBeforeDraft": [
|
|
872
|
-
"
|
|
873
|
-
"
|
|
891
|
+
"run background post-find-leads-message-scout when available",
|
|
892
|
+
"get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false"
|
|
874
893
|
],
|
|
875
|
-
"stateSource": "campaignBrief,
|
|
894
|
+
"stateSource": "campaignBrief, source, selectedLeadListId, workflowTableId, review-batch row ids/hash",
|
|
876
895
|
"outputState": "messageDraftRecommendation"
|
|
877
896
|
}
|
|
878
897
|
],
|
|
@@ -884,16 +903,16 @@
|
|
|
884
903
|
],
|
|
885
904
|
"allowedTools": [
|
|
886
905
|
"get_subskill_prompt",
|
|
887
|
-
"get_subskill_asset",
|
|
888
906
|
"get_campaign",
|
|
889
907
|
"get_rows_minimal",
|
|
908
|
+
"update_campaign",
|
|
890
909
|
"AskUserQuestion",
|
|
891
910
|
"request_user_input"
|
|
892
911
|
],
|
|
893
912
|
"toolRules": [
|
|
894
|
-
"
|
|
913
|
+
"Message Draft Builder must run as the background post-find-leads-message-scout when the host exposes it. If the host cannot launch the agent, the parent-thread fallback must execute the same full get_subskill_prompt({ subskillName: \"generate-messages\" }) from live state before drafting.",
|
|
895
914
|
"Do not use brief.md, lead-review.md, or lead-sample.json as required live state; those files are optional debug context only.",
|
|
896
|
-
"The
|
|
915
|
+
"The messageDraftRecommendation must return templateRecommendation, tokenFillRules, renderedSample, concerns, status, basisToken, outputAt, outputHash, and error or retry detail.",
|
|
897
916
|
"If campaign/source/table/review-batch basis does not match, classify the output stale or blocked."
|
|
898
917
|
],
|
|
899
918
|
"doNotAllow": [
|
|
@@ -902,7 +921,6 @@
|
|
|
902
921
|
"save_rubrics",
|
|
903
922
|
"import_leads",
|
|
904
923
|
"confirm_lead_list",
|
|
905
|
-
"update_campaign",
|
|
906
924
|
"queue_cells",
|
|
907
925
|
"start_campaign",
|
|
908
926
|
"generate_messages"
|
|
@@ -984,7 +1002,6 @@
|
|
|
984
1002
|
"allowedTools": [
|
|
985
1003
|
"AskUserQuestion",
|
|
986
1004
|
"request_user_input",
|
|
987
|
-
"get_subskill_asset",
|
|
988
1005
|
"update_campaign_brief",
|
|
989
1006
|
"update_campaign",
|
|
990
1007
|
"get_rows_minimal",
|
|
@@ -1124,8 +1141,14 @@
|
|
|
1124
1141
|
"cellSource": "pending_generate_message_cells_for_passing_rows using approved_campaign_brief_template"
|
|
1125
1142
|
},
|
|
1126
1143
|
{
|
|
1127
|
-
"tool": "
|
|
1128
|
-
"purpose": "
|
|
1144
|
+
"tool": "wait_for_rubric_results",
|
|
1145
|
+
"purpose": "wait_for_first_passing_generated_message",
|
|
1146
|
+
"requiredValues": {
|
|
1147
|
+
"includeRows": false,
|
|
1148
|
+
"minPassedCount": 1,
|
|
1149
|
+
"minMessagesCount": 1
|
|
1150
|
+
},
|
|
1151
|
+
"readVia": "stats_only_tool_result"
|
|
1129
1152
|
},
|
|
1130
1153
|
{
|
|
1131
1154
|
"action": "observe_generate_message_results",
|
|
@@ -1169,25 +1192,24 @@
|
|
|
1169
1192
|
"currentStep": "auto-execute-messaging",
|
|
1170
1193
|
"watchNarration.stage": "review-ready"
|
|
1171
1194
|
},
|
|
1172
|
-
"watchNarrationRule": "Say
|
|
1195
|
+
"watchNarrationRule": "Say the first passing generated message is ready in Messages; next is review before Settings."
|
|
1173
1196
|
},
|
|
1174
1197
|
{
|
|
1175
1198
|
"action": "ask_generated_message_review_choice",
|
|
1176
1199
|
"uses": "request_user_input",
|
|
1177
1200
|
"choices": [
|
|
1178
|
-
"Approve generated
|
|
1201
|
+
"Approve generated message and continue to Settings",
|
|
1179
1202
|
"Revise filters",
|
|
1180
1203
|
"Revise message template",
|
|
1181
1204
|
"Pause here"
|
|
1182
|
-
]
|
|
1183
|
-
"rule": "Do not advance to Settings until the generated review-batch messages have been reviewed and approved."
|
|
1205
|
+
]
|
|
1184
1206
|
}
|
|
1185
1207
|
],
|
|
1186
1208
|
"allowedTools": [
|
|
1187
1209
|
"get_subskill_asset",
|
|
1188
1210
|
"get_rows_minimal",
|
|
1189
1211
|
"queue_cells",
|
|
1190
|
-
"
|
|
1212
|
+
"wait_for_rubric_results",
|
|
1191
1213
|
"update_campaign",
|
|
1192
1214
|
"AskUserQuestion",
|
|
1193
1215
|
"request_user_input"
|
|
@@ -1201,6 +1223,7 @@
|
|
|
1201
1223
|
"hardRules": [
|
|
1202
1224
|
"critique_failure_never_escalates",
|
|
1203
1225
|
"critique_sample_size_bounded_by_config",
|
|
1226
|
+
"first_passing_generated_message_unblocks_review",
|
|
1204
1227
|
"critics_fixed_at_targeting_copy_voice",
|
|
1205
1228
|
"synthesis_enforces_phase_84_token_contract",
|
|
1206
1229
|
"opus_reserved_for_highest_value_subset",
|