@sellable/mcp 0.1.144 → 0.1.145

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ import { authToolDefinitions } from "./auth.js";
2
+ import { blueprintCommitToolDefinitions } from "./blueprint-commit.js";
3
+ import { bootstrapToolDefinitions } from "./bootstrap.js";
4
+ import { campaignToolDefinitions } from "./campaigns.js";
5
+ import { cellToolDefinitions } from "./cells.js";
6
+ import { startCliLoginToolDef, waitForCliLoginToolDef } from "./cli-login.js";
7
+ import { contextToolDefinitions } from "./context.js";
8
+ import { directCampaignToolDefinitions } from "./direct-campaigns.js";
9
+ import { engageBootstrapToolDefinitions } from "./engage-bootstrap.js";
10
+ import { engageDiscoveryToolDefinitions } from "./engage-discovery.js";
11
+ import { engageMemoryToolDefinitions } from "./engage-memory.js";
12
+ import { engageStateToolDefinitions } from "./engage-state.js";
13
+ import { enrichmentToolDefinitions } from "./enrichment.js";
14
+ import { frameworkToolDefinitions } from "./framework.js";
15
+ import { leadToolDefinitions } from "./leads.js";
16
+ import { linkedinToolDefinitions } from "./linkedin.js";
17
+ import { navigationToolDefinitions } from "./navigation.js";
18
+ import { onDemandToolDefinitions } from "./one-off.js";
19
+ import { processingToolDefinitions } from "./processing.js";
20
+ import { promptToolDefinitions } from "./prompts.js";
21
+ import { readinessToolDefinitions } from "./readiness.js";
22
+ import { rowToolDefinitions } from "./rows.js";
23
+ import { rubricToolDefinitions } from "./rubrics.js";
24
+ import { senderToolDefinitions } from "./senders.js";
25
+ import { sequencerToolDefinitions } from "./sequencer.js";
26
+ import { tableToolDefinitions } from "./tables.js";
27
+ import { verifyRowToolDefinitions } from "./verify-row.js";
28
+ import { workspaceToolDefinitions } from "./workspaces.js";
29
+ export const allTools = [
30
+ ...campaignToolDefinitions,
31
+ ...authToolDefinitions,
32
+ startCliLoginToolDef,
33
+ waitForCliLoginToolDef,
34
+ ...bootstrapToolDefinitions,
35
+ ...engageBootstrapToolDefinitions,
36
+ ...engageDiscoveryToolDefinitions,
37
+ ...workspaceToolDefinitions,
38
+ ...frameworkToolDefinitions,
39
+ ...contextToolDefinitions,
40
+ ...navigationToolDefinitions,
41
+ ...leadToolDefinitions,
42
+ ...enrichmentToolDefinitions,
43
+ ...processingToolDefinitions,
44
+ ...rubricToolDefinitions,
45
+ ...readinessToolDefinitions,
46
+ ...rowToolDefinitions,
47
+ ...cellToolDefinitions,
48
+ ...promptToolDefinitions,
49
+ ...linkedinToolDefinitions,
50
+ ...onDemandToolDefinitions,
51
+ ...directCampaignToolDefinitions,
52
+ ...senderToolDefinitions,
53
+ ...engageStateToolDefinitions,
54
+ ...engageMemoryToolDefinitions,
55
+ ...sequencerToolDefinitions,
56
+ ...tableToolDefinitions,
57
+ ...blueprintCommitToolDefinitions,
58
+ ...verifyRowToolDefinitions,
59
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.144",
3
+ "version": "0.1.145",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -152,13 +152,14 @@ For Signal Discovery, the customer-facing approval card must use the exact
152
152
  action shape "Approve scraping N Signal Discovery posts?" and the chat summary
153
153
  should be a compact `## Source Recommendation` block with:
154
154
 
155
- - goal: about 300 good-fit prospects after cleanup, enrichment, and filters
156
- - working assumption: about 15% of raw post engagers become good-fit prospects
157
- - engagers needed: about 2,000 raw engagers
155
+ - good-fit target: about 150 prospects after cleanup, enrichment, and filters
156
+ - source-candidate plan: about 1,000 raw engagers using a conservative 15%
157
+ fit-rate assumption unless sampled data supports a different number
158
+ - review checkpoint: import the first 25 leads for fit and message review
158
159
  - a selected-post table with post author/topic, why it fits, and visible
159
160
  engagement
160
161
  - total visible pool and estimated good-fit pool
161
- - first pass: build the source list, then import only 15 leads into the review
162
+ - first pass: build the source list, then import only the review
162
163
  batch
163
164
  - fallback: switch to Sales Nav recent activity if the review batch is
164
165
  vendor-heavy, agency-heavy, or off-ICP
@@ -251,7 +252,7 @@ After every `update_campaign({ campaignId, currentStep })`, use
251
252
  `get_campaign_navigation_state` when available as a compact orientation check:
252
253
  match the saved campaign state to the expected watch-link step, explain the
253
254
  current state in one sentence, and only then continue. Sender selection belongs
254
- at Settings after message approval and 15-row validation. After message
255
+ at Settings after message approval and review-batch validation. After message
255
256
  validation, use Settings to help the user connect or select a LinkedIn sender.
256
257
  Explain Slack reply review before launch. After sender selection, attach the
257
258
  recommended sequence and move the watched UI to Send. Do not start the campaign
@@ -614,9 +615,9 @@ updates.
614
615
  until `hasMore=false`. The create-campaign message-review safety gate is a
615
616
  supplemental approval checklist, not a replacement for the long prompt. Use
616
617
  campaign state, campaign brief content, selected source state, and imported
617
- review-batch rows as the source of truth; do not read stale local markdown,
618
- inspect the database directly, or synthesize local validation artifacts from
619
- general knowledge.
618
+ review-batch rows as the source of truth; do not read stale local markdown
619
+ such as `message-validation.md`, inspect the database directly, or synthesize
620
+ local validation artifacts from general knowledge.
620
621
  5. Create the campaign shell early with the v1 brief so the user can open the
621
622
  watch link and see useful setup state immediately. Import only the first
622
623
  bounded review batch after the source is attached to the campaign; do not
@@ -640,7 +641,7 @@ updates.
640
641
  `mcp__sellable__update_campaign({ campaignId, currentStep })` before major
641
642
  visible work so the user can watch progress in the app: `create-offer` for
642
643
  the brief, `pick-provider` or the selected provider step while sourcing,
643
- `filter-choice` after the 15-row review batch, `create-icp-rubric` as soon
644
+ `filter-choice` after the review batch, `create-icp-rubric` as soon
644
645
  as filters are approved, `apply-icp-rubric` after rubrics save and while
645
646
  waiting for message-template approval, `validate-sample` while the approved
646
647
  template unlocks bounded enrichment/filter scoring on Filter Leads,
@@ -167,9 +167,9 @@ selected posts exist:
167
167
 
168
168
  Use Signal Discovery first.
169
169
 
170
- **Goal:** ~300 good-fit prospects after cleanup, enrichment, and filters<br>
171
- **Working assumption:** ~15% of raw post engagers become good-fit prospects<br>
172
- **Engagers needed:** ~2,000 raw engagers
170
+ **Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
171
+ **Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
172
+ **Review checkpoint:** import the first 25 leads into the campaign for fit and message review before scaling<br>
173
173
 
174
174
  ### Selected posts
175
175
 
@@ -186,12 +186,12 @@ Use Signal Discovery first.
186
186
 
187
187
  Approve scraping these 3 posts.
188
188
 
189
- This gives enough volume to target ~300 good-fit prospects after cleanup, while
189
+ This gives enough volume to work toward ~150 good-fit prospects, while
190
190
  keeping the source tied to people already engaging with Claude Code outbound /
191
191
  AI-native sales workflows.
192
192
 
193
- **First pass:** build the source list, then import only 15 leads into the
194
- review batch so we can inspect quality before scaling.
193
+ **First pass:** build the source list, then import only the 25-lead review
194
+ batch so we can inspect fit and messages before scaling.
195
195
 
196
196
  **Fallback:** if the review batch is too vendor-heavy, agency-heavy, or
197
197
  off-ICP, switch to Sales Nav recent activity.
@@ -238,8 +238,8 @@ for source approval before import.
238
238
 
239
239
  For Signal Discovery, the second gate is not "approve source" in the abstract.
240
240
  It is a concrete scrape approval: show a compact `## Source Recommendation`
241
- with the ~300 good-fit prospect goal, 15% raw-engager assumption, selected-post
242
- table, total visible pool, estimated good-fit pool, first-pass 15-row review
241
+ with the ~150 good-fit prospect goal, 15% raw-engager assumption, selected-post
242
+ table, total visible pool, estimated good-fit pool, first-pass review
243
243
  batch, and fallback. The approval question should be "Approve scraping N Signal
244
244
  Discovery posts?"
245
245
 
@@ -33,16 +33,16 @@ the imported review batch for validation).
33
33
 
34
34
  - **`sampleSize`** — How many rows the validation loop pulls from the
35
35
  imported review batch. In v2 this matches the review-batch cap
36
- (default 15), so the user sees enough real rows to judge the campaign
36
+ (default 25), so the user sees enough real rows to judge the campaign
37
37
  without spending credits on hundreds more.
38
38
  - **`minProjectedPass`** — Passing-message floor required before handoff.
39
- The default requires 3 passing examples from the 15-row review batch.
39
+ The default requires 5 passing examples from the 25-row review batch.
40
40
  Math:
41
41
  ```text
42
42
  projectedPass = round(passInSample / sampleSize * importLimit)
43
43
  ```
44
- With defaults (sampleSize=15, importLimit=15), `projectedPass` equals
45
- the actual review-batch pass count. 3 passing rows is exactly at the
44
+ With defaults (sampleSize=25, importLimit=25), `projectedPass` equals
45
+ the actual review-batch pass count. 5 passing rows is exactly at the
46
46
  floor.
47
47
  - **`maxRevisionRounds`** — Hard cap before escalating to the user. A
48
48
  revision round is one full sample pass that triggered brief revision
@@ -17,7 +17,7 @@ import:
17
17
  # Initial review batch imported in Step 13 before the sample validation
18
18
  # loop. Import + enrichment must never exceed this cap before the user
19
19
  # reviews the sample and explicitly asks to expand.
20
- importLimit: 15
20
+ importLimit: 25
21
21
  # Provider is inherited from the campaign-attached source association created
22
22
  # during find-leads. Step 13 may re-run provider preflight in memory, but it
23
23
  # does not choose a new source.
@@ -27,11 +27,11 @@ sample:
27
27
  # Rows pulled from the imported cohort for the validation loop. In v2 this
28
28
  # equals the review-batch cap so the user sees a focused first test batch
29
29
  # without spending credits on hundreds of rows.
30
- sampleSize: 15
30
+ sampleSize: 25
31
31
  # Projected first-batch passing count required to proceed to sample
32
32
  # messaging. This is not approval to scale the full source list.
33
33
  # projectedPass = round(passInSample / sampleSize * importLimit).
34
- minProjectedPass: 3
34
+ minProjectedPass: 5
35
35
  # Hard cap on revision loops before escalating to the user. On a stale
36
36
  # resume the counter does NOT reset — the 3-round cap holds across
37
37
  # sessions.
@@ -106,7 +106,7 @@ handoff:
106
106
  # Orientation surfaced in Step 16 ("awaiting-user-greenlight") along with
107
107
  # the watch link. Keep this short and user-facing.
108
108
  orientation: >-
109
- Review the first 15 enriched leads and messages. If they look good,
109
+ Review the first 25 enriched leads and messages. If they look good,
110
110
  attach a sender in Settings, accept the recommended sequence, and start
111
111
  the campaign without spending credits on more leads first.
112
112
 
@@ -460,7 +460,7 @@
460
460
  "requiredInlineFields": [
461
461
  "primary source and exact filters/recipe",
462
462
  "specific source action awaiting approval",
463
- "for Signal Discovery: Source Recommendation markdown with goal ~300 good-fit prospects, ~15% raw-engager fit assumption, ~2,000 raw engagers needed, selected-post table, total visible pool, estimated good-fit pool, first pass, and fallback",
463
+ "for Signal Discovery: Source Recommendation markdown with ~150 good-fit prospects as the target, source-candidate plan ~1,000 raw engagers at a conservative ~15% fit assumption, review checkpoint size, selected-post table, total visible pool, estimated good-fit pool, first pass, and fallback",
464
464
  "for Signal Discovery: selected post count and target engager/source-candidate volume",
465
465
  "bounded review batch size",
466
466
  "runner-up and why it lost",
@@ -541,7 +541,7 @@
541
541
  "importLimit"
542
542
  ],
543
543
  "requiredValues": {
544
- "importLimit": 15
544
+ "importLimit": 25
545
545
  },
546
546
  "modeAddHandshake": {
547
547
  "firstCallReturns": "needsModeSelection when adding to an existing campaign-attached list",
@@ -15,7 +15,7 @@ packet.
15
15
 
16
16
  The approval gate used to be the place where the user authorized
17
17
  spend/send-adjacent mutation. It is now compatibility-only. New runs import the
18
- bounded 15-row review batch after source approval, save rubrics and the approved
18
+ bounded review batch after source approval, save rubrics and the approved
19
19
  message template after post-import review, and only then queue the cascade.
20
20
 
21
21
  If `campaign-shell.json` exists, a draft `CampaignOffer` row already exists but
@@ -174,6 +174,14 @@ If more than roughly 20% of the review batch appears to be the forbidden side,
174
174
  classify it as a list/source problem and return `revise-find-leads`; do not
175
175
  hide that problem behind narrow rubrics.
176
176
 
177
+ ## Suppression And Relationship Safety
178
+
179
+ Do not put DNC or one-off relationship-safety notes into production rubrics
180
+ unless the review batch shows that the pattern will leak at meaningful volume
181
+ and normal DNC/domain suppression will not catch it. Former employers, existing
182
+ customers, investors, partner lists, and one-off do-not-contact domains usually
183
+ belong in the recommendation as DNC/suppression instructions outside the rubric JSON.
184
+
177
185
  ## Production Rubric Shape
178
186
 
179
187
  Confirmed rubrics must use the production `LeadScoringRubric` fields exactly:
@@ -265,6 +273,40 @@ Interpretation:
265
273
  - Density dramatically below the band: likely source contamination, ICP drift,
266
274
  or provider-side weakness; investigate before launch.
267
275
 
276
+ ## Post-Filter Signal Enrichment Pass (Sales Nav lane)
277
+
278
+ Run this only for Sales Nav FIT rows when the downstream message step does not
279
+ already have row-level post evidence. In normal campaign-backed runs, use live
280
+ campaign-table row state as the source of truth. In explicit debug/UAT artifact
281
+ flows, append the diagnostic copy back to `lead-sample.json`.
282
+
283
+ This pass exists to protect the Earned-right and Read-as-1:1 substance filters.
284
+ Without row-level posts, message generation is likely to fall back to generic
285
+ category openers or presumed intent instead of evidence the recipient can
286
+ recognize.
287
+
288
+ Contract:
289
+
290
+ - scope: Sales Nav FIT rows only; do not enrich MAYBE or REJECT rows for this
291
+ pass
292
+ - budget cap: top 10 FIT rows by filter score
293
+ - tool: `mcp__sellable__fetch_linkedin_posts`, called per row
294
+ - fetch: most recent 3-5 public posts when available
295
+ - target surface: store each result as `recent_posts[]` entries with
296
+ `{ url, posted_at, excerpt }`; keep `recent_posts: []` for quiet profiles
297
+ - order of operations: run AFTER `lead-filter.md` is written, BEFORE
298
+ `message-validation.md` starts drafting
299
+
300
+ Record enrichment outcome in the filter summary: rows attempted, rows with
301
+ posts, rows with zero public posts, and tool failures. If more than half of the
302
+ attempted rows have zero posts, flag low signal density and tell message
303
+ generation to prefer trigger, peer-observation, or non-post proof instead of a
304
+ post-quote opener.
305
+
306
+ Do not convert "recently posted" or post availability into an ICP fit rubric.
307
+ The posts are message evidence only; buyer qualification still comes from role,
308
+ authority, account fit, capacity, geography, and exclusions.
309
+
268
310
  ## Decision Rules
269
311
 
270
312
  - Use `confirmed` when the source lane is viable and the rubrics are enough to
@@ -6,7 +6,7 @@ on every revision round.
6
6
 
7
7
  ## Principle
8
8
 
9
- We spend a bounded review batch (default 15 rows) to prove fit before the
9
+ We spend a bounded review batch (default 25 rows) to prove fit before the
10
10
  user spends credits on hundreds more leads. The sample loop has one job:
11
11
  answer the question "do we have enough real passing examples for the user to
12
12
  judge this campaign?" Message generation starts earlier: the first row that
@@ -23,7 +23,7 @@ auto-revise leads.
23
23
  - `CampaignOffer.currentStep === "apply-icp-rubric"` (the watched app is
24
24
  already on Filter Leads after `save_rubrics`; `validate-sample` is the
25
25
  logical loop name, not a visible route)
26
- - Imported review batch from Step 13 (size: `importLimit`, default 15)
26
+ - Imported review batch from Step 13 (size: `importLimit`, default 25)
27
27
  - Config from `auto-execute.yaml`: `sample.sampleSize`,
28
28
  `sample.minProjectedPass`, `sample.maxRevisionRounds`
29
29
  - Persisted counter `revisionRound` (starts at 0 on first entry; persists
@@ -56,7 +56,7 @@ auto-revise leads.
56
56
  6. wait_for_rubric_results(sample, targetCount = <cohortSize>, minPassedCount = 1)
57
57
  - cohortSize = stats.totalRows of the enrichment batch, or the
58
58
  imported batch count
59
- - default targetCount=15 matches the default review batch, but pass the
59
+ - default targetCount=25 matches the default review batch, but pass the
60
60
  explicit batch count anyway so future larger expansion batches do not
61
61
  accidentally stop early
62
62
  (see §Known Tool Behaviors #3)
@@ -172,8 +172,8 @@ company, enrichCellId, enrichStatus) over the default shape.
172
172
 
173
173
  ### 5. `wait_for_rubric_results` can timeout with enough signal to decide
174
174
 
175
- Observed: a 15-row review batch may return `ready=false`, `reason="timeout"`,
176
- and partial stats such as 13/15 scored, 2 passing, 2 messages generated. That is
175
+ Observed: a 25-row review batch may return `ready=false`, `reason="timeout"`,
176
+ and partial stats such as 20/25 scored, 4 passing, 4 messages generated. That is
177
177
  enough to diagnose an underperforming sample. Waiting again without active
178
178
  processing makes the experience feel frozen.
179
179
 
@@ -190,16 +190,16 @@ once only if active processing is still visible.
190
190
  projectedPass = round(passInSample / sampleSize * importLimit)
191
191
  ```
192
192
 
193
- Worked examples with defaults (sampleSize=15, importLimit=15):
193
+ Worked examples with defaults (sampleSize=25, importLimit=25):
194
194
 
195
- | passInSample | projectedPass | Handoff? (minProjectedPass=3) |
195
+ | passInSample | projectedPass | Handoff? (minProjectedPass=5) |
196
196
  | ------------ | ------------- | ----------------------------- |
197
197
  | 0 | 0 | No — escalate or revise |
198
- | 2 | 2 | No — escalate or revise |
199
- | 3 | 3 | Yes — exactly at floor |
200
- | 4 | 4 | Yes |
198
+ | 3 | 3 | No — escalate or revise |
199
+ | 5 | 5 | Yes — exactly at floor |
200
+ | 8 | 8 | Yes |
201
201
  | 10 | 10 | Yes |
202
- | 15 | 15 | Yes |
202
+ | 25 | 25 | Yes |
203
203
 
204
204
  When non-default importLimit/sampleSize are configured, the math scales
205
205
  the same way. In the default review-batch mode, the sample size equals the
@@ -263,8 +263,8 @@ rate is zero with no pattern that brief editing could fix.
263
263
 
264
264
  Signal examples:
265
265
 
266
- - 15/15 rows are wrong function / wrong seniority / wrong geo.
267
- - 12/15 rows enrich to empty strings for the tokens the brief needs.
266
+ - 25/25 rows are wrong function / wrong seniority / wrong geo.
267
+ - 20/25 rows enrich to empty strings for the tokens the brief needs.
268
268
  - Rubric passes 0 rows and the failure reasons are all "not ICP."
269
269
  - **Marketplace supply-side contamination:** >20% of sample rows match
270
270
  the brief §14 forbidden side (e.g. Skillsync sample contains
@@ -55,7 +55,7 @@ Supported branches:
55
55
  `import_leads({ campaignOfferId })` for Signal Discovery unless selected posts
56
56
  already exist on the campaign. Provider import materializes the source lead
57
57
  list from the approved source-capacity plan; it is not the same target as the
58
- 15-row campaign review batch.
58
+ default 25-row campaign review batch.
59
59
  - **Supplied LinkedIn profile CSV** — confirm `load_csv_linkedin_leads` only
60
60
  after rubrics and the approved message set are ready. Batch/materialize the
61
61
  uploaded CSV into a Sellable lead-list table. Persist the returned
@@ -106,9 +106,9 @@ fills the source lead list; it does **not** clone rows into the campaign table:
106
106
  ```text
107
107
  import_leads({
108
108
  campaignOfferId,
109
- targetLeadCount: <sourceTargetGoodFitLeads; default 300>,
109
+ targetLeadCount: <sourceCandidateTarget; provider default>,
110
110
  // Signal Discovery only:
111
- targetEngagerCount: <ceil(sourceTargetGoodFitLeads / sampledFitRateAfterCleanup)>,
111
+ targetEngagerCount: <ceil(targetGoodFitLeads / sampledFitRateAfterCleanup)>,
112
112
  maxPostsToScrape: <postsNeeded from approved math>
113
113
  })
114
114
  ```
@@ -120,9 +120,12 @@ so dedup ratios are visible.
120
120
 
121
121
  For Signal Discovery, do not scrape every currently selected/promoted sample
122
122
  post by default. Before `import_leads`, reconcile selected posts with the
123
- approved source math. If the math says 20 good fits per 100 engagers and the
124
- source target is 300 good-fit leads, pass `targetEngagerCount` around 1,500 and
125
- only enough posts to reach that engager count. The subsequent
123
+ approved source math. The default good-fit target is 150 and the conservative
124
+ fallback fit rate is 15%, so the default source-candidate plan is about 1,000
125
+ raw engagers. If the sampled fit rate is stronger or weaker, use the sampled
126
+ rate with a conservative cleanup factor, cap the source candidates at the
127
+ approved provider limit, and select only enough posts to reach that engager
128
+ count. The subsequent
126
129
  `confirm_lead_list` call still uses `targetLeadCount: <importLimit>` so only the
127
130
  bounded review batch enters the campaign table.
128
131
 
@@ -178,8 +178,8 @@ Source approved and import starting:
178
178
  {
179
179
  "stage": "review-batch",
180
180
  "headline": "Importing the review batch",
181
- "visibleState": "The browser is still showing the approved LinkedIn Engagement source leads.",
182
- "agentIntent": "Codex is importing only the bounded 15-row review batch into the campaign now.",
181
+ "visibleState": "The browser is still showing the approved LinkedIn Engagement source candidates.",
182
+ "agentIntent": "Codex is importing only the bounded review batch into the campaign now.",
183
183
  "nextAction": "Review batch ready"
184
184
  }
185
185
  ```
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: load-voice
3
+ description: Load Sellable voice/company memory before answering questions, writing posts, applications, replies, or other copy in the user's voice.
4
+ visibility: public
5
+ allowed-tools:
6
+ - Read
7
+ - Glob
8
+ - Grep
9
+ ---
10
+
11
+ # Load Sellable Voice
12
+
13
+ <role>
14
+ You are the Sellable voice loader. Your job is to read the user's durable
15
+ Sellable voice/company memory into the current thread before drafting,
16
+ answering, rewriting, reviewing, or calibrating copy in the user's voice.
17
+
18
+ This is a read-only usage workflow. Do not interview by default, do not write
19
+ memory files, and do not update `.sellable/**` unless the user explicitly asks
20
+ to switch into `$sellable:interview`.
21
+ </role>
22
+
23
+ <default_use_cases>
24
+ Use this workflow when the user asks to:
25
+
26
+ - answer questions on behalf of them
27
+ - write or rewrite a LinkedIn post
28
+ - answer an application, investor, customer, or sales question
29
+ - draft a sales reply, objection response, cold note, or website line
30
+ - review whether copy sounds like them
31
+ - "use my voice", "load my voice", "answer like me", or "write this as me"
32
+ </default_use_cases>
33
+
34
+ <load_order>
35
+ Read only relevant files. Start with the active `.sellable/configs` memory
36
+ layer, not random repo docs.
37
+
38
+ If `.sellable/configs` is not visible from the current working directory, use
39
+ `Glob` to find `**/.sellable/configs/core/my-company.md`, excluding
40
+ `node_modules`, `.next`, `dist`, and `.git`, then use the nearest parent as the
41
+ Sellable memory root.
42
+
43
+ ## Core Voice And Judgment
44
+
45
+ Read these when present:
46
+
47
+ - `.sellable/configs/core/about-me.md`
48
+ - `.sellable/configs/core/anti-ai-writing-style.md`
49
+ - `.sellable/configs/core/decision-rules.md`
50
+ - `.sellable/configs/core/context-modes.md`
51
+
52
+ ## Company Truth And Proof
53
+
54
+ Read these when present:
55
+
56
+ - `.sellable/configs/core/my-company.md`
57
+ - `.sellable/configs/core/answer-bank.md`
58
+ - `.sellable/configs/core/proof-ledger.md`
59
+ - `.sellable/configs/core/story-bank.md`
60
+ - `.sellable/configs/core/wins-ledger.md`
61
+
62
+ ## Writing-Specific Guidance
63
+
64
+ Read these when present and relevant to the task:
65
+
66
+ - `.sellable/configs/writing/styleguide-core.md`
67
+ - `.sellable/configs/writing/comments.md`
68
+
69
+ ## Transcript Or Topic Context
70
+
71
+ Do not bulk-read raw transcripts. If the user asks about a specific topic,
72
+ story, sales call, customer, market view, or correction, first read:
73
+
74
+ - `.sellable/configs/core/transcripts/INDEX.md`
75
+ - the most relevant file under `.sellable/configs/core/transcripts/topics/`
76
+
77
+ Only read raw archives under `.sellable/interviews/**` when the index/topic file
78
+ points to one and the current task needs that source detail.
79
+ </load_order>
80
+
81
+ <operating_rules>
82
+
83
+ - Keep the loader lightweight. The first pass should usually be 6-10 files, not
84
+ every file under `.sellable`.
85
+ - Apply the loaded profile silently after a short confirmation. Do not paste a
86
+ long summary of the memory unless the user asks for one.
87
+ - If the user already gave a concrete writing task, load the memory and then do
88
+ the task. Do not stop at "I loaded the files."
89
+ - If the user only asked to load voice, say what you loaded, name the strongest
90
+ active rules in 3-6 bullets, then ask what they want drafted, answered, or
91
+ reviewed.
92
+ - If exact proof, numbers, customer names, or timelines are not confirmed in
93
+ the loaded memory, preserve that uncertainty. Do not launder uncertain proof
94
+ into clean claims.
95
+ - Use the current `context-modes.md` behavior for the requested surface:
96
+ LinkedIn post, sales reply, website, investor/application answer, outbound, or
97
+ internal strategy.
98
+ - When answering on behalf of the user, write in first person unless the user
99
+ asks otherwise.
100
+ - If a question cannot be answered from memory, make the smallest honest
101
+ assumption or ask one specific follow-up. Do not invent private history,
102
+ metrics, customer facts, or beliefs.
103
+ - If the user says the output is wrong, ask what feels off and accept messy
104
+ dictated notes. Use that correction in the current thread. If they want the
105
+ correction saved durably, route them to `$sellable:interview`.
106
+ </operating_rules>
107
+
108
+ <response_shape>
109
+ After loading memory, use this shape when there is no concrete draft task yet:
110
+
111
+ ```text
112
+ I loaded your Sellable voice/company memory from {n} files. I’ll apply it
113
+ silently unless you override it.
114
+
115
+ The active rules I’m carrying forward:
116
+ - ...
117
+
118
+ What should I answer, write, or review?
119
+ ```
120
+
121
+ When there is already a concrete task, keep the confirmation to one sentence,
122
+ then produce the answer or draft.
123
+ </response_shape>
124
+
125
+ <quality_bar>
126
+ The result should feel like the user has a standing voice file in the thread:
127
+ specific, current, proof-safe, and ready to answer on their behalf without
128
+ forcing them to re-explain the same voice/company context every time.
129
+ </quality_bar>
@@ -62,7 +62,8 @@ search_prospeo({
62
62
  - Pass `searchId` on subsequent pages to paginate.
63
63
  - Use `import_leads` with `provider: \"prospeo\"` and the `searchId` to create a lead list and start import.
64
64
  - **IMPORTANT:** If `import_leads` returns `needsModeSelection: true`, use `AskUserQuestion` to ask "add to existing leads or replace?" Do NOT assume.
65
- - After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and `targetLeadCount` from `import_leads` to import into the campaign table.
65
+ - Default source target is 300+ good-fit leads, capped at 2,500 source candidates for now.
66
+ - After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and the review-batch `targetLeadCount` from the active campaign defaults to import only the review batch into the campaign table.
66
67
  - `import_leads` owns the watched move to `confirm-lead-list` after a lead list/job exists.
67
68
  - `confirm_lead_list` owns the watched move to `filter-choice` after the bounded review batch exists.
68
69
  - Post-confirm readback order is required:
@@ -349,9 +349,9 @@ Step 4 - Final Search + Confirm:
349
349
  What would you like?"
350
350
 
351
351
  User: "Save it"
352
- → import_leads({campaignOfferId: "cmp_xxx", searchId: "search_xxx", targetLeadCount: 100})
352
+ → import_leads({campaignOfferId: "cmp_xxx", searchId: "search_xxx", targetLeadCount: 300})
353
353
  → (wait for lead list to finish, ask user to confirm)
354
- → confirm_lead_list({campaignOfferId: "cmp_xxx", jobId: "<jobId from import_leads>", targetLeadCount: 100})
354
+ → confirm_lead_list({campaignOfferId: "cmp_xxx", jobId: "<jobId from import_leads>", targetLeadCount: 25})
355
355
  → wait_for_campaign_table_ready({campaignId: "cmp_xxx"})
356
356
  → get_campaign_context({campaignId: "cmp_xxx", refresh: true}) + get_rows_minimal(...)
357
357
  </iteration_example>
@@ -382,6 +382,8 @@ User: "Save it"
382
382
  <limits>
383
383
  - 25 results per page
384
384
  - Maximum 100 pages (2,500 leads)
385
+ - Default source target: 300+ good-fit leads, capped at 2,500 source
386
+ candidates for now
385
387
  - Maximum 5 search calls per session
386
388
  - If user needs more than 2,500: explain limit, suggest splitting by region
387
389
  </limits>