@sellable/mcp 0.1.143 → 0.1.145
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 +19 -6
- package/agents/post-find-leads-message-scout.md +44 -0
- package/agents/registry.json +2 -2
- package/agents/source-scout-linkedin-engagement.md +4 -3
- package/agents/source-scout-prospeo-contact.md +1 -1
- package/agents/source-scout-sales-nav.md +3 -2
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/tools/leads.js +168 -14
- package/dist/tools/processing.d.ts +1 -0
- package/dist/tools/prompts.js +3 -3
- package/dist/tools/rubrics.js +14 -9
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +55 -34
- package/skills/create-campaign-v2/SKILL.md +59 -9
- package/skills/create-campaign-v2/SOUL.md +20 -12
- package/skills/create-campaign-v2/core/auto-execute.README.md +4 -4
- package/skills/create-campaign-v2/core/auto-execute.yaml +4 -4
- package/skills/create-campaign-v2/core/flow.v2.json +55 -19
- package/skills/create-campaign-v2/references/approval-gate-framing.md +1 -1
- package/skills/create-campaign-v2/references/filter-leads.md +42 -0
- package/skills/create-campaign-v2/references/final-handoff-contract.md +5 -5
- package/skills/create-campaign-v2/references/message-review-safety-gate.md +88 -13
- package/skills/create-campaign-v2/references/sample-validation-loop.md +18 -15
- package/skills/create-campaign-v2/references/step-13-import-leads.md +9 -6
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +2 -3
- package/skills/create-campaign-v2/references/watch-guide-narration.md +39 -24
- package/skills/create-campaign-v2/references/watch-link-handoff.md +1 -1
- package/skills/create-campaign-v2-tail/SKILL.md +26 -13
- package/skills/load-voice/SKILL.md +129 -0
- package/skills/providers/prospeo.md +2 -1
- package/skills/providers/sales-nav.md +4 -2
- package/skills/providers/signal-discovery.md +12 -10
- package/skills/research/config.json +9 -0
|
@@ -86,7 +86,7 @@ or tool discovery. Start in product language:
|
|
|
86
86
|
```text
|
|
87
87
|
I’ll help you launch this as a Sellable campaign. First I’ll resolve the
|
|
88
88
|
client/company this campaign is for, then I’ll turn that into a campaign brief
|
|
89
|
-
before
|
|
89
|
+
before we move into lead sourcing.
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
If a linked/local skill file is stale or missing, silently use the installed
|
|
@@ -102,8 +102,14 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
|
|
|
102
102
|
- "a couple setup choices", not `request_user_input`
|
|
103
103
|
- "campaign brief", not prompt artifact
|
|
104
104
|
- "lead source", not provider internals unless comparing source options
|
|
105
|
-
- "I can create a draft shell for you to watch
|
|
106
|
-
|
|
105
|
+
- "I can create a draft shell for you to watch with approval gates before
|
|
106
|
+
sourcing", not mutation jargon
|
|
107
|
+
|
|
108
|
+
Approval and safety copy should be tasteful. State what the current approval
|
|
109
|
+
covers once, in one short sentence, then move on. Do not append repeated
|
|
110
|
+
"nothing starts / no leads import / no sending" disclaimers to routine progress
|
|
111
|
+
updates. Use positive gate language like "Next gate: selected-post scrape" or
|
|
112
|
+
"Approval covers scouting/search only" instead of long negative lists.
|
|
107
113
|
|
|
108
114
|
When explaining lead-source decisions, show the concrete counts behind the
|
|
109
115
|
logic: lanes searched, timeframe, raw result counts, finalist posts or preview
|
|
@@ -127,7 +133,7 @@ authorizes scouting/search only. The gate should say:
|
|
|
127
133
|
- why that lane fits the buyer, offer, and likely public activity
|
|
128
134
|
- what will be tested next
|
|
129
135
|
- the fallback lane if relevant posts or ICP engagement look thin
|
|
130
|
-
-
|
|
136
|
+
- what approval covers in one concise line
|
|
131
137
|
|
|
132
138
|
Do not surface blanket source heuristics as product copy. Make the
|
|
133
139
|
recommendation specific to the campaign. If Signal Discovery is recommended,
|
|
@@ -142,6 +148,21 @@ Signal Discovery, name how many selected posts will be scraped, the target
|
|
|
142
148
|
engager/source-candidate volume, and the bounded review-batch size. For Sales
|
|
143
149
|
Nav or Prospeo, name the specific approved import lane. Do not call
|
|
144
150
|
`import_leads` or `confirm_lead_list` until this second approval is granted.
|
|
151
|
+
For Signal Discovery, the customer-facing approval card must use the exact
|
|
152
|
+
action shape "Approve scraping N Signal Discovery posts?" and the chat summary
|
|
153
|
+
should be a compact `## Source Recommendation` block with:
|
|
154
|
+
|
|
155
|
+
- good-fit target: about 150 prospects after cleanup, enrichment, and filters
|
|
156
|
+
- source-candidate plan: about 1,000 raw engagers using a conservative 15%
|
|
157
|
+
fit-rate assumption unless sampled data supports a different number
|
|
158
|
+
- review checkpoint: import the first 25 leads for fit and message review
|
|
159
|
+
- a selected-post table with post author/topic, why it fits, and visible
|
|
160
|
+
engagement
|
|
161
|
+
- total visible pool and estimated good-fit pool
|
|
162
|
+
- first pass: build the source list, then import only the review
|
|
163
|
+
batch
|
|
164
|
+
- fallback: switch to Sales Nav recent activity if the review batch is
|
|
165
|
+
vendor-heavy, agency-heavy, or off-ICP
|
|
145
166
|
|
|
146
167
|
When the user has not supplied a source and multiple source angles are viable,
|
|
147
168
|
scout those angles as independent branches when the host can actually do it:
|
|
@@ -168,19 +189,17 @@ which posts are being sampled in the watched app. The watch guide should say
|
|
|
168
189
|
that we are pulling sample engagers from these posts to confirm the ICP is
|
|
169
190
|
actually engaging and the source is viable.
|
|
170
191
|
|
|
171
|
-
After
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
still orchestrates the same branches from the compact context with MCP
|
|
183
|
-
tools/assets.
|
|
192
|
+
After the bounded review batch exists, use the same registry pattern for
|
|
193
|
+
post-lead work. The create-campaign-v2 subskill calls
|
|
194
|
+
`get_post_find_leads_scout_registry`, then launches the returned
|
|
195
|
+
message-generation scout immediately when real subagents are available and the
|
|
196
|
+
current session exposes the returned name. If the user chooses filters, launch
|
|
197
|
+
the filter-leads scout then and join it with the already-running or completed
|
|
198
|
+
message draft before message review. Workflow cell execution still waits for
|
|
199
|
+
filter and template approval. AI Generated is an explicit opt-out that cancels
|
|
200
|
+
or ignores the background template draft. If the post-lead agents are absent,
|
|
201
|
+
the main thread still orchestrates the same branches from the compact context
|
|
202
|
+
with MCP tools/assets.
|
|
184
203
|
|
|
185
204
|
Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
|
|
186
205
|
lines short, use indexed section labels and bullets, and translate internal
|
|
@@ -233,7 +252,7 @@ After every `update_campaign({ campaignId, currentStep })`, use
|
|
|
233
252
|
`get_campaign_navigation_state` when available as a compact orientation check:
|
|
234
253
|
match the saved campaign state to the expected watch-link step, explain the
|
|
235
254
|
current state in one sentence, and only then continue. Sender selection belongs
|
|
236
|
-
at Settings after message approval and
|
|
255
|
+
at Settings after message approval and review-batch validation. After message
|
|
237
256
|
validation, use Settings to help the user connect or select a LinkedIn sender.
|
|
238
257
|
Explain Slack reply review before launch. After sender selection, attach the
|
|
239
258
|
recommended sequence and move the watched UI to Send. Do not start the campaign
|
|
@@ -412,7 +431,7 @@ First I’ll resolve the client/company this campaign is for. I’ll use that
|
|
|
412
431
|
context to choose the target, offer, proof, and lead source.
|
|
413
432
|
|
|
414
433
|
Then I’ll turn that into a campaign brief for you to approve before any leads
|
|
415
|
-
are
|
|
434
|
+
are sourced.
|
|
416
435
|
```
|
|
417
436
|
|
|
418
437
|
Do not silently ask Codex intake or approval questions as plain chat when
|
|
@@ -596,9 +615,9 @@ updates.
|
|
|
596
615
|
until `hasMore=false`. The create-campaign message-review safety gate is a
|
|
597
616
|
supplemental approval checklist, not a replacement for the long prompt. Use
|
|
598
617
|
campaign state, campaign brief content, selected source state, and imported
|
|
599
|
-
review-batch rows as the source of truth; do not read stale local markdown
|
|
600
|
-
inspect the database directly, or synthesize
|
|
601
|
-
general knowledge.
|
|
618
|
+
review-batch rows as the source of truth; do not read stale local markdown
|
|
619
|
+
such as `message-validation.md`, inspect the database directly, or synthesize
|
|
620
|
+
local validation artifacts from general knowledge.
|
|
602
621
|
5. Create the campaign shell early with the v1 brief so the user can open the
|
|
603
622
|
watch link and see useful setup state immediately. Import only the first
|
|
604
623
|
bounded review batch after the source is attached to the campaign; do not
|
|
@@ -609,9 +628,11 @@ updates.
|
|
|
609
628
|
call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
|
|
610
629
|
so the watched app moves to Filter Rules while rubrics are drafted/saved.
|
|
611
630
|
After rubrics save, move the watched app to `apply-icp-rubric` / Filter
|
|
612
|
-
Leads and say the fit rules are saved; approve the message template next
|
|
613
|
-
|
|
614
|
-
|
|
631
|
+
Leads and say the fit rules are saved; approve the message template next
|
|
632
|
+
while the browser stays on Filter Leads. After approval, save the template
|
|
633
|
+
to the campaign brief, then queue the bounded review-batch `enrichCellId`
|
|
634
|
+
cells to kick off enrichment/filtering. Move to Messages only after at
|
|
635
|
+
least one review row passes and Generate Message cells are running or ready.
|
|
615
636
|
Product Generate Message cells must not run from the background template
|
|
616
637
|
path before that template/token approval.
|
|
617
638
|
Do not ask the user to approve the brief before shell creation unless they
|
|
@@ -620,15 +641,15 @@ updates.
|
|
|
620
641
|
`mcp__sellable__update_campaign({ campaignId, currentStep })` before major
|
|
621
642
|
visible work so the user can watch progress in the app: `create-offer` for
|
|
622
643
|
the brief, `pick-provider` or the selected provider step while sourcing,
|
|
623
|
-
`filter-choice` after the
|
|
624
|
-
as filters are approved, `apply-icp-rubric` after rubrics save
|
|
625
|
-
for
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
`
|
|
631
|
-
step backward.
|
|
644
|
+
`filter-choice` after the review batch, `create-icp-rubric` as soon
|
|
645
|
+
as filters are approved, `apply-icp-rubric` after rubrics save and while
|
|
646
|
+
waiting for message-template approval, `validate-sample` while the approved
|
|
647
|
+
template unlocks bounded enrichment/filter scoring on Filter Leads,
|
|
648
|
+
`auto-execute-messaging` after at least one row passes and review-batch
|
|
649
|
+
messages are being generated or reviewed, `awaiting-user-greenlight` only
|
|
650
|
+
after generated review-batch messages are approved, `settings` for sender
|
|
651
|
+
selection, `sequence` after sender attach, and `send` once the recommended
|
|
652
|
+
sequence is attached. Do not advance the step backward.
|
|
632
653
|
7. Keep `selectedLeadListId` as the source list and `workflowTableId` as the
|
|
633
654
|
campaign table. Do not use disk files as the post-mint source of truth.
|
|
634
655
|
8. Do not ask the user to run another command.
|
|
@@ -47,8 +47,11 @@ for debug output.
|
|
|
47
47
|
rows.
|
|
48
48
|
11. Review and approve/revise the message.
|
|
49
49
|
12. Sync the approved template into the campaign brief.
|
|
50
|
-
13.
|
|
51
|
-
|
|
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, generate and
|
|
53
|
+
review bounded messages, then hand off to Settings, sender, sequence, and
|
|
54
|
+
explicit launch greenlight.
|
|
52
55
|
|
|
53
56
|
There is no normal approval-packet, commit-gate, atomic-mint, or local
|
|
54
57
|
artifact-validation step. Those belong only to legacy validation/rehearsal
|
|
@@ -151,10 +154,48 @@ After scouting, show a second approval gate for the concrete source action. For
|
|
|
151
154
|
Signal Discovery, this gate must say how many selected posts will be scraped,
|
|
152
155
|
the target engager/source-candidate volume, the bounded campaign review-batch
|
|
153
156
|
size, the cleanup risk, and the fallback if the selected posts look wrong. The
|
|
154
|
-
approval label
|
|
155
|
-
|
|
156
|
-
specific search/import lane. Do not call `import_leads` or
|
|
157
|
-
until this second source-action approval is granted.
|
|
157
|
+
approval label must describe the action with the count, such as "Approve
|
|
158
|
+
scraping 3 Signal Discovery posts?" For Sales Nav or Prospeo, the label should
|
|
159
|
+
name the specific search/import lane. Do not call `import_leads` or
|
|
160
|
+
`confirm_lead_list` until this second source-action approval is granted.
|
|
161
|
+
|
|
162
|
+
For Signal Discovery, use this compact source-action approval shape after
|
|
163
|
+
selected posts exist:
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
## Source Recommendation
|
|
167
|
+
|
|
168
|
+
Use Signal Discovery first.
|
|
169
|
+
|
|
170
|
+
**Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
|
|
171
|
+
**Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
|
|
172
|
+
**Review checkpoint:** import the first 25 leads into the campaign for fit and message review before scaling<br>
|
|
173
|
+
|
|
174
|
+
### Selected posts
|
|
175
|
+
|
|
176
|
+
| Post | Why it fits | Visible engagement |
|
|
177
|
+
| ---------------- | ----------------------------------------------- | -----------------: |
|
|
178
|
+
| Dylan Power | Claude outbound system | ~1,571 |
|
|
179
|
+
| Fivos Aresti | Replacing Clay outbound with Claude Code | ~734 |
|
|
180
|
+
| Divyanshi Sharma | LinkedIn lead-gen system built with Claude Code | ~508 |
|
|
181
|
+
|
|
182
|
+
**Total visible pool:** ~2,813 engagers<br>
|
|
183
|
+
**Estimated good-fit pool at 15%:** ~420 prospects before dedupe/risk cleanup
|
|
184
|
+
|
|
185
|
+
### Recommendation
|
|
186
|
+
|
|
187
|
+
Approve scraping these 3 posts.
|
|
188
|
+
|
|
189
|
+
This gives enough volume to work toward ~150 good-fit prospects, while
|
|
190
|
+
keeping the source tied to people already engaging with Claude Code outbound /
|
|
191
|
+
AI-native sales workflows.
|
|
192
|
+
|
|
193
|
+
**First pass:** build the source list, then import only the 25-lead review
|
|
194
|
+
batch so we can inspect fit and messages before scaling.
|
|
195
|
+
|
|
196
|
+
**Fallback:** if the review batch is too vendor-heavy, agency-heavy, or
|
|
197
|
+
off-ICP, switch to Sales Nav recent activity.
|
|
198
|
+
```
|
|
158
199
|
|
|
159
200
|
A source recommendation must show concrete evidence: source lane, filters or
|
|
160
201
|
recipe, raw volume, sample size, sampled fits as n/N plus percentage/range,
|
|
@@ -169,8 +210,15 @@ customer-facing source-choice labels.
|
|
|
169
210
|
|
|
170
211
|
After `confirm_lead_list` imports a non-empty bounded review batch and
|
|
171
212
|
`get_rows_minimal({ tableId: workflowTableId })` proves rows exist, call
|
|
172
|
-
`get_post_find_leads_scout_registry
|
|
173
|
-
|
|
213
|
+
`get_post_find_leads_scout_registry` and start the Message Draft Builder branch
|
|
214
|
+
immediately when the current host exposes that returned agent. Do this before
|
|
215
|
+
asking the filter-choice question. If no real background branch can start, say
|
|
216
|
+
the real sequence and do not claim background drafting is running.
|
|
217
|
+
|
|
218
|
+
The message branch uses live CampaignOffer/source/table state as the source of
|
|
219
|
+
truth and may draft while the user is choosing filters. It does not write
|
|
220
|
+
message cells, enrich rows, attach sequences, or unlock Settings. The Lead Fit
|
|
221
|
+
Builder branch starts only after the user chooses filters. Debug markdown/json
|
|
174
222
|
artifacts are optional only.
|
|
175
223
|
|
|
176
224
|
When the user chooses filters, immediately call
|
|
@@ -198,7 +246,9 @@ get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/
|
|
|
198
246
|
```
|
|
199
247
|
|
|
200
248
|
Do not load the full `generate-messages` prompt in the create-campaign parent
|
|
201
|
-
thread unless you are executing the parent-thread fallback for
|
|
249
|
+
thread unless you are executing the parent-thread fallback for the actual
|
|
250
|
+
message-draft branch. Parent-thread template approval uses only the compact
|
|
251
|
+
message-review safety gate.
|
|
202
252
|
|
|
203
253
|
## Hard Gates
|
|
204
254
|
|
|
@@ -35,7 +35,7 @@ tell them what they will see next.
|
|
|
35
35
|
is missing.
|
|
36
36
|
- "lead source" beats provider internals unless comparing options.
|
|
37
37
|
- "I’ll create the campaign shell with the brief so you can watch it fill in,
|
|
38
|
-
|
|
38
|
+
with approval gates before sourcing" beats mutation jargon.
|
|
39
39
|
- "I’m turning this into a brief now" beats "I’m persisting the draft."
|
|
40
40
|
- "Sorry, this is taking a little longer than expected" is appropriate when a
|
|
41
41
|
step overruns its estimate. Do not over-apologize; one calm acknowledgment is
|
|
@@ -148,9 +148,9 @@ unless the user asks for them.
|
|
|
148
148
|
Good opening:
|
|
149
149
|
|
|
150
150
|
```text
|
|
151
|
-
I’ll help you launch this as a Sellable campaign. First I’ll
|
|
152
|
-
|
|
153
|
-
before
|
|
151
|
+
I’ll help you launch this as a Sellable campaign. First I’ll confirm who we’re
|
|
152
|
+
sending from and which company this is for, then I’ll turn that into a campaign
|
|
153
|
+
brief before lead sourcing or anything can send.
|
|
154
154
|
```
|
|
155
155
|
|
|
156
156
|
Good identity setup:
|
|
@@ -236,6 +236,13 @@ source. That approval only authorizes scouting/search. Second, after the
|
|
|
236
236
|
source evidence exists, show counts, samples, fit math, cleanup risk, and ask
|
|
237
237
|
for source approval before import.
|
|
238
238
|
|
|
239
|
+
For Signal Discovery, the second gate is not "approve source" in the abstract.
|
|
240
|
+
It is a concrete scrape approval: show a compact `## Source Recommendation`
|
|
241
|
+
with the ~150 good-fit prospect goal, 15% raw-engager assumption, selected-post
|
|
242
|
+
table, total visible pool, estimated good-fit pool, first-pass review
|
|
243
|
+
batch, and fallback. The approval question should be "Approve scraping N Signal
|
|
244
|
+
Discovery posts?"
|
|
245
|
+
|
|
239
246
|
## Parallelism + Naming
|
|
240
247
|
|
|
241
248
|
Source selection is sequential by default. Start with the first recommended
|
|
@@ -257,14 +264,15 @@ scout loads only its matching provider prompt. If source work is sequential,
|
|
|
257
264
|
keep the output numeric but do not claim the source scout was parallel or
|
|
258
265
|
surface install status to the customer.
|
|
259
266
|
|
|
260
|
-
For post-lead work, call `get_post_find_leads_scout_registry` after
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
For post-lead work, call `get_post_find_leads_scout_registry` after
|
|
268
|
+
`confirm_lead_list` imports a non-empty bounded review batch and
|
|
269
|
+
`get_rows_minimal` proves rows exist. Start `post-find-leads-message-scout`
|
|
270
|
+
immediately when real subagents are available, before asking the filter-choice
|
|
271
|
+
question. Start `post-find-leads-filter-scout` only after the user chooses
|
|
272
|
+
filters. This is the same registry pattern as source scouting, but the trigger
|
|
273
|
+
for message drafting is review-batch import, not filter approval. The join gate
|
|
274
|
+
is live branch readiness: saved rubrics or a resolved skip-filter choice, plus a
|
|
275
|
+
message recommendation grounded in the same campaign/table basis.
|
|
268
276
|
|
|
269
277
|
Only promise parallel post-lead work when parallel work actually started. If the
|
|
270
278
|
host cannot or should not launch background branches, say the real sequence:
|
|
@@ -33,16 +33,16 @@ the imported review batch for validation).
|
|
|
33
33
|
|
|
34
34
|
- **`sampleSize`** — How many rows the validation loop pulls from the
|
|
35
35
|
imported review batch. In v2 this matches the review-batch cap
|
|
36
|
-
(default
|
|
36
|
+
(default 25), so the user sees enough real rows to judge the campaign
|
|
37
37
|
without spending credits on hundreds more.
|
|
38
38
|
- **`minProjectedPass`** — Passing-message floor required before handoff.
|
|
39
|
-
The default requires
|
|
39
|
+
The default requires 5 passing examples from the 25-row review batch.
|
|
40
40
|
Math:
|
|
41
41
|
```text
|
|
42
42
|
projectedPass = round(passInSample / sampleSize * importLimit)
|
|
43
43
|
```
|
|
44
|
-
With defaults (sampleSize=
|
|
45
|
-
the actual review-batch pass count.
|
|
44
|
+
With defaults (sampleSize=25, importLimit=25), `projectedPass` equals
|
|
45
|
+
the actual review-batch pass count. 5 passing rows is exactly at the
|
|
46
46
|
floor.
|
|
47
47
|
- **`maxRevisionRounds`** — Hard cap before escalating to the user. A
|
|
48
48
|
revision round is one full sample pass that triggered brief revision
|
|
@@ -17,7 +17,7 @@ import:
|
|
|
17
17
|
# Initial review batch imported in Step 13 before the sample validation
|
|
18
18
|
# loop. Import + enrichment must never exceed this cap before the user
|
|
19
19
|
# reviews the sample and explicitly asks to expand.
|
|
20
|
-
importLimit:
|
|
20
|
+
importLimit: 25
|
|
21
21
|
# Provider is inherited from the campaign-attached source association created
|
|
22
22
|
# during find-leads. Step 13 may re-run provider preflight in memory, but it
|
|
23
23
|
# does not choose a new source.
|
|
@@ -27,11 +27,11 @@ sample:
|
|
|
27
27
|
# Rows pulled from the imported cohort for the validation loop. In v2 this
|
|
28
28
|
# equals the review-batch cap so the user sees a focused first test batch
|
|
29
29
|
# without spending credits on hundreds of rows.
|
|
30
|
-
sampleSize:
|
|
30
|
+
sampleSize: 25
|
|
31
31
|
# Projected first-batch passing count required to proceed to sample
|
|
32
32
|
# messaging. This is not approval to scale the full source list.
|
|
33
33
|
# projectedPass = round(passInSample / sampleSize * importLimit).
|
|
34
|
-
minProjectedPass:
|
|
34
|
+
minProjectedPass: 5
|
|
35
35
|
# Hard cap on revision loops before escalating to the user. On a stale
|
|
36
36
|
# resume the counter does NOT reset — the 3-round cap holds across
|
|
37
37
|
# sessions.
|
|
@@ -106,7 +106,7 @@ handoff:
|
|
|
106
106
|
# Orientation surfaced in Step 16 ("awaiting-user-greenlight") along with
|
|
107
107
|
# the watch link. Keep this short and user-facing.
|
|
108
108
|
orientation: >-
|
|
109
|
-
Review the first
|
|
109
|
+
Review the first 25 enriched leads and messages. If they look good,
|
|
110
110
|
attach a sender in Settings, accept the recommended sequence, and start
|
|
111
111
|
the campaign without spending credits on more leads first.
|
|
112
112
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "v2.1-compact",
|
|
3
3
|
"workflow": "create-campaign-v2",
|
|
4
|
-
"principle": "CampaignOffer state and the watch link are canonical from the first brief onward. The active customer path is shell-first and state-first: create the watchable campaign shell with the brief, attach source/search state to that CampaignOffer, import one bounded review batch, persist rubrics
|
|
4
|
+
"principle": "CampaignOffer state and the watch link are canonical from the first brief onward. The active customer path is shell-first and state-first: create the watchable campaign shell with the brief, attach source/search state to that CampaignOffer, import one bounded review batch, persist rubrics, wait on Filter Leads for approved message-template review, save the approved template, validate the bounded review batch, generate and review bounded messages, then hand off to Settings, sequence, and explicit start.",
|
|
5
5
|
"normalCustomerPath": "Use campaign state, MCP tool responses, and concise watchNarration. Do not create, read, link, or surface local draft files in normal customer runs.",
|
|
6
6
|
"legacyCompatibility": {
|
|
7
7
|
"validationSubskill": "create-campaign-v2-validation",
|
|
@@ -460,6 +460,7 @@
|
|
|
460
460
|
"requiredInlineFields": [
|
|
461
461
|
"primary source and exact filters/recipe",
|
|
462
462
|
"specific source action awaiting approval",
|
|
463
|
+
"for Signal Discovery: Source Recommendation markdown with ~150 good-fit prospects as the target, source-candidate plan ~1,000 raw engagers at a conservative ~15% fit assumption, review checkpoint size, selected-post table, total visible pool, estimated good-fit pool, first pass, and fallback",
|
|
463
464
|
"for Signal Discovery: selected post count and target engager/source-candidate volume",
|
|
464
465
|
"bounded review batch size",
|
|
465
466
|
"runner-up and why it lost",
|
|
@@ -475,13 +476,13 @@
|
|
|
475
476
|
"action": "ask_source_review_choice",
|
|
476
477
|
"uses": "request_user_input",
|
|
477
478
|
"choices": [
|
|
478
|
-
"
|
|
479
|
+
"Approve scraping N Signal Discovery posts",
|
|
479
480
|
"Run the approved source import for the bounded review batch",
|
|
480
481
|
"Revise source",
|
|
481
482
|
"Pause here"
|
|
482
483
|
],
|
|
483
484
|
"approvalChoiceLabelsByProvider": {
|
|
484
|
-
"signal-discovery": "
|
|
485
|
+
"signal-discovery": "Approve scraping {selectedPostCount} Signal Discovery posts?",
|
|
485
486
|
"sales-nav": "Import the approved Sales Nav review batch",
|
|
486
487
|
"prospeo": "Import the approved Prospeo review batch"
|
|
487
488
|
}
|
|
@@ -540,7 +541,7 @@
|
|
|
540
541
|
"importLimit"
|
|
541
542
|
],
|
|
542
543
|
"requiredValues": {
|
|
543
|
-
"importLimit":
|
|
544
|
+
"importLimit": 25
|
|
544
545
|
},
|
|
545
546
|
"modeAddHandshake": {
|
|
546
547
|
"firstCallReturns": "needsModeSelection when adding to an existing campaign-attached list",
|
|
@@ -579,7 +580,18 @@
|
|
|
579
580
|
{
|
|
580
581
|
"action": "launch_message_draft_builder_after_review_batch_import",
|
|
581
582
|
"tool": "get_post_find_leads_scout_registry",
|
|
582
|
-
"
|
|
583
|
+
"target": "post-find-leads-message-scout",
|
|
584
|
+
"requiresNonEmptyRows": true,
|
|
585
|
+
"mustRunBefore": [
|
|
586
|
+
"filter-choice question",
|
|
587
|
+
"filter approval",
|
|
588
|
+
"save_rubrics"
|
|
589
|
+
],
|
|
590
|
+
"mode": "background_when_host_supports_subagents",
|
|
591
|
+
"fallback": "if no real background branch can start, say the real sequence and do not claim background drafting is running",
|
|
592
|
+
"toolCallRequiredInBranch": "get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false",
|
|
593
|
+
"runtimeProofTransport": "CampaignOffer.watchNarration.workerDetails.messageDraftBuilder",
|
|
594
|
+
"purpose": "start the provisional message draft from the imported review batch immediately; do not defer this to filter approval"
|
|
583
595
|
}
|
|
584
596
|
],
|
|
585
597
|
"requiredCampaignState": [
|
|
@@ -702,7 +714,7 @@
|
|
|
702
714
|
"purpose": "load canonical post-lead worker names"
|
|
703
715
|
},
|
|
704
716
|
{
|
|
705
|
-
"action": "
|
|
717
|
+
"action": "launch_or_reuse_lead_fit_builder_and_existing_message_draft",
|
|
706
718
|
"mode": "parallel_when_host_supports_subagents",
|
|
707
719
|
"inputs": [
|
|
708
720
|
"campaignId",
|
|
@@ -713,7 +725,8 @@
|
|
|
713
725
|
"filterChoice"
|
|
714
726
|
],
|
|
715
727
|
"stateSource": "CampaignOffer and workflow table rows",
|
|
716
|
-
"debugFilesOptionalOnly": true
|
|
728
|
+
"debugFilesOptionalOnly": true,
|
|
729
|
+
"messageDraftRule": "reuse or join the Message Draft Builder branch that started immediately after confirm_lead_list; do not start first-time message drafting here unless the earlier branch failed to start"
|
|
717
730
|
},
|
|
718
731
|
{
|
|
719
732
|
"action": "save_filter_rubrics_to_campaign",
|
|
@@ -727,7 +740,7 @@
|
|
|
727
740
|
"requiredSideEffects": {
|
|
728
741
|
"enableICPFilters": true,
|
|
729
742
|
"currentStep": "apply-icp-rubric",
|
|
730
|
-
"watchNarration.headline": "Filter
|
|
743
|
+
"watchNarration.headline": "Filter rules saved"
|
|
731
744
|
}
|
|
732
745
|
}
|
|
733
746
|
],
|
|
@@ -769,7 +782,8 @@
|
|
|
769
782
|
],
|
|
770
783
|
"hardRules": [
|
|
771
784
|
"after_save_rubrics_currentStep_must_be_apply-icp-rubric",
|
|
772
|
-
"do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped"
|
|
785
|
+
"do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped",
|
|
786
|
+
"message_draft_builder_start_is_not_deferred_until_filters"
|
|
773
787
|
],
|
|
774
788
|
"transitions": {
|
|
775
789
|
"post_lead_workstreams_ready": "message-review",
|
|
@@ -800,7 +814,7 @@
|
|
|
800
814
|
"requiredSideEffects": {
|
|
801
815
|
"enableICPFilters": true,
|
|
802
816
|
"currentStep": "apply-icp-rubric",
|
|
803
|
-
"watchNarration.headline": "Filter
|
|
817
|
+
"watchNarration.headline": "Filter rules saved"
|
|
804
818
|
}
|
|
805
819
|
}
|
|
806
820
|
],
|
|
@@ -968,17 +982,26 @@
|
|
|
968
982
|
"revise_messaging"
|
|
969
983
|
],
|
|
970
984
|
"transitions": {
|
|
971
|
-
"message_approved": "
|
|
985
|
+
"message_approved": "validate-sample",
|
|
972
986
|
"revise_messaging": "message-generation"
|
|
973
987
|
}
|
|
974
988
|
},
|
|
975
989
|
{
|
|
976
990
|
"id": "validate-sample",
|
|
977
|
-
"label": "Validate bounded review batch
|
|
978
|
-
"currentStepValue": "
|
|
979
|
-
"legacyOnly": true,
|
|
991
|
+
"label": "Validate bounded review batch",
|
|
992
|
+
"currentStepValue": "apply-icp-rubric",
|
|
980
993
|
"reference": "references/sample-validation-loop.md",
|
|
994
|
+
"visibleStepRule": "This is the same Filter Leads screen reached by save_rubrics. Do not route away from or back to Filter Leads on approve-message; save the approved template, refresh watch narration on apply-icp-rubric, then queue the bounded Enrich Prospect cells.",
|
|
981
995
|
"onEnter": [
|
|
996
|
+
{
|
|
997
|
+
"tool": "update_campaign",
|
|
998
|
+
"requiredValues": {
|
|
999
|
+
"currentStep": "apply-icp-rubric",
|
|
1000
|
+
"watchNarration.stage": "fit-message"
|
|
1001
|
+
},
|
|
1002
|
+
"purpose": "keep the watched UI on Filter Leads while the approved template starts the bounded cascade",
|
|
1003
|
+
"watchNarrationRule": "Say the template is saved and Filter Leads is now running the bounded enrichment and scoring pass."
|
|
1004
|
+
},
|
|
982
1005
|
{
|
|
983
1006
|
"tool": "queue_cells",
|
|
984
1007
|
"purpose": "queue ICP/enrichment cells for the bounded review batch only",
|
|
@@ -1121,10 +1144,21 @@
|
|
|
1121
1144
|
{
|
|
1122
1145
|
"tool": "update_campaign",
|
|
1123
1146
|
"requiredValues": {
|
|
1124
|
-
"currentStep": "
|
|
1147
|
+
"currentStep": "auto-execute-messaging",
|
|
1125
1148
|
"watchNarration.stage": "review-ready"
|
|
1126
1149
|
},
|
|
1127
|
-
"watchNarrationRule": "Say what just happened, that review-batch messages are ready, and that the next action is Settings
|
|
1150
|
+
"watchNarrationRule": "Say what just happened, that review-batch messages are ready in Messages, and that the next action is reviewing or approving generated messages before Settings."
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
"action": "ask_generated_message_review_choice",
|
|
1154
|
+
"uses": "request_user_input",
|
|
1155
|
+
"choices": [
|
|
1156
|
+
"Approve generated messages",
|
|
1157
|
+
"Revise filters",
|
|
1158
|
+
"Revise message template",
|
|
1159
|
+
"Pause here"
|
|
1160
|
+
],
|
|
1161
|
+
"rule": "Do not advance to Settings until the generated review-batch messages have been reviewed and approved."
|
|
1128
1162
|
}
|
|
1129
1163
|
],
|
|
1130
1164
|
"allowedTools": [
|
|
@@ -1151,11 +1185,13 @@
|
|
|
1151
1185
|
"proposed_token_never_persisted_in_rewrite"
|
|
1152
1186
|
],
|
|
1153
1187
|
"waitFor": [
|
|
1154
|
-
"
|
|
1188
|
+
"generated_messages_approved",
|
|
1155
1189
|
"sample_revision_required"
|
|
1156
1190
|
],
|
|
1157
1191
|
"transitions": {
|
|
1158
|
-
"
|
|
1192
|
+
"generated_messages_approved": "awaiting-user-greenlight",
|
|
1193
|
+
"revise_filters": "filter-rubric",
|
|
1194
|
+
"revise_messaging": "message-generation",
|
|
1159
1195
|
"escalation_triggered": "escalation"
|
|
1160
1196
|
}
|
|
1161
1197
|
},
|
|
@@ -1188,7 +1224,7 @@
|
|
|
1188
1224
|
"connect or select a LinkedIn sender",
|
|
1189
1225
|
"Slack reply review",
|
|
1190
1226
|
"recommended sequence",
|
|
1191
|
-
"
|
|
1227
|
+
"final launch confirmation is still ahead"
|
|
1192
1228
|
]
|
|
1193
1229
|
},
|
|
1194
1230
|
{
|
|
@@ -15,7 +15,7 @@ packet.
|
|
|
15
15
|
|
|
16
16
|
The approval gate used to be the place where the user authorized
|
|
17
17
|
spend/send-adjacent mutation. It is now compatibility-only. New runs import the
|
|
18
|
-
bounded
|
|
18
|
+
bounded review batch after source approval, save rubrics and the approved
|
|
19
19
|
message template after post-import review, and only then queue the cascade.
|
|
20
20
|
|
|
21
21
|
If `campaign-shell.json` exists, a draft `CampaignOffer` row already exists but
|
|
@@ -174,6 +174,14 @@ If more than roughly 20% of the review batch appears to be the forbidden side,
|
|
|
174
174
|
classify it as a list/source problem and return `revise-find-leads`; do not
|
|
175
175
|
hide that problem behind narrow rubrics.
|
|
176
176
|
|
|
177
|
+
## Suppression And Relationship Safety
|
|
178
|
+
|
|
179
|
+
Do not put DNC or one-off relationship-safety notes into production rubrics
|
|
180
|
+
unless the review batch shows that the pattern will leak at meaningful volume
|
|
181
|
+
and normal DNC/domain suppression will not catch it. Former employers, existing
|
|
182
|
+
customers, investors, partner lists, and one-off do-not-contact domains usually
|
|
183
|
+
belong in the recommendation as DNC/suppression instructions outside the rubric JSON.
|
|
184
|
+
|
|
177
185
|
## Production Rubric Shape
|
|
178
186
|
|
|
179
187
|
Confirmed rubrics must use the production `LeadScoringRubric` fields exactly:
|
|
@@ -265,6 +273,40 @@ Interpretation:
|
|
|
265
273
|
- Density dramatically below the band: likely source contamination, ICP drift,
|
|
266
274
|
or provider-side weakness; investigate before launch.
|
|
267
275
|
|
|
276
|
+
## Post-Filter Signal Enrichment Pass (Sales Nav lane)
|
|
277
|
+
|
|
278
|
+
Run this only for Sales Nav FIT rows when the downstream message step does not
|
|
279
|
+
already have row-level post evidence. In normal campaign-backed runs, use live
|
|
280
|
+
campaign-table row state as the source of truth. In explicit debug/UAT artifact
|
|
281
|
+
flows, append the diagnostic copy back to `lead-sample.json`.
|
|
282
|
+
|
|
283
|
+
This pass exists to protect the Earned-right and Read-as-1:1 substance filters.
|
|
284
|
+
Without row-level posts, message generation is likely to fall back to generic
|
|
285
|
+
category openers or presumed intent instead of evidence the recipient can
|
|
286
|
+
recognize.
|
|
287
|
+
|
|
288
|
+
Contract:
|
|
289
|
+
|
|
290
|
+
- scope: Sales Nav FIT rows only; do not enrich MAYBE or REJECT rows for this
|
|
291
|
+
pass
|
|
292
|
+
- budget cap: top 10 FIT rows by filter score
|
|
293
|
+
- tool: `mcp__sellable__fetch_linkedin_posts`, called per row
|
|
294
|
+
- fetch: most recent 3-5 public posts when available
|
|
295
|
+
- target surface: store each result as `recent_posts[]` entries with
|
|
296
|
+
`{ url, posted_at, excerpt }`; keep `recent_posts: []` for quiet profiles
|
|
297
|
+
- order of operations: run AFTER `lead-filter.md` is written, BEFORE
|
|
298
|
+
`message-validation.md` starts drafting
|
|
299
|
+
|
|
300
|
+
Record enrichment outcome in the filter summary: rows attempted, rows with
|
|
301
|
+
posts, rows with zero public posts, and tool failures. If more than half of the
|
|
302
|
+
attempted rows have zero posts, flag low signal density and tell message
|
|
303
|
+
generation to prefer trigger, peer-observation, or non-post proof instead of a
|
|
304
|
+
post-quote opener.
|
|
305
|
+
|
|
306
|
+
Do not convert "recently posted" or post availability into an ICP fit rubric.
|
|
307
|
+
The posts are message evidence only; buyer qualification still comes from role,
|
|
308
|
+
authority, account fit, capacity, geography, and exclusions.
|
|
309
|
+
|
|
268
310
|
## Decision Rules
|
|
269
311
|
|
|
270
312
|
- Use `confirmed` when the source lane is viable and the rubrics are enough to
|