@sellable/mcp 0.1.158 → 0.1.160
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/agents/source-scout-linkedin-engagement.md +8 -3
- package/dist/tools/bootstrap.js +1 -1
- package/dist/tools/leads.d.ts +20 -2
- package/dist/tools/leads.js +92 -31
- package/dist/tools/registry.d.ts +8 -2
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +45 -32
- package/skills/create-campaign-v2/SKILL.md +41 -16
- package/skills/create-campaign-v2/SOUL.md +9 -8
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1441
- package/skills/create-campaign-v2/references/approval-gate-framing.md +12 -1
- package/skills/create-campaign-v2/references/filter-leads.md +26 -0
- package/skills/create-campaign-v2/references/final-handoff-contract.md +15 -0
- package/skills/create-campaign-v2/references/sample-validation-loop.md +26 -0
- package/skills/create-campaign-v2/references/watch-link-handoff.md +10 -5
- package/skills/providers/signal-discovery.md +5 -3
|
@@ -1,1441 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "v2.1-compact",
|
|
3
|
-
"workflow": "create-campaign-v2",
|
|
4
|
-
"principle": "CampaignOffer state and watch link are canonical. Create the watched shell, approve source, materialize and confirm the source list, internally process the first campaign-table execution slice, save rubrics for approval, approve the message template, then run the bounded filter/message cascade before Settings, sequence, and explicit start.",
|
|
5
|
-
"normalCustomerPath": "Use campaign state, MCP responses, and concise watchNarration. Do not create, read, link, or surface local draft files.",
|
|
6
|
-
"legacyCompatibility": {
|
|
7
|
-
"validationSubskill": "create-campaign-v2-validation",
|
|
8
|
-
"tailSubskill": "create-campaign-v2-tail",
|
|
9
|
-
"rule": "Legacy validation/rehearsal files are opt-in diagnostics only and are not active flow gates."
|
|
10
|
-
},
|
|
11
|
-
"commitGateChoices": [
|
|
12
|
-
"approve",
|
|
13
|
-
"revise-brief",
|
|
14
|
-
"revise-leads",
|
|
15
|
-
"revise-rubric",
|
|
16
|
-
"revise-messaging",
|
|
17
|
-
"abort"
|
|
18
|
-
],
|
|
19
|
-
"canonicalStateFields": [
|
|
20
|
-
"campaignId",
|
|
21
|
-
"watchUrl",
|
|
22
|
-
"campaignBrief",
|
|
23
|
-
"currentStep",
|
|
24
|
-
"watchNarration",
|
|
25
|
-
"interactionMode",
|
|
26
|
-
"providerSearchAssociation",
|
|
27
|
-
"selectedLeadListId",
|
|
28
|
-
"workflowTableId",
|
|
29
|
-
"filterChoice",
|
|
30
|
-
"leadScoringRubrics",
|
|
31
|
-
"messageDraftRecommendation",
|
|
32
|
-
"approvedMessageTemplate",
|
|
33
|
-
"senderIds",
|
|
34
|
-
"sequenceTemplate",
|
|
35
|
-
"runningState"
|
|
36
|
-
],
|
|
37
|
-
"watchNarrationTransitionContract": {
|
|
38
|
-
"rule": "Every watched currentStep switch must include fresh watchNarration.",
|
|
39
|
-
"requiredFields": [
|
|
40
|
-
"stage",
|
|
41
|
-
"headline",
|
|
42
|
-
"visibleState",
|
|
43
|
-
"agentIntent",
|
|
44
|
-
"nextAction"
|
|
45
|
-
],
|
|
46
|
-
"copyMustInclude": [
|
|
47
|
-
"what just happened",
|
|
48
|
-
"current visible page/state",
|
|
49
|
-
"next user action"
|
|
50
|
-
],
|
|
51
|
-
"appliesToTools": [
|
|
52
|
-
"create_campaign",
|
|
53
|
-
"update_campaign",
|
|
54
|
-
"attach_recommended_sequence",
|
|
55
|
-
"start_campaign"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
"lazyReferences": {
|
|
59
|
-
"watch": [
|
|
60
|
-
"references/watch-link-handoff.md",
|
|
61
|
-
"references/watch-guide-narration.md"
|
|
62
|
-
],
|
|
63
|
-
"source": [
|
|
64
|
-
"references/lead-validation-preview.md",
|
|
65
|
-
"references/step-13-import-leads.md"
|
|
66
|
-
],
|
|
67
|
-
"filter": ["references/filter-leads.md"],
|
|
68
|
-
"message": [],
|
|
69
|
-
"tail": [
|
|
70
|
-
"references/sample-validation-loop.md",
|
|
71
|
-
"references/step-15-re-cascade.md",
|
|
72
|
-
"references/final-handoff-contract.md"
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
"safetyBoundaries": [
|
|
76
|
-
"Do not call list_senders before Settings after message approval.",
|
|
77
|
-
"Do not import leads until the source decision is approved.",
|
|
78
|
-
"Do not queue cells until confirmed source rows exist in the campaign and the message/filter gates are satisfied.",
|
|
79
|
-
"Do not call start_campaign until the user explicitly confirms launch.",
|
|
80
|
-
"Do not use local files as durable state in normal customer runs."
|
|
81
|
-
],
|
|
82
|
-
"yoloMode": {
|
|
83
|
-
"triggerPhrases": [
|
|
84
|
-
"yolo",
|
|
85
|
-
"--yolo",
|
|
86
|
-
"mode=yolo",
|
|
87
|
-
"autopilot",
|
|
88
|
-
"use best guesses",
|
|
89
|
-
"use best estimates",
|
|
90
|
-
"answer for me",
|
|
91
|
-
"just run it"
|
|
92
|
-
],
|
|
93
|
-
"identityRequestOnlyWhenMissing": true,
|
|
94
|
-
"operatorDirectionsRule": "Treat freeform directions supplied at invocation or later as durable operator directions; newest conflicting direction wins.",
|
|
95
|
-
"setInteractionModeAfterCampaignCreate": "autonomous",
|
|
96
|
-
"autoSelectsPreLaunchChoices": [
|
|
97
|
-
"campaign focus",
|
|
98
|
-
"brief approval",
|
|
99
|
-
"source scouting plan",
|
|
100
|
-
"source review/import approval",
|
|
101
|
-
"filters vs skip filters",
|
|
102
|
-
"filter rubric approval",
|
|
103
|
-
"message template approval when recommendation is approve-message",
|
|
104
|
-
"generated message review when quality floor passes",
|
|
105
|
-
"sender selection when exactly one connected sender is safe"
|
|
106
|
-
],
|
|
107
|
-
"mustPauseFor": [
|
|
108
|
-
"missing campaign identity",
|
|
109
|
-
"missing credentials or required data",
|
|
110
|
-
"ambiguous choice with no reasonable estimate",
|
|
111
|
-
"source/message/filter quality floor failure",
|
|
112
|
-
"final live launch confirmation"
|
|
113
|
-
],
|
|
114
|
-
"neverAutoStart": true
|
|
115
|
-
},
|
|
116
|
-
"steps": [
|
|
117
|
-
{
|
|
118
|
-
"id": "bootstrap",
|
|
119
|
-
"label": "Bootstrap",
|
|
120
|
-
"onEnter": [
|
|
121
|
-
{
|
|
122
|
-
"tool": "bootstrap_create_campaign",
|
|
123
|
-
"requiredValues": {
|
|
124
|
-
"flowVersion": "v2"
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"tool": "get_subskill_prompt",
|
|
129
|
-
"requiredValues": {
|
|
130
|
-
"subskillName": "create-campaign-v2"
|
|
131
|
-
},
|
|
132
|
-
"purpose": "load the compact entry prompt once"
|
|
133
|
-
}
|
|
134
|
-
],
|
|
135
|
-
"allowedTools": [
|
|
136
|
-
"bootstrap_create_campaign",
|
|
137
|
-
"get_auth_status",
|
|
138
|
-
"get_active_workspace",
|
|
139
|
-
"get_subskill_prompt",
|
|
140
|
-
"AskUserQuestion",
|
|
141
|
-
"request_user_input"
|
|
142
|
-
],
|
|
143
|
-
"doNotAllow": [
|
|
144
|
-
"create_campaign",
|
|
145
|
-
"list_senders",
|
|
146
|
-
"save_rubrics",
|
|
147
|
-
"import_leads",
|
|
148
|
-
"confirm_lead_list",
|
|
149
|
-
"update_campaign",
|
|
150
|
-
"queue_cells",
|
|
151
|
-
"start_campaign"
|
|
152
|
-
],
|
|
153
|
-
"waitFor": "bootstrap_complete",
|
|
154
|
-
"transitions": {
|
|
155
|
-
"bootstrap_complete": "brief-interview"
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
"id": "brief-interview",
|
|
160
|
-
"label": "Identity, research, and brief",
|
|
161
|
-
"onEnter": [
|
|
162
|
-
{
|
|
163
|
-
"action": "resolve_campaign_identity_before_strategy_packet",
|
|
164
|
-
"allowedTools": [
|
|
165
|
-
"fetch_company",
|
|
166
|
-
"fetch_linkedin_profile",
|
|
167
|
-
"WebFetch",
|
|
168
|
-
"WebSearch"
|
|
169
|
-
],
|
|
170
|
-
"mustNotInferFromNameOnly": true,
|
|
171
|
-
"doNotPresentSenderPickerBeforeIdentityInference": true,
|
|
172
|
-
"fallback": "Ask for the LinkedIn profile or company website before strategy questions."
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
"action": "run_campaign_identity_research_before_strategy_packet",
|
|
176
|
-
"target": "research-sender",
|
|
177
|
-
"requiredCompletion": "complete_sender_research",
|
|
178
|
-
"allowedTools": [
|
|
179
|
-
"get_subskill_prompt",
|
|
180
|
-
"fetch_linkedin_profile",
|
|
181
|
-
"fetch_company",
|
|
182
|
-
"fetch_linkedin_posts",
|
|
183
|
-
"fetch_company_posts",
|
|
184
|
-
"WebFetch",
|
|
185
|
-
"WebSearch",
|
|
186
|
-
"complete_sender_research"
|
|
187
|
-
]
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
"action": "ask_campaign_focus_only_when_ambiguous",
|
|
191
|
-
"uses": "request_user_input",
|
|
192
|
-
"singleChoice": true,
|
|
193
|
-
"requiredOption": "Other / custom",
|
|
194
|
-
"neverCollectOpenTextWithStructuredQuestion": true,
|
|
195
|
-
"skipIf": "yolo_mode with any reasonable best-estimate focus"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"action": "infer_strategy_packet_in_yolo_mode",
|
|
199
|
-
"when": "yolo_mode",
|
|
200
|
-
"skipStructuredSetupQuestions": true,
|
|
201
|
-
"inferFields": [
|
|
202
|
-
"buyer segment",
|
|
203
|
-
"offer/CTA",
|
|
204
|
-
"proof to use or avoid",
|
|
205
|
-
"lead source",
|
|
206
|
-
"filter choice",
|
|
207
|
-
"message direction"
|
|
208
|
-
],
|
|
209
|
-
"sourceOfTruth": "identity/company lookup plus operator directions",
|
|
210
|
-
"mustStateAssumptionsInBrief": true
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
"action": "create_watchable_campaign_shell_with_v1_brief",
|
|
214
|
-
"tool": "create_campaign",
|
|
215
|
-
"requiredFields": [
|
|
216
|
-
"name",
|
|
217
|
-
"campaignBrief",
|
|
218
|
-
"clientProspectId or senderLinkedinUrl",
|
|
219
|
-
"currentStep",
|
|
220
|
-
"watchNarration"
|
|
221
|
-
],
|
|
222
|
-
"requiredValues": {
|
|
223
|
-
"currentStep": "create-offer",
|
|
224
|
-
"watchNarration.stage": "brief"
|
|
225
|
-
},
|
|
226
|
-
"capture": ["campaignId", "watchUrl"],
|
|
227
|
-
"canonicalStateWrites": [
|
|
228
|
-
"campaignId",
|
|
229
|
-
"watchUrl",
|
|
230
|
-
"campaignBrief",
|
|
231
|
-
"currentStep:create-offer"
|
|
232
|
-
]
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
"action": "surface_campaign_shell_watch_link",
|
|
236
|
-
"watchUrlSource": "create_campaign.watchUrl",
|
|
237
|
-
"requiredWatchUrlShape": "direct /campaign-builder/{campaignId}?mode={claude|codex} watch URL with token auto-login and workspace routing",
|
|
238
|
-
"immediateNextMainChatLine": "Cool, let's find leads.",
|
|
239
|
-
"codexBrowserHandoff": {
|
|
240
|
-
"openWhenAvailable": false,
|
|
241
|
-
"printWatchLinkOnly": true,
|
|
242
|
-
"tellUserCommandEnterOrClick": true,
|
|
243
|
-
"mustNotUseBrowserAutomation": true,
|
|
244
|
-
"fallbackMustNotClaimInspection": true
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
],
|
|
248
|
-
"allowedTools": [
|
|
249
|
-
"get_subskill_prompt",
|
|
250
|
-
"fetch_company",
|
|
251
|
-
"fetch_company_posts",
|
|
252
|
-
"fetch_linkedin_profile",
|
|
253
|
-
"fetch_linkedin_posts",
|
|
254
|
-
"complete_sender_research",
|
|
255
|
-
"create_campaign",
|
|
256
|
-
"AskUserQuestion",
|
|
257
|
-
"request_user_input"
|
|
258
|
-
],
|
|
259
|
-
"doNotAllow": [
|
|
260
|
-
"list_senders",
|
|
261
|
-
"save_rubrics",
|
|
262
|
-
"import_leads",
|
|
263
|
-
"confirm_lead_list",
|
|
264
|
-
"queue_cells",
|
|
265
|
-
"start_campaign"
|
|
266
|
-
],
|
|
267
|
-
"waitFor": ["campaign_shell_created", "brief_ready", "confirm_with_user"],
|
|
268
|
-
"transitions": {
|
|
269
|
-
"campaign_shell_created": "brief-review",
|
|
270
|
-
"brief_ready": "brief-review",
|
|
271
|
-
"confirm_with_user": "brief-review"
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"id": "brief-review",
|
|
276
|
-
"label": "Brief review",
|
|
277
|
-
"onEnter": [
|
|
278
|
-
{
|
|
279
|
-
"action": "render_brief_inline",
|
|
280
|
-
"minimumVisibleDetail": "campaign direction, buyer, offer, proof, source plan, safety gates"
|
|
281
|
-
},
|
|
282
|
-
{
|
|
283
|
-
"action": "ask_brief_choice",
|
|
284
|
-
"uses": "request_user_input",
|
|
285
|
-
"choices": ["Approve brief", "Revise brief", "Pause here"],
|
|
286
|
-
"skipIf": "yolo_mode; auto_continue after rendering assumptions unless brief quality floor fails"
|
|
287
|
-
}
|
|
288
|
-
],
|
|
289
|
-
"requiredCampaignState": [
|
|
290
|
-
"campaignId",
|
|
291
|
-
"watchUrl",
|
|
292
|
-
"campaignBrief",
|
|
293
|
-
"currentStep"
|
|
294
|
-
],
|
|
295
|
-
"allowedTools": [
|
|
296
|
-
"AskUserQuestion",
|
|
297
|
-
"request_user_input",
|
|
298
|
-
"update_campaign"
|
|
299
|
-
],
|
|
300
|
-
"doNotAllow": [
|
|
301
|
-
"create_campaign",
|
|
302
|
-
"list_senders",
|
|
303
|
-
"import_leads",
|
|
304
|
-
"confirm_lead_list",
|
|
305
|
-
"queue_cells",
|
|
306
|
-
"start_campaign"
|
|
307
|
-
],
|
|
308
|
-
"waitFor": ["user_brief_confirmed", "revise_brief", "auto_continue"],
|
|
309
|
-
"transitions": {
|
|
310
|
-
"user_brief_confirmed": "find-leads",
|
|
311
|
-
"revise_brief": "brief-interview",
|
|
312
|
-
"auto_continue": "find-leads"
|
|
313
|
-
}
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
"id": "find-leads",
|
|
317
|
-
"label": "Find leads",
|
|
318
|
-
"sourceSelectionFunnel": {
|
|
319
|
-
"preScoutRecommendationGate": {
|
|
320
|
-
"required": true,
|
|
321
|
-
"label": "Source plan approval",
|
|
322
|
-
"mustHappenBefore": [
|
|
323
|
-
"get_provider_prompt",
|
|
324
|
-
"search_signals",
|
|
325
|
-
"search_sales_nav",
|
|
326
|
-
"search_prospeo",
|
|
327
|
-
"fetch_post_engagers",
|
|
328
|
-
"source-scout dispatch"
|
|
329
|
-
],
|
|
330
|
-
"show": [
|
|
331
|
-
"campaign-specific options considered",
|
|
332
|
-
"recommended first lane",
|
|
333
|
-
"why this lane matches the offer and ICP",
|
|
334
|
-
"expected evidence to gather",
|
|
335
|
-
"fallback lane if the first lane is weak",
|
|
336
|
-
"what approval authorizes"
|
|
337
|
-
],
|
|
338
|
-
"approvalAuthorizes": "source scouting/search only; no import/send",
|
|
339
|
-
"yoloMode": {
|
|
340
|
-
"autoApproveRecommendedLane": true,
|
|
341
|
-
"mustShowAssumedChoice": true,
|
|
342
|
-
"pauseIfConfidenceLow": true
|
|
343
|
-
}
|
|
344
|
-
},
|
|
345
|
-
"defaultWhenSourceUnspecified": [
|
|
346
|
-
"signal-discovery",
|
|
347
|
-
"sales-nav-recent-active",
|
|
348
|
-
"sales-nav-general",
|
|
349
|
-
"prospeo"
|
|
350
|
-
],
|
|
351
|
-
"userFacingFallbackOrder": [
|
|
352
|
-
"people engaging with relevant LinkedIn posts",
|
|
353
|
-
"Sales Nav to find ICP people actively posting on LinkedIn",
|
|
354
|
-
"search by titles",
|
|
355
|
-
"Prospeo for a broader account/contact path"
|
|
356
|
-
],
|
|
357
|
-
"parallelAllowedOnlyWhen": [
|
|
358
|
-
"user explicitly requested source comparison",
|
|
359
|
-
"resuming already-started parallel scouts",
|
|
360
|
-
"first viable source is borderline and one cheap fallback check is needed"
|
|
361
|
-
]
|
|
362
|
-
},
|
|
363
|
-
"onEnter": [
|
|
364
|
-
{
|
|
365
|
-
"tool": "update_campaign",
|
|
366
|
-
"requiredValues": {
|
|
367
|
-
"currentStep": "pick-provider",
|
|
368
|
-
"watchNarration.stage": "find-leads",
|
|
369
|
-
"watchNarration.headline": "Review the source plan",
|
|
370
|
-
"watchNarration.visibleState": "The browser is showing source selection before scouting starts.",
|
|
371
|
-
"watchNarration.agentIntent": "Codex is explaining the recommended campaign-specific source lane and fallback before any search runs.",
|
|
372
|
-
"watchNarration.nextAction": "Approve a scouting plan or choose another source",
|
|
373
|
-
"watchNarration.safety": "Approval here authorizes source scouting/search only; no selected-post scrape, lead import, filtering, messaging, sequence, or sending starts."
|
|
374
|
-
},
|
|
375
|
-
"purpose": "show the visible source-plan approval checkpoint before provider lanes"
|
|
376
|
-
},
|
|
377
|
-
{
|
|
378
|
-
"tool": "get_source_scout_registry",
|
|
379
|
-
"purpose": "load canonical source scout names before optional branch launch"
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
"action": "show_pre_scout_source_recommendation",
|
|
383
|
-
"uses": "request_user_input",
|
|
384
|
-
"oneShot": true,
|
|
385
|
-
"skipIf": "approved or leadSourceProvider or yolo_mode auto-selected source_lane_approved",
|
|
386
|
-
"requiredBeforeTools": [
|
|
387
|
-
"get_provider_prompt",
|
|
388
|
-
"search_signals",
|
|
389
|
-
"search_sales_nav",
|
|
390
|
-
"search_prospeo",
|
|
391
|
-
"fetch_post_engagers"
|
|
392
|
-
],
|
|
393
|
-
"requiredInlineFields": [
|
|
394
|
-
"plain-language source options for this campaign",
|
|
395
|
-
"recommended first source lane",
|
|
396
|
-
"why the lane is likely to have relevant active prospects",
|
|
397
|
-
"fallback lane if the recommended lane looks weak",
|
|
398
|
-
"what scouting will check next",
|
|
399
|
-
"what approval authorizes"
|
|
400
|
-
],
|
|
401
|
-
"choices": [
|
|
402
|
-
"Approve LinkedIn engagement scouting plan",
|
|
403
|
-
"Approve Sales Nav scouting plan",
|
|
404
|
-
"Approve Prospeo scouting plan",
|
|
405
|
-
"Choose different source",
|
|
406
|
-
"Pause here"
|
|
407
|
-
],
|
|
408
|
-
"approvalChoiceLabelsByProvider": {
|
|
409
|
-
"signal-discovery": "Approve LinkedIn engagement scouting plan",
|
|
410
|
-
"sales-nav": "Approve Sales Nav scouting plan",
|
|
411
|
-
"prospeo": "Approve Prospeo scouting plan"
|
|
412
|
-
},
|
|
413
|
-
"approvalState": "source_lane_approved"
|
|
414
|
-
},
|
|
415
|
-
{
|
|
416
|
-
"action": "persist_provider_search_step_before_search",
|
|
417
|
-
"tool": "update_campaign",
|
|
418
|
-
"requiredPrecondition": "source_lane_approved",
|
|
419
|
-
"providerCurrentStepMap": {
|
|
420
|
-
"signal-discovery": "signal-discovery",
|
|
421
|
-
"sales-nav": "sales-nav",
|
|
422
|
-
"prospeo": "prospeo"
|
|
423
|
-
},
|
|
424
|
-
"requiredValues": {
|
|
425
|
-
"leadSourceType": "new",
|
|
426
|
-
"leadSourceProvider": "approved provider",
|
|
427
|
-
"currentStep": "provider-specific current step",
|
|
428
|
-
"watchNarration.stage": "find-leads",
|
|
429
|
-
"watchNarration.headline": "Searching the approved source lane",
|
|
430
|
-
"watchNarration.safety": "Search/scouting only; no lead import or selected-post scrape starts from this update."
|
|
431
|
-
},
|
|
432
|
-
"mustRunBefore": [
|
|
433
|
-
"search_signals",
|
|
434
|
-
"search_sales_nav",
|
|
435
|
-
"search_prospeo",
|
|
436
|
-
"fetch_post_engagers"
|
|
437
|
-
]
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
"action": "run_sequential_source_funnel",
|
|
441
|
-
"requiredPrecondition": "source_lane_approved",
|
|
442
|
-
"defaultOrder": [
|
|
443
|
-
"source-scout-linkedin-engagement",
|
|
444
|
-
"source-scout-sales-nav",
|
|
445
|
-
"source-scout-prospeo-contact"
|
|
446
|
-
],
|
|
447
|
-
"campaignOfferIdRequired": true,
|
|
448
|
-
"stopOnFirstViableUnlessComparisonRequested": true
|
|
449
|
-
}
|
|
450
|
-
],
|
|
451
|
-
"requiredCampaignState": ["campaignId", "campaignBrief", "currentStep"],
|
|
452
|
-
"allowedTools": [
|
|
453
|
-
"get_source_scout_registry",
|
|
454
|
-
"get_provider_prompt",
|
|
455
|
-
"lookup_sales_nav_filter",
|
|
456
|
-
"search_sales_nav",
|
|
457
|
-
"search_prospeo",
|
|
458
|
-
"search_signals",
|
|
459
|
-
"select_promising_posts",
|
|
460
|
-
"fetch_post_engagers",
|
|
461
|
-
"fetch_company",
|
|
462
|
-
"fetch_linkedin_profile",
|
|
463
|
-
"load_csv_linkedin_leads",
|
|
464
|
-
"load_csv_domains",
|
|
465
|
-
"get_rows_minimal",
|
|
466
|
-
"update_campaign",
|
|
467
|
-
"AskUserQuestion",
|
|
468
|
-
"request_user_input"
|
|
469
|
-
],
|
|
470
|
-
"doNotAllow": [
|
|
471
|
-
"create_campaign",
|
|
472
|
-
"list_senders",
|
|
473
|
-
"save_rubrics",
|
|
474
|
-
"import_leads",
|
|
475
|
-
"confirm_lead_list",
|
|
476
|
-
"queue_cells",
|
|
477
|
-
"start_campaign"
|
|
478
|
-
],
|
|
479
|
-
"waitFor": ["lead_review_ready", "revise_brief", "confirm_with_user"],
|
|
480
|
-
"transitions": {
|
|
481
|
-
"lead_review_ready": "lead-review",
|
|
482
|
-
"revise_brief": "brief-interview",
|
|
483
|
-
"confirm_with_user": "lead-review"
|
|
484
|
-
}
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
"id": "lead-review",
|
|
488
|
-
"label": "Source approval",
|
|
489
|
-
"onEnter": [
|
|
490
|
-
{
|
|
491
|
-
"action": "show_source_decision_card",
|
|
492
|
-
"requiredInlineFields": [
|
|
493
|
-
"primary source and exact filters/recipe",
|
|
494
|
-
"specific source action awaiting approval",
|
|
495
|
-
"for Signal Discovery: compact Source Recommendation with target, raw-engager math, selected-post table, review checkpoint, estimated fit, and fallback",
|
|
496
|
-
"for Signal Discovery: selected post count and target engager/source-candidate volume",
|
|
497
|
-
"internal campaign-table execution slice size, clearly separate from source sampling",
|
|
498
|
-
"runner-up and why it lost",
|
|
499
|
-
"raw volume",
|
|
500
|
-
"sampled people",
|
|
501
|
-
"sampled fits as n/N plus percentage/range",
|
|
502
|
-
"estimated usable prospects",
|
|
503
|
-
"cleanup risk",
|
|
504
|
-
"what approval authorizes"
|
|
505
|
-
]
|
|
506
|
-
},
|
|
507
|
-
{
|
|
508
|
-
"action": "ask_source_review_choice",
|
|
509
|
-
"uses": "request_user_input",
|
|
510
|
-
"choices": [
|
|
511
|
-
"Approve scraping N selected LinkedIn posts",
|
|
512
|
-
"Run the approved source import",
|
|
513
|
-
"Revise source",
|
|
514
|
-
"Pause here"
|
|
515
|
-
],
|
|
516
|
-
"approvalChoiceLabelsByProvider": {
|
|
517
|
-
"signal-discovery": "Approve scraping {selectedPostCount} selected LinkedIn posts?",
|
|
518
|
-
"sales-nav": "Import the approved Sales Nav source list",
|
|
519
|
-
"prospeo": "Import the approved Prospeo source list"
|
|
520
|
-
},
|
|
521
|
-
"postApprovalContract": {
|
|
522
|
-
"singleUseApproval": true,
|
|
523
|
-
"doNotRepeatAfterApproval": [
|
|
524
|
-
"Source Recommendation",
|
|
525
|
-
"show_source_decision_card",
|
|
526
|
-
"ask_source_review_choice"
|
|
527
|
-
],
|
|
528
|
-
"requiredNextActionAfterApproval": "ack once; call import_leads immediately",
|
|
529
|
-
"signalDiscoveryNextTool": "import_leads({ provider: \"signal-discovery\", targetEngagerCount, maxPostsToScrape, confirmed: true })"
|
|
530
|
-
},
|
|
531
|
-
"autoSelectIf": "yolo_mode and projected usable pool clears the source quality floor"
|
|
532
|
-
}
|
|
533
|
-
],
|
|
534
|
-
"requiredCampaignState": [
|
|
535
|
-
"campaignId",
|
|
536
|
-
"campaignBrief",
|
|
537
|
-
"providerSearchAssociation"
|
|
538
|
-
],
|
|
539
|
-
"allowedTools": [
|
|
540
|
-
"AskUserQuestion",
|
|
541
|
-
"request_user_input",
|
|
542
|
-
"update_campaign"
|
|
543
|
-
],
|
|
544
|
-
"doNotAllow": [
|
|
545
|
-
"create_campaign",
|
|
546
|
-
"list_senders",
|
|
547
|
-
"save_rubrics",
|
|
548
|
-
"import_leads",
|
|
549
|
-
"confirm_lead_list",
|
|
550
|
-
"queue_cells",
|
|
551
|
-
"start_campaign"
|
|
552
|
-
],
|
|
553
|
-
"waitFor": [
|
|
554
|
-
"lead_review_confirmed",
|
|
555
|
-
"revise_leads",
|
|
556
|
-
"confirm_with_user",
|
|
557
|
-
"auto_continue"
|
|
558
|
-
],
|
|
559
|
-
"transitions": {
|
|
560
|
-
"lead_review_confirmed": "auto-execute-leads",
|
|
561
|
-
"revise_leads": "find-leads",
|
|
562
|
-
"confirm_with_user": "auto-execute-leads",
|
|
563
|
-
"auto_continue": "auto-execute-leads"
|
|
564
|
-
}
|
|
565
|
-
},
|
|
566
|
-
{
|
|
567
|
-
"id": "auto-execute-leads",
|
|
568
|
-
"label": "Materialize confirmed source list",
|
|
569
|
-
"currentStepValue": "auto-execute-leads",
|
|
570
|
-
"reference": "references/step-13-import-leads.md",
|
|
571
|
-
"onEnter": [
|
|
572
|
-
{
|
|
573
|
-
"tool": "get_subskill_prompt",
|
|
574
|
-
"requiredValues": {
|
|
575
|
-
"subskillName": "create-campaign-v2-tail"
|
|
576
|
-
},
|
|
577
|
-
"purpose": "load tail contract before execution tools"
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
"tool": "import_leads",
|
|
581
|
-
"requiredFields": [
|
|
582
|
-
"campaignOfferId",
|
|
583
|
-
"selected source/list",
|
|
584
|
-
"sourceListTarget or targetEngagerCount"
|
|
585
|
-
],
|
|
586
|
-
"requiredValues": {
|
|
587
|
-
"salesNavProspeoDefaultSourceListTarget": 1000,
|
|
588
|
-
"signalDiscoveryDefaultEngagerTarget": 1500
|
|
589
|
-
},
|
|
590
|
-
"modeAddHandshake": {
|
|
591
|
-
"firstCallReturns": "needsModeSelection when adding to an existing campaign-attached list",
|
|
592
|
-
"requiredFollowup": "retry with mode=add after explicit user/source-state compatibility is confirmed"
|
|
593
|
-
},
|
|
594
|
-
"surfaceDedupRatio": true
|
|
595
|
-
},
|
|
596
|
-
{
|
|
597
|
-
"tool": "wait_for_lead_list_ready"
|
|
598
|
-
},
|
|
599
|
-
{
|
|
600
|
-
"tool": "confirm_lead_list",
|
|
601
|
-
"requiredFields": [
|
|
602
|
-
"campaignOfferId",
|
|
603
|
-
"selectedLeadListId",
|
|
604
|
-
"reviewBatchLimit"
|
|
605
|
-
],
|
|
606
|
-
"requiredValues": {
|
|
607
|
-
"reviewBatchLimit": 15
|
|
608
|
-
},
|
|
609
|
-
"capture": ["workflowTableId", "reviewBatchRowIds"]
|
|
610
|
-
},
|
|
611
|
-
{
|
|
612
|
-
"tool": "wait_for_campaign_table_ready"
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
"tool": "get_rows_minimal",
|
|
616
|
-
"requiredValues": {
|
|
617
|
-
"tableId": "{workflowTableId}",
|
|
618
|
-
"limit": 15
|
|
619
|
-
},
|
|
620
|
-
"capture": ["reviewBatchRowHash"]
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
"action": "summarize_review_batch_and_advance_to_filter_choice",
|
|
624
|
-
"purpose": "ask filter choice immediately; no post-lead registries, filter refs, or message prompts first",
|
|
625
|
-
"maxCustomerCopyLines": 4
|
|
626
|
-
}
|
|
627
|
-
],
|
|
628
|
-
"requiredCampaignState": [
|
|
629
|
-
"campaignId",
|
|
630
|
-
"providerSearchAssociation",
|
|
631
|
-
"selectedLeadListId"
|
|
632
|
-
],
|
|
633
|
-
"allowedTools": [
|
|
634
|
-
"get_subskill_prompt",
|
|
635
|
-
"import_leads",
|
|
636
|
-
"wait_for_lead_list_ready",
|
|
637
|
-
"confirm_lead_list",
|
|
638
|
-
"wait_for_campaign_table_ready",
|
|
639
|
-
"get_rows_minimal",
|
|
640
|
-
"update_campaign",
|
|
641
|
-
"AskUserQuestion",
|
|
642
|
-
"request_user_input"
|
|
643
|
-
],
|
|
644
|
-
"doNotAllow": [
|
|
645
|
-
"get_post_find_leads_scout_registry",
|
|
646
|
-
"Task",
|
|
647
|
-
"spawn_agent",
|
|
648
|
-
"list_senders",
|
|
649
|
-
"queue_cells",
|
|
650
|
-
"start_campaign",
|
|
651
|
-
"enrich_with_prospeo",
|
|
652
|
-
"bulk_enrich_with_prospeo",
|
|
653
|
-
"save_rubrics"
|
|
654
|
-
],
|
|
655
|
-
"waitFor": "source_list_confirmed_and_review_sample_ready",
|
|
656
|
-
"transitions": {
|
|
657
|
-
"source_list_confirmed_and_review_sample_ready": "filter-choice",
|
|
658
|
-
"escalation_triggered": "escalation"
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
{
|
|
662
|
-
"id": "filter-choice",
|
|
663
|
-
"label": "Filter choice",
|
|
664
|
-
"currentStepValue": "filter-choice",
|
|
665
|
-
"onEnter": [
|
|
666
|
-
{
|
|
667
|
-
"tool": "update_campaign",
|
|
668
|
-
"requiredValues": {
|
|
669
|
-
"currentStep": "filter-choice",
|
|
670
|
-
"watchNarration.stage": "fit-message"
|
|
671
|
-
}
|
|
672
|
-
},
|
|
673
|
-
{
|
|
674
|
-
"action": "ask_filter_choice",
|
|
675
|
-
"uses": "request_user_input",
|
|
676
|
-
"choices": ["Use filters", "Skip filters", "Revise source"],
|
|
677
|
-
"autoSelectIf": "yolo_mode; choose filters unless source is tightly curated or user directed otherwise"
|
|
678
|
-
}
|
|
679
|
-
],
|
|
680
|
-
"hardRules": [
|
|
681
|
-
"ask_filter_choice_immediately_after_review_batch_import",
|
|
682
|
-
"do_not_call_get_subskill_prompt_before_filter_choice",
|
|
683
|
-
"do_not_call_get_subskill_asset_before_filter_choice",
|
|
684
|
-
"do_not_call_get_post_find_leads_scout_registry_before_filter_choice",
|
|
685
|
-
"do_not_spawn_post_lead_agents_before_filter_choice"
|
|
686
|
-
],
|
|
687
|
-
"requiredCampaignState": [
|
|
688
|
-
"campaignId",
|
|
689
|
-
"campaignBrief",
|
|
690
|
-
"selectedLeadListId",
|
|
691
|
-
"workflowTableId"
|
|
692
|
-
],
|
|
693
|
-
"allowedTools": [
|
|
694
|
-
"AskUserQuestion",
|
|
695
|
-
"request_user_input",
|
|
696
|
-
"update_campaign",
|
|
697
|
-
"get_campaign_navigation_state"
|
|
698
|
-
],
|
|
699
|
-
"doNotAllow": [
|
|
700
|
-
"get_subskill_prompt",
|
|
701
|
-
"get_subskill_asset",
|
|
702
|
-
"get_post_find_leads_scout_registry",
|
|
703
|
-
"Task",
|
|
704
|
-
"spawn_agent",
|
|
705
|
-
"create_campaign",
|
|
706
|
-
"list_senders",
|
|
707
|
-
"import_leads",
|
|
708
|
-
"confirm_lead_list",
|
|
709
|
-
"queue_cells",
|
|
710
|
-
"start_campaign",
|
|
711
|
-
"generate_messages"
|
|
712
|
-
],
|
|
713
|
-
"waitFor": ["filters_enabled", "filters_skipped", "revise_leads"],
|
|
714
|
-
"transitions": {
|
|
715
|
-
"filters_enabled": "post-lead-workstreams",
|
|
716
|
-
"filters_skipped": "message-generation",
|
|
717
|
-
"revise_leads": "find-leads"
|
|
718
|
-
}
|
|
719
|
-
},
|
|
720
|
-
{
|
|
721
|
-
"id": "post-lead-workstreams",
|
|
722
|
-
"label": "Filter workstream",
|
|
723
|
-
"onEnter": [
|
|
724
|
-
{
|
|
725
|
-
"action": "persist_add_filters_approval",
|
|
726
|
-
"tool": "update_campaign",
|
|
727
|
-
"when": "filters_enabled",
|
|
728
|
-
"requiredFields": [
|
|
729
|
-
"campaignId",
|
|
730
|
-
"enableICPFilters",
|
|
731
|
-
"currentStep",
|
|
732
|
-
"watchNarration"
|
|
733
|
-
],
|
|
734
|
-
"requiredValues": {
|
|
735
|
-
"enableICPFilters": true,
|
|
736
|
-
"currentStep": "create-icp-rubric",
|
|
737
|
-
"watchNarration.stage": "fit-message",
|
|
738
|
-
"watchNarration.headline": "Create filter rules",
|
|
739
|
-
"watchNarration.visibleState": "Filters are enabled and the browser is showing Filter Rules while Codex defines the rubric.",
|
|
740
|
-
"watchNarration.nextAction": "Review saved filter rules"
|
|
741
|
-
},
|
|
742
|
-
"mustRunBefore": [
|
|
743
|
-
"get_post_find_leads_scout_registry",
|
|
744
|
-
"launch_lead_fit_builder_after_filter_choice",
|
|
745
|
-
"save_rubrics"
|
|
746
|
-
]
|
|
747
|
-
},
|
|
748
|
-
{
|
|
749
|
-
"tool": "get_post_find_leads_scout_registry",
|
|
750
|
-
"purpose": "load canonical post-lead worker names only after the user has chosen filters"
|
|
751
|
-
},
|
|
752
|
-
{
|
|
753
|
-
"action": "launch_lead_fit_builder_after_filter_choice",
|
|
754
|
-
"mode": "parallel_when_host_supports_subagents",
|
|
755
|
-
"target": "post-find-leads-filter-scout",
|
|
756
|
-
"inputs": [
|
|
757
|
-
"campaignId",
|
|
758
|
-
"campaignBrief",
|
|
759
|
-
"selectedLeadListId",
|
|
760
|
-
"workflowTableId",
|
|
761
|
-
"reviewBatchRowIds/hash",
|
|
762
|
-
"filterChoice"
|
|
763
|
-
],
|
|
764
|
-
"stateSource": "live campaign/table",
|
|
765
|
-
"debugFilesOptionalOnly": true
|
|
766
|
-
},
|
|
767
|
-
{
|
|
768
|
-
"action": "launch_message_draft_builder_after_filter_decision",
|
|
769
|
-
"mode": "parallel_when_host_supports_subagents",
|
|
770
|
-
"target": "post-find-leads-message-scout",
|
|
771
|
-
"when": "filters_enabled",
|
|
772
|
-
"doesNotQueueCells": true,
|
|
773
|
-
"customerNarration": "Say message agent is drafting."
|
|
774
|
-
},
|
|
775
|
-
{
|
|
776
|
-
"action": "save_filter_rubrics_to_campaign",
|
|
777
|
-
"tool": "save_rubrics",
|
|
778
|
-
"when": "filters_enabled and rubrics are production-shaped",
|
|
779
|
-
"requiredFields": ["campaignOfferId", "leadScoringRubrics"],
|
|
780
|
-
"writesCampaignState": "leadScoringRubrics",
|
|
781
|
-
"requiredSideEffects": {
|
|
782
|
-
"enableICPFilters": true,
|
|
783
|
-
"currentStep": "create-icp-rubric",
|
|
784
|
-
"watchNarration.headline": "Filter rules saved for review"
|
|
785
|
-
}
|
|
786
|
-
},
|
|
787
|
-
{
|
|
788
|
-
"action": "ask_filter_rubric_review_choice",
|
|
789
|
-
"uses": "request_user_input",
|
|
790
|
-
"choices": ["Approve filters", "Revise filters", "Pause"],
|
|
791
|
-
"purpose": "let the user read saved rubrics before Filter Leads or enrichment",
|
|
792
|
-
"autoSelectIf": "yolo_mode and rubrics are production-shaped"
|
|
793
|
-
}
|
|
794
|
-
],
|
|
795
|
-
"requiredCampaignState": [
|
|
796
|
-
"campaignId",
|
|
797
|
-
"campaignBrief",
|
|
798
|
-
"selectedLeadListId",
|
|
799
|
-
"workflowTableId"
|
|
800
|
-
],
|
|
801
|
-
"allowedTools": [
|
|
802
|
-
"get_subskill_prompt",
|
|
803
|
-
"get_subskill_asset",
|
|
804
|
-
"get_post_find_leads_scout_registry",
|
|
805
|
-
"save_rubrics",
|
|
806
|
-
"get_campaign",
|
|
807
|
-
"get_rows_minimal",
|
|
808
|
-
"update_campaign",
|
|
809
|
-
"get_campaign_navigation_state",
|
|
810
|
-
"AskUserQuestion",
|
|
811
|
-
"request_user_input",
|
|
812
|
-
"Task",
|
|
813
|
-
"spawn_agent"
|
|
814
|
-
],
|
|
815
|
-
"doNotAllow": [
|
|
816
|
-
"create_campaign",
|
|
817
|
-
"list_senders",
|
|
818
|
-
"import_leads",
|
|
819
|
-
"confirm_lead_list",
|
|
820
|
-
"queue_cells",
|
|
821
|
-
"start_campaign",
|
|
822
|
-
"check_rubric",
|
|
823
|
-
"generate_messages"
|
|
824
|
-
],
|
|
825
|
-
"waitFor": [
|
|
826
|
-
"filter_rubrics_approved",
|
|
827
|
-
"revise_leads",
|
|
828
|
-
"revise_rubric",
|
|
829
|
-
"revise_messaging"
|
|
830
|
-
],
|
|
831
|
-
"hardRules": [
|
|
832
|
-
"after_save_rubrics_currentStep_must_stay_create-icp-rubric_until_filter_approval",
|
|
833
|
-
"filter_approval_required_before_apply-icp-rubric_or_queue_cells",
|
|
834
|
-
"do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped",
|
|
835
|
-
"no_post_lead_worker_or_deep_prompt_before_filter_choice",
|
|
836
|
-
"lead_fit_builder_starts_only_after_filters_enabled",
|
|
837
|
-
"msg_draft_after_filter_choice",
|
|
838
|
-
"msg_draft_no_cells"
|
|
839
|
-
],
|
|
840
|
-
"transitions": {
|
|
841
|
-
"filter_rubrics_approved": "message-generation",
|
|
842
|
-
"revise_leads": "find-leads",
|
|
843
|
-
"revise_rubric": "filter-rubric",
|
|
844
|
-
"revise_messaging": "message-generation",
|
|
845
|
-
"confirm_with_user": "message-review"
|
|
846
|
-
}
|
|
847
|
-
},
|
|
848
|
-
{
|
|
849
|
-
"id": "filter-rubric",
|
|
850
|
-
"label": "Rubric revision",
|
|
851
|
-
"onEnter": [
|
|
852
|
-
{
|
|
853
|
-
"tool": "get_subskill_asset",
|
|
854
|
-
"requiredValues": {
|
|
855
|
-
"subskillName": "create-campaign-v2",
|
|
856
|
-
"assetPath": "references/filter-leads.md"
|
|
857
|
-
}
|
|
858
|
-
},
|
|
859
|
-
{
|
|
860
|
-
"tool": "save_rubrics",
|
|
861
|
-
"requiredFields": ["campaignOfferId", "leadScoringRubrics"],
|
|
862
|
-
"writesCampaignState": "leadScoringRubrics",
|
|
863
|
-
"requiredSideEffects": {
|
|
864
|
-
"enableICPFilters": true,
|
|
865
|
-
"currentStep": "create-icp-rubric",
|
|
866
|
-
"watchNarration.headline": "Filter rules saved for review"
|
|
867
|
-
}
|
|
868
|
-
},
|
|
869
|
-
{
|
|
870
|
-
"action": "ask_filter_rubric_review_choice",
|
|
871
|
-
"uses": "request_user_input",
|
|
872
|
-
"choices": ["Approve filters", "Revise filters", "Pause"],
|
|
873
|
-
"autoSelectIf": "yolo_mode and rubrics are production-shaped"
|
|
874
|
-
}
|
|
875
|
-
],
|
|
876
|
-
"requiredCampaignState": ["campaignId", "workflowTableId"],
|
|
877
|
-
"allowedTools": [
|
|
878
|
-
"get_subskill_asset",
|
|
879
|
-
"save_rubrics",
|
|
880
|
-
"AskUserQuestion",
|
|
881
|
-
"request_user_input"
|
|
882
|
-
],
|
|
883
|
-
"doNotAllow": [
|
|
884
|
-
"create_campaign",
|
|
885
|
-
"list_senders",
|
|
886
|
-
"import_leads",
|
|
887
|
-
"confirm_lead_list",
|
|
888
|
-
"update_campaign",
|
|
889
|
-
"queue_cells",
|
|
890
|
-
"start_campaign",
|
|
891
|
-
"check_rubric"
|
|
892
|
-
],
|
|
893
|
-
"waitFor": [
|
|
894
|
-
"filter_rubrics_approved",
|
|
895
|
-
"revise_leads",
|
|
896
|
-
"confirm_with_user",
|
|
897
|
-
"auto_continue"
|
|
898
|
-
],
|
|
899
|
-
"transitions": {
|
|
900
|
-
"filter_rubrics_approved": "message-generation",
|
|
901
|
-
"revise_leads": "find-leads",
|
|
902
|
-
"confirm_with_user": "message-generation",
|
|
903
|
-
"auto_continue": "message-generation"
|
|
904
|
-
}
|
|
905
|
-
},
|
|
906
|
-
{
|
|
907
|
-
"id": "message-generation",
|
|
908
|
-
"label": "Message generation",
|
|
909
|
-
"onEnter": [
|
|
910
|
-
{
|
|
911
|
-
"action": "set_message_review_visible_step_by_filter_choice",
|
|
912
|
-
"tool": "update_campaign",
|
|
913
|
-
"branchRules": [
|
|
914
|
-
"yes after filter approval: currentStep=apply-icp-rubric; wait on Filter Leads",
|
|
915
|
-
"no: currentStep=messages; message review"
|
|
916
|
-
],
|
|
917
|
-
"watchNarration.stage": "fit-message"
|
|
918
|
-
},
|
|
919
|
-
{
|
|
920
|
-
"action": "run_or_reconcile_message_draft_builder",
|
|
921
|
-
"target": "post-find-leads-message-scout",
|
|
922
|
-
"toolCallRequiredBeforeDraft": [
|
|
923
|
-
"run background post-find-leads-message-scout when available",
|
|
924
|
-
"get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false"
|
|
925
|
-
],
|
|
926
|
-
"stateSource": "campaignBrief, source, selectedLeadListId, workflowTableId, execution-slice row ids/hash",
|
|
927
|
-
"outputState": "messageDraftRecommendation"
|
|
928
|
-
}
|
|
929
|
-
],
|
|
930
|
-
"requiredCampaignState": [
|
|
931
|
-
"campaignId",
|
|
932
|
-
"campaignBrief",
|
|
933
|
-
"selectedLeadListId",
|
|
934
|
-
"workflowTableId"
|
|
935
|
-
],
|
|
936
|
-
"allowedTools": [
|
|
937
|
-
"get_subskill_prompt",
|
|
938
|
-
"get_campaign",
|
|
939
|
-
"get_rows_minimal",
|
|
940
|
-
"update_campaign",
|
|
941
|
-
"AskUserQuestion",
|
|
942
|
-
"request_user_input"
|
|
943
|
-
],
|
|
944
|
-
"toolRules": [
|
|
945
|
-
"Run post-find-leads-message-scout when available; otherwise parent fallback must load get_subskill_prompt({ subskillName: \"generate-messages\" }) from live state.",
|
|
946
|
-
"brief.md, lead-review.md, and lead-sample.json are optional debug context only.",
|
|
947
|
-
"messageDraftRecommendation returns templateRecommendation, tokenFillRules, renderedSample, concerns, status, basisToken, outputAt, outputHash, and error/retry detail.",
|
|
948
|
-
"If campaign/source/table/execution-slice basis does not match, classify the output stale or blocked."
|
|
949
|
-
],
|
|
950
|
-
"doNotAllow": [
|
|
951
|
-
"create_campaign",
|
|
952
|
-
"list_senders",
|
|
953
|
-
"save_rubrics",
|
|
954
|
-
"import_leads",
|
|
955
|
-
"confirm_lead_list",
|
|
956
|
-
"queue_cells",
|
|
957
|
-
"start_campaign",
|
|
958
|
-
"generate_messages"
|
|
959
|
-
],
|
|
960
|
-
"waitFor": [
|
|
961
|
-
"message_validation_ready",
|
|
962
|
-
"revise_rubric",
|
|
963
|
-
"revise_messaging",
|
|
964
|
-
"confirm_with_user",
|
|
965
|
-
"auto_continue"
|
|
966
|
-
],
|
|
967
|
-
"transitions": {
|
|
968
|
-
"message_validation_ready": "message-review",
|
|
969
|
-
"revise_rubric": "filter-rubric",
|
|
970
|
-
"revise_messaging": "message-generation",
|
|
971
|
-
"confirm_with_user": "message-review",
|
|
972
|
-
"auto_continue": "message-review"
|
|
973
|
-
}
|
|
974
|
-
},
|
|
975
|
-
{
|
|
976
|
-
"id": "message-review",
|
|
977
|
-
"label": "Message review",
|
|
978
|
-
"onEnter": [
|
|
979
|
-
{
|
|
980
|
-
"action": "render_message_review_from_state",
|
|
981
|
-
"requiredState": [
|
|
982
|
-
"campaignBrief",
|
|
983
|
-
"selectedLeadListId",
|
|
984
|
-
"workflowTableId",
|
|
985
|
-
"messageDraftRecommendation"
|
|
986
|
-
],
|
|
987
|
-
"requiredVisibleLabels": [
|
|
988
|
-
"## Message Template",
|
|
989
|
-
"## Rendered Example",
|
|
990
|
-
"Good token fill:",
|
|
991
|
-
"My take:",
|
|
992
|
-
"Question: approve-message or revise-messaging?",
|
|
993
|
-
"Recommendation:"
|
|
994
|
-
],
|
|
995
|
-
"doNotShowByDefault": [
|
|
996
|
-
"Token Notes",
|
|
997
|
-
"Good omit / fallback",
|
|
998
|
-
"Bad fill to avoid",
|
|
999
|
-
"Token Adherence Table"
|
|
1000
|
-
],
|
|
1001
|
-
"internalPersistenceOnly": [
|
|
1002
|
-
"Token Fill Rules",
|
|
1003
|
-
"Token Fill Examples",
|
|
1004
|
-
"fallback guidance",
|
|
1005
|
-
"bad-fill avoidance notes"
|
|
1006
|
-
]
|
|
1007
|
-
},
|
|
1008
|
-
{
|
|
1009
|
-
"action": "ask_message_review_choice",
|
|
1010
|
-
"uses": "request_user_input",
|
|
1011
|
-
"choices": ["approve-message", "revise-messaging"],
|
|
1012
|
-
"autoSelectIf": "yolo_mode and Recommendation is approve-message; revise autonomously when Recommendation is revise-messaging"
|
|
1013
|
-
},
|
|
1014
|
-
{
|
|
1015
|
-
"action": "sync_approved_message_set_to_campaign_brief",
|
|
1016
|
-
"tool": "update_campaign_brief",
|
|
1017
|
-
"when": "after approve-message",
|
|
1018
|
-
"requiredFields": [
|
|
1019
|
-
"campaignId",
|
|
1020
|
-
"approvedMessageTemplate",
|
|
1021
|
-
"Token Fill Rules",
|
|
1022
|
-
"Token Fill Examples"
|
|
1023
|
-
],
|
|
1024
|
-
"writesCampaignState": "approvedMessageTemplate"
|
|
1025
|
-
}
|
|
1026
|
-
],
|
|
1027
|
-
"requiredCampaignState": [
|
|
1028
|
-
"campaignId",
|
|
1029
|
-
"workflowTableId",
|
|
1030
|
-
"messageDraftRecommendation"
|
|
1031
|
-
],
|
|
1032
|
-
"allowedTools": [
|
|
1033
|
-
"AskUserQuestion",
|
|
1034
|
-
"request_user_input",
|
|
1035
|
-
"update_campaign_brief",
|
|
1036
|
-
"update_campaign",
|
|
1037
|
-
"get_rows_minimal"
|
|
1038
|
-
],
|
|
1039
|
-
"doNotAllow": [
|
|
1040
|
-
"create_campaign",
|
|
1041
|
-
"list_senders",
|
|
1042
|
-
"save_rubrics",
|
|
1043
|
-
"import_leads",
|
|
1044
|
-
"confirm_lead_list",
|
|
1045
|
-
"start_campaign"
|
|
1046
|
-
],
|
|
1047
|
-
"waitFor": ["message_approved", "revise_messaging"],
|
|
1048
|
-
"transitions": {
|
|
1049
|
-
"message_approved": "validate-sample",
|
|
1050
|
-
"revise_messaging": "message-generation"
|
|
1051
|
-
}
|
|
1052
|
-
},
|
|
1053
|
-
{
|
|
1054
|
-
"id": "validate-sample",
|
|
1055
|
-
"label": "Validate campaign-table execution slice",
|
|
1056
|
-
"currentStepValue": "apply-icp-rubric",
|
|
1057
|
-
"reference": "references/sample-validation-loop.md",
|
|
1058
|
-
"visibleStepRule": "Filter Leads is reached only after saved-filter approval. On approve-message, save the template, refresh apply-icp-rubric narration, then queue bounded Enrich Prospect cells.",
|
|
1059
|
-
"onEnter": [
|
|
1060
|
-
{
|
|
1061
|
-
"tool": "update_campaign",
|
|
1062
|
-
"requiredValues": {
|
|
1063
|
-
"currentStep": "apply-icp-rubric",
|
|
1064
|
-
"watchNarration.stage": "fit-message"
|
|
1065
|
-
},
|
|
1066
|
-
"purpose": "keep the watched UI on Filter Leads while the approved template starts the bounded cascade",
|
|
1067
|
-
"watchNarrationRule": "Say the template is saved and Filter Leads is now running the bounded enrichment and scoring pass."
|
|
1068
|
-
},
|
|
1069
|
-
{
|
|
1070
|
-
"tool": "queue_cells",
|
|
1071
|
-
"purpose": "queue ICP/enrichment cells for the internal campaign-table execution slice only",
|
|
1072
|
-
"requiredFields": [
|
|
1073
|
-
"workflowTableId",
|
|
1074
|
-
"reviewBatchRowIds",
|
|
1075
|
-
"cellTypes"
|
|
1076
|
-
],
|
|
1077
|
-
"targetCountSource": "reviewBatchRowIds.length (default 15)"
|
|
1078
|
-
},
|
|
1079
|
-
{
|
|
1080
|
-
"tool": "wait_for_campaign_table_ready",
|
|
1081
|
-
"purpose": "wait_for_review_batch_scoring_cells"
|
|
1082
|
-
},
|
|
1083
|
-
{
|
|
1084
|
-
"tool": "get_rows_minimal",
|
|
1085
|
-
"requiredValues": {
|
|
1086
|
-
"includeRows": false
|
|
1087
|
-
},
|
|
1088
|
-
"purpose": "read compact row status only"
|
|
1089
|
-
},
|
|
1090
|
-
{
|
|
1091
|
-
"tool": "wait_for_rubric_results",
|
|
1092
|
-
"requiredFields": [
|
|
1093
|
-
"workflowTableId",
|
|
1094
|
-
"targetCount",
|
|
1095
|
-
"minPassedCount"
|
|
1096
|
-
],
|
|
1097
|
-
"requiredValues": {
|
|
1098
|
-
"includeRows": false,
|
|
1099
|
-
"minPassedCount": 1
|
|
1100
|
-
},
|
|
1101
|
-
"minPassedCountSource": "firstPassingRowForMessageStart",
|
|
1102
|
-
"readVia": "stats_only_tool_result"
|
|
1103
|
-
},
|
|
1104
|
-
{
|
|
1105
|
-
"action": "handle_partial_or_timeout_sample",
|
|
1106
|
-
"customerStatus": "sample-needs-revision",
|
|
1107
|
-
"rule": "Do not repeat waits indefinitely; surface partial status and route to revision."
|
|
1108
|
-
}
|
|
1109
|
-
],
|
|
1110
|
-
"requiredCampaignState": [
|
|
1111
|
-
"campaignId",
|
|
1112
|
-
"workflowTableId",
|
|
1113
|
-
"approvedMessageTemplate",
|
|
1114
|
-
"filterRubricsApproved when enableICPFilters=true"
|
|
1115
|
-
],
|
|
1116
|
-
"allowedTools": [
|
|
1117
|
-
"get_subskill_asset",
|
|
1118
|
-
"queue_cells",
|
|
1119
|
-
"wait_for_campaign_table_ready",
|
|
1120
|
-
"get_rows_minimal",
|
|
1121
|
-
"wait_for_rubric_results",
|
|
1122
|
-
"update_campaign",
|
|
1123
|
-
"AskUserQuestion",
|
|
1124
|
-
"request_user_input"
|
|
1125
|
-
],
|
|
1126
|
-
"doNotAllow": [
|
|
1127
|
-
"import_leads",
|
|
1128
|
-
"list_senders",
|
|
1129
|
-
"start_campaign",
|
|
1130
|
-
"enrich_with_prospeo",
|
|
1131
|
-
"bulk_enrich_with_prospeo",
|
|
1132
|
-
"check_rubric"
|
|
1133
|
-
],
|
|
1134
|
-
"hardRules": [
|
|
1135
|
-
"wait_for_rubric_results_never_retain_rows_payload_in_tail_context",
|
|
1136
|
-
"wait_for_rubric_results_targetCount_always_explicit",
|
|
1137
|
-
"timeout_never_repeats_without_customer_handoff",
|
|
1138
|
-
"timeout_or_underfloor_sample_never_advances_to_settings"
|
|
1139
|
-
],
|
|
1140
|
-
"waitFor": ["sample_validated", "sample_revision_required"],
|
|
1141
|
-
"transitions": {
|
|
1142
|
-
"sample_validated": "auto-execute-messaging",
|
|
1143
|
-
"sample_revision_required": "lead-review",
|
|
1144
|
-
"revise_leads": "find-leads",
|
|
1145
|
-
"revise_rubric": "filter-rubric",
|
|
1146
|
-
"escalation_triggered": "escalation"
|
|
1147
|
-
}
|
|
1148
|
-
},
|
|
1149
|
-
{
|
|
1150
|
-
"id": "auto-execute-messaging",
|
|
1151
|
-
"label": "Generate initial campaign-row messages",
|
|
1152
|
-
"currentStepValue": "auto-execute-messaging",
|
|
1153
|
-
"references": [
|
|
1154
|
-
"references/parallel-critique-protocol.md",
|
|
1155
|
-
"references/thomas-variant-selection.md",
|
|
1156
|
-
"references/thomas-revision-filters.md",
|
|
1157
|
-
"references/step-15-re-cascade.md"
|
|
1158
|
-
],
|
|
1159
|
-
"onEnter": [
|
|
1160
|
-
{
|
|
1161
|
-
"tool": "queue_cells",
|
|
1162
|
-
"batchSize": 100,
|
|
1163
|
-
"when": "any passing row has pending or empty Generate Message cell",
|
|
1164
|
-
"cellSource": "pending_generate_message_cells_for_passing_rows using approved_campaign_brief_template"
|
|
1165
|
-
},
|
|
1166
|
-
{
|
|
1167
|
-
"tool": "wait_for_rubric_results",
|
|
1168
|
-
"purpose": "wait_for_first_passing_generated_message",
|
|
1169
|
-
"requiredValues": {
|
|
1170
|
-
"includeRows": false,
|
|
1171
|
-
"minPassedCount": 1,
|
|
1172
|
-
"minMessagesCount": 1
|
|
1173
|
-
},
|
|
1174
|
-
"readVia": "stats_only_tool_result"
|
|
1175
|
-
},
|
|
1176
|
-
{
|
|
1177
|
-
"action": "observe_generate_message_results",
|
|
1178
|
-
"reference": "references/step-15-re-cascade.md"
|
|
1179
|
-
},
|
|
1180
|
-
{
|
|
1181
|
-
"action": "enforce_token_contract",
|
|
1182
|
-
"modeFromConfig": "messaging.tokenContract"
|
|
1183
|
-
},
|
|
1184
|
-
{
|
|
1185
|
-
"action": "optional_critique_pass",
|
|
1186
|
-
"enabledFromConfig": "messaging.critique.enabled",
|
|
1187
|
-
"plan": "85-03",
|
|
1188
|
-
"protocol": "references/parallel-critique-protocol.md",
|
|
1189
|
-
"sampleSizeFromConfig": "messaging.critique.sampleSize",
|
|
1190
|
-
"budgetUsdCapFromConfig": "messaging.critique.budgetUsdCap",
|
|
1191
|
-
"perCriticTimeoutFromConfig": "messaging.critique.perCriticTimeoutSeconds",
|
|
1192
|
-
"totalTimeoutFromConfig": "messaging.critique.totalTimeoutSeconds",
|
|
1193
|
-
"criticsFromConfig": "messaging.critique.critics",
|
|
1194
|
-
"enforceFinalizerPassFromConfig": "messaging.critique.synthesis.enforceFinalizerPass",
|
|
1195
|
-
"rejectOnFakeProofFromConfig": "messaging.critique.rejectOnFakeProof",
|
|
1196
|
-
"rejectOnUnsupportedTokenFromConfig": "messaging.critique.rejectOnUnsupportedToken",
|
|
1197
|
-
"onBudgetTrip": "halt_critique_continue_plain_tail",
|
|
1198
|
-
"onPerCriticTimeout": "drop_critic_proceed_with_remaining",
|
|
1199
|
-
"onTotalTimeout": "persist_plain_message_for_row",
|
|
1200
|
-
"onTokenContractViolation": "persist_plain_message_for_row",
|
|
1201
|
-
"onFakeProof": "persist_plain_message_for_row"
|
|
1202
|
-
},
|
|
1203
|
-
{
|
|
1204
|
-
"action": "optional_opus_subset",
|
|
1205
|
-
"enabledFromConfig": "messaging.critique.opus.enabled",
|
|
1206
|
-
"selection": "references/thomas-variant-selection.md",
|
|
1207
|
-
"maxMessagesPerPassFromConfig": "messaging.critique.opus.maxMessagesPerPass",
|
|
1208
|
-
"budgetUsdCapFromConfig": "messaging.critique.opus.budgetUsdCap",
|
|
1209
|
-
"onOpusBudgetTrip": "halt_opus_continue_non_opus",
|
|
1210
|
-
"onOpusTokenContractViolation": "fallback_to_non_opus_rewrite"
|
|
1211
|
-
},
|
|
1212
|
-
{
|
|
1213
|
-
"tool": "update_campaign",
|
|
1214
|
-
"requiredValues": {
|
|
1215
|
-
"currentStep": "auto-execute-messaging",
|
|
1216
|
-
"watchNarration.stage": "review-ready"
|
|
1217
|
-
},
|
|
1218
|
-
"watchNarrationRule": "Say the first passing generated message is ready in Messages; next is review before Settings."
|
|
1219
|
-
},
|
|
1220
|
-
{
|
|
1221
|
-
"action": "ask_generated_message_review_choice",
|
|
1222
|
-
"uses": "request_user_input",
|
|
1223
|
-
"choices": [
|
|
1224
|
-
"Approve generated message and continue to Settings",
|
|
1225
|
-
"Revise filters",
|
|
1226
|
-
"Revise message template",
|
|
1227
|
-
"Pause here"
|
|
1228
|
-
],
|
|
1229
|
-
"autoSelectIf": "yolo_mode and the first passing generated message clears the quality floor"
|
|
1230
|
-
}
|
|
1231
|
-
],
|
|
1232
|
-
"allowedTools": [
|
|
1233
|
-
"get_subskill_asset",
|
|
1234
|
-
"get_rows_minimal",
|
|
1235
|
-
"queue_cells",
|
|
1236
|
-
"wait_for_rubric_results",
|
|
1237
|
-
"update_campaign",
|
|
1238
|
-
"AskUserQuestion",
|
|
1239
|
-
"request_user_input"
|
|
1240
|
-
],
|
|
1241
|
-
"doNotAllow": [
|
|
1242
|
-
"import_leads",
|
|
1243
|
-
"list_senders",
|
|
1244
|
-
"start_campaign",
|
|
1245
|
-
"generate_messages"
|
|
1246
|
-
],
|
|
1247
|
-
"hardRules": [
|
|
1248
|
-
"critique_failure_never_escalates",
|
|
1249
|
-
"critique_sample_size_bounded_by_config",
|
|
1250
|
-
"first_passing_generated_message_unblocks_review",
|
|
1251
|
-
"critics_fixed_at_targeting_copy_voice",
|
|
1252
|
-
"synthesis_enforces_phase_84_token_contract",
|
|
1253
|
-
"opus_reserved_for_highest_value_subset",
|
|
1254
|
-
"proposed_token_never_persisted_in_rewrite"
|
|
1255
|
-
],
|
|
1256
|
-
"waitFor": ["generated_messages_approved", "sample_revision_required"],
|
|
1257
|
-
"transitions": {
|
|
1258
|
-
"generated_messages_approved": "awaiting-user-greenlight",
|
|
1259
|
-
"revise_filters": "filter-rubric",
|
|
1260
|
-
"revise_messaging": "message-generation",
|
|
1261
|
-
"escalation_triggered": "escalation"
|
|
1262
|
-
}
|
|
1263
|
-
},
|
|
1264
|
-
{
|
|
1265
|
-
"id": "awaiting-user-greenlight",
|
|
1266
|
-
"label": "Settings, sender, sequence, and greenlight",
|
|
1267
|
-
"currentStepValue": "awaiting-user-greenlight",
|
|
1268
|
-
"reference": "references/final-handoff-contract.md",
|
|
1269
|
-
"onEnter": [
|
|
1270
|
-
{
|
|
1271
|
-
"tool": "get_campaign",
|
|
1272
|
-
"purpose": "verify senderIds and sequence state before final handoff"
|
|
1273
|
-
},
|
|
1274
|
-
{
|
|
1275
|
-
"tool": "list_senders",
|
|
1276
|
-
"purpose": "surface available connected senders only at Settings"
|
|
1277
|
-
},
|
|
1278
|
-
{
|
|
1279
|
-
"tool": "update_campaign",
|
|
1280
|
-
"requiredValues": {
|
|
1281
|
-
"currentStep": "settings",
|
|
1282
|
-
"watchNarration.stage": "review-ready"
|
|
1283
|
-
},
|
|
1284
|
-
"purpose": "park the watched UI on Settings before sender selection",
|
|
1285
|
-
"watchNarrationRule": "Say message review is complete and the browser is now on Settings so the user can connect or choose a sender. Include that no launch happens from Settings."
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
"action": "surface_sender_and_slack_handoff",
|
|
1289
|
-
"requiredVisibleContent": [
|
|
1290
|
-
"connect or select a LinkedIn sender",
|
|
1291
|
-
"Slack reply review",
|
|
1292
|
-
"recommended sequence",
|
|
1293
|
-
"final launch confirmation is still ahead"
|
|
1294
|
-
]
|
|
1295
|
-
},
|
|
1296
|
-
{
|
|
1297
|
-
"action": "ask_sender_selection",
|
|
1298
|
-
"uses": "request_user_input",
|
|
1299
|
-
"singleChoice": true,
|
|
1300
|
-
"choices": [
|
|
1301
|
-
"Use this connected sender",
|
|
1302
|
-
"Connect a different sender in Settings",
|
|
1303
|
-
"Pause here"
|
|
1304
|
-
],
|
|
1305
|
-
"autoSelectIf": "yolo_mode and exactly one safe connected sender is available"
|
|
1306
|
-
},
|
|
1307
|
-
{
|
|
1308
|
-
"action": "attach_selected_sender",
|
|
1309
|
-
"tool": "update_campaign",
|
|
1310
|
-
"when": "user selected an available connected sender",
|
|
1311
|
-
"requiredValues": {
|
|
1312
|
-
"senderIds": ["{selectedSenderId}"],
|
|
1313
|
-
"currentStep": "sequence",
|
|
1314
|
-
"watchNarration.stage": "review-ready"
|
|
1315
|
-
},
|
|
1316
|
-
"watchNarrationRule": "Say the sender was attached and the browser is moving to Sequence."
|
|
1317
|
-
},
|
|
1318
|
-
{
|
|
1319
|
-
"tool": "attach_recommended_sequence",
|
|
1320
|
-
"when": "after senderIds are attached",
|
|
1321
|
-
"requiredValues": {
|
|
1322
|
-
"campaignId": "{campaignId}",
|
|
1323
|
-
"currentStep": "send",
|
|
1324
|
-
"watchNarration.stage": "review-ready"
|
|
1325
|
-
},
|
|
1326
|
-
"watchNarrationRule": "The sequence tool owns the visible beat: say the recommended sequence is attached, the browser is now on Send, and the next action is final launch greenlight. Do not follow with a separate step-only update_campaign fixup."
|
|
1327
|
-
},
|
|
1328
|
-
{
|
|
1329
|
-
"action": "ask_final_launch_greenlight",
|
|
1330
|
-
"uses": "request_user_input",
|
|
1331
|
-
"singleChoice": true,
|
|
1332
|
-
"choices": ["Start campaign", "Review campaign first", "Pause here"],
|
|
1333
|
-
"onUserStart": "claude-greenlight",
|
|
1334
|
-
"neverAutoSelectInYolo": true
|
|
1335
|
-
}
|
|
1336
|
-
],
|
|
1337
|
-
"allowedTools": [
|
|
1338
|
-
"get_campaign",
|
|
1339
|
-
"get_campaign_navigation_state",
|
|
1340
|
-
"list_senders",
|
|
1341
|
-
"update_campaign",
|
|
1342
|
-
"attach_recommended_sequence",
|
|
1343
|
-
"AskUserQuestion",
|
|
1344
|
-
"request_user_input"
|
|
1345
|
-
],
|
|
1346
|
-
"doNotAllow": ["start_campaign", "import_leads"],
|
|
1347
|
-
"autoStart": false,
|
|
1348
|
-
"watchRequired": true,
|
|
1349
|
-
"waitFor": [
|
|
1350
|
-
"sender_connection_required",
|
|
1351
|
-
"sender_attached",
|
|
1352
|
-
"sequence_attached",
|
|
1353
|
-
"ready_to_launch",
|
|
1354
|
-
"user_greenlight",
|
|
1355
|
-
"ui_start_detected"
|
|
1356
|
-
],
|
|
1357
|
-
"transitions": {
|
|
1358
|
-
"sender_connection_required": "awaiting-user-greenlight",
|
|
1359
|
-
"sender_attached": "awaiting-user-greenlight",
|
|
1360
|
-
"sequence_attached": "awaiting-user-greenlight",
|
|
1361
|
-
"ready_to_launch": "awaiting-user-greenlight",
|
|
1362
|
-
"user_greenlight": "claude-greenlight",
|
|
1363
|
-
"ui_start_detected": "running"
|
|
1364
|
-
}
|
|
1365
|
-
},
|
|
1366
|
-
{
|
|
1367
|
-
"id": "claude-greenlight",
|
|
1368
|
-
"label": "Explicit launch",
|
|
1369
|
-
"reference": "references/final-handoff-contract.md",
|
|
1370
|
-
"onEnter": [
|
|
1371
|
-
{
|
|
1372
|
-
"tool": "get_campaign",
|
|
1373
|
-
"purpose": "detect_already_running"
|
|
1374
|
-
},
|
|
1375
|
-
{
|
|
1376
|
-
"action": "verify_sequence_and_current_step_before_start",
|
|
1377
|
-
"requiredState": [
|
|
1378
|
-
"workflowTableId",
|
|
1379
|
-
"senderIds",
|
|
1380
|
-
"sequenceTemplate",
|
|
1381
|
-
"currentStep in awaiting-user-greenlight|claude-greenlight|send"
|
|
1382
|
-
]
|
|
1383
|
-
},
|
|
1384
|
-
{
|
|
1385
|
-
"tool": "start_campaign",
|
|
1386
|
-
"requiredFields": ["campaignId"],
|
|
1387
|
-
"persistsCurrentStep": "running",
|
|
1388
|
-
"watchNarrationRule": "After start_campaign succeeds, the running state must say the final greenlight was accepted, the campaign is now live/running, and the user can watch progress from the campaign."
|
|
1389
|
-
}
|
|
1390
|
-
],
|
|
1391
|
-
"allowedTools": [
|
|
1392
|
-
"get_campaign",
|
|
1393
|
-
"attach_recommended_sequence",
|
|
1394
|
-
"start_campaign",
|
|
1395
|
-
"AskUserQuestion",
|
|
1396
|
-
"request_user_input"
|
|
1397
|
-
],
|
|
1398
|
-
"watchRequired": true,
|
|
1399
|
-
"waitFor": "campaign_started",
|
|
1400
|
-
"transitions": {
|
|
1401
|
-
"campaign_started": "running"
|
|
1402
|
-
}
|
|
1403
|
-
},
|
|
1404
|
-
{
|
|
1405
|
-
"id": "running",
|
|
1406
|
-
"label": "Campaign is live",
|
|
1407
|
-
"currentStepValue": "running",
|
|
1408
|
-
"onEnter": [
|
|
1409
|
-
{
|
|
1410
|
-
"action": "surface_watch_link"
|
|
1411
|
-
},
|
|
1412
|
-
{
|
|
1413
|
-
"action": "surface_campaign_live_confirmation"
|
|
1414
|
-
}
|
|
1415
|
-
],
|
|
1416
|
-
"allowedTools": ["get_campaign", "AskUserQuestion", "request_user_input"],
|
|
1417
|
-
"doNotAllow": ["start_campaign"],
|
|
1418
|
-
"terminal": true
|
|
1419
|
-
},
|
|
1420
|
-
{
|
|
1421
|
-
"id": "escalation",
|
|
1422
|
-
"label": "Escalation",
|
|
1423
|
-
"reference": "references/escalation-ladder.md",
|
|
1424
|
-
"allowedTools": ["AskUserQuestion", "request_user_input"],
|
|
1425
|
-
"doNotAllow": ["start_campaign", "import_leads"],
|
|
1426
|
-
"transitions": {
|
|
1427
|
-
"revise_brief": "brief-interview",
|
|
1428
|
-
"revise_leads": "find-leads",
|
|
1429
|
-
"revise_rubric": "filter-rubric",
|
|
1430
|
-
"revise_messaging": "message-generation",
|
|
1431
|
-
"abort": "abort"
|
|
1432
|
-
}
|
|
1433
|
-
},
|
|
1434
|
-
{
|
|
1435
|
-
"id": "abort",
|
|
1436
|
-
"label": "Abort",
|
|
1437
|
-
"allowedTools": ["AskUserQuestion", "request_user_input"],
|
|
1438
|
-
"terminal": true
|
|
1439
|
-
}
|
|
1440
|
-
]
|
|
1441
|
-
}
|
|
1
|
+
{"version":"v2.1-compact","workflow":"create-campaign-v2","principle":"CampaignOffer state and watch link are canonical. Create the watched shell, approve source, materialize and confirm the source list, internally process the first campaign-table execution slice, save rubrics for approval, approve the message template, then run the bounded filter/message cascade before Settings, sequence, and explicit start.","normalCustomerPath":"Use campaign state, MCP responses, and concise watchNarration. Do not create, read, link, or surface local draft files.","legacyCompatibility":{"validationSubskill":"create-campaign-v2-validation","tailSubskill":"create-campaign-v2-tail","rule":"Legacy validation/rehearsal files are opt-in diagnostics only and are not active flow gates."},"commitGateChoices":["approve","revise-brief","revise-leads","revise-rubric","revise-messaging","abort"],"canonicalStateFields":["campaignId","watchUrl","campaignBrief","currentStep","watchNarration","interactionMode","providerSearchAssociation","selectedLeadListId","workflowTableId","filterChoice","leadScoringRubrics","messageDraftRecommendation","approvedMessageTemplate","senderIds","sequenceTemplate","runningState"],"watchNarrationTransitionContract":{"rule":"Every watched currentStep switch must include fresh watchNarration.","requiredFields":["stage","headline","visibleState","agentIntent","nextAction"],"copyMustInclude":["what just happened","current visible page/state","next user action"],"appliesToTools":["create_campaign","update_campaign","attach_recommended_sequence","start_campaign"]},"lazyReferences":{"watch":["references/watch-link-handoff.md","references/watch-guide-narration.md"],"source":["references/lead-validation-preview.md","references/step-13-import-leads.md"],"filter":["references/filter-leads.md"],"message":[],"tail":["references/sample-validation-loop.md","references/step-15-re-cascade.md","references/final-handoff-contract.md"]},"safetyBoundaries":["Do not call list_senders before Settings after message approval.","Do not import leads until the source decision is approved.","Do not queue cells until confirmed source rows exist in the campaign and the message/filter gates are satisfied.","Do not call start_campaign until the user explicitly confirms launch.","Do not use local files as durable state in normal customer runs."],"yoloMode":{"triggerPhrases":["yolo","--yolo","mode=yolo","autopilot","use best guesses","use best estimates","answer for me","just run it"],"identityRequestOnlyWhenMissing":true,"operatorDirectionsRule":"Treat freeform directions supplied at invocation or later as durable operator directions; newest conflicting direction wins.","setInteractionModeAfterCampaignCreate":"autonomous","autoSelectsPreLaunchChoices":["campaign focus","brief approval","source scouting plan","source review/import approval","filters vs skip filters","filter rubric approval","message template approval when recommendation is approve-message","generated message review when quality floor passes","sender selection when exactly one connected sender is safe"],"mustPauseFor":["missing LinkedIn profile or company website","missing credentials or required data","ambiguous choice with no reasonable estimate","source/message/filter quality floor failure","final live launch confirmation"],"neverAutoStart":true},"steps":[{"id":"bootstrap","label":"Bootstrap","onEnter":[{"tool":"bootstrap_create_campaign","requiredValues":{"flowVersion":"v2"}},{"tool":"get_subskill_prompt","requiredValues":{"subskillName":"create-campaign-v2"},"purpose":"load the compact entry prompt once"}],"allowedTools":["bootstrap_create_campaign","get_auth_status","get_active_workspace","get_subskill_prompt","AskUserQuestion","request_user_input"],"doNotAllow":["create_campaign","list_senders","save_rubrics","import_leads","confirm_lead_list","update_campaign","queue_cells","start_campaign"],"waitFor":"bootstrap_complete","transitions":{"bootstrap_complete":"brief-interview"}},{"id":"brief-interview","label":"Client, offer, research, and brief","onEnter":[{"action":"resolve_campaign_identity_before_strategy_packet","allowedTools":["fetch_company","fetch_linkedin_profile","WebFetch","WebSearch"],"mustNotInferFromNameOnly":true,"doNotPresentSenderPickerBeforeIdentityInference":true,"fallback":"Ask for the LinkedIn profile URL first; use the company website as the fallback before strategy questions."},{"action":"run_campaign_identity_research_before_strategy_packet","target":"research-sender","requiredCompletion":"complete_sender_research","allowedTools":["get_subskill_prompt","fetch_linkedin_profile","fetch_company","fetch_linkedin_posts","fetch_company_posts","WebFetch","WebSearch","complete_sender_research"]},{"action":"ask_campaign_focus_only_when_ambiguous","uses":"request_user_input","singleChoice":true,"requiredOption":"Other / custom","neverCollectOpenTextWithStructuredQuestion":true,"skipIf":"yolo_mode with any reasonable best-estimate focus"},{"action":"confirm_current_offer_before_strategy_packet","uses":"request_user_input","question":"Do you already know the offer for this campaign?","options":["Use my current offer","Use Sellable's researched recommendation","Shape the offer together"],"copyMustInclude":["research basis","public website or LinkedIn may be stale","recommendation is editable"],"skipIf":"user already supplied a clear current offer or yolo_mode with any reasonable researched recommendation"},{"action":"infer_strategy_packet_in_yolo_mode","when":"yolo_mode","skipStructuredSetupQuestions":true,"inferFields":["buyer segment","offer/CTA","proof to use or avoid","lead source","filter choice","message direction"],"sourceOfTruth":"identity/company lookup plus operator directions","mustStateAssumptionsInBrief":true},{"action":"create_watchable_campaign_shell_with_v1_brief","tool":"create_campaign","requiredFields":["name","campaignBrief","clientProspectId or senderLinkedinUrl","currentStep","watchNarration"],"requiredValues":{"currentStep":"create-offer","watchNarration.stage":"brief"},"capture":["campaignId","watchUrl"],"canonicalStateWrites":["campaignId","watchUrl","campaignBrief","currentStep:create-offer"]},{"action":"surface_campaign_shell_watch_link","watchUrlSource":"create_campaign.watchUrl","requiredWatchUrlShape":"direct /campaign-builder/{campaignId}?mode={claude|codex} watch URL with token auto-login and workspace routing","copyMustInclude":["I am creating the campaign through this chat.","Open this link if you want to watch the work being done and audit what changes.","You can still ask me to change anything here."],"immediateNextMainChatLine":"Cool, let's find leads.","codexBrowserHandoff":{"openWhenAvailable":false,"printWatchLinkOnly":true,"tellUserCommandEnterOrClick":true,"mustNotUseBrowserAutomation":true,"fallbackMustNotClaimInspection":true}}],"allowedTools":["get_subskill_prompt","fetch_company","fetch_company_posts","fetch_linkedin_profile","fetch_linkedin_posts","complete_sender_research","create_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["list_senders","save_rubrics","import_leads","confirm_lead_list","queue_cells","start_campaign"],"waitFor":["campaign_shell_created","brief_ready","confirm_with_user"],"transitions":{"campaign_shell_created":"brief-review","brief_ready":"brief-review","confirm_with_user":"brief-review"}},{"id":"brief-review","label":"Brief review","onEnter":[{"action":"render_brief_inline","minimumVisibleDetail":"campaign direction, buyer, offer, proof, source plan, safety gates","copyMustInclude":["compact provenance labels: [from you], [from LinkedIn], [from website], [from case study], or [Sellable recommendation]","This is based on what I found. If your site or LinkedIn is stale, tell me what to update before I build the lead list.","Do you agree with this researched campaign direction?"],"copyMustNotInclude":["quoted first-message copy","Message Angle as final proof"],"messageHintRule":"If any message-shape hint remains, keep it as non-final bullets and say real examples come after leads are found and filtered."},{"action":"ask_brief_choice","uses":"request_user_input","choices":["Approve brief","Revise brief","Pause here"],"skipIf":"yolo_mode; auto_continue after rendering assumptions unless brief quality floor fails"}],"requiredCampaignState":["campaignId","watchUrl","campaignBrief","currentStep"],"allowedTools":["AskUserQuestion","request_user_input","update_campaign"],"doNotAllow":["create_campaign","list_senders","import_leads","confirm_lead_list","queue_cells","start_campaign"],"waitFor":["user_brief_confirmed","revise_brief","auto_continue"],"transitions":{"user_brief_confirmed":"find-leads","revise_brief":"brief-interview","auto_continue":"find-leads"}},{"id":"find-leads","label":"Find leads","sourceSelectionFunnel":{"preScoutRecommendationGate":{"required":true,"label":"Source scouting approval","mustHappenBefore":["get_provider_prompt","search_signals","search_sales_nav","search_prospeo","fetch_post_engagers","source-scout dispatch"],"show":["campaign-specific options considered","recommended first lane","why this lane matches the offer and ICP","expected evidence to gather","fallback lane if the first lane is weak","what approval authorizes"],"approvalAuthorizes":"source scouting/search only; no import/send","explanationMustInclude":["what source is being tried","why it was recommended","precision/scale tradeoff","enough relevant leads","evidence quality","safe bounded pilot volume"],"yoloMode":{"autoApproveRecommendedLane":true,"mustShowAssumedChoice":true,"pauseIfConfidenceLow":true}},"defaultWhenSourceUnspecified":["signal-discovery","sales-nav-recent-active","sales-nav-general","prospeo"],"userFacingFallbackOrder":["people engaging with relevant LinkedIn posts","Sales Nav to find ICP people actively posting on LinkedIn","search by titles","Prospeo for a broader account/contact path"],"parallelAllowedOnlyWhen":["user explicitly requested source comparison","resuming already-started parallel scouts","first viable source is borderline and one cheap fallback check is needed"]},"onEnter":[{"tool":"update_campaign","requiredValues":{"currentStep":"pick-provider","watchNarration.stage":"find-leads","watchNarration.headline":"Review source scouting","watchNarration.visibleState":"The app is showing source selection before scouting starts.","watchNarration.agentIntent":"Codex is explaining the recommended source lane, precision/scale tradeoff, and fallback before any search runs.","watchNarration.nextAction":"Approve source scouting or choose another source","watchNarration.safety":"Approval here authorizes source scouting/search only; no selected-post scrape, lead import, filtering, messaging, sequence, or sending starts."},"purpose":"show the visible source-plan approval checkpoint before provider lanes"},{"tool":"get_source_scout_registry","purpose":"load canonical source scout names before optional branch launch"},{"action":"show_pre_scout_source_recommendation","uses":"request_user_input","oneShot":true,"skipIf":"approved or leadSourceProvider or yolo_mode auto-selected source_lane_approved","requiredBeforeTools":["get_provider_prompt","search_signals","search_sales_nav","search_prospeo","fetch_post_engagers"],"requiredInlineFields":["plain-language source scouting options for this campaign","recommended first source lane","why the lane is likely to have relevant active prospects","precision/scale tradeoff","what evidence quality the lane should prove","fallback lane if the recommended lane looks weak","what scouting will check next","what approval authorizes"],"choices":["Approve LinkedIn engagement scouting plan","Approve Sales Nav scouting plan","Approve Prospeo scouting plan","Choose different source","Pause here"],"approvalChoiceLabelsByProvider":{"signal-discovery":"Approve LinkedIn engagement scouting plan","sales-nav":"Approve Sales Nav scouting plan","prospeo":"Approve Prospeo scouting plan"},"approvalState":"source_lane_approved"},{"action":"persist_provider_search_step_before_search","tool":"update_campaign","requiredPrecondition":"source_lane_approved","providerCurrentStepMap":{"signal-discovery":"signal-discovery","sales-nav":"sales-nav","prospeo":"prospeo"},"requiredValues":{"leadSourceType":"new","leadSourceProvider":"approved provider","currentStep":"provider-specific current step","watchNarration.stage":"find-leads","watchNarration.headline":"Searching the approved source lane","watchNarration.safety":"Search/scouting only; no lead import or selected-post scrape starts from this update."},"mustRunBefore":["search_signals","search_sales_nav","search_prospeo","fetch_post_engagers"]},{"action":"run_sequential_source_funnel","requiredPrecondition":"source_lane_approved","defaultOrder":["source-scout-linkedin-engagement","source-scout-sales-nav","source-scout-prospeo-contact"],"campaignOfferIdRequired":true,"stopOnFirstViableUnlessComparisonRequested":true}],"requiredCampaignState":["campaignId","campaignBrief","currentStep"],"allowedTools":["get_source_scout_registry","get_provider_prompt","lookup_sales_nav_filter","search_sales_nav","search_prospeo","search_signals","select_promising_posts","fetch_post_engagers","fetch_company","fetch_linkedin_profile","load_csv_linkedin_leads","load_csv_domains","get_rows_minimal","update_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["create_campaign","list_senders","save_rubrics","import_leads","confirm_lead_list","queue_cells","start_campaign"],"waitFor":["lead_review_ready","revise_brief","confirm_with_user"],"transitions":{"lead_review_ready":"lead-review","revise_brief":"brief-interview","confirm_with_user":"lead-review"}},{"id":"lead-review","label":"Source approval","onEnter":[{"action":"show_source_decision_card","requiredInlineFields":["primary source and exact filters/recipe","specific source action awaiting approval","for Signal Discovery: compact Source Recommendation with target, raw-engager math, recommended scrape-set table, review checkpoint, estimated fit, and fallback","for Signal Discovery: recommended scrape post count and target engager/source-candidate volume","internal campaign-table execution slice size, clearly separate from source sampling","runner-up and why it lost","raw volume","sampled people","sampled fits as n/N plus percentage/range","estimated usable prospects","cleanup risk","what approval authorizes"]},{"action":"ask_source_review_choice","uses":"request_user_input","choices":["Approve scraping N recommended LinkedIn posts","Run the approved source import","Revise source","Pause here"],"approvalChoiceLabelsByProvider":{"signal-discovery":"Approve scraping {scrapePostCount} recommended LinkedIn posts?","sales-nav":"Import the approved Sales Nav source list","prospeo":"Import the approved Prospeo source list"},"postApprovalContract":{"singleUseApproval":true,"doNotRepeatAfterApproval":["Source Recommendation","show_source_decision_card","ask_source_review_choice"],"requiredNextActionAfterApproval":"ack once; call import_leads immediately","signalDiscoveryNextTool":"import_leads({ provider: \"signal-discovery\", targetEngagerCount, maxPostsToScrape, confirmed: true })"},"autoSelectIf":"yolo_mode and projected usable pool clears the source quality floor"}],"requiredCampaignState":["campaignId","campaignBrief","providerSearchAssociation"],"allowedTools":["AskUserQuestion","request_user_input","update_campaign"],"doNotAllow":["create_campaign","list_senders","save_rubrics","import_leads","confirm_lead_list","queue_cells","start_campaign"],"waitFor":["lead_review_confirmed","revise_leads","confirm_with_user","auto_continue"],"transitions":{"lead_review_confirmed":"auto-execute-leads","revise_leads":"find-leads","confirm_with_user":"auto-execute-leads","auto_continue":"auto-execute-leads"}},{"id":"auto-execute-leads","label":"Materialize confirmed source list","currentStepValue":"auto-execute-leads","reference":"references/step-13-import-leads.md","onEnter":[{"tool":"get_subskill_prompt","requiredValues":{"subskillName":"create-campaign-v2-tail"},"purpose":"load tail contract before execution tools"},{"tool":"import_leads","requiredFields":["campaignOfferId","selected source/list","sourceListTarget or targetEngagerCount"],"requiredValues":{"salesNavProspeoDefaultSourceListTarget":1000,"signalDiscoveryDefaultEngagerTarget":1500},"modeAddHandshake":{"firstCallReturns":"needsModeSelection when adding to an existing campaign-attached list","requiredFollowup":"retry with mode=add after explicit user/source-state compatibility is confirmed"},"surfaceDedupRatio":true},{"tool":"wait_for_lead_list_ready"},{"tool":"confirm_lead_list","requiredFields":["campaignOfferId","selectedLeadListId","reviewBatchLimit"],"requiredValues":{"reviewBatchLimit":15},"capture":["workflowTableId","reviewBatchRowIds"]},{"tool":"wait_for_campaign_table_ready"},{"tool":"get_rows_minimal","requiredValues":{"tableId":"{workflowTableId}","limit":15},"capture":["reviewBatchRowHash"]},{"action":"summarize_review_batch_and_advance_to_filter_choice","purpose":"ask filter choice immediately; no post-lead registries, filter refs, or message prompts first","maxCustomerCopyLines":4}],"requiredCampaignState":["campaignId","providerSearchAssociation","selectedLeadListId"],"allowedTools":["get_subskill_prompt","import_leads","wait_for_lead_list_ready","confirm_lead_list","wait_for_campaign_table_ready","get_rows_minimal","update_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["get_post_find_leads_scout_registry","Task","spawn_agent","list_senders","queue_cells","start_campaign","enrich_with_prospeo","bulk_enrich_with_prospeo","save_rubrics"],"waitFor":"source_list_confirmed_and_review_sample_ready","transitions":{"source_list_confirmed_and_review_sample_ready":"filter-choice","escalation_triggered":"escalation"}},{"id":"filter-choice","label":"Filter choice","currentStepValue":"filter-choice","onEnter":[{"tool":"update_campaign","requiredValues":{"currentStep":"filter-choice","watchNarration.stage":"fit-message"}},{"action":"ask_filter_choice","uses":"request_user_input","choices":["Use filters","Skip filters","Revise source"],"autoSelectIf":"yolo_mode; choose filters unless source is tightly curated or user directed otherwise"}],"hardRules":["ask_filter_choice_immediately_after_review_batch_import","do_not_call_get_subskill_prompt_before_filter_choice","do_not_call_get_subskill_asset_before_filter_choice","do_not_call_get_post_find_leads_scout_registry_before_filter_choice","do_not_spawn_post_lead_agents_before_filter_choice"],"requiredCampaignState":["campaignId","campaignBrief","selectedLeadListId","workflowTableId"],"allowedTools":["AskUserQuestion","request_user_input","update_campaign","get_campaign_navigation_state"],"doNotAllow":["get_subskill_prompt","get_subskill_asset","get_post_find_leads_scout_registry","Task","spawn_agent","create_campaign","list_senders","import_leads","confirm_lead_list","queue_cells","start_campaign","generate_messages"],"waitFor":["filters_enabled","filters_skipped","revise_leads"],"transitions":{"filters_enabled":"post-lead-workstreams","filters_skipped":"message-generation","revise_leads":"find-leads"}},{"id":"post-lead-workstreams","label":"Filter workstream","onEnter":[{"action":"persist_add_filters_approval","tool":"update_campaign","when":"filters_enabled","requiredFields":["campaignId","enableICPFilters","currentStep","watchNarration"],"requiredValues":{"enableICPFilters":true,"currentStep":"create-icp-rubric","watchNarration.stage":"fit-message","watchNarration.headline":"Create filter rules","watchNarration.visibleState":"Filters are enabled and the browser is showing Filter Rules while Codex defines the rubric.","watchNarration.nextAction":"Review saved filter rules"},"mustRunBefore":["get_post_find_leads_scout_registry","launch_lead_fit_builder_after_filter_choice","save_rubrics"]},{"tool":"get_post_find_leads_scout_registry","purpose":"load canonical post-lead worker names only after the user has chosen filters"},{"action":"launch_lead_fit_builder_after_filter_choice","mode":"parallel_when_host_supports_subagents","target":"post-find-leads-filter-scout","inputs":["campaignId","campaignBrief","selectedLeadListId","workflowTableId","reviewBatchRowIds/hash","filterChoice"],"stateSource":"live campaign/table","debugFilesOptionalOnly":true},{"action":"launch_message_draft_builder_after_filter_decision","mode":"parallel_when_host_supports_subagents","target":"post-find-leads-message-scout","when":"filters_enabled","doesNotQueueCells":true,"customerNarration":"Say message agent is drafting."},{"action":"save_filter_rubrics_to_campaign","tool":"save_rubrics","when":"filters_enabled and rubrics are production-shaped","requiredFields":["campaignOfferId","leadScoringRubrics"],"writesCampaignState":"leadScoringRubrics","requiredSideEffects":{"enableICPFilters":true,"currentStep":"create-icp-rubric","watchNarration.headline":"Filter rules saved for review"}},{"action":"ask_filter_rubric_review_choice","uses":"request_user_input","choices":["Approve filters","Revise filters","Pause"],"purpose":"let the user read saved rubrics before Filter Leads or enrichment","copyMustInclude":["These rules prevent wasted sends before I score/import the list.","Recommended because of the researched ICP, source sample, and repeated false-positive patterns.","one pass example and one block example when available","Approval here means approving filter rules, not message drafts or campaign launch."],"autoSelectIf":"yolo_mode and rubrics are production-shaped"}],"requiredCampaignState":["campaignId","campaignBrief","selectedLeadListId","workflowTableId"],"allowedTools":["get_subskill_prompt","get_subskill_asset","get_post_find_leads_scout_registry","save_rubrics","get_campaign","get_rows_minimal","update_campaign","get_campaign_navigation_state","AskUserQuestion","request_user_input","Task","spawn_agent"],"doNotAllow":["create_campaign","list_senders","import_leads","confirm_lead_list","queue_cells","start_campaign","check_rubric","generate_messages"],"waitFor":["filter_rubrics_approved","revise_leads","revise_rubric","revise_messaging"],"hardRules":["after_save_rubrics_currentStep_must_stay_create-icp-rubric_until_filter_approval","filter_approval_required_before_apply-icp-rubric_or_queue_cells","do_not_move_browser_to_messages_until_filter_leads_step_is_current_or_filters_are_explicitly_skipped","no_post_lead_worker_or_deep_prompt_before_filter_choice","lead_fit_builder_starts_only_after_filters_enabled","msg_draft_after_filter_choice","msg_draft_no_cells"],"transitions":{"filter_rubrics_approved":"message-generation","revise_leads":"find-leads","revise_rubric":"filter-rubric","revise_messaging":"message-generation","confirm_with_user":"message-review"}},{"id":"filter-rubric","label":"Rubric revision","onEnter":[{"tool":"get_subskill_asset","requiredValues":{"subskillName":"create-campaign-v2","assetPath":"references/filter-leads.md"}},{"tool":"save_rubrics","requiredFields":["campaignOfferId","leadScoringRubrics"],"writesCampaignState":"leadScoringRubrics","requiredSideEffects":{"enableICPFilters":true,"currentStep":"create-icp-rubric","watchNarration.headline":"Filter rules saved for review"}},{"action":"ask_filter_rubric_review_choice","uses":"request_user_input","choices":["Approve filters","Revise filters","Pause"],"copyMustInclude":["These rules prevent wasted sends before I score/import the list.","approval object is filter rules only","not campaign launch"],"autoSelectIf":"yolo_mode and rubrics are production-shaped"}],"requiredCampaignState":["campaignId","workflowTableId"],"allowedTools":["get_subskill_asset","save_rubrics","AskUserQuestion","request_user_input"],"doNotAllow":["create_campaign","list_senders","import_leads","confirm_lead_list","update_campaign","queue_cells","start_campaign","check_rubric"],"waitFor":["filter_rubrics_approved","revise_leads","confirm_with_user","auto_continue"],"transitions":{"filter_rubrics_approved":"message-generation","revise_leads":"find-leads","confirm_with_user":"message-generation","auto_continue":"message-generation"}},{"id":"message-generation","label":"Message generation","onEnter":[{"action":"set_message_review_visible_step_by_filter_choice","tool":"update_campaign","branchRules":["yes after filter approval: currentStep=apply-icp-rubric; wait on Filter Leads","no: currentStep=messages; message review"],"watchNarration.stage":"fit-message"},{"action":"run_or_reconcile_message_draft_builder","target":"post-find-leads-message-scout","toolCallRequiredBeforeDraft":["run background post-find-leads-message-scout when available","get_subskill_prompt({ subskillName: \"generate-messages\", offset, limit }) until hasMore=false"],"stateSource":"campaignBrief, source, selectedLeadListId, workflowTableId, execution-slice row ids/hash","outputState":"messageDraftRecommendation"}],"requiredCampaignState":["campaignId","campaignBrief","selectedLeadListId","workflowTableId"],"allowedTools":["get_subskill_prompt","get_campaign","get_rows_minimal","update_campaign","AskUserQuestion","request_user_input"],"toolRules":["Run post-find-leads-message-scout when available; otherwise parent fallback must load get_subskill_prompt({ subskillName: \"generate-messages\" }) from live state.","brief.md, lead-review.md, and lead-sample.json are optional debug context only.","messageDraftRecommendation returns templateRecommendation, tokenFillRules, renderedSample, concerns, status, basisToken, outputAt, outputHash, and error/retry detail.","If campaign/source/table/execution-slice basis does not match, classify the output stale or blocked."],"doNotAllow":["create_campaign","list_senders","save_rubrics","import_leads","confirm_lead_list","queue_cells","start_campaign","generate_messages"],"waitFor":["message_validation_ready","revise_rubric","revise_messaging","confirm_with_user","auto_continue"],"transitions":{"message_validation_ready":"message-review","revise_rubric":"filter-rubric","revise_messaging":"message-generation","confirm_with_user":"message-review","auto_continue":"message-review"}},{"id":"message-review","label":"Message review","onEnter":[{"action":"render_message_review_from_state","requiredState":["campaignBrief","selectedLeadListId","workflowTableId","messageDraftRecommendation"],"requiredVisibleLabels":["## Message Template","## Rendered Example","Good token fill:","My take:","Question: approve-message or revise-messaging?","Recommendation:"],"doNotShowByDefault":["Token Notes","Good omit / fallback","Bad fill to avoid","Token Adherence Table"],"internalPersistenceOnly":["Token Fill Rules","Token Fill Examples","fallback guidance","bad-fill avoidance notes"],"copyMustInclude":["QA receipt before approval","tokens resolved","company/person match","proof claim","prospect angle","language/tone when known","obvious bad fits","Would I take this call?","weak personalization can burn the sender's reputation","full list remains paused"]},{"action":"ask_message_review_choice","uses":"request_user_input","choices":["approve-message","revise-messaging"],"copyMustInclude":["approve the message direction only","not campaign launch","not LinkedIn sender approval"],"autoSelectIf":"yolo_mode and Recommendation is approve-message; revise autonomously when Recommendation is revise-messaging"},{"action":"sync_approved_message_set_to_campaign_brief","tool":"update_campaign_brief","when":"after approve-message","requiredFields":["campaignId","approvedMessageTemplate","Token Fill Rules","Token Fill Examples"],"writesCampaignState":"approvedMessageTemplate"}],"requiredCampaignState":["campaignId","workflowTableId","messageDraftRecommendation"],"allowedTools":["AskUserQuestion","request_user_input","update_campaign_brief","update_campaign","get_rows_minimal"],"doNotAllow":["create_campaign","list_senders","save_rubrics","import_leads","confirm_lead_list","start_campaign"],"waitFor":["message_approved","revise_messaging"],"transitions":{"message_approved":"validate-sample","revise_messaging":"message-generation"}},{"id":"validate-sample","label":"Validate campaign-table execution slice","currentStepValue":"apply-icp-rubric","reference":"references/sample-validation-loop.md","visibleStepRule":"Filter Leads is reached only after saved-filter approval. On approve-message, save the template, refresh apply-icp-rubric narration, then queue bounded Enrich Prospect cells.","onEnter":[{"tool":"update_campaign","requiredValues":{"currentStep":"apply-icp-rubric","watchNarration.stage":"fit-message"},"purpose":"keep the watched UI on Filter Leads while the approved template starts the bounded cascade","watchNarrationRule":"Say the template is saved and Filter Leads is now running the bounded enrichment and scoring pass."},{"tool":"queue_cells","purpose":"queue ICP/enrichment cells for the internal campaign-table execution slice only","requiredFields":["workflowTableId","reviewBatchRowIds","cellTypes"],"targetCountSource":"reviewBatchRowIds.length (default 15)"},{"tool":"wait_for_campaign_table_ready","purpose":"wait_for_review_batch_scoring_cells"},{"tool":"get_rows_minimal","requiredValues":{"includeRows":false},"purpose":"read compact row status only"},{"tool":"wait_for_rubric_results","requiredFields":["workflowTableId","targetCount","minPassedCount"],"requiredValues":{"includeRows":false,"minPassedCount":1},"minPassedCountSource":"firstPassingRowForMessageStart","readVia":"stats_only_tool_result","customerSummaryPattern":["{checked} leads checked","{passed} passed and have draft messages","{blocked} blocked before sending","full list remains paused until approval"]},{"action":"handle_partial_or_timeout_sample","customerStatus":"sample-needs-revision","rule":"Do not repeat waits indefinitely; surface partial status and route to revision.","copyMustInclude":"completed, passed, pending, blocked before sending, and full list remains paused"}],"requiredCampaignState":["campaignId","workflowTableId","approvedMessageTemplate","filterRubricsApproved when enableICPFilters=true"],"allowedTools":["get_subskill_asset","queue_cells","wait_for_campaign_table_ready","get_rows_minimal","wait_for_rubric_results","update_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["import_leads","list_senders","start_campaign","enrich_with_prospeo","bulk_enrich_with_prospeo","check_rubric"],"hardRules":["wait_for_rubric_results_never_retain_rows_payload_in_tail_context","wait_for_rubric_results_targetCount_always_explicit","timeout_never_repeats_without_customer_handoff","timeout_or_underfloor_sample_never_advances_to_settings"],"waitFor":["sample_validated","sample_revision_required"],"transitions":{"sample_validated":"auto-execute-messaging","sample_revision_required":"lead-review","revise_leads":"find-leads","revise_rubric":"filter-rubric","escalation_triggered":"escalation"}},{"id":"auto-execute-messaging","label":"Generate initial campaign-row messages","currentStepValue":"auto-execute-messaging","references":["references/parallel-critique-protocol.md","references/thomas-variant-selection.md","references/thomas-revision-filters.md","references/step-15-re-cascade.md"],"onEnter":[{"tool":"queue_cells","batchSize":100,"when":"any passing row has pending or empty Generate Message cell","cellSource":"pending_generate_message_cells_for_passing_rows using approved_campaign_brief_template"},{"tool":"wait_for_rubric_results","purpose":"wait_for_first_passing_generated_message","requiredValues":{"includeRows":false,"minPassedCount":1,"minMessagesCount":1},"readVia":"stats_only_tool_result"},{"action":"observe_generate_message_results","reference":"references/step-15-re-cascade.md"},{"action":"enforce_token_contract","modeFromConfig":"messaging.tokenContract"},{"action":"optional_critique_pass","enabledFromConfig":"messaging.critique.enabled","plan":"85-03","protocol":"references/parallel-critique-protocol.md","sampleSizeFromConfig":"messaging.critique.sampleSize","budgetUsdCapFromConfig":"messaging.critique.budgetUsdCap","perCriticTimeoutFromConfig":"messaging.critique.perCriticTimeoutSeconds","totalTimeoutFromConfig":"messaging.critique.totalTimeoutSeconds","criticsFromConfig":"messaging.critique.critics","enforceFinalizerPassFromConfig":"messaging.critique.synthesis.enforceFinalizerPass","rejectOnFakeProofFromConfig":"messaging.critique.rejectOnFakeProof","rejectOnUnsupportedTokenFromConfig":"messaging.critique.rejectOnUnsupportedToken","onBudgetTrip":"halt_critique_continue_plain_tail","onPerCriticTimeout":"drop_critic_proceed_with_remaining","onTotalTimeout":"persist_plain_message_for_row","onTokenContractViolation":"persist_plain_message_for_row","onFakeProof":"persist_plain_message_for_row"},{"action":"optional_opus_subset","enabledFromConfig":"messaging.critique.opus.enabled","selection":"references/thomas-variant-selection.md","maxMessagesPerPassFromConfig":"messaging.critique.opus.maxMessagesPerPass","budgetUsdCapFromConfig":"messaging.critique.opus.budgetUsdCap","onOpusBudgetTrip":"halt_opus_continue_non_opus","onOpusTokenContractViolation":"fallback_to_non_opus_rewrite"},{"tool":"update_campaign","requiredValues":{"currentStep":"auto-execute-messaging","watchNarration.stage":"review-ready"},"watchNarrationRule":"Say the first passing generated message is ready in Messages; next is review before Settings."},{"action":"ask_generated_message_review_choice","uses":"request_user_input","choices":["Approve reviewed draft rows and continue to Settings","Revise filters","Revise message template","Pause here"],"copyMustInclude":["approve these draft rows for the next review step","not approving the full campaign launch","not approving the user's LinkedIn account for sending yet","tokens resolved","company/person match","proof claim","prospect angle","language/tone when known","obvious bad fits","Would I take this call?","weak personalization can burn the sender's reputation","full list remains paused"],"autoSelectIf":"yolo_mode and the first passing generated message clears the quality floor"}],"allowedTools":["get_subskill_asset","get_rows_minimal","queue_cells","wait_for_rubric_results","update_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["import_leads","list_senders","start_campaign","generate_messages"],"hardRules":["critique_failure_never_escalates","critique_sample_size_bounded_by_config","first_passing_generated_message_unblocks_review","critics_fixed_at_targeting_copy_voice","synthesis_enforces_phase_84_token_contract","opus_reserved_for_highest_value_subset","proposed_token_never_persisted_in_rewrite"],"waitFor":["generated_messages_approved","sample_revision_required"],"transitions":{"generated_messages_approved":"awaiting-user-greenlight","revise_filters":"filter-rubric","revise_messaging":"message-generation","escalation_triggered":"escalation"}},{"id":"awaiting-user-greenlight","label":"Settings, sender, sequence, and greenlight","currentStepValue":"awaiting-user-greenlight","reference":"references/final-handoff-contract.md","onEnter":[{"tool":"get_campaign","purpose":"verify senderIds and sequence state before final handoff"},{"tool":"list_senders","purpose":"surface available connected senders only at Settings"},{"tool":"update_campaign","requiredValues":{"currentStep":"settings","watchNarration.stage":"review-ready"},"purpose":"park the watched UI on Settings before sender selection","watchNarrationRule":"Say message review is complete and the browser is now on Settings so the user can connect or choose a sender. Include that lead research and filtering already happened outside the user's LinkedIn account, this sender is only used for approved sending after final launch, and no launch happens from Settings."},{"action":"surface_sender_and_slack_handoff","requiredVisibleContent":["connect or select a LinkedIn sender","Lead research and filtering already happened outside your LinkedIn account.","This account is only used for approved sending after final launch.","Nothing sends until the final Start step.","Slack reply review","recommended sequence","final launch confirmation is still ahead"]},{"action":"ask_sender_selection","uses":"request_user_input","singleChoice":true,"choices":["Use this connected sender","Connect a different sender in Settings","Pause here"],"autoSelectIf":"yolo_mode and exactly one safe connected sender is available"},{"action":"attach_selected_sender","tool":"update_campaign","when":"user selected an available connected sender","requiredValues":{"senderIds":["{selectedSenderId}"],"currentStep":"sequence","watchNarration.stage":"review-ready"},"watchNarrationRule":"Say the sender was attached and the browser is moving to Sequence review. Include that the sequence is editable before launch and still not sending until Start."},{"tool":"attach_recommended_sequence","when":"after senderIds are attached","requiredValues":{"campaignId":"{campaignId}","currentStep":"send","watchNarration.stage":"review-ready"},"watchNarrationRule":"The sequence tool owns the visible beat: say the recommended follow-up sequence is attached, the browser is now on final launch review, and the next action is final launch greenlight. Include that it is still not sending until Start. Do not follow with a separate step-only update_campaign fixup."},{"action":"ask_final_launch_greenlight","uses":"request_user_input","singleChoice":true,"choices":["Start campaign","Review campaign first","Pause here"],"copyMustInclude":["quality confidence means sample messages and prospect angle were checked","launch confidence means sender, sequence, and Start are ready","approved messages begin sending according to the sequence","replies and meetings follow connected settings","you can monitor and pause","no hidden extra approval disappears after clicking Start"],"onUserStart":"claude-greenlight","neverAutoSelectInYolo":true}],"allowedTools":["get_campaign","get_campaign_navigation_state","list_senders","update_campaign","attach_recommended_sequence","AskUserQuestion","request_user_input"],"doNotAllow":["start_campaign","import_leads"],"autoStart":false,"watchRequired":true,"waitFor":["sender_connection_required","sender_attached","sequence_attached","ready_to_launch","user_greenlight","ui_start_detected"],"transitions":{"sender_connection_required":"awaiting-user-greenlight","sender_attached":"awaiting-user-greenlight","sequence_attached":"awaiting-user-greenlight","ready_to_launch":"awaiting-user-greenlight","user_greenlight":"claude-greenlight","ui_start_detected":"running"}},{"id":"claude-greenlight","label":"Explicit launch","reference":"references/final-handoff-contract.md","onEnter":[{"tool":"get_campaign","purpose":"detect_already_running"},{"action":"verify_sequence_and_current_step_before_start","requiredState":["workflowTableId","senderIds","sequenceTemplate","at least one approved generated message","currentStep in awaiting-user-greenlight|claude-greenlight|send"]},{"tool":"start_campaign","requiredFields":["campaignId"],"persistsCurrentStep":"running","watchNarrationRule":"After start_campaign succeeds, the running state must say the final greenlight was accepted, the campaign is now live/running, and the user can watch progress from the campaign."}],"allowedTools":["get_campaign","attach_recommended_sequence","start_campaign","AskUserQuestion","request_user_input"],"watchRequired":true,"waitFor":"campaign_started","transitions":{"campaign_started":"running"}},{"id":"running","label":"Campaign is live","currentStepValue":"running","onEnter":[{"action":"surface_watch_link"},{"action":"surface_campaign_live_confirmation"}],"allowedTools":["get_campaign","AskUserQuestion","request_user_input"],"doNotAllow":["start_campaign"],"terminal":true},{"id":"escalation","label":"Escalation","reference":"references/escalation-ladder.md","allowedTools":["AskUserQuestion","request_user_input"],"doNotAllow":["start_campaign","import_leads"],"transitions":{"revise_brief":"brief-interview","revise_leads":"find-leads","revise_rubric":"filter-rubric","revise_messaging":"message-generation","abort":"abort"}},{"id":"abort","label":"Abort","allowedTools":["AskUserQuestion","request_user_input"],"terminal":true}]}
|