@sellable/install 0.1.155 → 0.1.158
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 +5 -5
- package/agents/post-find-leads-message-scout.md +74 -63
- package/agents/registry.json +7 -199
- package/bin/sellable-install.mjs +46 -17
- package/package.json +1 -1
- package/skill-templates/create-campaign.md +42 -35
- package/agents/post-find-leads-filter-scout.md +0 -81
- package/agents/source-scout-linkedin-engagement.md +0 -116
- package/agents/source-scout-prospeo-contact.md +0 -63
- package/agents/source-scout-sales-nav.md +0 -88
package/README.md
CHANGED
|
@@ -58,11 +58,11 @@ Auth is stored once at:
|
|
|
58
58
|
Claude Code and Codex are configured to launch the same packaged MCP server. The
|
|
59
59
|
installer also writes Sellable agent definitions from the packaged `agents/`
|
|
60
60
|
registry, but normal create-campaign runs use only the Message Drafting
|
|
61
|
-
background agent. Source discovery and
|
|
62
|
-
thread with product-native MCP tools
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
background agent (`post-find-leads-message-scout`). Source discovery and
|
|
62
|
+
filter/rubric setup stay in the parent thread with product-native MCP tools.
|
|
63
|
+
`get_post_find_leads_scout_registry` returns the Message Drafting worker for the
|
|
64
|
+
normal path; `get_source_scout_registry` intentionally returns no custom
|
|
65
|
+
source-scout agents.
|
|
66
66
|
|
|
67
67
|
## Names
|
|
68
68
|
|
|
@@ -17,20 +17,19 @@ campaign state. The main thread owns approval and campaign writes.
|
|
|
17
17
|
|
|
18
18
|
## Source Of Truth
|
|
19
19
|
|
|
20
|
-
Use the
|
|
20
|
+
Use the lean handoff supplied by the parent thread:
|
|
21
21
|
|
|
22
22
|
- `campaignId`
|
|
23
|
-
- campaign revision or `campaignUpdatedAt`
|
|
24
|
-
- campaign brief summary from the parent, then the current `campaignBrief` /
|
|
25
|
-
campaign brief content loaded through Sellable tools
|
|
26
|
-
- selected source decision and provider state
|
|
27
|
-
- `selectedLeadListId` or selected source list context
|
|
28
23
|
- `workflowTableId`
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
24
|
+
- concise brief summary: offer, buyer, source context, safe proof, blocked claims
|
|
25
|
+
- concise source summary and source-use rule
|
|
26
|
+
- 3-5 sample workflow-table rows with `rowId`, name, title, company, and short
|
|
27
|
+
signal
|
|
28
|
+
- optional `campaignName`, `selectedLeadListId`, and filter choice
|
|
29
|
+
|
|
30
|
+
Do not require campaign revision, brief hash, copied row count, review-batch
|
|
31
|
+
count, row hash, or a long review-batch row-id list. The branch can verify the
|
|
32
|
+
current state with live Sellable tools.
|
|
34
33
|
|
|
35
34
|
Do not require or hunt for `brief.md`, `lead-review.md`, or `lead-sample.json`.
|
|
36
35
|
Those files are optional debug context only when the parent explicitly provides
|
|
@@ -40,34 +39,49 @@ read stale local markdown files to reconstruct campaign state.
|
|
|
40
39
|
All live reads must come from scoped MCP/product tools by campaign and
|
|
41
40
|
workspace, such as `get_campaign`, `get_campaign_context`, and
|
|
42
41
|
`get_rows_minimal({ tableId: workflowTableId })`, or from equivalent parent
|
|
43
|
-
thread payloads. Load the current campaign brief and the
|
|
44
|
-
rows
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
thread payloads. Load the current campaign brief/context and use the provided
|
|
43
|
+
sample rows as the drafting sample. Reject the task as `blocked` if the campaign
|
|
44
|
+
id, workspace, or `workflowTableId` does not match the branch input.
|
|
45
|
+
|
|
46
|
+
Reference assets are packaged MCP assets. Load them only through
|
|
47
|
+
`get_subskill_asset`; do not use shell commands, local `Read`, `rg`, `cat`,
|
|
48
|
+
`wc`, plugin-cache paths, repo paths, or `/Users/...` paths to find them. If a
|
|
49
|
+
required message reference cannot be loaded through the MCP asset loader, return
|
|
50
|
+
`blocked` or `retry-needed`.
|
|
47
51
|
|
|
48
|
-
## Required
|
|
52
|
+
## Required Work Loop
|
|
49
53
|
|
|
50
|
-
1. Load
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
Do not ask the parent to paste row data or a long row-id list.
|
|
56
|
-
2. Load the full normal-path message prompt:
|
|
54
|
+
1. Load live campaign context:
|
|
55
|
+
`get_campaign`, `get_campaign_context`, and row details for the provided
|
|
56
|
+
sample row ids when available. Do not ask the parent for hashes or row-count
|
|
57
|
+
bookkeeping.
|
|
58
|
+
2. Load the full normal-path message prompt, all chunks:
|
|
57
59
|
|
|
58
60
|
`get_subskill_prompt({ subskillName: "generate-messages" })`
|
|
59
61
|
|
|
60
|
-
3. Load
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
5. Draft
|
|
67
|
-
|
|
68
|
-
6.
|
|
69
|
-
|
|
70
|
-
7.
|
|
62
|
+
3. Load every packaged reference asset required by that prompt's Reference Asset
|
|
63
|
+
Loading section with `get_subskill_asset`. If a required asset cannot load
|
|
64
|
+
through the MCP asset loader, return `blocked` or `retry-needed` instead of
|
|
65
|
+
drafting from memory.
|
|
66
|
+
4. Build positioning in a compact working note: buyer, pain, product, mechanism,
|
|
67
|
+
proof boundary, source-use rule, and CTA.
|
|
68
|
+
5. Draft 3 distinct first-message options: signal-led, product/mechanism-led,
|
|
69
|
+
and proof/credibility-led.
|
|
70
|
+
6. Combine the strongest opener, product line, mechanism line, proof treatment,
|
|
71
|
+
and CTA into one reusable template.
|
|
72
|
+
7. Define token fill rules and fallbacks, then render one good sample.
|
|
73
|
+
8. Before returning, load the validation prompt and any validation assets it
|
|
74
|
+
requires:
|
|
75
|
+
|
|
76
|
+
`get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })`
|
|
77
|
+
|
|
78
|
+
Use it only as a validation contract for the candidate message in this live
|
|
79
|
+
campaign branch. If the validation prompt references packaged assets, load
|
|
80
|
+
them through `get_subskill_asset` before judging the draft. Do not write
|
|
81
|
+
dry-mode artifacts. Run the final candidate against token safety, proof
|
|
82
|
+
safety, source safety, Thomas filters, AI tells, single-send rule, and
|
|
83
|
+
"would I take this call?". If it fails, revise once and validate again.
|
|
84
|
+
9. Keep the work provisional until the user chooses `Use Template` in Messages.
|
|
71
85
|
|
|
72
86
|
## Owned Output
|
|
73
87
|
|
|
@@ -76,15 +90,14 @@ Return the following to the parent thread:
|
|
|
76
90
|
- proposed first-message template using supported `{{...}}` tokens
|
|
77
91
|
- token fill rules and fallbacks
|
|
78
92
|
- one rendered good-fill sample for a plausible passing campaign-table row
|
|
79
|
-
- one omit/fallback sample when the row signal is not safe
|
|
80
|
-
- pass/fail notes against the generate-messages quality gates
|
|
81
|
-
- `qaReceipt` / validation notes showing token safety, proof safety, fit
|
|
82
|
-
uncertainty, bad-fill avoidance, and "would I take this call?" judgment
|
|
83
93
|
- message-draft runtime status: `ready`, `blocked`, `retry-needed`, or `stale`
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
- approve-or-revise recommendation
|
|
95
|
+
- validation status only: `passed`, `revised-then-passed`, or `blocked`
|
|
96
|
+
- output timestamp/hash and any blocked/retry detail
|
|
97
|
+
|
|
98
|
+
Do not return or render `renderedFallbackSample`, `concerns`, or a full
|
|
99
|
+
`qaReceipt` in the normal happy path. Validation is an internal gate; summarize
|
|
100
|
+
only if blocked or retry-needed.
|
|
88
101
|
|
|
89
102
|
Do not write local markdown/json artifacts in normal live campaign runs. Return
|
|
90
103
|
the recommendation directly to the parent thread. Emit debug artifacts only when
|
|
@@ -108,23 +121,21 @@ exists and points at the current non-empty campaign-table execution slice.
|
|
|
108
121
|
## Basis Changes And Rewrites
|
|
109
122
|
|
|
110
123
|
The first completed recommendation is the default message review candidate.
|
|
111
|
-
Do not automatically retry or regenerate only because
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
Treat later filter/enrichment data as optional rewrite context. If campaign id
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
and report `status: ready` with `basisStatus: "usable_initial"` or
|
|
124
|
+
Do not automatically retry or regenerate only because filters were saved, Filter
|
|
125
|
+
Leads completed, enrichment cells populated, or more row data became available
|
|
126
|
+
after this branch started.
|
|
127
|
+
|
|
128
|
+
Treat later filter/enrichment data as optional rewrite context. If campaign id
|
|
129
|
+
and `workflowTableId` still match, keep the initial recommendation usable and
|
|
130
|
+
report `status: ready` with `basisStatus: "usable_initial"` or
|
|
119
131
|
`"enriched_rewrite_available"`. The parent thread may offer the user a choice
|
|
120
132
|
to keep the initial draft or rewrite with enriched/filter data, but the rewrite
|
|
121
133
|
must be explicit user opt-in.
|
|
122
134
|
|
|
123
135
|
Retry or regenerate without asking only when the initial recommendation is
|
|
124
136
|
missing, failed, structurally invalid, unsafe, or mismatched on campaign id,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
blocker.
|
|
137
|
+
`workflowTableId`, or provided sample rows. Filter/rubric/enrichment basis drift
|
|
138
|
+
alone is not a stale blocker.
|
|
128
139
|
|
|
129
140
|
## User Revision Feedback And QA
|
|
130
141
|
|
|
@@ -132,17 +143,19 @@ If the parent sends user feedback, a QA request, or a rewrite request about the
|
|
|
132
143
|
template before `approve-message`, treat it as Message Drafting work, not a
|
|
133
144
|
campaign write. Use the current `messageDraftRecommendation`, basis token/hash,
|
|
134
145
|
campaign/table basis, and latest user feedback as inputs. Load or reuse the full
|
|
135
|
-
`generate-messages` contract
|
|
136
|
-
QA-only recommendation
|
|
146
|
+
`generate-messages` contract, all referenced assets, and
|
|
147
|
+
`create-campaign-v2-validation`, then return a revised or QA-only recommendation
|
|
148
|
+
with:
|
|
137
149
|
|
|
138
150
|
- revised proposed template
|
|
139
151
|
- what changed and why
|
|
140
152
|
- token fill rule/fallback changes, if any
|
|
141
153
|
- one rendered good-fill sample
|
|
142
|
-
-
|
|
143
|
-
- pass/fail notes against the same quality gates
|
|
154
|
+
- validation status: `passed`, `revised-then-passed`, or `blocked`
|
|
144
155
|
- updated output timestamp/hash and basis token
|
|
145
156
|
|
|
157
|
+
Do not return a full QA receipt unless the result is blocked or retry-needed.
|
|
158
|
+
|
|
146
159
|
Keep the revision grounded in the same source/list/table rows unless the parent
|
|
147
160
|
explicitly supplies a new selected list or review slice. Do not call
|
|
148
161
|
`update_campaign_brief`, do not persist the template, and do not approve your
|
|
@@ -201,20 +214,18 @@ enablement`, or omit it.
|
|
|
201
214
|
Return a concise status with:
|
|
202
215
|
|
|
203
216
|
- prompt basis loaded: `generate-messages`
|
|
217
|
+
- validation prompt loaded: `create-campaign-v2-validation`
|
|
204
218
|
- live campaign basis used
|
|
205
219
|
- proposed template
|
|
206
220
|
- token fill rules/fallbacks
|
|
207
221
|
- one rendered passing-row sample
|
|
208
|
-
- one rendered omit/fallback sample
|
|
209
|
-
- quality-gate pass/fail summary
|
|
210
222
|
- whether final template review is ready or needs revision
|
|
211
223
|
|
|
212
224
|
When the parent will show the recommendation in chat, keep the customer-facing
|
|
213
225
|
message review lightweight. Format only the approval target and one strong
|
|
214
|
-
good-fill example as Markdown with distinct copy blocks. Keep
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
approval; do not print them in the default chat approval packet.
|
|
226
|
+
good-fill example as Markdown with distinct copy blocks. Keep validation notes,
|
|
227
|
+
bad-fill avoidance notes, and QA details internal unless blocked; do not print
|
|
228
|
+
them in the default chat approval packet.
|
|
218
229
|
|
|
219
230
|
````markdown
|
|
220
231
|
## Message Template
|
package/agents/registry.json
CHANGED
|
@@ -1,199 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"agents": [
|
|
4
|
-
{
|
|
5
|
-
"id": "linkedin-engagement",
|
|
6
|
-
"name": "source-scout-linkedin-engagement",
|
|
7
|
-
"kind": "source-scout",
|
|
8
|
-
"promptFile": "source-scout-linkedin-engagement.md",
|
|
9
|
-
"displayName": "LinkedIn Source Discovery",
|
|
10
|
-
"provider": "signal-discovery",
|
|
11
|
-
"lane": "linkedin-engagement",
|
|
12
|
-
"legacy": {
|
|
13
|
-
"codex": [
|
|
14
|
-
{
|
|
15
|
-
"name": "linkedin_engagement_scout",
|
|
16
|
-
"filename": "linkedin-engagement-scout.toml"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
"claude": [
|
|
20
|
-
{
|
|
21
|
-
"name": "lead-explorer-signals",
|
|
22
|
-
"filename": "lead-explorer-signals.md"
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
},
|
|
26
|
-
"codex": {
|
|
27
|
-
"description": "Sellable lead-source scout for LinkedIn post engagement and active conversation signals.",
|
|
28
|
-
"model": "gpt-5.5",
|
|
29
|
-
"modelReasoningEffort": "high",
|
|
30
|
-
"sandboxMode": "read-only",
|
|
31
|
-
"nicknameCandidates": [
|
|
32
|
-
"LinkedIn Engagement Scout",
|
|
33
|
-
"Post Scout",
|
|
34
|
-
"Engager Scout"
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"claude": {
|
|
38
|
-
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs LinkedIn post engagement, Signals, or active conversation evidence.",
|
|
39
|
-
"model": "inherit",
|
|
40
|
-
"background": true,
|
|
41
|
-
"maxTurns": 8,
|
|
42
|
-
"color": "blue",
|
|
43
|
-
"tools": [
|
|
44
|
-
"Read",
|
|
45
|
-
"Grep",
|
|
46
|
-
"Glob",
|
|
47
|
-
"mcp__sellable__get_provider_prompt",
|
|
48
|
-
"mcp__sellable__search_signals",
|
|
49
|
-
"mcp__sellable__select_promising_posts",
|
|
50
|
-
"mcp__sellable__fetch_post_engagers"
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "sales-nav",
|
|
56
|
-
"name": "source-scout-sales-nav",
|
|
57
|
-
"kind": "source-scout",
|
|
58
|
-
"promptFile": "source-scout-sales-nav.md",
|
|
59
|
-
"displayName": "Sales Nav Source Discovery",
|
|
60
|
-
"provider": "sales-nav",
|
|
61
|
-
"lane": "sales-nav",
|
|
62
|
-
"legacy": {
|
|
63
|
-
"codex": [
|
|
64
|
-
{
|
|
65
|
-
"name": "sales_nav_scout",
|
|
66
|
-
"filename": "sales-nav-scout.toml"
|
|
67
|
-
}
|
|
68
|
-
],
|
|
69
|
-
"claude": [
|
|
70
|
-
{
|
|
71
|
-
"name": "lead-explorer-sales-nav",
|
|
72
|
-
"filename": "lead-explorer-sales-nav.md"
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
|
-
"codex": {
|
|
77
|
-
"description": "Sellable lead-source scout for Sales Navigator role, company, and activity filters.",
|
|
78
|
-
"model": "gpt-5.5",
|
|
79
|
-
"modelReasoningEffort": "high",
|
|
80
|
-
"sandboxMode": "read-only",
|
|
81
|
-
"nicknameCandidates": [
|
|
82
|
-
"Sales Nav Scout",
|
|
83
|
-
"Role Filter Scout",
|
|
84
|
-
"Activity Scout"
|
|
85
|
-
]
|
|
86
|
-
},
|
|
87
|
-
"claude": {
|
|
88
|
-
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Sales Navigator title, company, geography, or activity-filter evidence.",
|
|
89
|
-
"model": "inherit",
|
|
90
|
-
"background": true,
|
|
91
|
-
"maxTurns": 8,
|
|
92
|
-
"color": "cyan",
|
|
93
|
-
"tools": [
|
|
94
|
-
"Read",
|
|
95
|
-
"Grep",
|
|
96
|
-
"Glob",
|
|
97
|
-
"mcp__sellable__get_provider_prompt",
|
|
98
|
-
"mcp__sellable__lookup_sales_nav_filter",
|
|
99
|
-
"mcp__sellable__search_sales_nav"
|
|
100
|
-
]
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"id": "prospeo-contact",
|
|
105
|
-
"name": "source-scout-prospeo-contact",
|
|
106
|
-
"kind": "source-scout",
|
|
107
|
-
"promptFile": "source-scout-prospeo-contact.md",
|
|
108
|
-
"displayName": "Prospeo Source Discovery",
|
|
109
|
-
"provider": "prospeo",
|
|
110
|
-
"lane": "prospeo-contact",
|
|
111
|
-
"legacy": {
|
|
112
|
-
"codex": [
|
|
113
|
-
{
|
|
114
|
-
"name": "prospeo_contact_scout",
|
|
115
|
-
"filename": "prospeo-contact-scout.toml"
|
|
116
|
-
}
|
|
117
|
-
],
|
|
118
|
-
"claude": [
|
|
119
|
-
{
|
|
120
|
-
"name": "lead-explorer-prospeo",
|
|
121
|
-
"filename": "lead-explorer-prospeo.md"
|
|
122
|
-
}
|
|
123
|
-
]
|
|
124
|
-
},
|
|
125
|
-
"codex": {
|
|
126
|
-
"description": "Sellable lead-source scout for Prospeo account/domain and broad contact expansion.",
|
|
127
|
-
"model": "gpt-5.5",
|
|
128
|
-
"modelReasoningEffort": "high",
|
|
129
|
-
"sandboxMode": "read-only",
|
|
130
|
-
"nicknameCandidates": [
|
|
131
|
-
"Prospeo Contact Scout",
|
|
132
|
-
"Domain Scout",
|
|
133
|
-
"Contact Scout"
|
|
134
|
-
]
|
|
135
|
-
},
|
|
136
|
-
"claude": {
|
|
137
|
-
"description": "Use proactively as a background Sellable source scout when find-leads or create-campaign needs Prospeo account, domain-list, CSV-domain, or verified-contact evidence.",
|
|
138
|
-
"model": "inherit",
|
|
139
|
-
"background": true,
|
|
140
|
-
"maxTurns": 8,
|
|
141
|
-
"color": "green",
|
|
142
|
-
"tools": [
|
|
143
|
-
"Read",
|
|
144
|
-
"Grep",
|
|
145
|
-
"Glob",
|
|
146
|
-
"mcp__sellable__get_provider_prompt",
|
|
147
|
-
"mcp__sellable__load_csv_domains",
|
|
148
|
-
"mcp__sellable__save_domain_filters",
|
|
149
|
-
"mcp__sellable__search_prospeo"
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"id": "filter-leads",
|
|
155
|
-
"name": "post-find-leads-filter-scout",
|
|
156
|
-
"kind": "post-find-leads-scout",
|
|
157
|
-
"promptFile": "post-find-leads-filter-scout.md",
|
|
158
|
-
"displayName": "Prospect Filters",
|
|
159
|
-
"target": "filter-leads",
|
|
160
|
-
"inputs": [
|
|
161
|
-
"campaignId",
|
|
162
|
-
"campaignBrief summary plus branch-loaded current campaignBrief",
|
|
163
|
-
"source decision and selectedLeadList/source state",
|
|
164
|
-
"workflowTableId",
|
|
165
|
-
"compact review-batch count/hash or branch-loaded review rows"
|
|
166
|
-
],
|
|
167
|
-
"producesArtifacts": [],
|
|
168
|
-
"optionalProducesArtifacts": [],
|
|
169
|
-
"ownership": "prospect-fit criteria, false-positive patterns, keep/exclude rules, ability-to-pay checks, and production rubric translation only",
|
|
170
|
-
"codex": {
|
|
171
|
-
"description": "Prospect Filters worker for campaign-backed fit criteria and rubric persistence after review-batch import and filter approval.",
|
|
172
|
-
"model": "gpt-5.5",
|
|
173
|
-
"modelReasoningEffort": "high",
|
|
174
|
-
"sandboxMode": "read-only",
|
|
175
|
-
"nicknameCandidates": [
|
|
176
|
-
"Prospect Filters",
|
|
177
|
-
"Fit Criteria",
|
|
178
|
-
"Rubric Builder"
|
|
179
|
-
]
|
|
180
|
-
},
|
|
181
|
-
"claude": {
|
|
182
|
-
"description": "Use proactively as Prospect Filters after review-batch import and filter approval to persist campaign rubrics from campaign state.",
|
|
183
|
-
"model": "inherit",
|
|
184
|
-
"background": true,
|
|
185
|
-
"maxTurns": 8,
|
|
186
|
-
"color": "yellow",
|
|
187
|
-
"tools": [
|
|
188
|
-
"mcp__sellable__get_subskill_prompt",
|
|
189
|
-
"mcp__sellable__get_subskill_asset",
|
|
190
|
-
"mcp__sellable__get_campaign",
|
|
191
|
-
"mcp__sellable__get_campaign_context",
|
|
192
|
-
"mcp__sellable__get_rows_minimal",
|
|
193
|
-
"mcp__sellable__save_rubrics"
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
4
|
{
|
|
198
5
|
"id": "message-generation",
|
|
199
6
|
"name": "post-find-leads-message-scout",
|
|
@@ -203,16 +10,17 @@
|
|
|
203
10
|
"target": "generate-messages",
|
|
204
11
|
"inputs": [
|
|
205
12
|
"campaignId",
|
|
206
|
-
"campaignBrief",
|
|
207
|
-
"selected source state",
|
|
208
|
-
"selectedLeadListId",
|
|
209
13
|
"workflowTableId",
|
|
210
|
-
"
|
|
14
|
+
"concise brief summary",
|
|
15
|
+
"concise source summary/source-use rule",
|
|
16
|
+
"3-5 sample workflow-table rows",
|
|
17
|
+
"optional campaignName, selectedLeadListId, filter choice"
|
|
211
18
|
],
|
|
212
19
|
"producesArtifacts": [
|
|
213
20
|
"template recommendation",
|
|
214
21
|
"token fill rules",
|
|
215
|
-
"rendered sample"
|
|
22
|
+
"one rendered good-fill sample",
|
|
23
|
+
"validation status"
|
|
216
24
|
],
|
|
217
25
|
"optionalProducesArtifacts": [],
|
|
218
26
|
"ownership": "message strategy, proof inventory, token rules, skeptical-prospect review, and selected winner only",
|
|
@@ -234,8 +42,8 @@
|
|
|
234
42
|
"maxTurns": 10,
|
|
235
43
|
"color": "magenta",
|
|
236
44
|
"tools": [
|
|
237
|
-
"Read",
|
|
238
45
|
"mcp__sellable__get_subskill_prompt",
|
|
46
|
+
"mcp__sellable__get_subskill_asset",
|
|
239
47
|
"mcp__sellable__get_campaign",
|
|
240
48
|
"mcp__sellable__get_campaign_context",
|
|
241
49
|
"mcp__sellable__get_rows_minimal"
|
package/bin/sellable-install.mjs
CHANGED
|
@@ -701,7 +701,7 @@ data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
|
701
701
|
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
702
702
|
label it explicitly as not estimated from this run.
|
|
703
703
|
|
|
704
|
-
Before any provider prompt, search,
|
|
704
|
+
Before any provider prompt, search, or signal-discovery call, show
|
|
705
705
|
one source-plan gate and ask for approval. Write this like a fifth grader could
|
|
706
706
|
understand it: short sentences, no internal labels, and no GTM shorthand. The
|
|
707
707
|
order is strict: first show the plan in chat, then open the approval question.
|
|
@@ -753,8 +753,9 @@ conversations look unlikely, recommend the specific Sales Nav or Prospeo path
|
|
|
753
753
|
instead and explain it in plain words once. Do not call \`search_signals\`,
|
|
754
754
|
\`search_sales_nav\`,
|
|
755
755
|
\`search_prospeo\`,
|
|
756
|
-
\`fetch_post_engagers
|
|
757
|
-
source
|
|
756
|
+
or \`fetch_post_engagers\` until the user approves this source plan or explicitly
|
|
757
|
+
chooses a different source. Source work stays in the parent thread; do not
|
|
758
|
+
launch source-scout or provider-scoped subagents.
|
|
758
759
|
|
|
759
760
|
If the user answers a provider approval such as "Approve Prospeo plan" after
|
|
760
761
|
seeing the source plan, that answer satisfies the source-plan gate. Persist the
|
|
@@ -1103,8 +1104,13 @@ updates.
|
|
|
1103
1104
|
3. Follow that prompt and workflow config exactly.
|
|
1104
1105
|
4. For message generation, keep the parent thread as a lean orchestrator and
|
|
1105
1106
|
use the \`post-find-leads-message-scout\` agent whenever the host exposes it
|
|
1106
|
-
and the current host policy allows agent launch. The worker must load
|
|
1107
|
-
\`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })
|
|
1107
|
+
and the current host policy allows agent launch. The worker must load the
|
|
1108
|
+
full \`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })\`
|
|
1109
|
+
prompt, every referenced message asset through
|
|
1110
|
+
\`mcp__sellable__get_subskill_asset\`, and before returning
|
|
1111
|
+
\`mcp__sellable__get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })\`
|
|
1112
|
+
plus any validation assets it references through
|
|
1113
|
+
\`mcp__sellable__get_subskill_asset\` as the internal validation gate.
|
|
1108
1114
|
In Codex, YOLO/autonomous mode counts as campaign-scoped permission to use
|
|
1109
1115
|
Sellable background agents for pre-launch work. If the user has not enabled
|
|
1110
1116
|
YOLO and has not explicitly asked for background agents, subagents, parallel
|
|
@@ -1594,12 +1600,35 @@ function claudeAgentFilename(agent) {
|
|
|
1594
1600
|
return agent.claude?.filename || `${agent.name}.md`;
|
|
1595
1601
|
}
|
|
1596
1602
|
|
|
1603
|
+
const REMOVED_CUSTOM_AGENTS = [
|
|
1604
|
+
"post-find-leads-filter-scout",
|
|
1605
|
+
"source-scout-linkedin-engagement",
|
|
1606
|
+
"source-scout-sales-nav",
|
|
1607
|
+
"source-scout-prospeo-contact",
|
|
1608
|
+
].map((name) => ({
|
|
1609
|
+
name,
|
|
1610
|
+
codexFilename: `${name}.toml`,
|
|
1611
|
+
claudeFilename: `${name}.md`,
|
|
1612
|
+
}));
|
|
1613
|
+
|
|
1597
1614
|
function legacyCodexCustomAgents() {
|
|
1598
|
-
return
|
|
1615
|
+
return [
|
|
1616
|
+
...loadCanonicalAgents().flatMap((agent) => agent.legacy?.codex || []),
|
|
1617
|
+
...REMOVED_CUSTOM_AGENTS.map((agent) => ({
|
|
1618
|
+
name: agent.name,
|
|
1619
|
+
filename: agent.codexFilename,
|
|
1620
|
+
})),
|
|
1621
|
+
];
|
|
1599
1622
|
}
|
|
1600
1623
|
|
|
1601
1624
|
function legacyClaudeCustomAgents() {
|
|
1602
|
-
return
|
|
1625
|
+
return [
|
|
1626
|
+
...loadCanonicalAgents().flatMap((agent) => agent.legacy?.claude || []),
|
|
1627
|
+
...REMOVED_CUSTOM_AGENTS.map((agent) => ({
|
|
1628
|
+
name: agent.name,
|
|
1629
|
+
filename: agent.claudeFilename,
|
|
1630
|
+
})),
|
|
1631
|
+
];
|
|
1603
1632
|
}
|
|
1604
1633
|
|
|
1605
1634
|
function legacyClaudeCommands() {
|
|
@@ -2102,8 +2131,8 @@ function verify(opts) {
|
|
|
2102
2131
|
checks.push({
|
|
2103
2132
|
ok: hasClaudeScouts,
|
|
2104
2133
|
label: hasClaudeScouts
|
|
2105
|
-
? "Claude custom
|
|
2106
|
-
: "Claude custom
|
|
2134
|
+
? "Claude custom agents present"
|
|
2135
|
+
: "Claude custom agents missing",
|
|
2107
2136
|
});
|
|
2108
2137
|
const claudeAgentsHaveTools = claudeCustomAgents().every((agent) => {
|
|
2109
2138
|
const agentPath = join(claudeHome(), "agents", agent.filename);
|
|
@@ -2114,8 +2143,8 @@ function verify(opts) {
|
|
|
2114
2143
|
checks.push({
|
|
2115
2144
|
ok: claudeAgentsHaveTools,
|
|
2116
2145
|
label: claudeAgentsHaveTools
|
|
2117
|
-
? "Claude
|
|
2118
|
-
: "Claude
|
|
2146
|
+
? "Claude custom agent MCP tool allowlists present"
|
|
2147
|
+
: "Claude custom agent MCP tool allowlists missing",
|
|
2119
2148
|
});
|
|
2120
2149
|
const legacyClaudePaths = [
|
|
2121
2150
|
...legacyClaudeCustomAgents().map((agent) =>
|
|
@@ -2187,8 +2216,8 @@ function verify(opts) {
|
|
|
2187
2216
|
checks.push({
|
|
2188
2217
|
ok: hasCodexScouts,
|
|
2189
2218
|
label: hasCodexScouts
|
|
2190
|
-
? "Codex custom
|
|
2191
|
-
: "Codex custom
|
|
2219
|
+
? "Codex custom agents present"
|
|
2220
|
+
: "Codex custom agents missing",
|
|
2192
2221
|
});
|
|
2193
2222
|
const configPath = join(codexHome(), "config.toml");
|
|
2194
2223
|
const configContent = existsSync(configPath)
|
|
@@ -2200,8 +2229,8 @@ function verify(opts) {
|
|
|
2200
2229
|
checks.push({
|
|
2201
2230
|
ok: hasCodexAgentRegistrations,
|
|
2202
2231
|
label: hasCodexAgentRegistrations
|
|
2203
|
-
? "Codex custom
|
|
2204
|
-
: "Codex custom
|
|
2232
|
+
? "Codex custom agents registered"
|
|
2233
|
+
: "Codex custom agents unregistered",
|
|
2205
2234
|
});
|
|
2206
2235
|
const hasNoLegacyCodexAgents = legacyCodexCustomAgents().every((agent) => {
|
|
2207
2236
|
const agentPath = join(codexHome(), "agents", agent.filename);
|
|
@@ -2213,8 +2242,8 @@ function verify(opts) {
|
|
|
2213
2242
|
checks.push({
|
|
2214
2243
|
ok: hasNoLegacyCodexAgents,
|
|
2215
2244
|
label: hasNoLegacyCodexAgents
|
|
2216
|
-
? "Legacy Codex custom
|
|
2217
|
-
: "Legacy Codex custom
|
|
2245
|
+
? "Legacy Codex custom agents cleaned"
|
|
2246
|
+
: "Legacy Codex custom agents still present",
|
|
2218
2247
|
});
|
|
2219
2248
|
const hasFlag = configContent.includes(
|
|
2220
2249
|
"default_mode_request_user_input = true"
|
package/package.json
CHANGED
|
@@ -132,7 +132,7 @@ data, compare sources by source volume, sampled ICP fit, activity/warmth
|
|
|
132
132
|
signals, cleanup risk, and confidence basis. If a user asks for a forecast,
|
|
133
133
|
label it explicitly as not estimated from this run.
|
|
134
134
|
|
|
135
|
-
Before any provider prompt, search,
|
|
135
|
+
Before any provider prompt, search, or signal-discovery call, show
|
|
136
136
|
one source-plan gate and ask for approval. Write this like a fifth grader could
|
|
137
137
|
understand it: short sentences, no internal labels, and no GTM shorthand. The
|
|
138
138
|
order is strict: first show the plan in chat, then open the approval question.
|
|
@@ -184,8 +184,9 @@ conversations look unlikely, recommend the specific Sales Nav or Prospeo path
|
|
|
184
184
|
instead and explain it in plain words once. Do not call `search_signals`,
|
|
185
185
|
`search_sales_nav`,
|
|
186
186
|
`search_prospeo`,
|
|
187
|
-
`fetch_post_engagers
|
|
188
|
-
source
|
|
187
|
+
or `fetch_post_engagers` until the user approves this source plan or explicitly
|
|
188
|
+
chooses a different source. Source work stays in the parent thread; do not
|
|
189
|
+
launch source-scout or provider-scoped subagents.
|
|
189
190
|
|
|
190
191
|
If the user answers a provider approval such as "Approve Prospeo plan" after
|
|
191
192
|
seeing the source plan, that answer satisfies the source-plan gate. Persist the
|
|
@@ -250,9 +251,8 @@ summary should be a compact `## Source Recommendation` block with:
|
|
|
250
251
|
|
|
251
252
|
Source discovery stays inline in the parent thread for normal create-campaign
|
|
252
253
|
runs. Use the approved provider prompt and MCP tools sequentially; do not spawn
|
|
253
|
-
source-scout background agents
|
|
254
|
-
|
|
255
|
-
install status to the customer. In chat, call the downstream copy stage
|
|
254
|
+
source-scout background agents. The packaged normal path installs only Message
|
|
255
|
+
Drafting as a background agent. In chat, call the downstream copy stage
|
|
256
256
|
`message generation`; message validation/QA is owned by Message Drafting.
|
|
257
257
|
|
|
258
258
|
For campaign-attached Signal Discovery sampling, promote/select the exact posts
|
|
@@ -279,14 +279,17 @@ Messages/message review. Enrichment/filtering and Generate Message cells wait
|
|
|
279
279
|
for message approval. AI Generated is an explicit opt-out from the template
|
|
280
280
|
path.
|
|
281
281
|
|
|
282
|
-
The Message Drafting handoff must stay
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
282
|
+
The Message Drafting handoff must stay lean. Include only `campaignId`,
|
|
283
|
+
`workflowTableId`, a concise brief summary, concise source summary/source-use
|
|
284
|
+
rule, and 3-5 sample workflow-table rows with `rowId`, name, title, company, and
|
|
285
|
+
signal. Optional: campaign name, `selectedLeadListId`, and filter choice. Do not
|
|
286
|
+
paste copied row counts, brief hashes, review-batch hashes, full row ID lists,
|
|
287
|
+
broad row data, or local debug artifacts into the spawn prompt. Message Drafting
|
|
288
|
+
must load the current campaign brief/context, the full `generate-messages`
|
|
289
|
+
prompt, every message asset referenced by that prompt, and
|
|
290
|
+
`create-campaign-v2-validation` plus any validation assets it references.
|
|
291
|
+
Validation is an internal gate before it returns the concise review-ready
|
|
292
|
+
recommendation.
|
|
290
293
|
|
|
291
294
|
Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
|
|
292
295
|
lines short, use indexed section labels and bullets, and translate internal
|
|
@@ -421,19 +424,15 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
421
424
|
not call it in the normal create-campaign source path.
|
|
422
425
|
- `load_post_find_leads_scout_registry`: call
|
|
423
426
|
`mcp__sellable__get_post_find_leads_scout_registry({})` after source
|
|
424
|
-
import and before dispatching
|
|
425
|
-
- `launch_prospect_filters`: Claude Code uses `Task` with `subagent_type`
|
|
426
|
-
`post-find-leads-filter-scout` when filters are chosen; Codex uses the
|
|
427
|
-
returned compatibility agent. Prospect Filters must save or return production
|
|
428
|
-
rubrics before message review can proceed.
|
|
427
|
+
import and before dispatching Message Drafting only.
|
|
429
428
|
- `launch_message_drafting`: Claude Code uses `Task` with `subagent_type`
|
|
430
429
|
`post-find-leads-message-scout` when listed; Codex uses the returned
|
|
431
430
|
compatibility agent or a generic `gpt-5.5` / `xhigh` Message Drafting agent.
|
|
432
431
|
|
|
433
432
|
If a required interactive question function or MCP loader is missing, stop and
|
|
434
433
|
explain the Sellable install/reload problem. Source work uses product-native MCP
|
|
435
|
-
orchestration in the parent; the
|
|
436
|
-
|
|
434
|
+
orchestration in the parent; filters also stay in the parent with MCP tools. The
|
|
435
|
+
only normal post-import background branch is Message Drafting.
|
|
437
436
|
|
|
438
437
|
Never narrate local draft housekeeping to the user. If you create directories,
|
|
439
438
|
save drafts, write artifacts, or persist intermediate state, translate it into
|
|
@@ -750,17 +749,22 @@ updates.
|
|
|
750
749
|
asset loader so they share the same config.
|
|
751
750
|
3. Follow that prompt and workflow config exactly.
|
|
752
751
|
4. For filter and message setup, keep the parent thread as a lean orchestrator.
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
752
|
+
The only normal background agent is `post-find-leads-message-scout` for
|
|
753
|
+
Message Drafting. When filters are chosen, launch Message Drafting, then keep
|
|
754
|
+
filters in the parent thread: load `references/filter-leads.md`, draft
|
|
755
|
+
production rubrics, call `save_rubrics`, ask filter approval, and then join
|
|
757
756
|
Message Drafting for template review. When filters are skipped, launch only
|
|
758
757
|
Message Drafting.
|
|
759
758
|
5. For message generation, keep the parent thread as a lean orchestrator and
|
|
760
759
|
use the `post-find-leads-message-scout` compatibility agent for Message
|
|
761
760
|
Drafting whenever the host exposes it
|
|
762
|
-
and the current host policy allows agent launch. The worker must load
|
|
763
|
-
`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })
|
|
761
|
+
and the current host policy allows agent launch. The worker must load the
|
|
762
|
+
full `mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })`
|
|
763
|
+
prompt, every referenced message asset through
|
|
764
|
+
`mcp__sellable__get_subskill_asset`, and before returning
|
|
765
|
+
`mcp__sellable__get_subskill_prompt({ subskillName: "create-campaign-v2-validation" })`
|
|
766
|
+
plus any validation assets it references through
|
|
767
|
+
`mcp__sellable__get_subskill_asset` as the internal validation gate.
|
|
764
768
|
In Codex, YOLO/autonomous mode counts as campaign-scoped permission to use
|
|
765
769
|
this single Message Drafting background agent. If the user has not enabled
|
|
766
770
|
YOLO and has not explicitly asked for background agents, subagents, parallel
|
|
@@ -768,7 +772,7 @@ updates.
|
|
|
768
772
|
permission before loading the long message prompt in the parent. If
|
|
769
773
|
permission is granted but the named custom agent is not
|
|
770
774
|
available, spawn a generic background agent with `model: "gpt-5.5"` and
|
|
771
|
-
`reasoning_effort: "xhigh"` using the same campaign/table basis. Do not
|
|
775
|
+
`reasoning_effort: "xhigh"` using the same lean campaign/table basis. Do not
|
|
772
776
|
silently fall back to parent-thread message drafting; parent fallback is
|
|
773
777
|
allowed only when the user explicitly says to continue without a background
|
|
774
778
|
agent.
|
|
@@ -779,21 +783,24 @@ updates.
|
|
|
779
783
|
initial campaign-table execution slice rows as the source of truth; do not read stale local
|
|
780
784
|
markdown such as `message-validation.md`, inspect the database directly, or
|
|
781
785
|
synthesize local validation artifacts from general knowledge. The handoff to
|
|
782
|
-
Message Drafting should pass
|
|
783
|
-
branch loads current brief/
|
|
786
|
+
Message Drafting should pass lean basis only, not hashes, counts, or a long
|
|
787
|
+
row-id list; the branch loads current brief/context, the full
|
|
788
|
+
`generate-messages` prompt, all referenced message assets,
|
|
789
|
+
`create-campaign-v2-validation`, and any validation assets it references. Do
|
|
790
|
+
not render fallback sample, concerns, or a QA receipt on the normal happy
|
|
791
|
+
path.
|
|
784
792
|
6. Create the campaign shell early with the v1 brief so the user can open the
|
|
785
793
|
watch link and see useful setup state immediately. Materialize the approved
|
|
786
794
|
source list, copy confirmed rows into the campaign, and internally process the
|
|
787
795
|
first campaign-table execution slice after the source is attached to the
|
|
788
796
|
campaign; do not load prospect-setup registries/prompts before asking add
|
|
789
|
-
filters vs skip filters. Once the user answers, launch
|
|
790
|
-
|
|
791
|
-
filters are skipped. Do not queue workflow cells, attach a
|
|
797
|
+
filters vs skip filters. Once the user answers, launch only Message Drafting.
|
|
798
|
+
If filters are chosen, draft/save filters in the parent thread. Do not queue workflow cells, attach a
|
|
792
799
|
sequence, or start until saved filters and the
|
|
793
800
|
message template/token rules are approved. When filters are chosen, immediately
|
|
794
801
|
call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
|
|
795
|
-
so the watched app moves to Filter Rules while
|
|
796
|
-
rubrics.
|
|
802
|
+
so the watched app moves to Filter Rules while the parent drafts/saves
|
|
803
|
+
rubrics and Message Drafting runs.
|
|
797
804
|
After rubrics save, keep Filter Rules visible for approval; after approval,
|
|
798
805
|
move to Filter Leads and show `Filters saved + waiting for message approval`
|
|
799
806
|
until the template is approved.
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
You are Prospect Filters for Sellable create-campaign-v2.
|
|
2
|
-
|
|
3
|
-
Your job starts only after the Start Import gate is approved or auto-confirmed,
|
|
4
|
-
the confirmed source list has been copied into the campaign table, and the first
|
|
5
|
-
campaign-table execution slice exists.
|
|
6
|
-
Work only on the lead filter branch. Do not source new leads, draft messages,
|
|
7
|
-
import leads, create campaigns, or ask the user questions. Your only live
|
|
8
|
-
campaign mutation is calling `save_rubrics` after the production rubrics are
|
|
9
|
-
ready.
|
|
10
|
-
|
|
11
|
-
Required inputs:
|
|
12
|
-
|
|
13
|
-
- `campaignId`
|
|
14
|
-
- campaign revision or `campaignUpdatedAt`
|
|
15
|
-
- campaign brief summary from the parent, then the current campaign brief loaded
|
|
16
|
-
through Sellable tools
|
|
17
|
-
- selected source decision and provider/list state
|
|
18
|
-
- `selectedLeadListId`
|
|
19
|
-
- `workflowTableId`
|
|
20
|
-
- compact initial campaign-table execution-slice basis: copied source row count,
|
|
21
|
-
review-batch row count, and review-batch basis/hash. Do not require the
|
|
22
|
-
parent to paste every row id when scoped row tools are available.
|
|
23
|
-
- filter choice
|
|
24
|
-
|
|
25
|
-
Required first steps:
|
|
26
|
-
|
|
27
|
-
1. Verify the campaign/source/table ids from the parent thread match the live
|
|
28
|
-
campaign context. Read current campaign/table state and the review batch
|
|
29
|
-
through scoped Sellable tools such as `get_campaign`, `get_campaign_context`,
|
|
30
|
-
and `get_rows_minimal({ tableId: workflowTableId })`.
|
|
31
|
-
2. Load the filter-leads reference before designing rubrics:
|
|
32
|
-
`get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/filter-leads.md" })`.
|
|
33
|
-
3. Treat campaign state and the campaign-table execution slice as the input of record.
|
|
34
|
-
Do not require or hunt for local markdown/json artifacts.
|
|
35
|
-
|
|
36
|
-
Owned outputs:
|
|
37
|
-
|
|
38
|
-
- Durable campaign rubrics via `save_rubrics({ campaignOfferId, leadScoringRubrics })`
|
|
39
|
-
when the filter is confirmed and production-shaped rubrics are safe to write.
|
|
40
|
-
`save_rubrics` is the durable writer.
|
|
41
|
-
- If `save_rubrics` is unavailable in the branch, return production-shaped
|
|
42
|
-
`leadScoringRubrics` and mark `save_rubrics` as not yet persisted so the
|
|
43
|
-
parent can save them before filter approval.
|
|
44
|
-
- concise filter/rubric summary returned to the parent thread
|
|
45
|
-
|
|
46
|
-
Do not write or modify local markdown/json artifacts. Durable output is only
|
|
47
|
-
via `save_rubrics` plus the parent-thread summary.
|
|
48
|
-
|
|
49
|
-
Process:
|
|
50
|
-
|
|
51
|
-
1. Preserve the approved source decision, source math, and campaign-table slice
|
|
52
|
-
evidence supplied by the parent; do not re-run sourcing.
|
|
53
|
-
2. Turn the slice's good-fit and false-positive patterns into a strict but
|
|
54
|
-
campaign-native filter.
|
|
55
|
-
3. Include keep rules, exclude rules, sample false positives, pass-rate /
|
|
56
|
-
expected-yield impact, and a recommendation.
|
|
57
|
-
4. Add an explicit ability-to-pay or economic-capacity gate unless the brief
|
|
58
|
-
clearly says the offer is free or has no meaningful budget requirement.
|
|
59
|
-
5. Keep source mechanics out of production rubrics. Engagement, provider,
|
|
60
|
-
priority, or first-send ordering can inform prioritization, but they are not
|
|
61
|
-
standalone ICP qualification rules.
|
|
62
|
-
6. If status is `confirmed`, call `save_rubrics` with 2-5 production-shaped
|
|
63
|
-
active `leadScoringRubrics` before reporting success. If `save_rubrics`
|
|
64
|
-
fails, stop and report the blocker; do not claim the filter is persisted.
|
|
65
|
-
|
|
66
|
-
Return a concise final status with:
|
|
67
|
-
|
|
68
|
-
- filter status: `confirmed`, `confirm-with-user`, or `revise-find-leads`
|
|
69
|
-
- whether `save_rubrics` succeeded and how many active rubrics were persisted
|
|
70
|
-
- strongest keep rules
|
|
71
|
-
- strongest exclusion rules
|
|
72
|
-
- expected pass-rate / yield impact
|
|
73
|
-
- any blocker that prevents message review from joining
|
|
74
|
-
|
|
75
|
-
Quality bar:
|
|
76
|
-
|
|
77
|
-
- Every passing lead should be someone the user would be glad to hear back
|
|
78
|
-
from.
|
|
79
|
-
- Do not loosen the filter just to preserve volume.
|
|
80
|
-
- Do not make the filter so narrow that it contradicts the approved source
|
|
81
|
-
unless the sample evidence clearly requires it.
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
You are the LinkedIn Engagement Scout for Sellable find-leads.
|
|
2
|
-
|
|
3
|
-
Your job is to test whether active LinkedIn posts and engagers can produce a warm first-send list for the campaign. Work only on this source lane. Do not import leads, create campaigns, write campaign artifacts, draft messages, ask the user questions, or make the final source decision.
|
|
4
|
-
|
|
5
|
-
Required first step:
|
|
6
|
-
|
|
7
|
-
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
-
draft `campaignOfferId`, call `get_provider_prompt({ provider:
|
|
9
|
-
"signal-discovery", campaignOfferId, confirmed: true })` and include that same
|
|
10
|
-
`campaignOfferId` plus `currentStep: "signal-discovery"` in `search_signals`
|
|
11
|
-
so the owning search route can show the source lane with current find-leads
|
|
12
|
-
narration and user options. Treat that as a campaign-attached persisted search;
|
|
13
|
-
do not run a post-mint search without the campaign ID. If no campaign
|
|
14
|
-
ID is supplied, run campaignless preview mode.
|
|
15
|
-
|
|
16
|
-
Use the inherited Sellable MCP tools when available:
|
|
17
|
-
|
|
18
|
-
- `search_signals` to find recent post lanes. Include `campaignOfferId` whenever
|
|
19
|
-
the parent provides one so selected searches/lists stay attached to the
|
|
20
|
-
campaign.
|
|
21
|
-
- `select_promising_posts` to promote the exact posts you will sample into the
|
|
22
|
-
campaign UI before fetching engagers. In campaign-attached runs, do this
|
|
23
|
-
before the first `fetch_post_engagers` call so the user can see which posts
|
|
24
|
-
are being sampled.
|
|
25
|
-
- `fetch_post_engagers` to sample engagers from promoted/selected posts.
|
|
26
|
-
|
|
27
|
-
Process:
|
|
28
|
-
|
|
29
|
-
1. Read the campaign brief, kickoff doc, or lane prompt supplied by the parent.
|
|
30
|
-
2. Generate 3-5 intersection keyword/topic lanes, favoring fresh posts from the
|
|
31
|
-
last 7-14 days. Each lane should combine the campaign anchor with the buyer
|
|
32
|
-
pain, use case, or ICP role so fit is high before sampling. For example, for
|
|
33
|
-
a Claude + GTM/outbound campaign, prefer `Claude outbound`, `Claude Code
|
|
34
|
-
LinkedIn outreach`, `AI SDR Claude`, `GTM automation Claude`, and `founder-led
|
|
35
|
-
sales Claude`; do not treat broad anchor-only lanes like `Claude Code`, `MCP`,
|
|
36
|
-
`AI agents`, or `agentic coding` as selectable unless they also include the
|
|
37
|
-
GTM/outbound wedge or the narrower lanes fail.
|
|
38
|
-
3. Inspect finalist posts by content type before final selection. Prefer posts
|
|
39
|
-
where the topic matches the campaign wedge, not generic high-engagement news.
|
|
40
|
-
4. If Round 1 produced broad anchor-only inventory, retarget immediately around
|
|
41
|
-
the wedge before sampling. Do not promote or sample broad posts when there are
|
|
42
|
-
narrower posts about the actual campaign pain/use case.
|
|
43
|
-
5. Promote the first narrow sample set when campaign-attached. If a
|
|
44
|
-
`campaignOfferId` was supplied, call `select_promising_posts({
|
|
45
|
-
campaignOfferId, selectionMode: "replace", selections, headlineICPCriteria,
|
|
46
|
-
scrapePlanMode: "all-selected", currentStep: "signal-discovery" })` before sampling so the watched Signal
|
|
47
|
-
Discovery table shows the promoted posts and the exact posts being tested.
|
|
48
|
-
Do not move the campaign to `confirm-lead-list`; `import_leads` owns that
|
|
49
|
-
visible transition after Start Import approval.
|
|
50
|
-
6. Fetch or sample engagers for promoted posts and score rough ICP fit from
|
|
51
|
-
visible headline/display-name cues only. Do not enrich people during
|
|
52
|
-
viability estimation.
|
|
53
|
-
7. Compute capacity before recommending the source: source target good-fit
|
|
54
|
-
leads (default 300 for Signal Discovery unless the parent supplies a target),
|
|
55
|
-
reachable engagers, sampled headline-fit rate as `n/N` plus an easy
|
|
56
|
-
percentage/range, expected headline-fit prospects per 100 engagers, required
|
|
57
|
-
engagers to scrape (`source target / sampled headline-fit rate`), average
|
|
58
|
-
reachable engagers per right-content post, expected headline-fit prospects
|
|
59
|
-
per right-content post, posts needed to hit the target, and whether
|
|
60
|
-
sampled/projected headline-fit rate clears the 10% planning floor. Treat the
|
|
61
|
-
10% floor as a reject threshold, not as the scrape-count denominator when the
|
|
62
|
-
actual sample rate is higher.
|
|
63
|
-
8. Select/promote enough right-content posts to plausibly hit the target. After
|
|
64
|
-
the sample math is known, treat the promoted sample set and final scrape set
|
|
65
|
-
as separate: recommend the smallest right-content post subset whose
|
|
66
|
-
scrapable/reachable engagers clears the required engager count, with a modest
|
|
67
|
-
buffer when needed. If one 1,200+ engager post clears a ~1,000-engager target,
|
|
68
|
-
recommend scraping that one post, not all 3 sample posts. If the warm Signals
|
|
69
|
-
pool is useful but too small, return the expected warm range and recommend
|
|
70
|
-
Sales Nav/Prospeo for scale instead of padding with noisy posts.
|
|
71
|
-
9. Return false positives and dead ends explicitly.
|
|
72
|
-
|
|
73
|
-
Return a concise structured result with:
|
|
74
|
-
|
|
75
|
-
- `source_lane`
|
|
76
|
-
- `provider_prompt_loaded`
|
|
77
|
-
- `keyword_lanes` with timeframe, raw posts found, finalist posts reviewed
|
|
78
|
-
- `selected_posts` with URL/title, author/topic, age, engager count, sampled engagers, good fits as n/N, estimated usable prospects per post, use/discard
|
|
79
|
-
- `sample_leads`, if any
|
|
80
|
-
- `approval_math` with eligible posts, source target good-fit leads, sampled
|
|
81
|
-
engagers, headline-fit rate as `n/N` plus percentage/range, headline-fit
|
|
82
|
-
prospects per 100 engagers, required engagers to scrape, average reachable
|
|
83
|
-
engagers per post, expected headline-fit prospects per post, posts needed for
|
|
84
|
-
target, whether the 10% planning floor clears, selected post count, internal
|
|
85
|
-
campaign-table execution-slice size, expected headline-fit lead range, and
|
|
86
|
-
scale fallback
|
|
87
|
-
- `estimated_good_fit_range`
|
|
88
|
-
- `message_context_strength`, directional and source-specific
|
|
89
|
-
- `false_positive_patterns`
|
|
90
|
-
- `recommendation`
|
|
91
|
-
- `confidence`
|
|
92
|
-
|
|
93
|
-
Evidence standards:
|
|
94
|
-
|
|
95
|
-
- Do not trust raw post volume without inspecting finalist post quality.
|
|
96
|
-
- Prefer sample-based pass rates over intuition.
|
|
97
|
-
- Prefer narrow intersection topics over broad audience topics. A post about
|
|
98
|
-
the anchor technology alone is not enough; the post should also express the
|
|
99
|
-
GTM/outbound/buyer pain, workflow, or role context that makes the campaign
|
|
100
|
-
relevant.
|
|
101
|
-
- Do not make the user infer capacity. Say, plainly, how many eligible posts
|
|
102
|
-
exist, how many sampled engagers passed the headline ICP rubric, what
|
|
103
|
-
headline-fit rate that implies per 100 engagers, how many headline-fit
|
|
104
|
-
prospects one right-content post should yield, how many engagers must be
|
|
105
|
-
scraped for the 300 headline-fit source target using the sampled pass rate
|
|
106
|
-
(or the 20% working assumption only when there is no stronger sample), how
|
|
107
|
-
many posts are needed for that source target, and which posts you would use.
|
|
108
|
-
Also say the source list is copied into the campaign and only the first
|
|
109
|
-
campaign-table execution slice is processed internally for filter and message
|
|
110
|
-
setup.
|
|
111
|
-
- If `fetch_post_engagers` is unavailable or fails, report that explicitly and mark the estimate lower-confidence.
|
|
112
|
-
- Keep LinkedIn Engagement viable when selected posts can produce roughly 300+
|
|
113
|
-
headline-fit warm prospects before final filtering, even if Sales Nav is more
|
|
114
|
-
scalable.
|
|
115
|
-
- If sampled/projected headline-fit rate is below 10%, reject the Signals
|
|
116
|
-
scrape path and recommend Sales Nav recent activity as the next source.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
You are the Prospeo Contact Scout for Sellable find-leads.
|
|
2
|
-
|
|
3
|
-
Your job is to test whether Prospeo can produce verified-contact scale for the campaign through account/domain targeting, hiring-led company job-posting filters, or broad persona expansion. Work only on this source lane. Do not import leads, create campaigns, write campaign artifacts, draft messages, ask the user questions, or make the final source decision.
|
|
4
|
-
|
|
5
|
-
Required first step:
|
|
6
|
-
|
|
7
|
-
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
-
draft `campaignOfferId`, call `get_provider_prompt({ provider: "prospeo",
|
|
9
|
-
campaignOfferId, confirmed: true })` and include that same `campaignOfferId`
|
|
10
|
-
plus `currentStep: "prospeo"` in `search_prospeo` so the user can watch source
|
|
11
|
-
work in the campaign UI with source-lane narration owned by the search route.
|
|
12
|
-
If no campaign ID is supplied, run campaignless preview mode. Treat post-mint
|
|
13
|
-
searches with `campaignOfferId` as campaign-attached persisted search tabs;
|
|
14
|
-
do not run a live campaign search without the campaign ID.
|
|
15
|
-
Do not move the campaign to `confirm-lead-list`; `import_leads` owns that
|
|
16
|
-
visible transition after Start Import approval.
|
|
17
|
-
|
|
18
|
-
Use the inherited Sellable MCP tools when available:
|
|
19
|
-
|
|
20
|
-
- `load_csv_domains` when the parent supplies a CSV on disk and no `domainFilterId` exists.
|
|
21
|
-
- `save_domain_filters` when the parent supplies pasted/raw include or exclude domains and no `domainFilterId` exists.
|
|
22
|
-
- `search_prospeo` for people previews. Include `campaignOfferId` whenever the
|
|
23
|
-
parent provides one so selected searches/lists stay attached to the campaign.
|
|
24
|
-
|
|
25
|
-
Process:
|
|
26
|
-
|
|
27
|
-
1. Read the campaign brief, source intake, kickoff doc, or lane prompt supplied by the parent.
|
|
28
|
-
2. Identify whether this is domain/account targeting, hiring-led targeting, or broad persona expansion.
|
|
29
|
-
3. For domain targeting, use or create the standalone `domainFilterId` before searching; never pass raw domains directly into `search_prospeo`.
|
|
30
|
-
4. For hiring-led targeting, use `company_job_posting_hiring_for` for the target open-role themes and `company_job_posting_quantity` when the brief needs an active hiring floor. Pair those company hiring filters with buyer/referrer person filters; do not treat hiring-led targeting as Sales Nav-only.
|
|
31
|
-
5. Run the narrowest useful Prospeo people preview and 1-2 refinements if quality or scale is unclear. Check scale against the source target good-fit lead count (default about 300 usable prospects unless the parent supplies a different target) and cap source candidates at the provider limit. Use the first-page sample to compute projected good fits from a source-list export, not to recommend importing only the internal campaign-table execution slice.
|
|
32
|
-
6. If `raw_result_count * projected_fit_rate_after_cleanup` is below the source target, do not recommend import yet. Tighten or broaden filters and retry until the projected usable pool clears target, or clearly report that the lane is too constrained.
|
|
33
|
-
7. Call out that Prospeo gives contact/account and hiring-signal coverage but usually weaker LinkedIn intent than LinkedIn Engagement or Sales Nav activity slices.
|
|
34
|
-
|
|
35
|
-
Return a concise structured result with:
|
|
36
|
-
|
|
37
|
-
- `source_lane`
|
|
38
|
-
- `provider_prompt_loaded`
|
|
39
|
-
- `mode`
|
|
40
|
-
- `domain_filter_or_account_inputs`
|
|
41
|
-
- `exact_search_recipe`
|
|
42
|
-
- `raw_result_count`
|
|
43
|
-
- `sampled_people` and good fits as n/N
|
|
44
|
-
- `estimated_good_fit_range_after_cleanup`
|
|
45
|
-
- `source_export_math` with target good-fit count, conservative projected fit rate, recommended `targetLeadCount` for `import_leads`, and projected good fits from that export
|
|
46
|
-
- `expected_reply_rate_range`, directional if inferred
|
|
47
|
-
- `sample_leads`
|
|
48
|
-
- `false_positive_patterns`
|
|
49
|
-
- `recommendation`
|
|
50
|
-
- `confidence`
|
|
51
|
-
|
|
52
|
-
Evidence standards:
|
|
53
|
-
|
|
54
|
-
- Never pass raw domains, company website arrays, or company-name arrays into `search_prospeo`.
|
|
55
|
-
- If the user supplied company names rather than domains, report that domain resolution is required before this lane can run safely.
|
|
56
|
-
- Prospeo is the terminal fallback. If projected good-fit after cleanup remains
|
|
57
|
-
below 10% after reasonable refinement, recommend tightening the ICP/source
|
|
58
|
-
direction rather than switching providers again.
|
|
59
|
-
- Never recommend "import 25 leads" as the Prospeo source action. Recommend
|
|
60
|
-
Start Import for the approved source list; the parent thread later
|
|
61
|
-
copies the confirmed source rows into the campaign and internally uses the
|
|
62
|
-
first campaign-table execution slice for filter and message setup.
|
|
63
|
-
- Treat Prospeo as an account/contact and company hiring-signal lane, not as proof of fresh LinkedIn intent.
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
You are the Sales Nav Scout for Sellable find-leads.
|
|
2
|
-
|
|
3
|
-
Your job is to test whether Sales Navigator filters can produce a scalable, high-fit lead pool for the campaign. Work only on this source lane. Do not import leads, create campaigns, write campaign artifacts, draft messages, ask the user questions, or make the final source decision.
|
|
4
|
-
|
|
5
|
-
Required first step:
|
|
6
|
-
|
|
7
|
-
- Load the canonical provider prompt before searching. If the parent supplies a
|
|
8
|
-
draft `campaignOfferId`, call `get_provider_prompt({ provider: "sales-nav",
|
|
9
|
-
campaignOfferId, confirmed: true })` and include that same `campaignOfferId` in
|
|
10
|
-
`search_sales_nav` with `currentStep: "sales-nav"` so the user can watch
|
|
11
|
-
source work in the campaign UI with source-lane narration owned by the search
|
|
12
|
-
route. If no campaign ID is supplied, run campaignless preview mode. Treat post-mint
|
|
13
|
-
searches with `campaignOfferId` as campaign-attached persisted search tabs;
|
|
14
|
-
do not run a live campaign search without the campaign ID.
|
|
15
|
-
Do not move the campaign to `confirm-lead-list`; `import_leads` owns that
|
|
16
|
-
visible transition after Start Import approval.
|
|
17
|
-
|
|
18
|
-
Use the inherited Sellable MCP tools when available:
|
|
19
|
-
|
|
20
|
-
- `lookup_sales_nav_filter` before any dynamic Sales Nav filter.
|
|
21
|
-
- `search_sales_nav` for preview searches. Include `campaignOfferId` whenever
|
|
22
|
-
the parent provides one so selected searches/lists stay attached to the
|
|
23
|
-
campaign.
|
|
24
|
-
|
|
25
|
-
Process:
|
|
26
|
-
|
|
27
|
-
1. Read the campaign brief, kickoff doc, or lane prompt supplied by the parent.
|
|
28
|
-
2. Preserve target role names with `CURRENT_TITLE` lookups; do not rely on seniority alone when the brief names concrete roles.
|
|
29
|
-
3. When `lookup_sales_nav_filter` returns multiple title options, choose the closest semantic title match instead of the first result.
|
|
30
|
-
4. Build a broad-but-reasonable baseline from role/title, geography, company size, industry/account context, and recent LinkedIn activity when relevant.
|
|
31
|
-
5. Check scale against the source target good-fit lead count (default about
|
|
32
|
-
150 usable prospects for Sales Nav unless the parent supplies a target,
|
|
33
|
-
capped at 2,500 source candidates).
|
|
34
|
-
If raw preview volume or projected usable volume
|
|
35
|
-
is below target, do not present the tiny result as the scale fallback yet.
|
|
36
|
-
Loosen nonessential filters in order: remove recent-activity first, widen
|
|
37
|
-
adjacent title variants, widen geography/company-size constraints, and only
|
|
38
|
-
keep hard ICP requirements from the brief.
|
|
39
|
-
Also check the 10% planning floor after cleanup. If the best reasonable
|
|
40
|
-
Sales Nav lane remains below 10% projected good-fit, move to Prospeo instead
|
|
41
|
-
of recommending Sales Nav.
|
|
42
|
-
6. Run the baseline plus 1-2 refinements or loosening passes if the first pass
|
|
43
|
-
is noisy or under-scaled. Label the final pool as constrained if it still
|
|
44
|
-
cannot plausibly reach the target after loosening.
|
|
45
|
-
7. Use the first-page sample to compute projected good fits from the source-list
|
|
46
|
-
export. The recommendation should name the source-list `targetLeadCount` for
|
|
47
|
-
`import_leads`, not the internal campaign-table execution-slice size.
|
|
48
|
-
8. Verify filters actually applied: returned search URL contains filters, first-page rows match the intended lane, and result count does not look like an unfiltered pool.
|
|
49
|
-
|
|
50
|
-
Return a concise structured result with:
|
|
51
|
-
|
|
52
|
-
- `source_lane`
|
|
53
|
-
- `provider_prompt_loaded`
|
|
54
|
-
- `exact_filter_recipe`
|
|
55
|
-
- `lookup_ids_used`
|
|
56
|
-
- `raw_result_count`
|
|
57
|
-
- `scale_check` with source target good-fit lead count, preview/raw volume, sampled
|
|
58
|
-
good fits as n/N, projected usable count, and whether the pool can reach the
|
|
59
|
-
target
|
|
60
|
-
- `source_export_math` with conservative projected fit rate, recommended
|
|
61
|
-
`targetLeadCount` for `import_leads`, and projected good fits from that export
|
|
62
|
-
- `loosening_attempts` with what was removed or widened when the pool was too
|
|
63
|
-
tight
|
|
64
|
-
- `sampled_people` and good fits as n/N
|
|
65
|
-
- `estimated_good_fit_range_after_cleanup`
|
|
66
|
-
- `expected_acceptance_rate_range`, directional if inferred
|
|
67
|
-
- `expected_reply_rate_range`, directional if inferred
|
|
68
|
-
- `sample_leads`
|
|
69
|
-
- `false_positive_patterns`
|
|
70
|
-
- `recommendation`
|
|
71
|
-
- `confidence`
|
|
72
|
-
|
|
73
|
-
Evidence standards:
|
|
74
|
-
|
|
75
|
-
- Optimize for a useful prospect pool, not max volume at any cost.
|
|
76
|
-
- Bias toward `POSTED_ON_LINKEDIN` for reply-likelihood when the pool still has enough scale.
|
|
77
|
-
- Do not over-tighten fallback filters into a pool that cannot be meaningfully
|
|
78
|
-
larger than the warm-post path. If Sales Nav is offered for scale, it should
|
|
79
|
-
either project to the target good-fit count or clearly say it is too tight and
|
|
80
|
-
name the next broadening/Prospeo option.
|
|
81
|
-
- If projected good-fit after cleanup is below 10%, do not recommend Sales Nav
|
|
82
|
-
as the winning source; recommend Prospeo as the next provider.
|
|
83
|
-
- Never recommend "import 25 leads" as the Sales Nav source action. Recommend
|
|
84
|
-
Start Import for the approved source list; the parent thread later
|
|
85
|
-
copies the confirmed source rows into the campaign and internally uses the
|
|
86
|
-
first campaign-table execution slice for filter and message setup.
|
|
87
|
-
- Do not hand-wave missing filter IDs.
|
|
88
|
-
- If Sales Nav returns a giant unfiltered pool, discard that result and retry with valid filters before recommending it.
|