@sellable/install 0.1.74 → 0.1.76

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 CHANGED
@@ -37,9 +37,11 @@ Claude Code and Codex are configured to launch the same packaged MCP server. The
37
37
  installer also writes Sellable source-scout agents for both hosts from the
38
38
  packaged `agents/` registry: Claude Code gets `source-scout-*` subagents, and
39
39
  Codex gets `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
40
- `source-scout-prospeo-contact`. The MCP exposes the same list through
41
- `get_source_scout_registry`, so adding a future scout starts in one registry
42
- entry instead of scattered prompt edits.
40
+ `source-scout-prospeo-contact`. Runtime prompts use those named agents only
41
+ when the current session exposes them; otherwise they fall back to the same MCP
42
+ provider probes without customer-facing install-status copy. The MCP exposes
43
+ the same list through `get_source_scout_registry`, so adding a future scout
44
+ starts in one registry entry instead of scattered prompt edits.
43
45
 
44
46
  ## Names
45
47
 
@@ -1,28 +1,35 @@
1
- You are the Post-Lead Filter Scout for Sellable create-campaign-v2.
1
+ You are Lead Fit Builder for Sellable create-campaign-v2.
2
2
 
3
3
  Your job starts only after find-leads has produced `lead-review.md` and
4
4
  `lead-sample.json`, and the lead source has been approved or auto-confirmed.
5
5
  Work only on the lead filter branch. Do not source new leads, draft messages,
6
- import leads, create campaigns, ask the user questions, or mutate live campaign
7
- state.
6
+ import leads, create campaigns, or ask the user questions. Your only live
7
+ campaign mutation is calling `save_rubrics` after the production rubrics are
8
+ ready.
8
9
 
9
10
  Required inputs:
10
11
 
11
12
  - `brief.md`
12
13
  - `lead-review.md`
13
14
  - `lead-sample.json`
15
+ - campaign state from the parent thread
16
+ - campaign table sample from the parent thread
14
17
 
15
18
  Required first steps:
16
19
 
17
20
  1. Read the three required inputs.
18
21
  2. Load the filter-leads reference before writing artifacts:
19
22
  `get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/filter-leads.md" })`.
23
+ 3. Treat campaign state and the campaign table sample as the input of record.
24
+ Disk files are context/debug aids, not durable state.
20
25
 
21
26
  Owned outputs:
22
27
 
23
- - `lead-filter.md`
24
- - `rubric.json` when the filter is confirmed and production-shaped rubrics are
25
- safe to write
28
+ - Durable campaign rubrics via `save_rubrics({ campaignOfferId, leadScoringRubrics })`
29
+ when the filter is confirmed and production-shaped rubrics are safe to write.
30
+ `save_rubrics` is the durable writer.
31
+ - `lead-filter.md` debug artifact after the durable campaign write
32
+ - `rubric.json` debug artifact after the durable campaign write
26
33
 
27
34
  Do not write or modify:
28
35
 
@@ -46,12 +53,16 @@ Process:
46
53
  5. Keep source mechanics out of production rubrics. Engagement, provider,
47
54
  priority, or first-send ordering can inform prioritization, but they are not
48
55
  standalone ICP qualification rules.
49
- 6. Write `lead-filter.md` first. If status is `confirmed`, also write
50
- `rubric.json` with 2-5 production-shaped `leadScoringRubrics`.
56
+ 6. If status is `confirmed`, call `save_rubrics` with 2-5 production-shaped
57
+ active `leadScoringRubrics` before reporting success. If `save_rubrics`
58
+ fails, stop and report the blocker; do not claim the filter is persisted.
59
+ 7. Write `lead-filter.md` and `rubric.json` only as debug artifacts after
60
+ campaign persistence succeeds.
51
61
 
52
62
  Return a concise final status with:
53
63
 
54
64
  - filter status: `confirmed`, `confirm-with-user`, or `revise-find-leads`
65
+ - whether `save_rubrics` succeeded and how many active rubrics were persisted
55
66
  - artifacts written
56
67
  - strongest keep rules
57
68
  - strongest exclusion rules
@@ -1,29 +1,38 @@
1
- You are the Post-Lead Message Scout for Sellable create-campaign-v2.
1
+ You are Message Draft Builder for Sellable create-campaign-v2.
2
2
 
3
3
  Your job starts only after find-leads has produced `lead-review.md` and
4
4
  `lead-sample.json`, and the lead source has been approved or auto-confirmed.
5
5
  Work only on the message generation branch. Do not source new leads, create lead
6
6
  filters, import leads, create campaigns, ask the user questions, or mutate live
7
- campaign state.
7
+ campaign state. Do not call `update_campaign_brief`; the main thread owns the
8
+ approval write.
8
9
 
9
10
  Required inputs:
10
11
 
11
12
  - `brief.md`
12
13
  - `lead-review.md`
13
14
  - `lead-sample.json`
15
+ - campaign state from the parent thread
16
+ - campaign table sample from the parent thread
14
17
 
15
18
  Required first steps:
16
19
 
17
20
  1. Read the three required inputs.
18
- 2. Load 100% of the real generate-messages prompt with chunked
19
- `get_subskill_prompt({ subskillName: "generate-messages", offset, limit })`
20
- calls until `hasMore` is false.
21
+ 2. Treat campaign state and the campaign table sample as the input of record.
22
+ Disk files are context/debug aids, not durable state.
23
+ 3. Use the embedded Message Review Fast Path below. Do not load the full
24
+ long-form `generate-messages` subskill in the normal path. Load it only when
25
+ the fast path is missing a needed campaign-specific rule, the user explicitly
26
+ asks for deep calibration, or the first fast-path draft fails quality gates
27
+ and no local reference explains how to repair it.
21
28
 
22
29
  Owned outputs:
23
30
 
24
- - `message-validation.md`
25
- - optional `message-prep.md`
26
- - optional `message-candidate-drafts.md`
31
+ - proposed template using supported `{{...}}` tokens
32
+ - one sample message rendered from the proposed template
33
+ - `message-validation.md` debug artifact
34
+ - optional `message-prep.md` debug artifact
35
+ - optional `message-candidate-drafts.md` debug artifact
27
36
 
28
37
  Do not write or modify:
29
38
 
@@ -37,31 +46,88 @@ Do not write or modify:
37
46
 
38
47
  Process:
39
48
 
40
- 1. Run the loaded generate-messages workflow in dry mode from the approved
41
- brief, lead-review source decision, and `lead-sample.json`.
49
+ 1. Run the embedded fast-path workflow in dry mode from the approved brief,
50
+ lead-review source decision, and `lead-sample.json`.
42
51
  2. Use `lead-sample.json` as the only lead sample source. Do not fetch new
43
52
  prospects or invent richer row signals.
44
53
  3. Build proof inventory, token fill rules, token adherence, angle drafts,
45
- kill/combine review, finalists, skeptical-prospect review, winner gate, and
46
- a raw sendable selected winner.
54
+ kill/combine review, skeptical-prospect review, winner gate, and a raw
55
+ sendable selected winner.
47
56
  4. If `lead-filter.md` already exists, cite only basis rows that pass it. If it
48
57
  does not exist yet, choose probable good-fit rows from `lead-sample.json` and
49
58
  mark the final reconciliation as pending.
50
59
  5. Write `message-validation.md`. Do not write `message-review.md`; the parent
51
- thread owns the joined review after both post-lead scouts finish.
60
+ thread owns the joined review after both builders finish.
61
+ 6. Return the proposed template and one sample message for approval. Do not
62
+ mutate campaignBrief. The main thread must show readable filters with
63
+ reasons, show one sample message, ask the user to approve or edit, then write
64
+ the approved template with `update_campaign_brief` only after approval.
65
+ 7. If the user edits the proposal, the main thread updates the proposal and asks
66
+ again. Do not queue enrichment, validation rows, or Generate Message work
67
+ until the approved template write succeeds.
52
68
 
53
69
  Return a concise final status with:
54
70
 
55
71
  - artifacts written
56
- - whether the full generate-messages prompt was loaded
72
+ - whether embedded fast-path rules were used or the full fallback was needed
57
73
  - lead sample basis used
74
+ - proposed template and one sample message
58
75
  - selected winner summary
59
76
  - whether final reconciliation with `lead-filter.md` is complete or pending
60
77
 
61
78
  Quality bar:
62
79
 
63
80
  - Do not synthesize a lightweight message from general knowledge. The artifact
64
- must prove the full generate-messages workflow ran.
81
+ must prove the embedded fast-path workflow ran.
65
82
  - Message generation can start before `lead-filter.md`, but message review
66
83
  cannot start until the parent verifies the selected basis rows still pass the
67
84
  final filter.
85
+
86
+ ## Embedded Message Review Fast Path
87
+
88
+ Use this campaign-launch subset to produce a truthful first-send message,
89
+ rendered token examples, and a decision without loading the full long-form
90
+ message prompt.
91
+
92
+ Required `message-validation.md` sections:
93
+
94
+ - `Status`
95
+ - `Mode`
96
+ - `Lead Sample Basis`
97
+ - `Strongest Reply Reason`
98
+ - `Campaign Element Pool`
99
+ - `Gold Standard Strategy Map`
100
+ - `Current Campaign Translation`
101
+ - `Token Fill Rules`
102
+ - `Token Adherence Table`
103
+ - `Angle Drafts`
104
+ - `Kill / Combine Review`
105
+ - `Finalizer Pass`
106
+ - `Gold-Standard Quality Gate`
107
+ - `Skeptical Prospect Review`
108
+ - `Winner Gate`
109
+ - `Selected Winner`
110
+ - `Findings`
111
+ - `Recommendation`
112
+
113
+ Quality gates:
114
+
115
+ - The selected winner is one first outbound send only. No post-accept DM,
116
+ follow-up, cadence branch, or sequence copy.
117
+ - Explain what the product is and what it does in plain language before asking
118
+ for a call.
119
+ - Use only proof from the brief, source review, sample, campaign state, or
120
+ explicit user answers. Unsupported reply-rate, meeting-rate, ROI, revenue,
121
+ and customer-logo claims are blocked.
122
+ - Include at least one supported `{{token}}` when templating, plus a complete
123
+ rendered good-fill example and a complete rendered omit/fallback example.
124
+ - Do not use internal tokens such as `{{profile_signal}}` in customer-facing
125
+ copy.
126
+ - Do not put bracketed instructions in the message body, such as `[ROW_BRIDGE]`,
127
+ `[insert]`, or `[generated]`.
128
+ - Optional row-specific personalization must be grounded in a row field or
129
+ omitted entirely.
130
+ - Subjects should be short, buyer-relevant, and specific. Avoid `quick
131
+ question`, `demo`, `founder call`, sender names, and generic `outbound`.
132
+ - If the message is plausible but not ready to send, set `Recommendation:
133
+ revise-messaging`.
@@ -154,25 +154,33 @@
154
154
  "name": "post-find-leads-filter-scout",
155
155
  "kind": "post-find-leads-scout",
156
156
  "promptFile": "post-find-leads-filter-scout.md",
157
- "displayName": "Post-Lead Filter Scout",
157
+ "displayName": "Lead Fit Builder",
158
158
  "target": "filter-leads",
159
- "inputs": ["brief.md", "lead-review.md", "lead-sample.json"],
160
- "producesArtifacts": ["lead-filter.md"],
161
- "optionalProducesArtifacts": ["rubric.json"],
159
+ "inputs": [
160
+ "brief.md",
161
+ "lead-review.md",
162
+ "lead-sample.json"
163
+ ],
164
+ "producesArtifacts": [
165
+ "lead-filter.md"
166
+ ],
167
+ "optionalProducesArtifacts": [
168
+ "rubric.json"
169
+ ],
162
170
  "ownership": "lead quality, false-positive patterns, keep/exclude rules, ability-to-pay checks, and production rubric translation only",
163
171
  "codex": {
164
- "description": "Sellable post-find-leads scout for lead filtering and rubric generation after source approval.",
172
+ "description": "Lead Fit Builder for campaign-backed lead filtering and rubric persistence after source approval.",
165
173
  "model": "gpt-5.5",
166
174
  "modelReasoningEffort": "high",
167
175
  "sandboxMode": "workspace-write",
168
176
  "nicknameCandidates": [
169
- "Lead Filter Scout",
170
- "Filter Scout",
171
- "Rubric Scout"
177
+ "Lead Fit Builder",
178
+ "Fit Builder",
179
+ "Rubric Builder"
172
180
  ]
173
181
  },
174
182
  "claude": {
175
- "description": "Use proactively as a background Sellable post-find-leads scout after lead source approval to produce lead-filter.md and rubric.json from brief.md, lead-review.md, and lead-sample.json.",
183
+ "description": "Use proactively as Lead Fit Builder after lead source approval to persist campaign rubrics and write lead-filter debug artifacts from campaign state.",
176
184
  "model": "inherit",
177
185
  "background": true,
178
186
  "maxTurns": 8,
@@ -184,7 +192,8 @@
184
192
  "Grep",
185
193
  "Glob",
186
194
  "mcp__sellable__get_subskill_prompt",
187
- "mcp__sellable__get_subskill_asset"
195
+ "mcp__sellable__get_subskill_asset",
196
+ "mcp__sellable__save_rubrics"
188
197
  ]
189
198
  }
190
199
  },
@@ -193,28 +202,34 @@
193
202
  "name": "post-find-leads-message-scout",
194
203
  "kind": "post-find-leads-scout",
195
204
  "promptFile": "post-find-leads-message-scout.md",
196
- "displayName": "Post-Lead Message Scout",
205
+ "displayName": "Message Draft Builder",
197
206
  "target": "generate-messages",
198
- "inputs": ["brief.md", "lead-review.md", "lead-sample.json"],
199
- "producesArtifacts": ["message-validation.md"],
207
+ "inputs": [
208
+ "brief.md",
209
+ "lead-review.md",
210
+ "lead-sample.json"
211
+ ],
212
+ "producesArtifacts": [
213
+ "message-validation.md"
214
+ ],
200
215
  "optionalProducesArtifacts": [
201
216
  "message-prep.md",
202
217
  "message-candidate-drafts.md"
203
218
  ],
204
219
  "ownership": "proof inventory, token strategy, angle drafting, skeptical-prospect review, and selected winner only",
205
220
  "codex": {
206
- "description": "Sellable post-find-leads scout for dry-mode message generation after source approval.",
221
+ "description": "Message Draft Builder for campaign-backed template proposals and sample messages after source approval.",
207
222
  "model": "gpt-5.5",
208
223
  "modelReasoningEffort": "high",
209
224
  "sandboxMode": "workspace-write",
210
225
  "nicknameCandidates": [
211
- "Message Scout",
212
- "Message Generation Scout",
213
- "Copy Scout"
226
+ "Message Draft Builder",
227
+ "Draft Builder",
228
+ "Template Builder"
214
229
  ]
215
230
  },
216
231
  "claude": {
217
- "description": "Use proactively as a background Sellable post-find-leads scout after lead source approval to run dry-mode message generation from brief.md, lead-review.md, and lead-sample.json.",
232
+ "description": "Use proactively as Message Draft Builder after lead source approval to propose an approved-template candidate and sample message from campaign state.",
218
233
  "model": "inherit",
219
234
  "background": true,
220
235
  "maxTurns": 10,
@@ -4,11 +4,19 @@ Your job is to test whether active LinkedIn posts and engagers can produce a war
4
4
 
5
5
  Required first step:
6
6
 
7
- - Load the canonical provider prompt before searching: `get_provider_prompt({ provider: "signal-discovery", confirmed: true })`.
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` in `search_signals` so the user can watch source work in the
11
+ campaign UI. Treat that as a campaign-attached persisted search; do not run a
12
+ post-mint search without the campaign ID. If no campaign ID is supplied, run
13
+ campaignless preview mode.
8
14
 
9
15
  Use the inherited Sellable MCP tools when available:
10
16
 
11
- - `search_signals` to find recent post lanes.
17
+ - `search_signals` to find recent post lanes. Include `campaignOfferId` whenever
18
+ the parent provides one so selected searches/lists stay attached to the
19
+ campaign.
12
20
  - `fetch_post_engagers` to sample engagers from selected posts.
13
21
 
14
22
  Process:
@@ -4,13 +4,20 @@ Your job is to test whether Prospeo can produce verified-contact scale for the c
4
4
 
5
5
  Required first step:
6
6
 
7
- - Load the canonical provider prompt before searching: `get_provider_prompt({ provider: "prospeo", confirmed: true })`.
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` in
10
+ `search_prospeo` so the user can watch source work in the campaign UI. If no
11
+ campaign ID is supplied, run campaignless preview mode. Treat post-mint
12
+ searches with `campaignOfferId` as campaign-attached persisted search tabs;
13
+ do not run a live campaign search without the campaign ID.
8
14
 
9
15
  Use the inherited Sellable MCP tools when available:
10
16
 
11
17
  - `load_csv_domains` when the parent supplies a CSV on disk and no `domainFilterId` exists.
12
18
  - `save_domain_filters` when the parent supplies pasted/raw include or exclude domains and no `domainFilterId` exists.
13
- - `search_prospeo` for campaignless people previews.
19
+ - `search_prospeo` for people previews. Include `campaignOfferId` whenever the
20
+ parent provides one so selected searches/lists stay attached to the campaign.
14
21
 
15
22
  Process:
16
23
 
@@ -4,12 +4,20 @@ Your job is to test whether Sales Navigator filters can produce a scalable, high
4
4
 
5
5
  Required first step:
6
6
 
7
- - Load the canonical provider prompt before searching: `get_provider_prompt({ provider: "sales-nav", confirmed: true })`.
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` so the user can watch source work in the campaign UI. If no
11
+ campaign ID is supplied, run campaignless preview mode. Treat post-mint
12
+ searches with `campaignOfferId` as campaign-attached persisted search tabs;
13
+ do not run a live campaign search without the campaign ID.
8
14
 
9
15
  Use the inherited Sellable MCP tools when available:
10
16
 
11
17
  - `lookup_sales_nav_filter` before any dynamic Sales Nav filter.
12
- - `search_sales_nav` for campaignless preview searches.
18
+ - `search_sales_nav` for preview searches. Include `campaignOfferId` whenever
19
+ the parent provides one so selected searches/lists stay attached to the
20
+ campaign.
13
21
 
14
22
  Process:
15
23
 
@@ -40,7 +40,7 @@ function getMcpVersion() {
40
40
  } catch {}
41
41
  return "latest";
42
42
  }
43
- const CODEX_PLUGIN_VERSION = "0.1.29";
43
+ const CODEX_PLUGIN_VERSION = "0.1.30";
44
44
  const CODEX_PLUGIN_COMPAT_VERSIONS = [
45
45
  "0.1.8",
46
46
  "0.1.9",
@@ -63,6 +63,7 @@ const CODEX_PLUGIN_COMPAT_VERSIONS = [
63
63
  "0.1.26",
64
64
  "0.1.27",
65
65
  "0.1.28",
66
+ "0.1.29",
66
67
  ];
67
68
  const INSTALL_PACKAGE_SPEC =
68
69
  process.env.SELLABLE_INSTALL_PACKAGE_SPEC || "@sellable/install@latest";
@@ -566,9 +567,9 @@ instruction loading, file lookup, plugin cache versions, missing linked files,
566
567
  or tool discovery. Start in product language:
567
568
 
568
569
  \`\`\`text
569
- I’ll help you launch this as a Sellable campaign. First I’ll confirm who we’re
570
- sending from and which company this is for, then I’ll turn that into a campaign
571
- brief before anything is created.
570
+ I’ll help you launch this as a Sellable campaign. First I’ll resolve the
571
+ client/company this campaign is for, then I’ll turn that into a campaign brief
572
+ before anything is created.
572
573
  \`\`\`
573
574
 
574
575
  If a linked/local skill file is stale or missing, silently use the installed
@@ -584,7 +585,8 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
584
585
  - "a couple setup choices", not \`request_user_input\`
585
586
  - "campaign brief", not prompt artifact
586
587
  - "lead source", not provider internals unless comparing source options
587
- - "nothing is created until you approve", not mutation jargon
588
+ - "I can create a draft shell for you to watch, but no leads import and nothing
589
+ sends until you approve", not mutation jargon
588
590
 
589
591
  When explaining lead-source decisions, show the concrete counts behind the
590
592
  logic: lanes searched, timeframe, raw result counts, finalist posts or preview
@@ -592,6 +594,13 @@ rows, sampled people, sampled fits as n/N (%), estimated usable people, and the
592
594
  confidence basis. Never show a percent like "73% match" without the numerator,
593
595
  denominator, and sample basis.
594
596
 
597
+ Do not forecast LinkedIn connection acceptance rates, reply rates, meetings,
598
+ pipeline, revenue, or ROI in customer-facing source reviews unless the user
599
+ supplied verified benchmark data for this exact workspace/sender. Without that
600
+ data, compare sources by source volume, sampled ICP fit, activity/warmth
601
+ signals, cleanup risk, and confidence basis. If a user asks for a forecast,
602
+ label it explicitly as not estimated from this run.
603
+
595
604
  Every approval gate must include artifact access after the readable inline
596
605
  content. Show an \`Open artifacts:\` line with clickable markdown links using
597
606
  absolute paths when the host supports them, plus the plain path for CLI users.
@@ -667,18 +676,20 @@ Treat host capabilities as concrete functions, not prose conventions:
667
676
  \`mcp__sellable__get_post_find_leads_scout_registry({})\` after source
668
677
  approval and before dispatching the post-lead filter/message scouts.
669
678
  - \`launch_source_scout\`: Claude Code uses \`Task\` with \`subagent_type\` equal to
670
- the registry \`name\`; Codex uses named custom agents such as
679
+ the registry \`name\` only when the session lists those agents; Codex uses
680
+ named custom agents such as
671
681
  \`source-scout-linkedin-engagement\`, \`source-scout-sales-nav\`, and
672
682
  \`source-scout-prospeo-contact\` when subagents are available.
673
683
  - \`launch_post_find_leads_scout\`: Claude Code uses \`Task\` with
674
- \`subagent_type\` equal to the returned post-lead registry \`name\`; Codex
675
- uses the returned custom agents such as \`post-find-leads-filter-scout\` and
676
- \`post-find-leads-message-scout\` when subagents are available.
684
+ \`subagent_type\` equal to the returned post-lead registry \`name\` only when
685
+ the session lists those agents; Codex uses the returned custom agents such as
686
+ \`post-find-leads-filter-scout\` and \`post-find-leads-message-scout\` when
687
+ subagents are available.
677
688
 
678
- If a required interactive host function is missing, stop and explain the
679
- Sellable install/reload problem. Do not silently simulate structured choices,
680
- subprompt loading, source-scout dispatch, or post-lead scout dispatch with local
681
- scripts.
689
+ If a required interactive question function or MCP loader is missing, stop and
690
+ explain the Sellable install/reload problem. Named scout agents are optional
691
+ acceleration: if they are absent, do not surface install status to the customer;
692
+ fall back to product-native MCP orchestration instead of local scripts.
682
693
 
683
694
  Never narrate local draft housekeeping to the user. If you create directories,
684
695
  save drafts, write artifacts, or persist intermediate state, translate it into
@@ -691,106 +702,56 @@ customer-facing progress copy.
691
702
 
692
703
  Do not treat the active Sellable workspace as the campaign subject. The
693
704
  workspace only tells you where the campaign will be saved. Before buyer, CTA,
694
- proof, or source questions, identify two things:
695
-
696
- 1. who/what company this campaign is for, and
697
- 2. who the LinkedIn messages should send from.
705
+ proof, or source questions, identify the campaign identity: the person/profile
706
+ or company this campaign is for, plus enough company/product context to build
707
+ the brief. This is only the client-prospect/bootstrap identity for
708
+ \`clientProspectId\` or \`senderLinkedinUrl\`; it is not a connected-sender check.
709
+
710
+ Do not call \`mcp__sellable__list_senders\`, \`mcp__sellable__get_sender\`, or
711
+ surface connected/missing sender state during setup, brief, source, filter, or
712
+ message review. Sender availability belongs only to the Settings/final launch
713
+ handoff after message approval and the 10-lead validation sample.
714
+
715
+ If the invocation or user answer includes an existing \`clientProspectId\`, keep
716
+ it as the preferred \`create_campaign\` identity input. If it includes a LinkedIn
717
+ profile URL, keep that URL as \`senderLinkedinUrl\` so the backend can
718
+ resolve/materialize the sender prospect when the watchable campaign shell is
719
+ created. Do not require a connected sender before shell creation.
698
720
 
699
721
  If the user supplied a LinkedIn profile, website, domain, company name, or
700
- sender name in the invocation, do one lightweight lookup first:
722
+ explicit client prospect identity in the invocation, do one lightweight lookup
723
+ first:
701
724
 
702
725
  - LinkedIn profile: call \`mcp__sellable__fetch_linkedin_profile\`.
703
726
  - Website/domain/company: call \`mcp__sellable__fetch_company\` when possible,
704
727
  otherwise one web lookup.
705
- - Workspace sender id or known sender: call \`mcp__sellable__get_sender\` or
706
- \`mcp__sellable__enrich_sender\`.
728
+ - Existing client prospect id: use it directly and do one company/profile lookup
729
+ only if a URL/domain is also available.
707
730
 
708
731
  Then summarize what you found in one or two lines and ask the user to confirm
709
- the campaign subject and sender before continuing.
732
+ the campaign identity/focus before continuing. Do not mention connected sender
733
+ availability in this confirmation.
710
734
 
711
- If the user did not provide the launch identity, quietly call
712
- \`mcp__sellable__list_senders\` once if available. This is a shortcut to deduce
713
- who the user might be from their Sellable API token and connected LinkedIn
714
- accounts. Do not ask the user to pick an input type before checking connected
715
- senders. If there is any likely connected sender, use
716
- \`mcp__sellable__enrich_sender\` on the best match to infer their current or most
717
- recent company, then ask a structured confirmation question:
718
-
719
- \`\`\`text
720
- I’m ready to build this in {workspace}. I found {matched sender} connected here.
721
-
722
- Is that you, and is this campaign for {company}?
723
- \`\`\`
724
-
725
- The structured options must be no more than three choices:
726
-
727
- 1. \`Yes — use {matched sender} for {company}\`
728
- 2. \`No — I'll paste a LinkedIn profile\`
729
- 3. \`Use a company domain instead\`
730
-
731
- If there are multiple likely connected senders, mention the best one in the
732
- question and use option 2 for either a different connected sender or a pasted
733
- LinkedIn profile.
734
-
735
- Use the structured question tool only for the choice. Do not use
736
- \`request_user_input\`/\`AskUserQuestion\` to collect a LinkedIn URL, company
737
- domain, or freeform text. If the user chooses option 2, ask in normal chat:
738
- \`Paste the LinkedIn URL I should use, and I’ll look it up.\` Then call
739
- \`mcp__sellable__fetch_linkedin_profile\`, infer their current or most recent
740
- company, and confirm company and sender again. If the user chooses option 3, ask
741
- in normal chat: \`Paste the company domain, and I’ll do a quick lookup before we
742
- keep going.\` Then call \`mcp__sellable__fetch_company\` when possible, otherwise
743
- one web lookup, and ask who the LinkedIn messages should send from.
744
-
745
- If \`mcp__sellable__list_senders\` returns zero connected senders, avoid the
746
- sender-confirmation branch entirely. Do not ask the user to choose an input type
747
- with the structured question tool. Ask in normal chat for the user's LinkedIn
748
- URL or the company they want to send on behalf of so you can research context:
735
+ If the user did not provide the launch identity, ask in normal chat for the
736
+ LinkedIn profile or company website to use as the campaign identity. Do not ask
737
+ them to choose an input type with the structured question tool:
749
738
 
750
739
  \`\`\`text
751
740
  I’m ready to build this in {workspace}.
752
741
 
753
- First, paste your LinkedIn URL or the company website you want to send on
754
- behalf of. I’ll use that to understand the company before we pick the target,
755
- offer, proof, and lead source.
756
- \`\`\`
757
-
758
- If there is no strong sender match, do not show a structured choice that says
759
- "LinkedIn profile" vs "Company website". The point of this gate is not "pick a
760
- sender" or "pick an input type"; it is to learn who the user is, infer the
761
- current or most recent company, and then confirm who we are sending from. The
762
- customer-facing shape should be:
763
-
764
- \`\`\`text
765
- I’m ready to build this in {workspace}.
766
-
767
- First, what’s your LinkedIn URL? If you’d rather start from the company, paste
768
- the company website instead.
769
- \`\`\`
770
-
771
- After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
772
- \`mcp__sellable__fetch_linkedin_profile\` and infer the user's current or most
773
- recent company from the profile. For a company website, call
774
- \`mcp__sellable__fetch_company\` when possible, otherwise one web lookup.
775
-
776
- If \`mcp__sellable__list_senders\` did not already run, call it once after the
777
- lookup to see whether the fetched user appears to match a connected sender. If
778
- there is a likely match, ask:
779
-
780
- \`\`\`text
781
- Cool — are you {matched sender}, and is this campaign for {company}?
782
- \`\`\`
783
-
784
- If there is no likely sender match, ask:
785
-
786
- \`\`\`text
787
- Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
742
+ First, paste the LinkedIn profile or company website for the client/company this
743
+ campaign is for. I’ll use that to resolve the campaign identity before we pick
744
+ the target, offer, proof, and lead source.
788
745
  \`\`\`
789
746
 
790
- Sender options should include connected sender names if available, \`same as
791
- me\`, \`I’ll paste a different sender profile\`, and \`Other / custom\`.
747
+ After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
748
+ profile, call \`mcp__sellable__fetch_linkedin_profile\` and infer the current or
749
+ most recent company from the profile. For a company website, call
750
+ \`mcp__sellable__fetch_company\` when possible, otherwise one web lookup. If a
751
+ LinkedIn profile URL is available, retain it as \`senderLinkedinUrl\` for
752
+ \`create_campaign\`; if a \`clientProspectId\` is available, pass that instead.
792
753
 
793
- After the user confirms the subject and sender, run one lightweight company
754
+ After the user confirms the campaign identity, run one lightweight company
794
755
  lookup if it has not already run, then ask the campaign setup questions. The
795
756
  setup questions should use the confirmed company context so they do not feel
796
757
  generic.
@@ -800,10 +761,8 @@ Before the identity gate, use this customer-facing shape:
800
761
  \`\`\`text
801
762
  I’m ready to build the campaign in {workspace}.
802
763
 
803
- First I’ll check whether you already have a connected LinkedIn account here. If
804
- I can’t confirm it, I’ll ask for your LinkedIn URL or company website and use
805
- that to understand the company before we choose the target, offer, proof, and
806
- lead source.
764
+ First I’ll resolve the client/company this campaign is for. I’ll use that
765
+ context to choose the target, offer, proof, and lead source.
807
766
 
808
767
  Then I’ll turn that into a campaign brief for you to approve before anything is created.
809
768
  \`\`\`
@@ -881,14 +840,15 @@ updates.
881
840
  copies of this file; packaged Claude Code and Codex runs must use the MCP
882
841
  asset loader so they share the same config.
883
842
  3. Follow that prompt and workflow config exactly.
884
- 4. For message generation, load the full \`generate-messages\` prompt in the
885
- same run with chunked
886
- \`mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages", offset, limit })\`
887
- calls until \`hasMore\` is false. Do not synthesize
888
- \`message-validation.md\` from the brief, lead review, or general knowledge.
843
+ 4. For message generation, use the \`post-find-leads-message-scout\` agent when
844
+ available; its prompt carries the campaign-launch message rules. In the
845
+ parent-thread fallback, load
846
+ \`mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })\`.
847
+ Do not synthesize \`message-validation.md\` from the brief, lead review, or
848
+ general knowledge.
889
849
  5. Treat message quality as the gate before minting. Do not create a campaign,
890
850
  show a commit gate, or mint anything until \`message-validation.md\` proves
891
- the full generate-messages workflow ran and \`message-review.md\` recommends
851
+ the fast-path message workflow ran and \`message-review.md\` recommends
892
852
  \`approve-message\` against the gold-standard rules.
893
853
  6. Do not create or mutate the live campaign until the approval gate returns
894
854
  \`approve\`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.74",
3
+ "version": "0.1.76",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code and Codex",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: create-campaign
3
- description: Create a Sellable campaign through the approval-gated workflow.
3
+ description: Create a Sellable campaign through the shell-first CampaignOffer workflow.
4
4
  visibility: public
5
5
  allowed-tools:
6
6
  - mcp__sellable__get_auth_status
@@ -66,6 +66,14 @@ allowed-tools:
66
66
 
67
67
  Use this as the customer-facing entrypoint for Sellable campaign creation.
68
68
 
69
+ CampaignOffer state is canonical; disk artifacts are a debug trail. The
70
+ internal create-campaign-v2 flow still writes the diagnostics, and all 14 disk
71
+ artifacts remain as debug outputs, but resume, gating, and handoff read campaign
72
+ state first. The
73
+ watchable campaign exists after the short brief; lead import is bounded to the
74
+ first review batch, and enrichment/message generation waits until rubrics and
75
+ the approved message template are saved on the campaign.
76
+
69
77
  ## Opening Turn Contract
70
78
 
71
79
  On the first visible response after this skill is invoked, do not narrate
@@ -73,9 +81,9 @@ instruction loading, file lookup, plugin cache versions, missing linked files,
73
81
  or tool discovery. Start in product language:
74
82
 
75
83
  ```text
76
- I’ll help you launch this as a Sellable campaign. First I’ll confirm who we’re
77
- sending from and which company this is for, then I’ll turn that into a campaign
78
- brief before anything is created.
84
+ I’ll help you launch this as a Sellable campaign. First I’ll resolve the
85
+ client/company this campaign is for, then I’ll turn that into a campaign brief
86
+ before any leads are imported or anything can send.
79
87
  ```
80
88
 
81
89
  If a linked/local skill file is stale or missing, silently use the installed
@@ -91,7 +99,8 @@ clear business decisions, tradeoffs, and approval gates. Use product language:
91
99
  - "a couple setup choices", not `request_user_input`
92
100
  - "campaign brief", not prompt artifact
93
101
  - "lead source", not provider internals unless comparing source options
94
- - "nothing is created until you approve", not mutation jargon
102
+ - "I can create a draft shell for you to watch, but no leads import and nothing
103
+ sends until you approve", not mutation jargon
95
104
 
96
105
  When explaining lead-source decisions, show the concrete counts behind the
97
106
  logic: lanes searched, timeframe, raw result counts, finalist posts or preview
@@ -99,28 +108,40 @@ rows, sampled people, sampled fits as n/N (%), estimated usable people, and the
99
108
  confidence basis. Never show a percent like "73% match" without the numerator,
100
109
  denominator, and sample basis.
101
110
 
111
+ Do not forecast LinkedIn connection acceptance rates, reply rates, meetings,
112
+ pipeline, revenue, or ROI in customer-facing source reviews unless the user
113
+ supplied verified benchmark data for this exact workspace/sender. Without that
114
+ data, compare sources by source volume, sampled ICP fit, activity/warmth
115
+ signals, cleanup risk, and confidence basis. If a user asks for a forecast,
116
+ label it explicitly as not estimated from this run.
117
+
102
118
  When the user has not supplied a source and multiple source angles are viable,
103
119
  scout those angles as independent branches when the host can actually do it:
104
120
  LinkedIn Engagement / active post engagers (internal `signal-discovery`
105
121
  provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
106
122
  domains only when relevant. In Codex, explicitly spawn the named custom scouts
107
- `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and `source-scout-prospeo-contact` for
108
- the credible lanes; Codex does not infer subagent fan-out from generic source
123
+ `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
124
+ `source-scout-prospeo-contact` for the credible lanes only when the current host
125
+ exposes those names; Codex does not infer subagent fan-out from generic source
109
126
  comparison wording. In Claude Code, invoke the generated `source-scout-*`
110
- Task/Agent subagents for all credible lanes in one assistant message; the
111
- installer writes them from the same canonical Sellable agent registry with
112
- explicit Sellable MCP tool allowlists. The create-campaign-v2 subskill calls
113
- `get_source_scout_registry` before dispatch so the current registry, not this
114
- copy, is the runtime source of truth. If the host runs them sequentially, do not
115
- claim they ran in parallel. In chat, call the downstream copy stage `message generation`;
127
+ Task/Agent subagents for all credible lanes in one assistant message only when
128
+ the current session lists those names. The installer writes them from the same
129
+ canonical Sellable agent registry with explicit Sellable MCP tool allowlists.
130
+ The create-campaign-v2 subskill calls `get_source_scout_registry` before
131
+ dispatch so the current registry, not this copy, is the runtime source of truth.
132
+ If the host runs them sequentially or the named agents are unavailable, do not
133
+ claim they ran in parallel and do not surface install status to the customer. In
134
+ chat, call the downstream copy stage `message generation`;
116
135
  `message-validation.md` is only an internal proof artifact.
117
136
 
118
137
  After find-leads returns a lead source and the user approves it, use the same
119
138
  registry pattern for the two post-lead branches. The create-campaign-v2 subskill
120
139
  calls `get_post_find_leads_scout_registry`, then launches the returned
121
140
  filter-leads scout and message-generation scout together when real subagents are
122
- available. Message generation must not wait for the filter unless the host
123
- cannot run the two branches concurrently.
141
+ available and the current session exposes the returned names. Message
142
+ generation must not wait for the filter unless the host cannot run the two
143
+ branches concurrently. If the post-lead agents are absent, the main thread still
144
+ orchestrates the same branches from the compact context with MCP tools/assets.
124
145
 
125
146
  Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
126
147
  lines short, use indexed section labels and bullets, and translate internal
@@ -130,7 +151,7 @@ Every approval gate must include artifact access after the readable inline
130
151
  content. Show a short `Open artifact:` line with the one key clickable markdown
131
152
  link for that stage. Do not show raw filesystem paths unless links cannot be
132
153
  created or the user asks. Do this for brief approval, lead-source
133
- approval/review, lead-filter review, message review, and final approval packet.
154
+ approval/review, lead-filter review, and message review.
134
155
  The link is for deeper inspection; never use it as a substitute for showing the
135
156
  content in chat.
136
157
 
@@ -202,18 +223,20 @@ Treat host capabilities as concrete functions, not prose conventions:
202
223
  `mcp__sellable__get_post_find_leads_scout_registry({})` after source
203
224
  approval and before dispatching the post-lead filter/message scouts.
204
225
  - `launch_source_scout`: Claude Code uses `Task` with `subagent_type` equal to
205
- the registry `name`; Codex uses named custom agents such as
226
+ the registry `name` only when the session lists those agents; Codex uses
227
+ named custom agents such as
206
228
  `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
207
229
  `source-scout-prospeo-contact` when subagents are available.
208
230
  - `launch_post_find_leads_scout`: Claude Code uses `Task` with `subagent_type`
209
- equal to the returned post-lead registry `name`; Codex uses the returned
210
- custom agents such as `post-find-leads-filter-scout` and
211
- `post-find-leads-message-scout` when subagents are available.
231
+ equal to the returned post-lead registry `name` only when the session lists
232
+ those agents; Codex uses the returned custom agents such as
233
+ `post-find-leads-filter-scout` and `post-find-leads-message-scout` when
234
+ subagents are available.
212
235
 
213
- If a required interactive host function is missing, stop and explain the
214
- Sellable install/reload problem. Do not silently simulate structured choices,
215
- subprompt loading, source-scout dispatch, or post-lead scout dispatch with local
216
- scripts.
236
+ If a required interactive question function or MCP loader is missing, stop and
237
+ explain the Sellable install/reload problem. Named scout agents are optional
238
+ acceleration: if they are absent, do not surface install status to the customer;
239
+ fall back to product-native MCP orchestration instead of local scripts.
217
240
 
218
241
  Never narrate local draft housekeeping to the user. If you create directories,
219
242
  save drafts, write artifacts, or persist intermediate state, translate it into
@@ -226,106 +249,56 @@ customer-facing progress copy.
226
249
 
227
250
  Do not treat the active Sellable workspace as the campaign subject. The
228
251
  workspace only tells you where the campaign will be saved. Before buyer, CTA,
229
- proof, or source questions, identify two things:
230
-
231
- 1. who/what company this campaign is for, and
232
- 2. who the LinkedIn messages should send from.
252
+ proof, or source questions, identify the campaign identity: the person/profile
253
+ or company this campaign is for, plus enough company/product context to build
254
+ the brief. This is only the client-prospect/bootstrap identity for
255
+ `clientProspectId` or `senderLinkedinUrl`; it is not a connected-sender check.
256
+
257
+ Do not call `mcp__sellable__list_senders`, `mcp__sellable__get_sender`, or
258
+ surface connected/missing sender state during setup, brief, source, filter, or
259
+ message review. Sender availability belongs only to the Settings/final launch
260
+ handoff after message approval and the 10-lead validation sample.
261
+
262
+ If the invocation or user answer includes an existing `clientProspectId`, keep
263
+ it as the preferred `create_campaign` identity input. If it includes a LinkedIn
264
+ profile URL, keep that URL as `senderLinkedinUrl` so the backend can
265
+ resolve/materialize the sender prospect when the watchable campaign shell is
266
+ created. Do not require a connected sender before shell creation.
233
267
 
234
268
  If the user supplied a LinkedIn profile, website, domain, company name, or
235
- sender name in the invocation, do one lightweight lookup first:
269
+ explicit client prospect identity in the invocation, do one lightweight lookup
270
+ first:
236
271
 
237
272
  - LinkedIn profile: call `mcp__sellable__fetch_linkedin_profile`.
238
273
  - Website/domain/company: call `mcp__sellable__fetch_company` when possible,
239
274
  otherwise one web lookup.
240
- - Workspace sender id or known sender: call `mcp__sellable__get_sender` or
241
- `mcp__sellable__enrich_sender`.
275
+ - Existing client prospect id: use it directly and do one company/profile lookup
276
+ only if a URL/domain is also available.
242
277
 
243
278
  Then summarize what you found in one or two lines and ask the user to confirm
244
- the campaign subject and sender before continuing.
245
-
246
- If the user did not provide the launch identity, quietly call
247
- `mcp__sellable__list_senders` once if available. This is a shortcut to deduce
248
- who the user might be from their Sellable API token and connected LinkedIn
249
- accounts. Do not ask the user to pick an input type before checking connected
250
- senders. If there is any likely connected sender, use
251
- `mcp__sellable__enrich_sender` on the best match to infer their current or most
252
- recent company, then ask a structured confirmation question:
253
-
254
- ```text
255
- I’m ready to build this in {workspace}. I found {matched sender} connected here.
256
-
257
- Is that you, and is this campaign for {company}?
258
- ```
259
-
260
- The structured options must be no more than three choices:
261
-
262
- 1. `Yes — use {matched sender} for {company}`
263
- 2. `No — I'll paste a LinkedIn profile`
264
- 3. `Use a company domain instead`
265
-
266
- If there are multiple likely connected senders, mention the best one in the
267
- question and use option 2 for either a different connected sender or a pasted
268
- LinkedIn profile.
279
+ the campaign identity/focus before continuing. Do not mention connected sender
280
+ availability in this confirmation.
269
281
 
270
- Use the structured question tool only for the choice. Do not use
271
- `request_user_input`/`AskUserQuestion` to collect a LinkedIn URL, company
272
- domain, or freeform text. If the user chooses option 2, ask in normal chat:
273
- `Paste the LinkedIn URL I should use, and I’ll look it up.` Then call
274
- `mcp__sellable__fetch_linkedin_profile`, infer their current or most recent
275
- company, and confirm company and sender again. If the user chooses option 3, ask
276
- in normal chat: `Paste the company domain, and I’ll do a quick lookup before we
277
- keep going.` Then call `mcp__sellable__fetch_company` when possible, otherwise
278
- one web lookup, and ask who the LinkedIn messages should send from.
279
-
280
- If `mcp__sellable__list_senders` returns zero connected senders, avoid the
281
- sender-confirmation branch entirely. Do not ask the user to choose an input type
282
- with the structured question tool. Ask in normal chat for the user's LinkedIn
283
- URL or the company they want to send on behalf of so you can research context:
282
+ If the user did not provide the launch identity, ask in normal chat for the
283
+ LinkedIn profile or company website to use as the campaign identity. Do not ask
284
+ them to choose an input type with the structured question tool:
284
285
 
285
286
  ```text
286
287
  I’m ready to build this in {workspace}.
287
288
 
288
- First, paste your LinkedIn URL or the company website you want to send on
289
- behalf of. I’ll use that to understand the company before we pick the target,
290
- offer, proof, and lead source.
291
- ```
292
-
293
- If there is no strong sender match, do not show a structured choice that says
294
- "LinkedIn profile" vs "Company website". The point of this gate is not "pick a
295
- sender" or "pick an input type"; it is to learn who the user is, infer the
296
- current or most recent company, and then confirm who we are sending from. The
297
- customer-facing shape should be:
298
-
299
- ```text
300
- I’m ready to build this in {workspace}.
301
-
302
- First, what’s your LinkedIn URL? If you’d rather start from the company, paste
303
- the company website instead.
304
- ```
305
-
306
- After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
307
- `mcp__sellable__fetch_linkedin_profile` and infer the user's current or most
308
- recent company from the profile. For a company website, call
309
- `mcp__sellable__fetch_company` when possible, otherwise one web lookup.
310
-
311
- If `mcp__sellable__list_senders` did not already run, call it once after the
312
- lookup to see whether the fetched user appears to match a connected sender. If
313
- there is a likely match, ask:
314
-
315
- ```text
316
- Cool — are you {matched sender}, and is this campaign for {company}?
317
- ```
318
-
319
- If there is no likely sender match, ask:
320
-
321
- ```text
322
- Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
289
+ First, paste the LinkedIn profile or company website for the client/company this
290
+ campaign is for. I’ll use that to resolve the campaign identity before we pick
291
+ the target, offer, proof, and lead source.
323
292
  ```
324
293
 
325
- Sender options should include connected sender names if available, `same as
326
- me`, `I’ll paste a different sender profile`, and `Other / custom`.
294
+ After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
295
+ profile, call `mcp__sellable__fetch_linkedin_profile` and infer the current or
296
+ most recent company from the profile. For a company website, call
297
+ `mcp__sellable__fetch_company` when possible, otherwise one web lookup. If a
298
+ LinkedIn profile URL is available, retain it as `senderLinkedinUrl` for
299
+ `create_campaign`; if a `clientProspectId` is available, pass that instead.
327
300
 
328
- After the user confirms the subject and sender, run one lightweight company
301
+ After the user confirms the campaign identity, run one lightweight company
329
302
  lookup if it has not already run, then ask the campaign setup questions. The
330
303
  setup questions should use the confirmed company context so they do not feel
331
304
  generic.
@@ -335,12 +308,11 @@ Before the identity gate, use this customer-facing shape:
335
308
  ```text
336
309
  I’m ready to build the campaign in {workspace}.
337
310
 
338
- First I’ll check whether you already have a connected LinkedIn account here. If
339
- I can’t confirm it, I’ll ask for your LinkedIn URL or company website and use
340
- that to understand the company before we choose the target, offer, proof, and
341
- lead source.
311
+ First I’ll resolve the client/company this campaign is for. I’ll use that
312
+ context to choose the target, offer, proof, and lead source.
342
313
 
343
- Then I’ll turn that into a campaign brief for you to approve before anything is created.
314
+ Then I’ll turn that into a campaign brief for you to approve before any leads
315
+ are imported or anything can send.
344
316
  ```
345
317
 
346
318
  Do not silently ask Codex intake or approval questions as plain chat when
@@ -374,7 +346,7 @@ No problem. You can still continue by switching Codex to Plan mode and running:
374
346
 
375
347
  $sellable:create-campaign
376
348
 
377
- I won’t create or change anything in Sellable until you approve the final campaign.
349
+ I won’t import leads, attach a sequence, or start anything until the brief, source, filters, and message are set.
378
350
  ```
379
351
 
380
352
  Plain chat questions are only acceptable in non-interactive `codex exec`
@@ -515,17 +487,21 @@ updates.
515
487
  copies of this file; packaged Claude Code and Codex runs must use the MCP
516
488
  asset loader so they share the same config.
517
489
  3. Follow that prompt and workflow config exactly.
518
- 4. For message generation, load the full `generate-messages` prompt in the
519
- same run with chunked
520
- `mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages", offset, limit })`
521
- calls until `hasMore` is false. Do not synthesize
522
- `message-validation.md` from the brief, lead review, or general knowledge.
523
- 5. Treat message quality as the gate before minting. Do not create a campaign,
524
- show a commit gate, or mint anything until `message-validation.md` proves
525
- the full generate-messages workflow ran and `message-review.md` recommends
526
- `approve-message` against the gold-standard rules.
527
- 6. Do not create or mutate the live campaign until the approval gate returns
528
- `approve`.
490
+ 4. For message generation, use the `post-find-leads-message-scout` agent when
491
+ available; its prompt carries the campaign-launch message rules. In the
492
+ parent-thread fallback, load
493
+ `mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })`.
494
+ Do not synthesize `message-validation.md` from the brief, lead review, or
495
+ general knowledge.
496
+ 5. Create the campaign shell early with the v1 brief so the user can open the
497
+ watch link and see useful setup state immediately. Import only the first
498
+ bounded review batch after the source is attached to the campaign; do not
499
+ queue workflow cells, attach a sequence, or start until
500
+ `message-validation.md` proves the fast-path message workflow ran,
501
+ `message-review.md` approves the template, rubrics are saved, and the
502
+ approved message set is synced into the campaign brief.
503
+ 6. Keep `selectedLeadListId` as the source list and `workflowTableId` as the
504
+ campaign table. Do not use disk files as the post-mint source of truth.
529
505
  7. Do not ask the user to run another command.
530
506
 
531
507
  ## Fallback