@sellable/mcp 0.1.90 → 0.1.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/agents/post-find-leads-message-scout.md +61 -10
- package/dist/tools/prompts.js +7 -7
- package/dist/tools/rubrics.d.ts +32 -0
- package/dist/tools/rubrics.js +24 -2
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +32 -24
- package/skills/create-campaign-v2/SKILL.md +60 -36
- package/skills/create-campaign-v2/SOUL.md +15 -11
- package/skills/create-campaign-v2/core/flow.v2.json +28 -10
- package/skills/create-campaign-v2/references/message-review-fast-path.md +91 -0
- package/skills/create-campaign-v2/references/sample-validation-loop.md +34 -2
- package/skills/create-campaign-v2-tail/SKILL.md +15 -1
- package/skills/find-leads/SKILL.md +22 -13
package/README.md
CHANGED
|
@@ -248,9 +248,10 @@ Parallel execution contract:
|
|
|
248
248
|
use that registry to launch the filter-leads scout and message-generation
|
|
249
249
|
scout together when the host supports real subagents.
|
|
250
250
|
- Claude host: use the installed `source-scout-linkedin-engagement`,
|
|
251
|
-
`source-scout-sales-nav`, and `source-scout-prospeo-contact` Task/Agent
|
|
252
|
-
for parallel lead-source scouting
|
|
253
|
-
|
|
251
|
+
`source-scout-sales-nav`, and `source-scout-prospeo-contact` Task/Agent
|
|
252
|
+
subagents for parallel lead-source scouting only when the current session
|
|
253
|
+
exposes those agent names. Launch all credible lanes in one assistant message
|
|
254
|
+
so Claude Code can run them concurrently/background.
|
|
254
255
|
- Codex host: use named custom scouts for source-angle work when subagents are
|
|
255
256
|
available: `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
256
257
|
`source-scout-prospeo-contact`. Use `multi_tool_use.parallel` for independent
|
|
@@ -258,8 +259,9 @@ Parallel execution contract:
|
|
|
258
259
|
batched lookups.
|
|
259
260
|
- For the post-lead stage, Codex/Claude should launch
|
|
260
261
|
`post-find-leads-filter-scout` and `post-find-leads-message-scout` in the
|
|
261
|
-
same turn/message when subagents are available
|
|
262
|
-
|
|
262
|
+
same turn/message when those subagents are available in the current session.
|
|
263
|
+
If not, run them sequentially with MCP tools/assets, do not surface install
|
|
264
|
+
status to the customer, and do not claim parallel work.
|
|
263
265
|
- If neither backend is available, run sequentially with the same output schema.
|
|
264
266
|
|
|
265
267
|
Config path resolution (in order):
|
|
@@ -18,11 +18,13 @@ Required inputs:
|
|
|
18
18
|
Required first steps:
|
|
19
19
|
|
|
20
20
|
1. Read the three required inputs.
|
|
21
|
-
2.
|
|
22
|
-
`get_subskill_prompt({ subskillName: "generate-messages", offset, limit })`
|
|
23
|
-
calls until `hasMore` is false.
|
|
24
|
-
3. Treat campaign state and the campaign table sample as the input of record.
|
|
21
|
+
2. Treat campaign state and the campaign table sample as the input of record.
|
|
25
22
|
Disk files are context/debug aids, not durable state.
|
|
23
|
+
3. Use the embedded Message Review Fast Path below. Do not load the full
|
|
24
|
+
long-form `generate-messages` subskill in the normal path. Load it only when
|
|
25
|
+
the fast path is missing a needed campaign-specific rule, the user explicitly
|
|
26
|
+
asks for deep calibration, or the first fast-path draft fails quality gates
|
|
27
|
+
and no local reference explains how to repair it.
|
|
26
28
|
|
|
27
29
|
Owned outputs:
|
|
28
30
|
|
|
@@ -44,13 +46,13 @@ Do not write or modify:
|
|
|
44
46
|
|
|
45
47
|
Process:
|
|
46
48
|
|
|
47
|
-
1. Run the
|
|
48
|
-
|
|
49
|
+
1. Run the embedded fast-path workflow in dry mode from the approved brief,
|
|
50
|
+
lead-review source decision, and `lead-sample.json`.
|
|
49
51
|
2. Use `lead-sample.json` as the only lead sample source. Do not fetch new
|
|
50
52
|
prospects or invent richer row signals.
|
|
51
53
|
3. Build proof inventory, token fill rules, token adherence, angle drafts,
|
|
52
|
-
kill/combine review,
|
|
53
|
-
|
|
54
|
+
kill/combine review, skeptical-prospect review, winner gate, and a raw
|
|
55
|
+
sendable selected winner.
|
|
54
56
|
4. If `lead-filter.md` already exists, cite only basis rows that pass it. If it
|
|
55
57
|
does not exist yet, choose probable good-fit rows from `lead-sample.json` and
|
|
56
58
|
mark the final reconciliation as pending.
|
|
@@ -67,7 +69,7 @@ Process:
|
|
|
67
69
|
Return a concise final status with:
|
|
68
70
|
|
|
69
71
|
- artifacts written
|
|
70
|
-
- whether the full
|
|
72
|
+
- whether embedded fast-path rules were used or the full fallback was needed
|
|
71
73
|
- lead sample basis used
|
|
72
74
|
- proposed template and one sample message
|
|
73
75
|
- selected winner summary
|
|
@@ -76,7 +78,56 @@ Return a concise final status with:
|
|
|
76
78
|
Quality bar:
|
|
77
79
|
|
|
78
80
|
- Do not synthesize a lightweight message from general knowledge. The artifact
|
|
79
|
-
must prove the
|
|
81
|
+
must prove the embedded fast-path workflow ran.
|
|
80
82
|
- Message generation can start before `lead-filter.md`, but message review
|
|
81
83
|
cannot start until the parent verifies the selected basis rows still pass the
|
|
82
84
|
final filter.
|
|
85
|
+
|
|
86
|
+
## Embedded Message Review Fast Path
|
|
87
|
+
|
|
88
|
+
Use this campaign-launch subset to produce a truthful first-send message,
|
|
89
|
+
rendered token examples, and a decision without loading the full long-form
|
|
90
|
+
message prompt.
|
|
91
|
+
|
|
92
|
+
Required `message-validation.md` sections:
|
|
93
|
+
|
|
94
|
+
- `Status`
|
|
95
|
+
- `Mode`
|
|
96
|
+
- `Lead Sample Basis`
|
|
97
|
+
- `Strongest Reply Reason`
|
|
98
|
+
- `Campaign Element Pool`
|
|
99
|
+
- `Gold Standard Strategy Map`
|
|
100
|
+
- `Current Campaign Translation`
|
|
101
|
+
- `Token Fill Rules`
|
|
102
|
+
- `Token Adherence Table`
|
|
103
|
+
- `Angle Drafts`
|
|
104
|
+
- `Kill / Combine Review`
|
|
105
|
+
- `Finalizer Pass`
|
|
106
|
+
- `Gold-Standard Quality Gate`
|
|
107
|
+
- `Skeptical Prospect Review`
|
|
108
|
+
- `Winner Gate`
|
|
109
|
+
- `Selected Winner`
|
|
110
|
+
- `Findings`
|
|
111
|
+
- `Recommendation`
|
|
112
|
+
|
|
113
|
+
Quality gates:
|
|
114
|
+
|
|
115
|
+
- The selected winner is one first outbound send only. No post-accept DM,
|
|
116
|
+
follow-up, cadence branch, or sequence copy.
|
|
117
|
+
- Explain what the product is and what it does in plain language before asking
|
|
118
|
+
for a call.
|
|
119
|
+
- Use only proof from the brief, source review, sample, campaign state, or
|
|
120
|
+
explicit user answers. Unsupported reply-rate, meeting-rate, ROI, revenue,
|
|
121
|
+
and customer-logo claims are blocked.
|
|
122
|
+
- Include at least one supported `{{token}}` when templating, plus a complete
|
|
123
|
+
rendered good-fill example and a complete rendered omit/fallback example.
|
|
124
|
+
- Do not use internal tokens such as `{{profile_signal}}` in customer-facing
|
|
125
|
+
copy.
|
|
126
|
+
- Do not put bracketed instructions in the message body, such as `[ROW_BRIDGE]`,
|
|
127
|
+
`[insert]`, or `[generated]`.
|
|
128
|
+
- Optional row-specific personalization must be grounded in a row field or
|
|
129
|
+
omitted entirely.
|
|
130
|
+
- Subjects should be short, buyer-relevant, and specific. Avoid `quick
|
|
131
|
+
question`, `demo`, `founder call`, sender names, and generic `outbound`.
|
|
132
|
+
- If the message is plausible but not ready to send, set `Recommendation:
|
|
133
|
+
revise-messaging`.
|
package/dist/tools/prompts.js
CHANGED
|
@@ -132,7 +132,7 @@ export const promptToolDefinitions = [
|
|
|
132
132
|
},
|
|
133
133
|
{
|
|
134
134
|
name: "get_source_scout_registry",
|
|
135
|
-
description: "Return the canonical Sellable source-scout agent names and host filenames. Use this before lead-source scouting so Codex and Claude launch the same named scouts from one registry.",
|
|
135
|
+
description: "Return the canonical Sellable source-scout agent names and host filenames. Use this before lead-source scouting so Codex and Claude can launch the same named scouts from one registry when the current host exposes them.",
|
|
136
136
|
inputSchema: {
|
|
137
137
|
type: "object",
|
|
138
138
|
properties: {},
|
|
@@ -242,9 +242,9 @@ export function getSourceScoutRegistry() {
|
|
|
242
242
|
legacy: agent.legacy,
|
|
243
243
|
})),
|
|
244
244
|
usage: {
|
|
245
|
-
codex: "Spawn credible scouts by the returned `name` values in one assistant turn when the
|
|
246
|
-
claude: "Invoke Claude Code Task/Agent subagents with subagent_type equal to the returned `name` values.",
|
|
247
|
-
parentThreadRule: "Do not preload every provider prompt
|
|
245
|
+
codex: "Spawn credible scouts by the returned `name` values in one assistant turn only when the current Codex host exposes those custom agents.",
|
|
246
|
+
claude: "Invoke Claude Code Task/Agent subagents with subagent_type equal to the returned `name` values only when the current Claude session lists those agents.",
|
|
247
|
+
parentThreadRule: "Named agents are optional acceleration. If they are absent, do not customer-surface install status; run the same provider probes with MCP tools from the parent thread. Do not preload every provider prompt before spawning agents; each scout loads only the provider prompt for its lane.",
|
|
248
248
|
},
|
|
249
249
|
};
|
|
250
250
|
}
|
|
@@ -287,9 +287,9 @@ export function getPostFindLeadsScoutRegistry() {
|
|
|
287
287
|
nextStage: "message-review",
|
|
288
288
|
},
|
|
289
289
|
usage: {
|
|
290
|
-
codex: "After the user approves or auto-confirms the lead source, spawn both returned scout `name` values in one assistant turn when
|
|
291
|
-
claude: "After lead source approval, invoke both returned Task/Agent subagents in one assistant message so filter-leads and message generation run concurrently.",
|
|
292
|
-
parentThreadRule: "
|
|
290
|
+
codex: "After the user approves or auto-confirms the lead source, spawn both returned scout `name` values in one assistant turn only when the current Codex host exposes those custom agents.",
|
|
291
|
+
claude: "After lead source approval, invoke both returned Task/Agent subagents in one assistant message only when the current Claude session lists those agents, so filter-leads and message generation run concurrently.",
|
|
292
|
+
parentThreadRule: "Named agents are optional acceleration. If they are absent, do not customer-surface install status; the main thread still orchestrates filter and message branches from brief.md, lead-review.md, and lead-sample.json. The message branch should use the baked-in message-scout prompt or the create-campaign-v2 message-review fast-path asset, not the full long generate-messages prompt in the normal path. Join before message review.",
|
|
293
293
|
},
|
|
294
294
|
};
|
|
295
295
|
}
|
package/dist/tools/rubrics.d.ts
CHANGED
|
@@ -39,9 +39,18 @@ type WaitForRubricResultsInput = {
|
|
|
39
39
|
type WorkflowTableStats = {
|
|
40
40
|
tableId: string;
|
|
41
41
|
totalRows: number;
|
|
42
|
+
enrichedCount?: number;
|
|
43
|
+
needsEnrichCount?: number;
|
|
44
|
+
messagesCount?: number;
|
|
45
|
+
needsApprovalCount?: number;
|
|
46
|
+
processingCount?: number;
|
|
47
|
+
failedCount?: number;
|
|
42
48
|
passRate?: {
|
|
43
49
|
completed: number;
|
|
44
50
|
passed: number;
|
|
51
|
+
pending?: number;
|
|
52
|
+
percent?: number;
|
|
53
|
+
targetCount?: number;
|
|
45
54
|
};
|
|
46
55
|
};
|
|
47
56
|
export declare const rubricToolDefinitions: ({
|
|
@@ -491,8 +500,12 @@ export declare function waitForRubricResults(input: WaitForRubricResultsInput):
|
|
|
491
500
|
passed: number;
|
|
492
501
|
percent: number;
|
|
493
502
|
targetCount: number;
|
|
503
|
+
pending?: undefined;
|
|
494
504
|
};
|
|
495
505
|
reason?: undefined;
|
|
506
|
+
partialResult?: undefined;
|
|
507
|
+
diagnostic?: undefined;
|
|
508
|
+
guidance?: undefined;
|
|
496
509
|
} | {
|
|
497
510
|
ready: boolean;
|
|
498
511
|
reason: string;
|
|
@@ -502,9 +515,28 @@ export declare function waitForRubricResults(input: WaitForRubricResultsInput):
|
|
|
502
515
|
passRate: {
|
|
503
516
|
completed: number;
|
|
504
517
|
passed: number;
|
|
518
|
+
pending: number;
|
|
505
519
|
percent: number;
|
|
506
520
|
targetCount: number;
|
|
507
521
|
};
|
|
522
|
+
partialResult: {
|
|
523
|
+
completed: number;
|
|
524
|
+
passed: number;
|
|
525
|
+
pending: number;
|
|
526
|
+
percent: number;
|
|
527
|
+
targetCount: number;
|
|
528
|
+
enoughToDiagnose: boolean;
|
|
529
|
+
};
|
|
530
|
+
diagnostic: {
|
|
531
|
+
totalRows: number;
|
|
532
|
+
enrichedCount: number | undefined;
|
|
533
|
+
needsEnrichCount: number | undefined;
|
|
534
|
+
messagesCount: number | undefined;
|
|
535
|
+
needsApprovalCount: number | undefined;
|
|
536
|
+
processingCount: number | undefined;
|
|
537
|
+
failedCount: number | undefined;
|
|
538
|
+
};
|
|
539
|
+
guidance: string;
|
|
508
540
|
stats: WorkflowTableStats | null;
|
|
509
541
|
}>;
|
|
510
542
|
export {};
|
package/dist/tools/rubrics.js
CHANGED
|
@@ -332,7 +332,7 @@ export const rubricToolDefinitions = [
|
|
|
332
332
|
},
|
|
333
333
|
{
|
|
334
334
|
name: "wait_for_rubric_results",
|
|
335
|
-
description: "Wait for ICP rubric pass-rate results to complete for queued prospects.",
|
|
335
|
+
description: "Wait for ICP rubric pass-rate results to complete for queued prospects. On timeout, returns partial diagnostic stats; create-campaign-v2 should not poll indefinitely.",
|
|
336
336
|
inputSchema: {
|
|
337
337
|
type: "object",
|
|
338
338
|
properties: {
|
|
@@ -672,6 +672,9 @@ export async function waitForRubricResults(input) {
|
|
|
672
672
|
const completed = lastStats?.passRate?.completed ?? 0;
|
|
673
673
|
const passed = lastStats?.passRate?.passed ?? 0;
|
|
674
674
|
const percent = completed > 0 ? Math.round((passed / completed) * 100) : 0;
|
|
675
|
+
const totalRows = lastStats?.totalRows ?? 0;
|
|
676
|
+
const effectiveTarget = totalRows > 0 ? Math.min(targetCount, totalRows) : targetCount;
|
|
677
|
+
const pending = Math.max(effectiveTarget - completed, 0);
|
|
675
678
|
return {
|
|
676
679
|
ready: false,
|
|
677
680
|
reason: "timeout",
|
|
@@ -681,9 +684,28 @@ export async function waitForRubricResults(input) {
|
|
|
681
684
|
passRate: {
|
|
682
685
|
completed,
|
|
683
686
|
passed,
|
|
687
|
+
pending,
|
|
684
688
|
percent,
|
|
685
|
-
targetCount,
|
|
689
|
+
targetCount: effectiveTarget,
|
|
686
690
|
},
|
|
691
|
+
partialResult: {
|
|
692
|
+
completed,
|
|
693
|
+
passed,
|
|
694
|
+
pending,
|
|
695
|
+
percent,
|
|
696
|
+
targetCount: effectiveTarget,
|
|
697
|
+
enoughToDiagnose: completed > 0,
|
|
698
|
+
},
|
|
699
|
+
diagnostic: {
|
|
700
|
+
totalRows,
|
|
701
|
+
enrichedCount: lastStats?.enrichedCount,
|
|
702
|
+
needsEnrichCount: lastStats?.needsEnrichCount,
|
|
703
|
+
messagesCount: lastStats?.messagesCount,
|
|
704
|
+
needsApprovalCount: lastStats?.needsApprovalCount,
|
|
705
|
+
processingCount: lastStats?.processingCount,
|
|
706
|
+
failedCount: lastStats?.failedCount,
|
|
707
|
+
},
|
|
708
|
+
guidance: "If this is create-campaign-v2 validate-sample, do not repeat waits indefinitely. Use passRate/stats to diagnose and surface sample_revision_required before Settings when the sample is under the pass floor or messages are incomplete.",
|
|
687
709
|
stats: lastStats,
|
|
688
710
|
};
|
|
689
711
|
}
|
package/package.json
CHANGED
|
@@ -120,23 +120,28 @@ scout those angles as independent branches when the host can actually do it:
|
|
|
120
120
|
LinkedIn Engagement / active post engagers (internal `signal-discovery`
|
|
121
121
|
provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
|
|
122
122
|
domains only when relevant. In Codex, explicitly spawn the named custom scouts
|
|
123
|
-
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
124
|
-
the credible lanes
|
|
123
|
+
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
124
|
+
`source-scout-prospeo-contact` for the credible lanes only when the current host
|
|
125
|
+
exposes those names; Codex does not infer subagent fan-out from generic source
|
|
125
126
|
comparison wording. In Claude Code, invoke the generated `source-scout-*`
|
|
126
|
-
Task/Agent subagents for all credible lanes in one assistant message
|
|
127
|
-
installer writes them from the same
|
|
128
|
-
explicit Sellable MCP tool allowlists.
|
|
129
|
-
`get_source_scout_registry` before
|
|
130
|
-
copy, is the runtime source of truth.
|
|
131
|
-
|
|
127
|
+
Task/Agent subagents for all credible lanes in one assistant message only when
|
|
128
|
+
the current session lists those names. The installer writes them from the same
|
|
129
|
+
canonical Sellable agent registry with explicit Sellable MCP tool allowlists.
|
|
130
|
+
The create-campaign-v2 subskill calls `get_source_scout_registry` before
|
|
131
|
+
dispatch so the current registry, not this copy, is the runtime source of truth.
|
|
132
|
+
If the host runs them sequentially or the named agents are unavailable, do not
|
|
133
|
+
claim they ran in parallel and do not surface install status to the customer. In
|
|
134
|
+
chat, call the downstream copy stage `message generation`;
|
|
132
135
|
`message-validation.md` is only an internal proof artifact.
|
|
133
136
|
|
|
134
137
|
After find-leads returns a lead source and the user approves it, use the same
|
|
135
138
|
registry pattern for the two post-lead branches. The create-campaign-v2 subskill
|
|
136
139
|
calls `get_post_find_leads_scout_registry`, then launches the returned
|
|
137
140
|
filter-leads scout and message-generation scout together when real subagents are
|
|
138
|
-
available
|
|
139
|
-
cannot run the two
|
|
141
|
+
available and the current session exposes the returned names. Message
|
|
142
|
+
generation must not wait for the filter unless the host cannot run the two
|
|
143
|
+
branches concurrently. If the post-lead agents are absent, the main thread still
|
|
144
|
+
orchestrates the same branches from the compact context with MCP tools/assets.
|
|
140
145
|
|
|
141
146
|
Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
|
|
142
147
|
lines short, use indexed section labels and bullets, and translate internal
|
|
@@ -218,18 +223,20 @@ Treat host capabilities as concrete functions, not prose conventions:
|
|
|
218
223
|
`mcp__sellable__get_post_find_leads_scout_registry({})` after source
|
|
219
224
|
approval and before dispatching the post-lead filter/message scouts.
|
|
220
225
|
- `launch_source_scout`: Claude Code uses `Task` with `subagent_type` equal to
|
|
221
|
-
the registry `name
|
|
226
|
+
the registry `name` only when the session lists those agents; Codex uses
|
|
227
|
+
named custom agents such as
|
|
222
228
|
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
223
229
|
`source-scout-prospeo-contact` when subagents are available.
|
|
224
230
|
- `launch_post_find_leads_scout`: Claude Code uses `Task` with `subagent_type`
|
|
225
|
-
equal to the returned post-lead registry `name
|
|
226
|
-
custom agents such as
|
|
227
|
-
`post-find-leads-message-scout` when
|
|
231
|
+
equal to the returned post-lead registry `name` only when the session lists
|
|
232
|
+
those agents; Codex uses the returned custom agents such as
|
|
233
|
+
`post-find-leads-filter-scout` and `post-find-leads-message-scout` when
|
|
234
|
+
subagents are available.
|
|
228
235
|
|
|
229
|
-
If a required interactive
|
|
230
|
-
Sellable install/reload problem.
|
|
231
|
-
|
|
232
|
-
scripts.
|
|
236
|
+
If a required interactive question function or MCP loader is missing, stop and
|
|
237
|
+
explain the Sellable install/reload problem. Named scout agents are optional
|
|
238
|
+
acceleration: if they are absent, do not surface install status to the customer;
|
|
239
|
+
fall back to product-native MCP orchestration instead of local scripts.
|
|
233
240
|
|
|
234
241
|
Never narrate local draft housekeeping to the user. If you create directories,
|
|
235
242
|
save drafts, write artifacts, or persist intermediate state, translate it into
|
|
@@ -480,16 +487,17 @@ updates.
|
|
|
480
487
|
copies of this file; packaged Claude Code and Codex runs must use the MCP
|
|
481
488
|
asset loader so they share the same config.
|
|
482
489
|
3. Follow that prompt and workflow config exactly.
|
|
483
|
-
4. For message generation,
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
`message-validation.md` from the brief, lead review, or
|
|
490
|
+
4. For message generation, use the `post-find-leads-message-scout` agent when
|
|
491
|
+
available; its prompt carries the campaign-launch message rules. In the
|
|
492
|
+
parent-thread fallback, load
|
|
493
|
+
`mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })`.
|
|
494
|
+
Do not synthesize `message-validation.md` from the brief, lead review, or
|
|
495
|
+
general knowledge.
|
|
488
496
|
5. Create the campaign shell early with the v1 brief so the user can open the
|
|
489
497
|
watch link and see useful setup state immediately. Import only the first
|
|
490
498
|
bounded review batch after the source is attached to the campaign; do not
|
|
491
499
|
queue workflow cells, attach a sequence, or start until
|
|
492
|
-
`message-validation.md` proves the
|
|
500
|
+
`message-validation.md` proves the fast-path message workflow ran,
|
|
493
501
|
`message-review.md` approves the template, rubrics are saved, and the
|
|
494
502
|
approved message set is synced into the campaign brief.
|
|
495
503
|
6. Keep `selectedLeadListId` as the source list and `workflowTableId` as the
|
|
@@ -368,11 +368,12 @@ Validated draft directory:
|
|
|
368
368
|
not "looks good".
|
|
369
369
|
Approval options should refer to what the user just read, e.g. `Approve this
|
|
370
370
|
brief`, `Revise target`, `Revise offer/proof`, and `Other / custom`.
|
|
371
|
-
When the user chose `Find people for me` and the
|
|
372
|
-
make the recommended approval label
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
371
|
+
When the user chose `Find people for me` and the current runtime exposes the
|
|
372
|
+
named Sellable source-scout agents, make the recommended approval label
|
|
373
|
+
explicit: `Approve brief + use background source scouts`. If those agents are
|
|
374
|
+
not visible in this session, use `Approve brief + compare source paths`
|
|
375
|
+
instead. The customer approves the sourcing decision, not the host
|
|
376
|
+
implementation detail.
|
|
376
377
|
Include an `Open artifact:` link to `brief.md` before the approval question.
|
|
377
378
|
The visible brief must come before local persistence chrome. After the brief
|
|
378
379
|
is synthesized, render the approval-ready brief in chat before running visible
|
|
@@ -402,7 +403,7 @@ campaign table, then use that same batch to tighten the fit filter and draft the
|
|
|
402
403
|
message we should test.`
|
|
403
404
|
- During long post-intake work, show concise progress checkpoints before the
|
|
404
405
|
next expensive stage: source being checked, source switch/tradeoff if any,
|
|
405
|
-
lead sample usable, filter/message drafting, and
|
|
406
|
+
lead sample usable, filter/message drafting, and message-review rule loading.
|
|
406
407
|
Each checkpoint should include a rough remaining time when useful. If a step
|
|
407
408
|
exceeds its estimate by roughly a minute or more, acknowledge it lightly once
|
|
408
409
|
and explain why the extra care helps the campaign. Example:
|
|
@@ -443,14 +444,18 @@ message we should test.`
|
|
|
443
444
|
campaign table `workflowTableId` exist, the normal path is the
|
|
444
445
|
`post-lead-workstreams` step. Launch `filter leads` and `message generation`
|
|
445
446
|
from the same basis (`brief.md`, `lead-review.md`, `lead-sample.json`, and
|
|
446
|
-
the imported review-batch rows) as separate workstreams when the host
|
|
447
|
-
real
|
|
447
|
+
the imported review-batch rows) as separate workstreams when the host exposes
|
|
448
|
+
the named Sellable post-find-leads agents or real background work.
|
|
448
449
|
First call `get_post_find_leads_scout_registry` and use the returned
|
|
449
|
-
canonical `name` values
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
450
|
+
canonical `name` values only when those names are available in the current
|
|
451
|
+
runtime. In Claude Code, use both returned Task/Agent subagents in the same
|
|
452
|
+
assistant message when the session lists them; in Codex, use both returned
|
|
453
|
+
custom scouts as disjoint subagents in the same assistant turn when the host
|
|
454
|
+
exposes them. If the names are absent, the main thread still orchestrates the
|
|
455
|
+
same filter and message branches with MCP tools/assets from the same compact
|
|
456
|
+
context. Do not surface agent install status to the customer. The existing
|
|
457
|
+
`filter-rubric` and `message-generation` steps remain focused retry and
|
|
458
|
+
resume targets.
|
|
454
459
|
- Message generation does not need `lead-filter.md` to start. The moment the
|
|
455
460
|
bounded review batch is imported and `workflowTableId` is ready, start the
|
|
456
461
|
message-generation workstream from `brief.md`, `lead-review.md`,
|
|
@@ -473,19 +478,23 @@ message we should test.`
|
|
|
473
478
|
- Parallel means real parallel execution, not optimistic progress copy. For the
|
|
474
479
|
lead-source scout, first call `get_source_scout_registry` and use the
|
|
475
480
|
returned canonical `name` values. In Codex, explicitly spawn one named custom scout per
|
|
476
|
-
credible source lane when subagents are
|
|
481
|
+
credible source lane when those subagents are visible in the current runtime:
|
|
482
|
+
`source-scout-linkedin-engagement`
|
|
477
483
|
(display: LinkedIn Engagement Scout, powered by the `signal-discovery`
|
|
478
484
|
provider prompt), `source-scout-sales-nav` (Sales Nav Scout), and
|
|
479
|
-
`source-scout-prospeo-contact` (Prospeo Contact Scout). For Claude Code,
|
|
480
|
-
invoke the generated `source-scout-*` Task/Agent subagents
|
|
481
|
-
|
|
482
|
-
installed from the same canonical Sellable agent registry and carry
|
|
483
|
-
Sellable MCP tool allowlists
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
485
|
+
`source-scout-prospeo-contact` (Prospeo Contact Scout). For Claude Code,
|
|
486
|
+
invoke the generated `source-scout-*` Task/Agent subagents for all credible
|
|
487
|
+
lanes in one assistant message only when the session exposes those names.
|
|
488
|
+
They are installed from the same canonical Sellable agent registry and carry
|
|
489
|
+
explicit Sellable MCP tool allowlists when `@sellable/install` is active. The
|
|
490
|
+
parent thread should not preload every provider prompt before spawning scouts;
|
|
491
|
+
each scout loads only its own provider prompt. If host subagents are
|
|
492
|
+
unavailable or the names are not visible, use the same provider probes via
|
|
493
|
+
independent MCP/tool calls in the parent thread or dedicated Sellable MCP
|
|
494
|
+
tools that perform server-side `Promise.all` fan-out. Do not write "source
|
|
495
|
+
scout agents are not installed" or similar host status into customer-facing
|
|
496
|
+
output. If real parallel execution is not available or not allowed, run the
|
|
497
|
+
same DAG sequentially and use honest copy: `I’ll tighten the filter first,
|
|
489
498
|
then draft the message from the same sample.` Never say `kicking off two
|
|
490
499
|
workstreams`, `in parallel`, or `background` unless parallel branches were
|
|
491
500
|
actually launched.
|
|
@@ -698,15 +707,19 @@ Required behavior:
|
|
|
698
707
|
branches, then compare the outputs in `lead-review.md`. Call
|
|
699
708
|
`get_source_scout_registry` first so new scouts can be added without prompt
|
|
700
709
|
rewrites. In Codex, explicitly
|
|
701
|
-
spawn named custom subagents in the same turn:
|
|
702
|
-
`source-scout-
|
|
703
|
-
|
|
710
|
+
spawn named custom subagents in the same turn when the host exposes them:
|
|
711
|
+
`source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
|
|
712
|
+
`source-scout-prospeo-contact` for the credible lanes. Codex does not infer
|
|
713
|
+
this from generic "compare paths" wording. If the realistic
|
|
704
714
|
source set is LinkedIn Engagement + Sales Nav (Signals + Sales Nav), run both.
|
|
705
715
|
If it is LinkedIn Engagement + Prospeo Contact (Signals + Prospeo), run both.
|
|
706
716
|
If all three are credible, run all three when the host/runtime supports it.
|
|
707
717
|
In Claude Code, launch the matching `source-scout-linkedin-engagement`,
|
|
708
|
-
`source-scout-sales-nav`, and/or `source-scout-prospeo-contact` Task/Agent
|
|
709
|
-
in the same assistant message
|
|
718
|
+
`source-scout-sales-nav`, and/or `source-scout-prospeo-contact` Task/Agent
|
|
719
|
+
subagents in the same assistant message only when the current session lists
|
|
720
|
+
those names, not as sequential scout turns. If they are absent, run the same
|
|
721
|
+
provider probes with MCP tools from the parent thread and keep
|
|
722
|
+
`lead-review.md` focused on source evidence, not host-agent availability.
|
|
710
723
|
- Branch A: LinkedIn Engagement / active LinkedIn posts (internal provider:
|
|
711
724
|
Signals / `signal-discovery`). Search relevant keyword lanes, review
|
|
712
725
|
finalist posts, fetch top-post engagers, and estimate warm-fit volume.
|
|
@@ -1042,17 +1055,28 @@ Do not:
|
|
|
1042
1055
|
|
|
1043
1056
|
## Step 3: Generate Message
|
|
1044
1057
|
|
|
1045
|
-
Step 3
|
|
1046
|
-
|
|
1047
|
-
|
|
1058
|
+
Step 3 is orchestrated by the main thread and executed either by the
|
|
1059
|
+
`post-find-leads-message-scout` worker or by the parent-thread fallback. The
|
|
1060
|
+
worker carries the campaign-launch message rules in its agent prompt. The
|
|
1061
|
+
parent-thread fallback must load the small fast-path reference before writing
|
|
1062
|
+
message artifacts:
|
|
1048
1063
|
|
|
1049
1064
|
```
|
|
1050
|
-
|
|
1065
|
+
mcp__sellable__get_subskill_asset({ subskillName: "create-campaign-v2", assetPath: "references/message-review-fast-path.md" })
|
|
1051
1066
|
```
|
|
1052
1067
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1068
|
+
Do not force the main thread to load the full long-form `generate-messages`
|
|
1069
|
+
subskill in the normal path. Load the full `generate-messages` subskill only
|
|
1070
|
+
when the fast path is missing a needed campaign-specific rule, the user
|
|
1071
|
+
explicitly asks for deep calibration, or the first fast-path draft fails quality
|
|
1072
|
+
gates and no local reference explains how to repair it.
|
|
1073
|
+
|
|
1074
|
+
Do NOT proceed to Step 4 (message review gate) unless `message-validation.md`
|
|
1075
|
+
contains the fast-path required sections, a raw sendable Selected Winner, and an
|
|
1076
|
+
explicit single-first-send PASS. If `message-validation.md` contains post-accept
|
|
1077
|
+
DM, follow-up, second-touch, cadence, branch, or other sequence-shaped copy, do
|
|
1078
|
+
not summarize it as ready; route back to message-generation and require a
|
|
1079
|
+
single first outbound send.
|
|
1056
1080
|
|
|
1057
1081
|
After the main-chat message approval, update_campaign_brief writes `## Approved
|
|
1058
1082
|
Message Template` with `{{...}}` tokens before any Generate Message cascade is
|
|
@@ -233,22 +233,26 @@ supplied and multiple source angles are viable, scout Signals, Sales Nav, and
|
|
|
233
233
|
relevant domain/contact paths as independent branches when the host can do so.
|
|
234
234
|
Call `get_source_scout_registry` first and use the returned canonical `name`
|
|
235
235
|
values; the names below are the current registry entries. In Codex, explicitly
|
|
236
|
-
spawn named custom scouts in the same turn
|
|
236
|
+
spawn named custom scouts in the same turn when the current runtime exposes
|
|
237
|
+
them:
|
|
237
238
|
`source-scout-linkedin-engagement` (LinkedIn Engagement Scout, backed by the
|
|
238
239
|
`signal-discovery` provider prompt), `source-scout-sales-nav` (Sales Nav Scout), and
|
|
239
240
|
`source-scout-prospeo-contact` (Prospeo Contact Scout) for the credible lanes. Codex
|
|
240
241
|
does not infer subagent fan-out from generic "compare paths" wording. In Claude
|
|
241
242
|
Code, invoke the generated `source-scout-linkedin-engagement`, `source-scout-sales-nav`,
|
|
242
|
-
and/or `source-scout-prospeo-contact` Task/Agent subagents in one assistant
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
243
|
+
and/or `source-scout-prospeo-contact` Task/Agent subagents in one assistant
|
|
244
|
+
message only when the session lists those names, so Claude can run the source
|
|
245
|
+
lanes concurrently/background. These agents come from the same canonical
|
|
246
|
+
Sellable registry and must load their matching provider prompt before
|
|
247
|
+
searching. The parent thread should not fetch every provider prompt first; that
|
|
248
|
+
burns time and often degenerates into parallel tool calls instead of true
|
|
249
|
+
subagents. When asking the user to approve a brief with Sellable finding leads,
|
|
250
|
+
use an explicit label like `Approve brief + use background source scouts` only
|
|
251
|
+
when the current runtime exposes the named agents; otherwise use `Approve brief
|
|
252
|
+
|
|
253
|
+
- compare source paths`. If the host runs them sequentially or the named agents
|
|
254
|
+
are absent, keep the output numeric but do not claim the source scout was
|
|
255
|
+
parallel or surface install status to the customer.
|
|
252
256
|
|
|
253
257
|
For post-lead work, call `get_post_find_leads_scout_registry` after source
|
|
254
258
|
approval and use the returned canonical `name` values. Launch both returned
|
|
@@ -947,11 +947,11 @@
|
|
|
947
947
|
"ownership": "proof inventory, token strategy, angle drafting, skeptical-prospect review, and selected winner only"
|
|
948
948
|
}
|
|
949
949
|
],
|
|
950
|
-
"earlyMessageStartRule": "After auto-execute-leads confirms the 10-row review batch and workflowTableId is ready, launch message-generation from brief.md, lead-review.md, lead-sample.json, and the imported campaign table sample. Legacy/resume preview prep still requires at least 5 probable good-fit rows. It may run beside filter-leads, but the cascade cannot queue until save_rubrics and update_campaign_brief both succeed.",
|
|
950
|
+
"earlyMessageStartRule": "After auto-execute-leads confirms the 10-row review batch and workflowTableId is ready, launch message-generation from brief.md, lead-review.md, lead-sample.json, and the imported campaign table sample. The message worker carries the campaign-launch message rules in its agent prompt; parent-thread fallback loads references/message-review-fast-path.md. Legacy/resume preview prep still requires at least 5 probable good-fit rows. It may run beside filter-leads, but the cascade cannot queue until save_rubrics and update_campaign_brief both succeed.",
|
|
951
951
|
"finalMessageReconcileRule": "message-validation.md may start before lead-filter.md exists, but before message-review it must cite only imported review-batch rows that still pass lead-filter.md. If the selected winner depends on a row later excluded by lead-filter.md, revise message-generation before message review.",
|
|
952
|
-
"claudeRule": "In Claude Code, launch both returned post-find-leads scouts with Task/Agent subagents in the same assistant message when
|
|
953
|
-
"codexRule": "In Codex, launch both returned post-find-leads scout names as disjoint subagents in the same assistant turn when the host exposes
|
|
954
|
-
"fallback": "If real parallel branches are unavailable, run filter-leads and then message-generation in the parent thread. Do not claim background or parallel work in that fallback."
|
|
952
|
+
"claudeRule": "In Claude Code, launch both returned post-find-leads scouts with Task/Agent subagents in the same assistant message only when the current session lists those agent names. Do not run filter first and then message generation unless subagents/background work are unavailable.",
|
|
953
|
+
"codexRule": "In Codex, launch both returned post-find-leads scout names as disjoint subagents in the same assistant turn only when the host exposes those custom agents for this run. If the host cannot spawn them, run the same branches sequentially and say so.",
|
|
954
|
+
"fallback": "If real parallel branches are unavailable or the named agents are absent, run filter-leads and then message-generation in the parent thread with product MCP tools/assets. Do not customer-surface agent install status, and do not claim background or parallel work in that fallback."
|
|
955
955
|
},
|
|
956
956
|
{
|
|
957
957
|
"action": "wait_for_post_lead_artifacts",
|
|
@@ -1014,7 +1014,7 @@
|
|
|
1014
1014
|
"The post-lead workstreams are disjoint: filter-leads owns lead-filter.md/rubric.json; message-generation owns message-validation.md/message-prep.md/message-candidate-drafts.md.",
|
|
1015
1015
|
"message-generation can start before lead-filter.md, but message-review cannot start until both lead-filter.md and message-validation.md exist and reconcile against the same lead-sample.json.",
|
|
1016
1016
|
"Do not let filter-leads create a new message sample. Do not let message-generation fetch new prospects.",
|
|
1017
|
-
"Before writing message-validation.md, message-generation must
|
|
1017
|
+
"Before writing message-validation.md, message-generation must either run in the post-find-leads-message-scout agent that carries the campaign-launch message rules in its prompt or load get_subskill_asset({ subskillName: \"create-campaign-v2\", assetPath: \"references/message-review-fast-path.md\" }) in the parent-thread fallback. Do not load the full long generate-messages prompt in the normal path.",
|
|
1018
1018
|
"Do not queue, enrich, attach sequence, or start until save_rubrics succeeds and the approved message set is synced into campaignBrief."
|
|
1019
1019
|
],
|
|
1020
1020
|
"doNotAllow": [
|
|
@@ -1181,11 +1181,11 @@
|
|
|
1181
1181
|
"onEnter": [
|
|
1182
1182
|
{
|
|
1183
1183
|
"action": "run_or_reconcile_subskill",
|
|
1184
|
-
"target": "
|
|
1184
|
+
"target": "message-review-fast-path",
|
|
1185
1185
|
"mode": "DRY MODE",
|
|
1186
1186
|
"sampleSource": "lead-sample.json from find-leads",
|
|
1187
1187
|
"toolCallRequiredBeforeArtifacts": [
|
|
1188
|
-
"
|
|
1188
|
+
"get_subskill_asset({ subskillName: \"create-campaign-v2\", assetPath: \"references/message-review-fast-path.md\" }) unless the post-find-leads-message-scout agent prompt already supplied these rules"
|
|
1189
1189
|
],
|
|
1190
1190
|
"skipIfFreshArtifactExists": "message-validation.md",
|
|
1191
1191
|
"reconcileWith": "lead-filter.md; lead-sample.json remains the sample source"
|
|
@@ -1210,12 +1210,12 @@
|
|
|
1210
1210
|
"request_user_input"
|
|
1211
1211
|
],
|
|
1212
1212
|
"toolRules": [
|
|
1213
|
-
"Before writing message-validation.md, message-review.md, or a message-review AskUserQuestion, the current run must
|
|
1213
|
+
"Before writing message-validation.md, message-review.md, or a message-review AskUserQuestion, the current run must either execute inside the post-find-leads-message-scout agent that carries the campaign-launch message rules in its prompt or load get_subskill_asset({ subskillName: \"create-campaign-v2\", assetPath: \"references/message-review-fast-path.md\" }) in the parent-thread fallback.",
|
|
1214
1214
|
"Lead Sample Basis must cite rows from lead-sample.json produced by find-leads. lead-filter.md only gates those rows; it is not a source for a new sample.",
|
|
1215
1215
|
"Do not hand-write message-validation.md from message-prep.md, message-candidate-drafts.md, or general campaign knowledge.",
|
|
1216
|
-
"message-validation.md must prove the
|
|
1216
|
+
"message-validation.md must prove the fast-path workflow ran: Gold Standard Strategy Map, Campaign Element Pool, Current Campaign Translation, Token Fill Rules, Token Adherence Table, Angle Drafts, Kill / Combine Review, Finalizer Pass, Gold-Standard Quality Gate, Skeptical Prospect Review, Winner Gate, and a raw sendable Selected Winner are required before message-review can recommend approve-message.",
|
|
1217
1217
|
"If the Codex-hosted output is plausible but weaker than the loaded gold-standard examples, stop at message-review with revise-messaging. Do not continue to approval or mint just because the mechanical flow worked.",
|
|
1218
|
-
"
|
|
1218
|
+
"Load the full generate-messages subskill only when the fast path is missing a needed campaign-specific rule, the user explicitly asks for deep calibration, or the first fast-path draft fails quality gates and no local reference explains how to repair it.",
|
|
1219
1219
|
"The approved message set must be written back into campaignBrief before validate-sample queues the review-batch cascade."
|
|
1220
1220
|
],
|
|
1221
1221
|
"doNotAllow": [
|
|
@@ -1867,6 +1867,19 @@
|
|
|
1867
1867
|
"doNotRetain": "rows_payload",
|
|
1868
1868
|
"contextBloatNote": "Pass includeRows=false so the MCP tool returns stats only; 25 rows ≈ 67KB and 100 rows ≈ 268KB when row payloads are retained (see references/sample-validation-loop.md §Known Tool Behaviors #2)."
|
|
1869
1869
|
},
|
|
1870
|
+
{
|
|
1871
|
+
"action": "handle_partial_or_timeout_sample",
|
|
1872
|
+
"when": "wait_for_rubric_results.ready_false_or_reason_timeout",
|
|
1873
|
+
"rule": "Do not repeat waits indefinitely. If active processing is visible, wait once more at most. Otherwise treat returned passRate/stats as a partial sample and stop before Settings with sample_revision_required when passed rows are below minProjectedPass or generated messages are incomplete.",
|
|
1874
|
+
"customerStatus": "sample-needs-revision",
|
|
1875
|
+
"showFields": [
|
|
1876
|
+
"passRate.completed",
|
|
1877
|
+
"passRate.passed",
|
|
1878
|
+
"passRate.pending",
|
|
1879
|
+
"passRate.percent",
|
|
1880
|
+
"stats.messagesCount"
|
|
1881
|
+
]
|
|
1882
|
+
},
|
|
1870
1883
|
{
|
|
1871
1884
|
"action": "compute_projected_pass",
|
|
1872
1885
|
"formula": "round(passInSample / sampleSize * importLimit)",
|
|
@@ -1906,6 +1919,8 @@
|
|
|
1906
1919
|
"revision_round_persists_across_resume",
|
|
1907
1920
|
"wait_for_rubric_results_never_retain_rows_payload_in_tail_context",
|
|
1908
1921
|
"wait_for_rubric_results_targetCount_always_explicit",
|
|
1922
|
+
"timeout_never_repeats_without_customer_handoff",
|
|
1923
|
+
"timeout_or_underfloor_sample_never_advances_to_settings",
|
|
1909
1924
|
"review_batch_cascade_waits_for_saved_rubrics_and_approved_template"
|
|
1910
1925
|
],
|
|
1911
1926
|
"watchRequired": true,
|
|
@@ -1915,6 +1930,9 @@
|
|
|
1915
1930
|
],
|
|
1916
1931
|
"transitions": {
|
|
1917
1932
|
"sample_validated": "auto-execute-messaging",
|
|
1933
|
+
"sample_revision_required": "lead-review",
|
|
1934
|
+
"revise_leads": "find-leads",
|
|
1935
|
+
"revise_rubric": "filter-rubric",
|
|
1918
1936
|
"escalation_triggered": "escalation"
|
|
1919
1937
|
},
|
|
1920
1938
|
"requiredCampaignState": [
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Message Review Fast Path
|
|
2
|
+
|
|
3
|
+
Use this reference for `create-campaign-v2` message review. It is the
|
|
4
|
+
campaign-launch subset of `generate-messages`: enough to produce a truthful
|
|
5
|
+
first-send message, rendered token examples, and an approval decision without
|
|
6
|
+
loading the full long-form message-generation prompt into Claude/Codex.
|
|
7
|
+
|
|
8
|
+
Load the full `generate-messages` subskill only when the fast path is missing a
|
|
9
|
+
needed campaign-specific rule, the user explicitly asks for deep calibration, or
|
|
10
|
+
the first fast-path draft fails quality gates and no local reference explains
|
|
11
|
+
how to repair it.
|
|
12
|
+
|
|
13
|
+
## Required Workflow
|
|
14
|
+
|
|
15
|
+
1. Read `brief.md`, `lead-review.md`, `lead-sample.json`, and `lead-filter.md`
|
|
16
|
+
when present.
|
|
17
|
+
2. Pick 2-3 sample rows from `lead-sample.json`, preferring rows that pass the
|
|
18
|
+
filter or are likely to pass. Do not invent new rows.
|
|
19
|
+
3. Build the message from the approved brief and the sampled rows. Use only
|
|
20
|
+
proof that appears in the brief, source review, sample, or explicit user
|
|
21
|
+
answers. Unsupported reply-rate, meeting-rate, ROI, revenue, and customer-logo
|
|
22
|
+
claims are blocked.
|
|
23
|
+
4. Produce `message-validation.md` with the required sections below.
|
|
24
|
+
5. Produce `message-review.md` as the customer-facing checkpoint.
|
|
25
|
+
6. Ask exactly `approve-message` or `revise-messaging`. Do not import, queue,
|
|
26
|
+
attach sequence, or start before `approve-message`.
|
|
27
|
+
|
|
28
|
+
## Required `message-validation.md` Sections
|
|
29
|
+
|
|
30
|
+
- `Status`
|
|
31
|
+
- `Mode`
|
|
32
|
+
- `Lead Sample Basis`
|
|
33
|
+
- `Strongest Reply Reason`
|
|
34
|
+
- `Campaign Element Pool`
|
|
35
|
+
- `Gold Standard Strategy Map`
|
|
36
|
+
- `Current Campaign Translation`
|
|
37
|
+
- `Token Fill Rules`
|
|
38
|
+
- `Token Adherence Table`
|
|
39
|
+
- `Angle Drafts`
|
|
40
|
+
- `Kill / Combine Review`
|
|
41
|
+
- `Finalizer Pass`
|
|
42
|
+
- `Gold-Standard Quality Gate`
|
|
43
|
+
- `Skeptical Prospect Review`
|
|
44
|
+
- `Winner Gate`
|
|
45
|
+
- `Selected Winner`
|
|
46
|
+
- `Findings`
|
|
47
|
+
- `Recommendation`
|
|
48
|
+
|
|
49
|
+
Keep this artifact concise. It should prove the reasoning path, not reproduce
|
|
50
|
+
the full framework.
|
|
51
|
+
|
|
52
|
+
## Message Quality Gates
|
|
53
|
+
|
|
54
|
+
- The selected winner must be one first outbound send only. No post-accept DM,
|
|
55
|
+
follow-up, cadence branch, or sequence copy.
|
|
56
|
+
- The message must explain what the product is and what it does in plain
|
|
57
|
+
language before asking for a call.
|
|
58
|
+
- The message must use a truthful buyer-side reply reason, not just sender
|
|
59
|
+
biography.
|
|
60
|
+
- If using a template, include at least one supported `{{token}}` and show a
|
|
61
|
+
complete rendered good-fill example and complete rendered omit/fallback
|
|
62
|
+
example.
|
|
63
|
+
- Do not use internal tokens such as `{{profile_signal}}` in customer-facing
|
|
64
|
+
copy.
|
|
65
|
+
- Do not put bracketed instructions in the message body, such as `[ROW_BRIDGE]`,
|
|
66
|
+
`[insert]`, `[generated]`, or any instruction for a later model to fill.
|
|
67
|
+
- Optional row-specific personalization must be grounded in a row field or
|
|
68
|
+
omitted entirely. Never use generic filler like "your work" or "your team."
|
|
69
|
+
- Subject lines should be short, buyer-relevant, and specific. Avoid
|
|
70
|
+
`quick question`, `demo`, `founder call`, sender names, and generic `outbound`.
|
|
71
|
+
- If the message is plausible but not ready to send, set
|
|
72
|
+
`Recommendation: revise-messaging`.
|
|
73
|
+
|
|
74
|
+
## Customer-Facing `message-review.md`
|
|
75
|
+
|
|
76
|
+
Render this in chat before asking:
|
|
77
|
+
|
|
78
|
+
- `Status: message-review`
|
|
79
|
+
- `Subject:`
|
|
80
|
+
- `Message:` with the tokenized template or approved AI-native message
|
|
81
|
+
- `Rendered examples:`
|
|
82
|
+
- `Good token fill:`
|
|
83
|
+
- `Good omit:`
|
|
84
|
+
- `Token notes:`
|
|
85
|
+
- `My take:`
|
|
86
|
+
- `Suggested adjustment:`
|
|
87
|
+
- `Question: approve-message or revise-messaging?`
|
|
88
|
+
- `Recommendation: approve-message` or `Recommendation: revise-messaging`
|
|
89
|
+
|
|
90
|
+
`My take` and `Suggested adjustment` must be specific. The adjustment can be
|
|
91
|
+
"approve as-is, or revise once to X if you want Y"; it must not be empty.
|
|
@@ -58,18 +58,37 @@ auto-revise leads.
|
|
|
58
58
|
|
|
59
59
|
7. call `wait_for_rubric_results` with `includeRows=false`; extract ONLY:
|
|
60
60
|
- ready: boolean
|
|
61
|
+
- reason: string when `ready=false`
|
|
61
62
|
- passRate.completed: number
|
|
63
|
+
- passRate.passed: number
|
|
64
|
+
- partialResult: object when present
|
|
62
65
|
- stats: object
|
|
63
66
|
Never retain the full rows payload in tail context.
|
|
64
67
|
- 25 rows ≈ 67KB of payload (full post bodies in carryData)
|
|
65
68
|
- 100 rows ≈ 268KB; 500 rows ≈ 1.3MB — blows context on Opus
|
|
66
69
|
(see §Known Tool Behaviors #2)
|
|
67
70
|
|
|
68
|
-
8.
|
|
71
|
+
8. if `ready=false` and `reason="timeout"`:
|
|
72
|
+
- do NOT keep polling indefinitely
|
|
73
|
+
- treat the returned passRate/stats as a partial sample
|
|
74
|
+
- if active processing is visible (`processingCount > 0` or a similar
|
|
75
|
+
running-cell stat), one additional wait is allowed
|
|
76
|
+
- otherwise diagnose the partial sample now
|
|
77
|
+
- if passed rows are below `sample.minProjectedPass` or generated messages
|
|
78
|
+
are missing for passing rows, stop before Settings with:
|
|
79
|
+
`Status: sample-needs-revision`
|
|
80
|
+
- show the concrete numbers: completed, passed, pending, pass percent, and
|
|
81
|
+
message count when available
|
|
82
|
+
- offer the next product choices: revise source, revise filter/rubric, or
|
|
83
|
+
wait once only if there is active processing
|
|
84
|
+
- never advance to Settings or awaiting-user-greenlight on a timeout or
|
|
85
|
+
underfloor partial sample
|
|
86
|
+
|
|
87
|
+
9. compute metrics:
|
|
69
88
|
passInSample = count of review-batch rows where rubric passed
|
|
70
89
|
projectedPass = round(passInSample / sampleSize * importLimit)
|
|
71
90
|
|
|
72
|
-
|
|
91
|
+
10. branch:
|
|
73
92
|
if projectedPass >= minProjectedPass:
|
|
74
93
|
proceed to Step 15 (auto-execute-messaging) with this review batch
|
|
75
94
|
else:
|
|
@@ -140,6 +159,19 @@ Workaround: strip `carryData` from each row IMMEDIATELY after reading
|
|
|
140
159
|
and BEFORE retaining. Prefer a minimal projection (name, title,
|
|
141
160
|
company, enrichCellId, enrichStatus) over the default shape.
|
|
142
161
|
|
|
162
|
+
### 5. `wait_for_rubric_results` can timeout with enough signal to decide
|
|
163
|
+
|
|
164
|
+
Observed: a 10-row review batch may return `ready=false`, `reason="timeout"`,
|
|
165
|
+
and partial stats such as 9/10 scored, 2 passing, 2 messages generated. That is
|
|
166
|
+
enough to diagnose an underperforming sample. Waiting again without active
|
|
167
|
+
processing makes the experience feel frozen.
|
|
168
|
+
|
|
169
|
+
Workaround: treat timeout stats as a partial sample. If the pass count is below
|
|
170
|
+
the configured floor or message generation has not covered the passing rows,
|
|
171
|
+
stop at `Status: sample-needs-revision` before Settings. Show the completed /
|
|
172
|
+
passed / pending counts and ask whether to revise source, revise filter/rubric,
|
|
173
|
+
or wait once only if active processing is still visible.
|
|
174
|
+
|
|
143
175
|
## Projected Pass Math
|
|
144
176
|
|
|
145
177
|
```text
|
|
@@ -269,10 +269,19 @@ Shape:
|
|
|
269
269
|
queue_cells({ tableId: workflowTableId, cellIds: reviewBatchEnrichCellIds })
|
|
270
270
|
wait_for_campaign_table_ready({ tableId: workflowTableId })
|
|
271
271
|
get_rows_minimal({ tableId: workflowTableId })
|
|
272
|
+
wait_for_rubric_results({ tableId: workflowTableId, targetCount: cohortSize, includeRows: false })
|
|
272
273
|
passInSample = count of first sampleSize review-batch rows with passesRubric === true
|
|
273
274
|
projectedPass = round(passInSample / sampleSize * importLimit)
|
|
274
275
|
|
|
275
|
-
if
|
|
276
|
+
if wait_for_rubric_results.ready === false and reason === "timeout":
|
|
277
|
+
use the partial passRate/stats as the sample diagnostic
|
|
278
|
+
if active processing is visible:
|
|
279
|
+
wait one more time at most
|
|
280
|
+
else:
|
|
281
|
+
stop before Settings with Status: sample-needs-revision
|
|
282
|
+
show completed, passed, pending, pass percent, and message count when available
|
|
283
|
+
ask whether to revise source, revise filter/rubric, or wait once only if still processing
|
|
284
|
+
else if projectedPass >= minProjectedPass:
|
|
276
285
|
advance to Step 15
|
|
277
286
|
else:
|
|
278
287
|
diagnose brief-vs-list per sample-validation-loop.md
|
|
@@ -293,6 +302,11 @@ Do NOT reset to 0 on resume — a stale resume must still respect the
|
|
|
293
302
|
A "list problem" diagnosis NEVER triggers autonomous
|
|
294
303
|
`update_campaign_brief`. Escalate instead.
|
|
295
304
|
|
|
305
|
+
A timeout or underfloor partial sample NEVER advances to Settings,
|
|
306
|
+
awaiting-user-greenlight, or start-campaign. It must hand off as
|
|
307
|
+
`sample_revision_required` with the observed counts so the user can decide
|
|
308
|
+
whether the source or filter should change.
|
|
309
|
+
|
|
296
310
|
When the sample passes the projected-pass floor, call
|
|
297
311
|
`update_campaign({ campaignId, currentStep: "auto-execute-messaging" })`
|
|
298
312
|
and orient the user that messaging will complete for the review batch only.
|
|
@@ -68,9 +68,10 @@ The kickoff doc is the resume surface. Re-open it before repeating discovery wor
|
|
|
68
68
|
- Before source-scout dispatch, call `get_source_scout_registry` and use the
|
|
69
69
|
returned `name` values. The current canonical names are listed below for
|
|
70
70
|
readability, but the registry is the source of truth for install/runtime.
|
|
71
|
-
- If Codex subagents are available
|
|
72
|
-
|
|
73
|
-
lane results before
|
|
71
|
+
- If Codex subagents are available and the current runtime exposes the returned
|
|
72
|
+
names, run the scout lanes with named custom agents. Spawn one agent per
|
|
73
|
+
credible lane in the same turn, then wait for all lane results before
|
|
74
|
+
synthesizing `lead-review.md`:
|
|
74
75
|
- `source-scout-linkedin-engagement` (display: LinkedIn Engagement Scout) for
|
|
75
76
|
active LinkedIn posts and engagers; internally this uses the
|
|
76
77
|
`signal-discovery` provider prompt plus `search_signals` /
|
|
@@ -81,15 +82,20 @@ The kickoff doc is the resume surface. Re-open it before repeating discovery wor
|
|
|
81
82
|
account/domain and verified-contact expansion.
|
|
82
83
|
- Common parallel comparisons are LinkedIn Engagement + Sales Nav, LinkedIn
|
|
83
84
|
Engagement + Prospeo Contact, or all three when each lane is credible.
|
|
84
|
-
- If Claude `Task`/`Agent` is available
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
- If Claude `Task`/`Agent` is available and the current Claude session lists
|
|
86
|
+
the returned source-scout names, deep exploration uses the file-backed Claude
|
|
87
|
+
explorer agents installed from the same canonical Sellable agent registry.
|
|
88
|
+
Launch every credible lane in the same assistant message so Claude Code can
|
|
89
|
+
run them concurrently/background:
|
|
88
90
|
- `./.claude/agents/source-scout-linkedin-engagement.md`
|
|
89
91
|
- `./.claude/agents/source-scout-sales-nav.md`
|
|
90
92
|
- `./.claude/agents/source-scout-prospeo-contact.md`
|
|
91
93
|
- These Claude agents must have explicit Sellable MCP tool allowlists and must
|
|
92
|
-
load the matching provider prompt before searching.
|
|
94
|
+
load the matching provider prompt before searching. They are optional
|
|
95
|
+
acceleration: if the names are absent, do not mention the missing install or
|
|
96
|
+
agent availability in customer-facing output. Run the same provider probes
|
|
97
|
+
from the parent thread with MCP tools and keep `lead-review.md` focused on
|
|
98
|
+
source evidence.
|
|
93
99
|
- The parent thread should not preload every provider prompt before launching
|
|
94
100
|
scouts. Spawn the credible scouts first; each scout loads only the provider
|
|
95
101
|
prompt for its lane and returns structured evidence.
|
|
@@ -261,9 +267,10 @@ If the first probe is weak or noisy and enough context exists, try 1-2 alternate
|
|
|
261
267
|
If the first probe has good quality but insufficient scale, iterate 1-2 times to widen intelligently before returning.
|
|
262
268
|
When two or more source angles are viable, run the provider probes in real
|
|
263
269
|
parallel when the host/runtime allows it. For Codex, explicitly spawn the
|
|
264
|
-
named source scout agents above
|
|
265
|
-
general "compare sources" wording.
|
|
266
|
-
matching `source-scout-*` Task/Agent
|
|
270
|
+
named source scout agents above only when those returned names are visible;
|
|
271
|
+
Codex will not infer subagent fan-out from general "compare sources" wording.
|
|
272
|
+
For Claude Code, explicitly invoke the matching `source-scout-*` Task/Agent
|
|
273
|
+
subagents in one message only when the current session exposes them, instead of
|
|
267
274
|
probing one lane, waiting, then probing the next. Examples: LinkedIn Engagement
|
|
268
275
|
|
|
269
276
|
- Sales Nav, LinkedIn Engagement + Prospeo Contact, or Sales Nav + Prospeo
|
|
@@ -433,8 +440,10 @@ Show the light-touch results and ask whether to deep-dispatch or iterate.
|
|
|
433
440
|
## Layer 3: Selective deep exploration
|
|
434
441
|
|
|
435
442
|
Spawn only the validated paths from Gate 1. In Claude Code, invoke all selected
|
|
436
|
-
`source-scout-*` agents in one turn
|
|
437
|
-
runtime supports it.
|
|
443
|
+
`source-scout-*` agents in one turn only when the current session exposes those
|
|
444
|
+
agent names, so source scouting is concurrent when the runtime supports it. If
|
|
445
|
+
they are absent, run the validated provider probes from the parent thread
|
|
446
|
+
without telling the customer about host-agent install state.
|
|
438
447
|
|
|
439
448
|
- `source-scout-linkedin-engagement`
|
|
440
449
|
- `source-scout-sales-nav`
|