@sellable/mcp 0.1.142 → 0.1.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +5 -3
  2. package/agents/post-find-leads-message-scout.md +47 -3
  3. package/agents/registry.json +3 -7
  4. package/dist/index-dev.js +0 -0
  5. package/dist/index.js +0 -0
  6. package/dist/server.js +59 -29
  7. package/dist/tools/auth.js +5 -5
  8. package/dist/tools/leads.js +107 -8
  9. package/dist/tools/processing.d.ts +1 -0
  10. package/dist/tools/prompts.js +3 -3
  11. package/dist/tools/rubrics.js +14 -9
  12. package/package.json +1 -1
  13. package/skills/create-campaign/SKILL.md +52 -32
  14. package/skills/create-campaign-brief/SKILL.md +4 -0
  15. package/skills/create-campaign-v2/SKILL.md +59 -9
  16. package/skills/create-campaign-v2/SOUL.md +21 -12
  17. package/skills/create-campaign-v2/core/flow.v2.json +54 -18
  18. package/skills/create-campaign-v2/core/policy.md +35 -39
  19. package/skills/create-campaign-v2/references/draft-lifecycle.md +20 -104
  20. package/skills/create-campaign-v2/references/filter-leads.md +199 -525
  21. package/skills/create-campaign-v2/references/final-handoff-contract.md +5 -5
  22. package/skills/create-campaign-v2/references/message-review-safety-gate.md +109 -28
  23. package/skills/create-campaign-v2/references/sample-validation-loop.md +5 -2
  24. package/skills/create-campaign-v2/references/step-15-re-cascade.md +2 -3
  25. package/skills/create-campaign-v2/references/watch-guide-narration.md +37 -22
  26. package/skills/create-campaign-v2/references/watch-link-handoff.md +1 -1
  27. package/skills/create-campaign-v2-tail/SKILL.md +26 -13
  28. package/skills/research/config.json +9 -0
  29. package/dist/tools/registry.d.ts +0 -4186
  30. package/dist/tools/registry.js +0 -59
@@ -1,143 +1,134 @@
1
1
  # Filter Leads
2
2
 
3
- CampaignOffer state and the watch link are canonical. Disk artifacts are
4
- optional debug/UAT diagnostics, and normal customer runs should not expose local
5
- draft files. Resume, gating, and handoff read campaign state first. Filter design
6
- may use the live lead sample or optional debug sample, but the active rubric save
7
- is `save_rubrics({ campaignOfferId, leadScoringRubrics }) after the campaign
8
- table exists`.
3
+ CampaignOffer state, the watched app, and campaign-table rows are canonical for
4
+ normal create-campaign-v2 runs. Do not read, write, link, or surface local
5
+ markdown/json progress artifacts in customer runs. Debug artifacts belong only
6
+ to explicit debug/UAT or the legacy validation harness, and they are never the
7
+ source of truth after a campaign shell exists.
8
+
9
+ The middle step is a lightweight lead-quality audit and decision gate. It should
10
+ add fidelity to the source estimate, convert repeated false positives into
11
+ production rubrics, and protect the user from replies they would not want to
12
+ take. It should not re-run sourcing, create a second source plan, or build a
13
+ large scoring framework.
14
+
15
+ ## Inputs
16
+
17
+ Use only live campaign inputs supplied by the parent thread or scoped MCP tools:
18
+
19
+ - `campaignId`
20
+ - campaign revision or `campaignUpdatedAt`
21
+ - campaign brief content
22
+ - approved source decision and selected lead list/source state
23
+ - `workflowTableId`
24
+ - imported bounded review-batch rows, including row ids/hash when available
25
+ - user's filter choice and any explicit exclusions or tradeoffs
26
+
27
+ The filter may inspect campaign-table rows through scoped tools such as
28
+ `get_rows_minimal({ tableId: workflowTableId })` or equivalent parent-thread
29
+ payloads. If the campaign id, selected source/list id, table id, or review-batch
30
+ row ids do not match the branch input, report `stale` or `blocked`.
9
31
 
10
- The middle step is a lightweight lane audit and decision gate. It should add
11
- fidelity to the find-leads estimate, not re-run sourcing or produce a large
12
- scoring framework.
32
+ ## Evaluation Data Scope
13
33
 
14
- The business goal is not "find people who might reply." It is "every reply the
15
- user gets should come from someone they would be excited to hear back from:
16
- inside the ICP, able to act, and with a realistic path to buying." A lead who may
17
- reply but cannot buy, lacks budget, sits at the wrong account type, is a
18
- vendor/competitor, or is on the wrong side of a marketplace is not a good lead.
34
+ Do not write final filters that depend on fields visible only in a source
35
+ provider preview card. Sales Nav cards, Prospeo rows, and Signals rows are
36
+ sampling evidence, not the full data contract.
19
37
 
20
- The exact qualification gates are client- and offer-specific, but the standard
21
- does not change: anyone we reach out to, and anyone who replies, should be worth
22
- the user's time to talk to. Use the client's price point, buyer, channel,
23
- delivery constraints, market, and competitor landscape to define the concrete
24
- gates for that campaign.
38
+ Production rubrics should describe what we will decide after normal enrichment
39
+ and public research have run. For example:
25
40
 
26
- Source interest is not qualification. A lead who engaged with a post, appeared
27
- in a Signals search, recently posted on LinkedIn, or "showed interest" in the
28
- topic has only supplied discovery context. That context can justify the source
29
- lane, improve pass-rate confidence, or help message generation; it must not
30
- become a production filter or `leadScoringRubric` item. If the source lane was
31
- built from topical engagement, the filter should still ask: is this the right
32
- role, seniority, account type, budget band, market, and non-competitor?
41
+ - Good: keep US-licensed MD/DO dermatologists; verify credentials from the
42
+ enriched LinkedIn profile, professional bio, state-license page, or another
43
+ public source.
44
+ - Bad: exclude rows missing MD/DO on the preview card.
33
45
 
34
- Ability to pay must be considered for every campaign, but it is only a required
35
- filter/rubric when the client, offer, or price point makes affordability a real
36
- qualification risk. Do not force an enterprise-budget screen onto a low-cost B2C,
37
- creator, prosumer, or small-team offer. Do not use a loose consumer-style screen
38
- for an enterprise, services-heavy, implementation-heavy, or paid-pilot offer.
39
- When affordability is material, `lead-filter.md` must name the campaign-native
40
- proxy that proves the prospect can afford this specific offer at this specific
41
- price point. Do not dodge this gate because the exact budget is unknown; use a
42
- reasonable public proxy such as funding, headcount, revenue band, team maturity,
43
- current tool spend, practice size, location count, consumer purchasing power,
44
- job-to-be-done intensity, or buyer budget ownership. If affordability is material
45
- and no reliable proxy exists in the sample or through normal enrichment, set
46
- `Status: confirm-with-user` and ask for the budget proxy before moving to message
47
- generation.
46
+ If a preview row lacks enough evidence to prove a required rule, mark it as
47
+ needs enrichment or borderline pending verification in the summary. Do not turn
48
+ preview-card missingness into a hard production exclusion unless the same field
49
+ will remain missing after enrichment.
48
50
 
49
- Use price-point proportionality:
51
+ ## Outputs
50
52
 
51
- - inexpensive B2C / prosumer / creator offers: do not require an explicit
52
- ability-to-pay rule unless affordability is central to the ICP; fit is usually
53
- based on use case, audience, life context, or intent, not company budget
54
- - a few-hundred-dollar SMB or self-serve B2B offer: require evidence of an
55
- active business, relevant workflow, and enough commercial seriousness to pay
56
- hundreds, but do not require enterprise scale
57
- - mid-market / paid pilot / agency or implementation-supported offer: require a
58
- team, operational pain, and a likely owner for the budget
59
- - enterprise / high-ACV offer: require enterprise or upper-mid-market account
60
- fit, budget-owning seniority, department maturity, and buying-process plausibility
53
+ For `Status: confirmed`, persist durable rubrics with:
61
54
 
62
- Inputs:
55
+ ```js
56
+ save_rubrics({ campaignOfferId, leadScoringRubrics });
57
+ ```
63
58
 
64
- - `brief.md`
65
- - `lead-review.md`
66
- - `lead-sample.json`
59
+ Return a concise parent-thread summary containing:
67
60
 
68
- Outputs:
61
+ - filter status: `confirmed`, `confirm-with-user`, or `revise-find-leads`
62
+ - strongest keep rules
63
+ - strongest exclusion rules
64
+ - expected pass-rate / yield impact
65
+ - production rubric JSON when confirmed
66
+ - whether `save_rubrics` succeeded
67
+ - any blocker that prevents message review from joining
69
68
 
70
- - `lead-filter.md`
71
- - optional `rubric.json`
69
+ Do not create local filter files, sidecar JSON, or progress notes in normal
70
+ customer runs. If debug/UAT output is explicitly requested, label it as a
71
+ diagnostic copy and keep live campaign state as the durable source.
72
72
 
73
- Core constraint:
73
+ ## Qualification Standard
74
74
 
75
- - Every accepted filter in `lead-filter.md` must be directly translatable into
76
- the production `LeadScoringRubric` shape. If a filter cannot become a
77
- runnable rubric criterion from available row data or public research, it is
78
- not an accepted filter; convert it to an optional enrichment note, a user
79
- tradeoff, or a lead-source revision reason.
75
+ The business goal is not "find people who might reply." It is "every reply the
76
+ user gets should come from someone they would be excited to hear back from:
77
+ inside the ICP, able to act, and with a realistic path to buying."
80
78
 
81
- ## Evaluation Data Scope
79
+ The exact gates are client- and offer-specific, but the standard does not
80
+ change: anyone we reach out to, and anyone who replies, should be worth the
81
+ user's time to talk to. Use the client's price point, buyer, channel, delivery
82
+ constraints, market, and competitor landscape to define concrete gates for this
83
+ campaign.
82
84
 
83
- Do not write final filters that depend on the limited fields visible in the
84
- source-provider preview card. Sales Nav cards, Prospeo rows, and Signals rows
85
- are sampling evidence, not the full data contract.
85
+ Source interest is not qualification. A lead who engaged with a post, appeared
86
+ in a Signals search, recently posted on LinkedIn, or showed interest in a topic
87
+ has supplied discovery context only. That context can justify the source lane,
88
+ improve pass-rate confidence, or help message generation; it must not become a
89
+ production rubric item by itself.
86
90
 
87
- Production rubrics should describe what we will decide after normal enrichment
88
- and public research have run. For example:
91
+ ## Ability To Pay
89
92
 
90
- - Good: "Keep US-licensed MD/DO dermatologists; verify credentials from the
91
- enriched LinkedIn profile, professional bio, NPI/state-license page, or other
92
- public source."
93
- - Bad: "Exclude rows missing MD/DO on the Sales Nav card."
93
+ Ability to pay must be considered for every campaign, but it is only a required
94
+ rubric when the client, offer, or price point makes affordability a real
95
+ qualification risk.
94
96
 
95
- If a preview row lacks enough evidence to prove a required rule, mark it as
96
- `needs enrichment` or `borderline pending verification` in sample findings. Do
97
- not turn preview-card missingness into a hard production exclusion unless the
98
- same missing field will remain missing after enrichment.
99
-
100
- ## Primary Goal
101
-
102
- Use the actual sample to answer:
103
-
104
- - was the Step 2 projected-good-fit estimate basically right or wrong
105
- - which leads clearly match the buyer hypothesis
106
- - which leads are noise
107
- - which repeated false positives must become explicit exclusions
108
- - whether filters are enough, or whether the source lane would make the
109
- campaign miss if launched as-is
110
- - whether the filtered leads are worth sending to for this client's offer and
111
- price point, using an economic-fit proxy only when affordability is material
112
-
113
- ## Table-Stakes Qualification Gates
114
-
115
- Confirmed production filters should fail closed on buyer quality. The default
116
- confirmed filter set must explicitly include each table-stakes gate below, or
117
- `lead-filter.md` must state why a gate is irrelevant for this campaign:
118
-
119
- Customize the concrete threshold for each gate to the client and offer. For
120
- example, "can afford this" might mean nothing explicit for a low-cost B2C tool,
121
- an active business for a few-hundred-dollar SMB offer, enterprise headcount for
122
- one client, a funded seed-stage team for another, multi-location practice size
123
- for another, or existing tool spend for another. Do not hard-code Sellable's
124
- exact budget, geography, or title rules into unrelated campaigns; hard-code the
125
- principle that passing leads must be worth the customer's time.
126
- Do not hard-code Sellable's exact budget into the filter; translate affordability
127
- into the client's native buying proxy.
97
+ Use price-point proportionality:
98
+
99
+ - inexpensive B2C, prosumer, creator, or community offers: usually qualify by
100
+ use case, audience, life context, or intent; do not require an explicit
101
+ budget rule unless affordability is central to the ICP
102
+ - few-hundred-dollar SMB or self-serve B2B offers: require an active business,
103
+ relevant workflow, and enough commercial seriousness to pay hundreds
104
+ - mid-market, paid-pilot, agency, or implementation-supported offers: require a
105
+ team, operational pain, and a likely owner for the budget
106
+ - enterprise or high-ACV offers: require upper-mid-market or enterprise account
107
+ fit, budget-owning seniority, department maturity, and buying-process
108
+ plausibility
109
+
110
+ When affordability is material, name the campaign-native proxy that proves the
111
+ prospect can afford this specific offer at this specific price point. Use a
112
+ reasonable public proxy such as funding, headcount, revenue band, team maturity,
113
+ current tool spend, practice size, location count, consumer purchasing power,
114
+ job-to-be-done intensity, or buyer budget ownership. If no reliable proxy exists
115
+ in the review batch or normal enrichment path, return `confirm-with-user` and
116
+ ask the parent to get the budget proxy before message approval.
117
+
118
+ ## Table-Stakes Gates
119
+
120
+ Confirmed production rubrics should fail closed on buyer quality. The confirmed
121
+ filter set must cover each relevant gate below, or the summary must explain why
122
+ the gate is irrelevant for this campaign:
128
123
 
129
124
  - right role / function: the person owns or directly influences the buyer
130
125
  problem; wrong-function leads fail even when they match the source topic
131
126
  - right seniority / authority: the person can approve, pilot, champion, or
132
- materially influence adoption; junior ICs fail unless the brief explicitly
133
- targets them
127
+ materially influence adoption; junior ICs fail unless the brief targets them
134
128
  - account and channel fit: the company is the right account type and its buyers
135
- are reachable through the chosen channel, such as LinkedIn for LinkedIn
136
- outbound campaigns
137
- - economic capacity / ability to buy, when material: the prospect has an
138
- appropriate price-point proxy for the offer, such as active business status,
139
- headcount, revenue, funding, team size, practice size, location count,
140
- department maturity, existing tooling, or budget ownership
129
+ are reachable through the chosen channel
130
+ - economic capacity / ability to buy, when material: the prospect has a
131
+ price-point-appropriate proxy for the offer
141
132
  - competitor / vendor / wrong-side exclusion: competitors, adjacent vendors,
142
133
  agencies/service providers, resellers, and marketplace-side conflicts fail
143
134
  unless the brief explicitly targets that group
@@ -147,83 +138,45 @@ into the client's native buying proxy.
147
138
  - active current-role safety: score the person's current role and company, not
148
139
  stale prior roles, advisor blurbs, investor bios, or old engagement context
149
140
 
150
- Do not replace these gates with a "shown interest" or "engaged with relevant
151
- content" rule. Interest can help find a warmer list, but it does not prove the
152
- lead is a buyer.
153
-
154
- ## Standard Competitor / Vendor Exclusion
141
+ ## Competitor / Vendor Exclusion
155
142
 
156
143
  Every confirmed filter should include a competitor / vendor / wrong-side
157
- exclusion unless the brief and sample make it clearly irrelevant. This is a
158
- standard production safety rule, not an optional nice-to-have.
144
+ exclusion unless the brief and review batch make it clearly irrelevant.
159
145
 
160
- Use this simple test:
146
+ Use this test:
161
147
 
162
148
  - Would this company, product, service provider, agency, consultant, reseller,
163
149
  or marketplace participant appear on the same comparison page as the client?
164
150
  - Would they compete for the same customer budget, sell into the same buyer
165
151
  workflow, or sit on the wrong side of the marketplace?
166
- - Did the sample show adjacent companies that a client would likely reject only
167
- after seeing the list?
152
+ - Did the review batch show adjacent companies that the customer would likely
153
+ reject only after seeing the list?
168
154
 
169
155
  If yes, add an explicit exclude rule. Include named competitors from the brief,
170
- sample, or user context when available, plus the general category exclusion so
171
- new lookalike competitors are also blocked. If a competitor/vendor exclusion is
172
- omitted, `lead-filter.md` must say why it is not applicable.
173
-
174
- Treat this as part of the manual review loop. When the user or client sees a
175
- sample and says "these companies are not a fit," update the exclusion watchlist
176
- and filter draft before Step 4. Use `confirm-with-user` when the sample contains
177
- ambiguous adjacent vendors, competitors, agencies, marketplace-side conflicts,
178
- or reseller/consultant roles where excluding them would materially shrink the
179
- lane.
180
-
181
- ## `lead-filter.md` Shape
182
-
183
- ````md
184
- # Lead Filter
185
-
186
- Status: confirmed | confirm-with-user | revise-find-leads
187
-
188
- ## Decision
189
-
190
- - continue | confirm with user | revise find-leads
191
- - one plain-English sentence saying why
192
-
193
- ## Who We'll Keep
156
+ review batch, or user context when available, plus the general category
157
+ exclusion so new lookalike competitors are also blocked.
194
158
 
195
- - buyers we would be excited to get a reply from, including the role, authority,
196
- account type, and price-point-appropriate commercial-fit signal that make the
197
- reply worth taking
159
+ ## Marketplace Safety
198
160
 
199
- ## Who We'll Exclude
161
+ Two-sided marketplaces need an explicit wrong-side exclusion when the same
162
+ public lead pool can contain both the intended buyer and a forbidden
163
+ counterparty. If the campaign brief declares a marketplace, the filter must name
164
+ the accepted side of market and the forbidden side of market.
200
165
 
201
- - people who may reply but are not worth sending to because they lack authority,
202
- lack a plausible budget path when budget is material, sit at the wrong account
203
- type, or are competitors/vendors/wrong-side marketplace participants
166
+ Examples:
204
167
 
205
- ## Sample False Positives
168
+ - Demand-side buyer campaign: exclude supply-side contractors, contributors,
169
+ applicants, or providers even if they match topical signals.
170
+ - Supply-side acquisition campaign: exclude demand-side buyers or employers when
171
+ they are not the outbound target.
206
172
 
207
- - ...
173
+ If more than roughly 20% of the review batch appears to be the forbidden side,
174
+ classify it as a list/source problem and return `revise-find-leads`; do not
175
+ hide that problem behind narrow rubrics.
208
176
 
209
- ## Optional Supporting Rule
177
+ ## Production Rubric Shape
210
178
 
211
- - omit this section unless exactly one supporting rule materially helps messaging or prioritization
212
-
213
- ## Pass Rate
214
-
215
- - ...
216
-
217
- ## Recommendation
218
-
219
- - proceed to generate message
220
- - or revise leads / revise filter
221
-
222
- ## Implementation Details
223
-
224
- If `Status: confirmed`, include production rubrics. The `economic_capacity`
225
- example below applies when affordability is material; omit it for inexpensive
226
- B2C/prosumer/community offers where ability to pay is not a meaningful fit gate:
179
+ Confirmed rubrics must use the production `LeadScoringRubric` fields exactly:
227
180
 
228
181
  ```json
229
182
  {
@@ -236,383 +189,104 @@ B2C/prosumer/community offers where ability to pay is not a meaningful fit gate:
236
189
  "isRequiredCheck": true,
237
190
  "allowPartialCredit": false,
238
191
  "strictMatching": false
239
- },
240
- {
241
- "checkName": "company_fit",
242
- "description": "Lead works at a company type validated by the sample.",
243
- "criterion": "Yes if the current company matches the accepted account type from the brief and sample. No if the company is a vendor, agency, competitor, or structurally wrong account type.",
244
- "reason": "The message thesis depends on this company context being true.",
245
- "isRequiredCheck": true,
246
- "allowPartialCredit": false,
247
- "strictMatching": false
248
- },
249
- {
250
- "checkName": "economic_capacity",
251
- "description": "Prospect has a price-point-appropriate ability-to-pay proxy.",
252
- "criterion": "Yes if public or enriched data shows the prospect is likely able to afford this specific offer using the campaign's chosen proxy, scaled to the price point. For low-cost B2C/prosumer offers, this may be personal fit and purchasing power. For a few-hundred-dollar SMB/self-serve offer, this may be an active business and relevant workflow. For paid-pilot, implementation-heavy, mid-market, or enterprise offers, this may require funding, revenue, headcount, department maturity, existing tool spend, location count, or budget-owner title. No if the prospect is structurally unable to buy at the offer's price point or missing the required proxy after enrichment.",
253
- "reason": "Replies from accounts without a realistic budget path waste the user's time even when the person is warm or interested.",
254
- "isRequiredCheck": true,
255
- "allowPartialCredit": false,
256
- "strictMatching": false
257
192
  }
258
193
  ]
259
194
  }
260
195
  ```
261
196
 
262
- If `Status: confirm-with-user` or `Status: revise-find-leads`, do not include
263
- production rubrics yet. Explain why the draft filter is not locked downstream.
264
-
265
- ## Required Keep Rules
266
-
267
- - technical source rules, if different from the plain-English keep list
268
-
269
- ## Required Exclude Rules
197
+ Rules:
270
198
 
271
- - technical source rules, if different from the plain-English exclude list
272
- ````
199
+ - persist 2-5 rubric criteria total
200
+ - default every rule to `isRequiredCheck: true`
201
+ - allow at most one optional/non-required rule
202
+ - do not duplicate two rules that restate the same keep/exclude idea
203
+ - keep title / role fit explicit with concrete pass and fail title patterns
204
+ - use `allowPartialCredit: false` for hard gates where ambiguity should fail
205
+ - use `strictMatching: true` only for exact named-account or exact-token matching
206
+ - write criteria that can be evaluated from campaign-table rows, enrichment, or
207
+ normal public research
208
+ - keep source mechanics out of production rubrics: provider lane, recently
209
+ posted, first-send order, engagement source, priority cohort, and topical
210
+ interest can inform messaging or prioritization, but they are not ICP fit
273
211
 
274
- Rules:
212
+ Recommended grouping:
275
213
 
276
- - `Decision` is mandatory and must appear before filter details
277
- - default to `Status: confirmed` when the source lane is viable and filters are
278
- enough to protect the campaign
279
- - use `confirm-with-user` only when the lane is viable but there is a real
280
- strategic tradeoff the user must choose before launch
281
- - use `revise-find-leads` only when filters would be so heavy, low-volume, or
282
- thesis-distorting that launching from this lane would likely miss
283
- - always emit a readable draft filter, even when status is `confirm-with-user`
284
- or `revise-find-leads`, so the user can inspect and edit the AI's definition
285
- of a good fit
286
- - `Who We'll Keep` and `Who We'll Exclude` are mandatory user-facing sections
287
- - `Required Keep Rules` and `Required Exclude Rules` are allowed as technical
288
- source sections, but should appear after `Implementation Details` if present
289
- - `Sample False Positives` must be grounded in observed sample leads
290
- - `Optional Supporting Rule` is allowed only when one rule clearly helps later
291
- messaging or prioritization
292
- - never emit more than one optional/non-required rule
293
- - `Implementation Details` is mandatory for every status
294
- - `Implementation Details` must contain one fenced JSON object with
295
- `leadScoringRubrics` only when `Status: confirmed`
296
- - non-confirmed filters are draft/user-review artifacts, not official Step 4
297
- inputs
298
- - `leadScoringRubrics` must contain 2-5 production-shaped rubric items, not one
299
- item per bullet
300
- - confirmed `leadScoringRubrics` must include an explicit ability-to-pay /
301
- economic-capacity check when affordability is material to fit: a few-hundred-
302
- dollar B2B offer, paid pilot, implementation-heavy sale, mid-market sale, or
303
- enterprise/high-ACV motion. Do not require this check for inexpensive B2C,
304
- prosumer, creator, community, or otherwise low-friction offers unless
305
- affordability is central to the ICP. When present, the check must be
306
- price-point-appropriate for the client and offer: commercial-seriousness based
307
- for a few hundred dollars, budget-owner based for mid-market/enterprise. Do not
308
- rely on role fit, company fit, or source engagement to imply this.
309
- - do not put source-path mechanics or send-priority hints into
310
- `leadScoringRubrics`. Examples: recently posted on LinkedIn, came from a
311
- Signals search, appeared in Sales Nav, was found by Prospeo, first-send wave,
312
- priority cohort, engaged with selected posts, showed interest in the topic,
313
- or matched a signal-discovery keyword. If that signal was already used in the
314
- search, mention it in `Pass Rate` or `Recommendation`; if it helps messaging,
315
- pass it to message generation as source context, not as a production rubric or
316
- supporting fit rule.
317
- - do not put DNC or one-off relationship-safety notes into
318
- `leadScoringRubrics` unless the sample shows that family is likely to leak at
319
- meaningful volume and normal DNC/domain suppression will not catch it. Former
320
- employers, existing customers, investors, partner lists, and "do not contact"
321
- domains usually belong in `Recommendation` or a DNC note, not in ICP scoring.
322
- - confirmed `leadScoringRubrics` must protect sales quality, not just surface
323
- similarity. They must cover the table-stakes qualification gates unless
324
- `lead-filter.md` explicitly justifies why a gate is irrelevant:
325
- - right role / function fit
326
- - buyer seniority / authority
327
- - account or company-type fit
328
- - economic capacity / ability to buy, when material, using a campaign-native
329
- proxy such as active business status, headcount, revenue, funding, practice
330
- size, location count, patient volume, department maturity, existing tooling,
331
- or budget-owner title
332
- - geography / market, when relevant
333
- - active-current-role safety
334
- - hard exclusions for competitors, vendors, agencies, job seekers,
335
- wrong-function leads, and wrong-side marketplace participants
336
- - confirmed `leadScoringRubrics` should include a competitor / vendor /
337
- wrong-side exclusion by default. It can be bundled with account-fit only when
338
- the criterion still names both the accepted account type and the excluded
339
- competitor/vendor/wrong-side categories.
340
- - when one production rubric bundles multiple families, the criterion must say
341
- exactly which buyer-quality gates it covers
342
- - if the filter cannot be compiled into 2-5 production rubric items, do not
343
- confirm; return `confirm-with-user` or `revise-find-leads`
344
- - hide raw rubric flags from the top user-facing sections; keep
345
- `isRequiredCheck`, `allowPartialCredit`, and `strictMatching` inside
346
- `Implementation Details`
347
-
348
- ## Rule Families To Preserve
349
-
350
- When relevant to the brief and sample, preserve these recurring families:
351
-
352
- - buyer role / seniority
353
- - wrong-function exclusions
354
- - company-type exclusions
355
- - economic capacity / ability-to-pay proxy
356
- - competitor / vendor / intermediary exclusions
357
- - geography
358
- - company size
359
- - active current-role status
214
+ - buyer authority / role fit
215
+ - company / industry / provider-lane fit
216
+ - economic capacity / ability to buy, when material
217
+ - geography / size / stage fit, when relevant
218
+ - competitor / vendor / wrong-side / repeated false-positive exclusion
219
+ - one optional buyer-quality qualifier, at most, only when it changes fit
220
+ scoring rather than send ordering
360
221
 
361
222
  ## Sample-Judging Method
362
223
 
363
224
  For each proposed rule:
364
225
 
365
- 1. inspect matching and failing sample leads
366
- 2. decide whether the rule removes real noise or blocks real buyers
367
- 3. mark the rule as necessary, loosen, or remove
368
- 4. record the resulting pass rate
226
+ 1. Inspect matching and failing review-batch rows.
227
+ 2. Decide whether the rule removes real noise or blocks real buyers.
228
+ 3. Mark the rule as necessary, loosen, or remove.
229
+ 4. Estimate the resulting pass rate and yield impact.
369
230
 
370
231
  Repeated false positives should become explicit exclude rules whenever the same
371
- pattern appears more than once in the sample.
232
+ pattern appears more than once in the review batch. Preview-card missingness is
233
+ not a hard production exclusion unless the same missing evidence will remain
234
+ missing after normal enrichment/public research.
372
235
 
373
- ## `rubric.json` Sidecar
236
+ ## Source Contradictions
374
237
 
375
- Only emit a sidecar when a downstream step needs a separate file. The same
376
- production-shaped items must always appear as fenced JSON in `lead-filter.md`
377
- under `## Implementation Details`, even when `rubric.json` is omitted.
238
+ If review-batch evidence contradicts the approved source thesis, do not rewrite
239
+ the campaign brief silently. Return one of these instead:
378
240
 
379
- Shape:
241
+ - `confirm-with-user` when a viable alternative source or filter tradeoff needs
242
+ customer choice.
243
+ - `revise-find-leads` when the selected lane is contaminated, too low-yield, or
244
+ aimed at the wrong buyer side.
380
245
 
381
- ```json
382
- {
383
- "leadScoringRubrics": [
384
- {
385
- "checkName": "role_fit",
386
- "description": "Lead holds one of the validated buyer titles.",
387
- "criterion": "Yes if the current title matches one of the accepted buyer titles. No if the title is a wrong-function, junior, advisory-only, or service-provider title.",
388
- "reason": "The campaign only works when the recipient owns the buyer problem and can act on the offer.",
389
- "isRequiredCheck": true,
390
- "allowPartialCredit": false,
391
- "strictMatching": false
392
- }
393
- ]
394
- }
395
- ```
246
+ Only the parent thread updates campaign brief/source state, and only after the
247
+ user approves the change.
396
248
 
397
- Rules:
249
+ ## Provider-Lane Fit Density Anchors
398
250
 
399
- - derive every sidecar rule from `lead-filter.md`
400
- - default every rule to `isRequiredCheck: true`
401
- - allow at most one `isRequiredCheck: false` rule
402
- - do not add a rule that is not present in `lead-filter.md`
403
- - do not duplicate two rules that restate the same keep/exclude idea
404
- - use the production fields exactly: `checkName`, `description`, `criterion`,
405
- `reason`, `isRequiredCheck`, `allowPartialCredit`, and `strictMatching`
406
- - prefer 2-5 rubric criteria total; do not map every keep/exclude bullet into
407
- its own scoring row
408
- - include an explicit ability-to-pay criterion when affordability is material to
409
- fit. It may be bundled with company size/stage only when the `checkName`,
410
- `description`, and `criterion` still name the budget proxy directly.
411
- - production rubric criteria should be buyer-quality gates, not execution
412
- metadata. Do not create rubric rows for provider source, recently-posted
413
- priority, first-send ordering, or other search mechanics unless the user
414
- explicitly asks to score that as part of ICP fit.
415
- - production rubric criteria should not become one-off DNC lists. Named-company
416
- exclusions are appropriate when they represent a repeated false-positive
417
- category, a true competitor class, or a material lane risk; otherwise preserve
418
- them as DNC/suppression instructions outside the rubric JSON.
419
- - do not write "these rules are expressible as rubrics" as a substitute for the
420
- actual 2-5 item draft
421
- - bundle repeated false positives into a single exclusion criterion when they
422
- are the same kind of failure, for example vendors / competitors /
423
- wrong-side providers
424
- - keep title / role fit as its own explicit criterion with concrete pass and
425
- fail title patterns
426
- - use `allowPartialCredit: false` for hard gates where ambiguity should fail
427
- - use `strictMatching: true` only when the rule depends on exact named-account
428
- or exact-token matching
251
+ Use these as rough regression anchors, not hard pass/fail rules:
429
252
 
430
- Recommended rubric grouping:
253
+ | Lane | Typical FIT density | Archetype |
254
+ | ------------------------------------ | ------------------: | ----------------------------------------- |
255
+ | Prospeo vertical SMB | 60-80% | vertical owner/operator lists |
256
+ | Sales Nav horizontal enterprise | 40-55% | broad executive or department-owner lists |
257
+ | Sales Nav dev tools / specific infra | 30-45% | SRE, platform, engineering infrastructure |
258
+ | Signals overlay | 20-35% | topical engagement layered onto an ICP |
431
259
 
432
- - buyer authority / role fit
433
- - company / industry / provider-lane fit
434
- - economic capacity / ability to buy, when material
435
- - geography / size / stage fit, when relevant
436
- - competitor / vendor / wrong-side / repeated false-positive exclusion
437
- - one optional buyer-quality qualifier, at most, only when it changes fit scoring
438
- rather than send ordering
260
+ Interpretation:
439
261
 
440
- Rubric-readiness checklist:
262
+ - Density near the high end: source lane is probably fresh and viable.
263
+ - Density below the band: inspect whether the filter is too tight or the lane is
264
+ approaching exhaustion.
265
+ - Density dramatically below the band: likely source contamination, ICP drift,
266
+ or provider-side weakness; investigate before launch.
441
267
 
442
- - Can this rule be evaluated from `lead-sample.json`, provider row fields,
443
- enrichment, or normal public research?
444
- - Does the criterion say both what passes and what fails?
445
- - Is the reason a business rationale, not a restatement of the criterion?
446
- - Would `save_rubrics` accept this without adding missing fields?
447
- - Would `evaluate-icp-fit-enriched` have enough prospect-side data or
448
- Googleable facts to score it?
268
+ ## Decision Rules
449
269
 
450
- ## Prohibited During Phase 84
270
+ - Use `confirmed` when the source lane is viable and the rubrics are enough to
271
+ protect reply quality.
272
+ - Use `confirm-with-user` when the lane is viable but there is a real strategic
273
+ tradeoff or missing business proxy the user must choose before message
274
+ approval.
275
+ - Use `revise-find-leads` when filters would be so heavy, low-volume, or
276
+ thesis-distorting that launching from this lane would likely miss.
277
+ - Do not save rubrics for `confirm-with-user` or `revise-find-leads`.
278
+ - Do not loosen the filter just to preserve volume.
279
+ - Do not make the filter so narrow that it contradicts the approved source
280
+ unless review-batch evidence clearly requires it.
281
+
282
+ ## Prohibited During Normal Create-Campaign
451
283
 
452
284
  - calling `check_rubric`
453
- - calling `save_rubrics`
454
- - using campaign-backed rubric tools
455
285
  - creating a second independent rubric design
456
- - blocking Phase 84 when only `rubric.json` fails and `lead-filter.md` is valid
457
-
458
- ## Marketplace safety rail (two-sided archetypes)
459
-
460
- When brief §14 declares a marketplace with an explicit forbidden
461
- side-of-market (e.g. Skillsync forbids cold-outbound to supply-side
462
- GitHub contributors; the indexed pool is NEVER the outbound target),
463
- the lead-filter MUST include a forbidden-role exclude rule naming the
464
- supply-side title family.
465
-
466
- ### Enforcement at filter-write time
467
-
468
- - `lead-filter.md` Required Exclude Rules MUST contain at least one
469
- rule pattern-matching the forbidden side's title family (e.g.
470
- "exclude 'Software Engineer' / 'Staff Engineer' / GitHub
471
- contributor profile signal for Skillsync-like marketplaces").
472
- - If brief §14 declares the marketplace but the filter does NOT include
473
- the forbidden-side exclude rule, surface this as a `revise-rubric`
474
- precondition failure. Do NOT proceed to the commit gate.
475
-
476
- ### Enforcement at validate-sample time
477
-
478
- - The Plan 85-02 validate-sample loop treats `>20% of sample rows
479
- matching the brief §14 forbidden side` as a **LIST problem** (not a
480
- brief problem). Rationale: the sourced list is contaminated with
481
- the wrong side of the marketplace; operator must re-source.
482
- - Detection signal: row title/profile matches the supply-side family
483
- declared in brief §14, even if the title whitelist at §5 ICP
484
- accidentally allows it.
485
-
486
- ### Why this matters
487
-
488
- Marketplaces are the only B2B archetype where the same LinkedIn pool
489
- contains both the intended buyer and the forbidden counterparty. A
490
- marketplace operator who accidentally drafts InMail to a supply-side
491
- contributor has simultaneously:
492
-
493
- 1. Violated their own TOS with that contributor (cold InMail for a
494
- non-applied-to "hiring" pitch).
495
- 2. Leaked their own product positioning (we target engineers,
496
- implying we sell you as a vendor).
497
- 3. Poisoned the cohort's recall rate for real demand-side buyers.
498
-
499
- A filter-spec safety rail catches the drift BEFORE Step 13 import.
500
- A validate-sample signal catches the drift if it still slips through.
501
-
502
- Plan 95-07 surfaced this residual on the Skillsync walkthrough; Plan
503
- 95-08 ships the rail.
504
-
505
- ## Post-Filter Signal Enrichment Pass (Sales Nav lane)
506
-
507
- After `lead-filter.md` lands and the Pass Rate is recorded, run a bounded
508
- signal-enrichment pass on FIT rows whose primary lane is Sales Nav and
509
- whose `lead-sample.json` entry has `recent_posts.length === 0` (the
510
- Sales Nav lane does not carry post data natively).
511
-
512
- This pass directly addresses the Earned-right + Read-as-1:1 substance
513
- filters in Phase 84. Without row-level post data, the generator has
514
- nothing to quote back, forcing either (a) category-level openers that
515
- trip Read-as-1:1, or (b) presumption-led openers that trip Earned-right.
516
-
517
- Contract:
518
-
519
- - **Scope:** only FIT rows (or the top K rows when FIT count > K).
520
- - **Budget cap K:** top 10 FIT rows by score. Do NOT enrich MAYBE or
521
- REJECT rows in Phase 84 — they are not headed to messaging.
522
- - **Tool:** `mcp__sellable__fetch_linkedin_posts` (per-row call). If the
523
- tool is unavailable in the current harness, skip the pass entirely
524
- and document in Findings.
525
- - **Fetch:** the most recent 3-5 posts per row.
526
- - **Append to `lead-sample.json`:** each enriched row gets a
527
- `recent_posts[]` array with `{ url, posted_at, excerpt }` entries
528
- (200 char excerpt cap per post).
529
- - **Rows with zero public posts:** keep `recent_posts: []`. This is
530
- valid data — the absence signals "quiet-profile row, use trigger or
531
- peer-observation angle instead".
532
- - **Order of operations:** run AFTER `lead-filter.md` is written, BEFORE
533
- `message-validation.md` starts drafting. The enriched
534
- `lead-sample.json` is the input to the per-row signal extraction pass
535
- in the generator.
536
-
537
- Findings update:
538
-
539
- - Record enrichment outcome at the bottom of `lead-filter.md` under a
540
- new `## Signal Enrichment` heading: rows attempted, rows with posts,
541
- rows with zero posts, tool failures.
542
- - If more than 50% of enriched rows have zero posts, flag the sample as
543
- "low signal density" and recommend the generator's peer-observation
544
- fallback angle with the Findings-surface warning.
545
-
546
- This pass does NOT apply to:
547
-
548
- - Signals-lane rows (already carry post data natively)
549
- - Prospeo-lane rows (messaging is usually event/job-post-led, post
550
- data is secondary)
551
- - live-campaign mode (enrichment happens per-row during Research)
552
-
553
- ## Brief-Validated Rewrite Authority
554
-
555
- When `lead-review.md` shows that the Phase-83 primary lead-source picked an
556
- UNVALIDATED lane (no source-material support) AND the alternative source
557
- yields ≥ 5× FIT leads in the same sample, `brief-validated.md` may rewrite
558
- exactly two Phase-83 brief sections:
559
-
560
- - §3 Campaign Thesis — update the source-hypothesis line to reflect the
561
- higher-yielding lane as primary.
562
- - §12 Next Steps — update the first lead-search step to start on the
563
- higher-yielding lane.
564
-
565
- Every rewrite must include an evidence citation block quoting
566
- `lead-review.md`:
567
-
568
- ```md
569
- > Evidence (from lead-review.md):
570
- >
571
- > - Signals sample: 2 rows, 0 FIT
572
- > - Sales Nav sample: 25 rows, 3 FIT + 7 MAYBE
573
- > - Primary-lane reversal: Sales Nav ≥ 5× Signals FIT yield in the same
574
- > preview.
575
- ```
576
-
577
- All OTHER Phase-83 brief sections remain read-only during Phase-84. This
578
- authority is narrowly scoped to one specific failure mode — UNVALIDATED
579
- primary-source picks contradicted by real preview data. It is NOT a general
580
- brief-rewrite license. Do not use it to rewrite ICP, Buyer Pain, Offer
581
- Strategy, Social Proof, Differentiators, Message Thesis, or any other
582
- section. Those deltas continue to flow through `lead-filter.md` and
583
- `message-validation.md` as today.
584
-
585
- If the evidence is ambiguous (e.g. 2 FIT Signals vs 4 FIT Sales Nav — under
586
- 5× ratio), DO NOT rewrite. Flag the weak preference in `lead-filter.md`
587
- § Recommendation instead.
588
-
589
- ## Provider-lane expected FIT density
590
-
591
- Observed during Phase 94 + Phase 95 UAT. Use as anchor for judging whether
592
- a lane is "lane exhausted" (see `references/step-13-import-leads.md`) or
593
- genuinely weak.
594
-
595
- | Lane | Typical FIT density | Archetype examples |
596
- | ------------------------------------------ | ------------------- | ------------------------------------------------------------ |
597
- | **Prospeo** (vertical SMB) | 60-80% | Patientdesk (dental practice owners); vertical B2C-style SMB |
598
- | **Sales Nav** (horizontal enterprise) | 40-55% | Ambral (enterprise CS); Skillsync (eng-led companies) |
599
- | **Sales Nav** (dev tools / specific infra) | 30-45% | IncidentFox (SRE/Platform leaders at Series B-D SaaS) |
600
- | **Signals** (overlay — warm-scored) | 20-35% | Overlay added to any lane; rate depends on topical density |
601
-
602
- Interpretation:
286
+ - reading or writing local markdown/json progress artifacts
287
+ - inspecting the product database directly
288
+ - queueing enrichment, filtering, or Generate Message cells
289
+ - claiming filters are persisted before `save_rubrics` succeeds
603
290
 
604
- - **Density at the high end of the band** fresh lane; import cap should
605
- be aggressive (bump importLimit from 100 default to 200+ if needed).
606
- - **Density below the band** — either the filter is too tight OR the lane
607
- is approaching exhaustion (most good rows already imported in prior runs).
608
- Check dedup ratios to distinguish.
609
- - **Density dramatically below band** — likely a brief problem (ICP too
610
- narrow) or a provider-side issue. Diagnose before reruning.
611
-
612
- Plan 95-05 Patientdesk observed ~70% FIT density on Prospeo (top of band).
613
- Plan 95-03 Ambral observed ~47% on Sales Nav horizontal enterprise (mid band).
614
- Plan 95-01 IncidentFox observed ~36% on Sales Nav dev-infra (mid-low band).
615
- Plan 94-07 Skillsync observed ~32% on Signals (mid band for overlay).
616
-
617
- Use these as regression anchors: a 10%+ drop from the archetype's
618
- historical density on a lane = investigate before escalating to operator.
291
+ Workflow cell execution waits until filters are resolved, rubrics are saved when
292
+ filters are enabled, and the user approves the message template/token rules.