@sellable/mcp 0.1.212 → 0.1.214
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 -7
- package/agents/post-find-leads-message-scout.md +176 -134
- package/dist/engage-memory.js +0 -5
- package/dist/identity-memory.js +0 -4
- package/dist/tools/engage-memory.js +2 -2
- package/dist/tools/leads.js +7 -3
- package/dist/tools/prompts.js +18 -12
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +11 -12
- package/skills/create-campaign/context/learnings.md +1 -1
- package/skills/create-campaign/references/brief-template.md +2 -2
- package/skills/create-campaign-brief/references/brief-template.md +2 -2
- package/skills/create-campaign-brief/references/draft-lifecycle.md +1 -1
- package/skills/create-campaign-brief/references/examples/briefs/gelee.md +2 -2
- package/skills/create-campaign-brief/references/examples/briefs/superpower.md +41 -28
- package/skills/create-campaign-brief/references/phase75-active-runtime-message-pack.md +27 -36
- package/skills/create-campaign-v2/SKILL.md +16 -9
- package/skills/create-campaign-v2/core/auto-execute.README.md +11 -11
- package/skills/create-campaign-v2/core/auto-execute.yaml +4 -4
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/create-campaign-v2/references/ai-tells.md +54 -19
- package/skills/create-campaign-v2/references/approval-gate-framing.md +10 -10
- package/skills/create-campaign-v2/references/escalation-ladder.md +3 -3
- package/skills/create-campaign-v2/references/final-handoff-contract.md +3 -3
- package/skills/create-campaign-v2/references/gold-standard-message-examples.md +295 -226
- package/skills/create-campaign-v2/references/gold-standard-message-patterns.md +48 -9
- package/skills/create-campaign-v2/references/gold-standard-message-validation-example.md +4 -4
- package/skills/create-campaign-v2/references/lead-validation-preview.md +1 -1
- package/skills/create-campaign-v2/references/parallel-critique-protocol.md +10 -10
- package/skills/create-campaign-v2/references/sample-validation-loop.md +3 -3
- package/skills/create-campaign-v2/references/{thomas-revision-filters.md → sellable-cleanup-rules.md} +29 -19
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +1 -1
- package/skills/create-campaign-v2/references/thomas-variant-selection.md +1 -1
- package/skills/create-campaign-v2/references/validation-criteria.md +24 -18
- package/skills/create-campaign-v2-tail/SKILL.md +7 -7
- package/skills/create-campaign-v2-validation/SKILL.md +23 -7
- package/skills/create-post/SKILL.md +27 -27
- package/skills/engage/SKILL.md +12 -12
- package/skills/engage/core/README.md +14 -14
- package/skills/find-leads/SKILL.md +1 -1
- package/skills/generate-messages/SKILL.md +305 -147
- package/skills/interview/SKILL.md +24 -24
- package/skills/interview/references/legacy-linkedin-interview.md +12 -12
- package/skills/interview/references/reference-curation.md +4 -4
- package/skills/interview/references/voice-capture-method.md +1 -1
- package/skills/load-voice/SKILL.md +21 -25
- package/skills/research/SKILL.md +1 -1
- package/skills/research/config.json +9 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Gold-Standard Message Patterns
|
|
2
2
|
|
|
3
|
-
Use these patterns when validating or drafting
|
|
3
|
+
Use these patterns when validating or drafting Sellable campaign messages.
|
|
4
4
|
|
|
5
5
|
The priority is not "write generally good outbound." The priority is:
|
|
6
6
|
|
|
@@ -147,6 +147,41 @@ Shape:
|
|
|
147
147
|
- bring the strongest proof
|
|
148
148
|
- give a low-friction next step
|
|
149
149
|
|
|
150
|
+
### Pattern 2B: Sender-Owned Post Acknowledgment
|
|
151
|
+
|
|
152
|
+
Use when the sender/client authored the source post and row data proves the
|
|
153
|
+
recipient reacted or commented.
|
|
154
|
+
|
|
155
|
+
Shape:
|
|
156
|
+
|
|
157
|
+
- light first-person acknowledgment of the post support
|
|
158
|
+
- soft relevance bridge from the post topic into the buyer context
|
|
159
|
+
- simple product framing or problem line
|
|
160
|
+
- low-friction next step
|
|
161
|
+
- every line must create the need for the next line; the message should read as
|
|
162
|
+
post support -> why the topic may matter now -> what the product/problem does
|
|
163
|
+
about that topic -> next step
|
|
164
|
+
|
|
165
|
+
Preferred bridge:
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
Appreciate you showing some love on my post about {{signal_topic}}.
|
|
169
|
+
|
|
170
|
+
Figured this might be relevant if {{channel_context}} is becoming more of a {{workflow_context}} for {{company_context}}.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Why it works:
|
|
174
|
+
|
|
175
|
+
- acknowledges the real sender-owned source without sounding like an activity log
|
|
176
|
+
- avoids overclaiming that a reaction means buying intent
|
|
177
|
+
- gives the body a reason to move from the post topic into the product/problem
|
|
178
|
+
- prevents orphan product lines that sound pasted underneath a source opener
|
|
179
|
+
|
|
180
|
+
Avoid jumping directly from the acknowledgment into generic category pain like
|
|
181
|
+
`a lot of B2B teams...` or `most teams...`; that transition sounds assembled.
|
|
182
|
+
If the next line would still make sense after deleting the acknowledgment and
|
|
183
|
+
bridge, the source opener is not doing real work and should be rewritten or cut.
|
|
184
|
+
|
|
150
185
|
### Pattern 2A: Signal-Led Honest Operator
|
|
151
186
|
|
|
152
187
|
Use this subpattern when the signal is real, the sender can sound direct and
|
|
@@ -158,14 +193,15 @@ Shape:
|
|
|
158
193
|
- plain signal mention first
|
|
159
194
|
- one line that makes the relevance feel honest
|
|
160
195
|
- simple product framing
|
|
161
|
-
-
|
|
196
|
+
- specific low-friction next step
|
|
162
197
|
- optional short `PS` with proof as the final line
|
|
163
198
|
|
|
164
199
|
Prefer:
|
|
165
200
|
|
|
166
201
|
- lowercase or casual casing when the motion supports it
|
|
167
|
-
- an honest line like "
|
|
168
|
-
-
|
|
202
|
+
- an honest line like "hope this is relevant" or "so may be off, but this seemed relevant"
|
|
203
|
+
- a concrete CTA that names the useful conversation or asset
|
|
204
|
+
- binary options only when the brief explicitly supports two real next steps
|
|
169
205
|
- direct wording over polished marketing language
|
|
170
206
|
|
|
171
207
|
Avoid:
|
|
@@ -194,11 +230,11 @@ Use only when event, signal, and hiring hooks are unavailable.
|
|
|
194
230
|
|
|
195
231
|
This is the fallback most likely to drift into bland copy, so keep it tight.
|
|
196
232
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
category
|
|
233
|
+
Use the proof-led fallback logic below directly. Do not retrieve a deleted
|
|
234
|
+
stack-replacement archive example as copy. The useful rhythm is: observed
|
|
235
|
+
current-state → what breaks → product-name-first mechanism → strongest true
|
|
236
|
+
proof or useful CTA. That rhythm generalizes across proof-led fallbacks even
|
|
237
|
+
when the category is not literally stack replacement.
|
|
202
238
|
|
|
203
239
|
Shape:
|
|
204
240
|
|
|
@@ -242,6 +278,9 @@ Prefer:
|
|
|
242
278
|
- product-name-first mechanism lines when the product can be named cleanly
|
|
243
279
|
- a short `PS` for social proof, backing, prior-company proof, or category-first
|
|
244
280
|
proof when that proof is real and would otherwise bloat the main body
|
|
281
|
+
- backing proof in a `PS` must translate into buyer value, not seller focus:
|
|
282
|
+
`backed by [X] to help [buyer segment] [buyer outcome]` beats
|
|
283
|
+
`backed by [X] and focused on [category/problem]`
|
|
245
284
|
- if a `PS` is used, keep it to the final line of the message
|
|
246
285
|
- short words and plain sentences a busy buyer can scan fast
|
|
247
286
|
- one sentence per line in the final draft when the channel is InMail or email
|
|
@@ -19,7 +19,7 @@ Status: confirmed
|
|
|
19
19
|
Mode: DRY MODE (no DB mutation)
|
|
20
20
|
Template Used: event-led canonical template
|
|
21
21
|
Primary Example: Example 1 — Revvix / Spektion Event-Led Security
|
|
22
|
-
Secondary Influence: Example
|
|
22
|
+
Secondary Influence: Example 6 — Useful CTA Shapes (binary option)
|
|
23
23
|
Lead Sample Basis: 3 validated leads (Dana Patel — VP Security Eng at Arco;
|
|
24
24
|
Mariko Stein — Head of AppSec at Fernway; Ben Oduya — Director, Vuln Mgmt
|
|
25
25
|
at Plantform)
|
|
@@ -52,7 +52,7 @@ No other tokens are allowed in this campaign.
|
|
|
52
52
|
|
|
53
53
|
## Token Adherence Table
|
|
54
54
|
|
|
55
|
-
| Sample | Supported Tokens Only | All Tokens Resolved | Proof Safe | Personalization Grounded |
|
|
55
|
+
| Sample | Supported Tokens Only | All Tokens Resolved | Proof Safe | Personalization Grounded | Sellable Cleanup Rules | Result |
|
|
56
56
|
| ------ | --------------------- | ------------------- | ---------- | ------------------------ | -------------- | ------ |
|
|
57
57
|
| Dana | yes | yes | yes | yes | pass | pass |
|
|
58
58
|
| Mariko | yes | yes | yes | yes | pass | pass |
|
|
@@ -135,7 +135,7 @@ No other tokens are allowed in this campaign.
|
|
|
135
135
|
- Best bridge: **Candidate A** — single-line transition from pain to
|
|
136
136
|
mechanism without editorializing.
|
|
137
137
|
- Best CTA: **Candidate C** — "Happy to grab coffee or send a short
|
|
138
|
-
overview first" is the binary option from Example
|
|
138
|
+
overview first" is the binary option from Example 6 and matches the
|
|
139
139
|
low-pressure event motion better than A's open-ended close.
|
|
140
140
|
- Assembly note: clean combination — opener from C, bridge + mechanism from
|
|
141
141
|
A, CTA from C, plus a new short `PS` carrying the rank-5 founder proof
|
|
@@ -203,7 +203,7 @@ No other tokens are allowed in this campaign.
|
|
|
203
203
|
generic credibility sentence."
|
|
204
204
|
- Token fill rules are declared once, with source fields and fallbacks, and
|
|
205
205
|
the adherence table reports pass/fail per lead.
|
|
206
|
-
- The "What Good Looks Like" bar in `
|
|
206
|
+
- The "What Good Looks Like" bar in `sellable-cleanup-rules.md` is met:
|
|
207
207
|
sharp voice, grounded personalization, motion-aligned structure, useful
|
|
208
208
|
CTA proportional to signal.
|
|
209
209
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Parallel Critique Protocol
|
|
2
2
|
|
|
3
|
-
This reference governs the optional Step 15 critique pass
|
|
4
|
-
|
|
3
|
+
This reference governs the optional Step 15 critique pass. Load this file
|
|
4
|
+
whenever `messaging.critique.enabled === true`
|
|
5
5
|
in `core/auto-execute.yaml`. When the flag is `false`, the plain Step 15
|
|
6
6
|
path runs unchanged and none of the protocol below applies.
|
|
7
7
|
|
|
8
8
|
## Principle
|
|
9
9
|
|
|
10
10
|
Step 15 (`auto-execute-messaging`) already generates messages under the
|
|
11
|
-
|
|
11
|
+
offline-validation token contract. The critique pass is a bounded, opt-in quality
|
|
12
12
|
lens on top of that output. It is NOT a second drafting pass. It never
|
|
13
13
|
invents new tokens, new proof, or new personalization, and it never
|
|
14
14
|
ships a rewrite that violates the token contract.
|
|
@@ -20,7 +20,7 @@ The critique pass is:
|
|
|
20
20
|
- **Parallel.** Three fixed critic groups (targeting, copy, voice)
|
|
21
21
|
run in parallel and return structured JSON.
|
|
22
22
|
- **Synthesized.** One synthesis step merges the three voices into a
|
|
23
|
-
single rewrite and re-runs the
|
|
23
|
+
single rewrite and re-runs the offline-validation finalizer pass.
|
|
24
24
|
- **Budget-capped.** A trip on `budgetUsdCap` HALTS critique for the
|
|
25
25
|
remaining sample and continues the plain tail. Cost never explodes
|
|
26
26
|
silently.
|
|
@@ -47,8 +47,8 @@ calibration.
|
|
|
47
47
|
- `lead-sample.json`, `lead-filter.md`, `brief.md` (read-only — these
|
|
48
48
|
are the same artifacts the plain drafter used).
|
|
49
49
|
- `messaging.critique.*` config values from `auto-execute.yaml`.
|
|
50
|
-
- The
|
|
51
|
-
`references/
|
|
50
|
+
- The offline-validation token contract rules in
|
|
51
|
+
`references/sellable-cleanup-rules.md`.
|
|
52
52
|
|
|
53
53
|
## Step Shape
|
|
54
54
|
|
|
@@ -201,7 +201,7 @@ the protocol file).
|
|
|
201
201
|
|
|
202
202
|
Rules:
|
|
203
203
|
|
|
204
|
-
1. **Token contract first.** The synthesizer enforces the
|
|
204
|
+
1. **Token contract first.** The synthesizer enforces the offline-validation
|
|
205
205
|
token contract verbatim:
|
|
206
206
|
|
|
207
207
|
- Use only tokens documented in `brief.md` as supported fields.
|
|
@@ -216,7 +216,7 @@ Rules:
|
|
|
216
216
|
voice. Do not blend two motions into one rewrite.
|
|
217
217
|
|
|
218
218
|
3. **Finalizer pass last.** If `synthesis.enforceFinalizerPass` is
|
|
219
|
-
`true` (default), re-run the
|
|
219
|
+
`true` (default), re-run the offline-validation finalizer pass on the
|
|
220
220
|
synthesis output. The finalizer is the last guardrail against
|
|
221
221
|
critic-introduced token drift. A finalizer failure falls back to
|
|
222
222
|
the plain message for that row.
|
|
@@ -346,14 +346,14 @@ passes.
|
|
|
346
346
|
|
|
347
347
|
## Hard Rules
|
|
348
348
|
|
|
349
|
-
- Critique is OFF by default.
|
|
349
|
+
- Critique is OFF by default. The plain campaign tail never flips the flag.
|
|
350
350
|
- Sample size is bounded by `messaging.critique.sampleSize`. The
|
|
351
351
|
pass NEVER runs against the full cohort.
|
|
352
352
|
- Three critic groups only: targeting, copy, voice. Do NOT add a
|
|
353
353
|
fourth.
|
|
354
354
|
- Every critic returns the structured JSON envelope above. Free-form
|
|
355
355
|
critic output is discarded.
|
|
356
|
-
- The synthesizer enforces the
|
|
356
|
+
- The synthesizer enforces the offline-validation token contract verbatim.
|
|
357
357
|
- The synthesis step MUST re-run the finalizer pass when
|
|
358
358
|
`enforceFinalizerPass === true` (default).
|
|
359
359
|
- Opus is reserved for the highest-value subset only and gated
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sample Validation Loop
|
|
2
2
|
|
|
3
|
-
This reference governs Step 14 (`validate-sample`) of the
|
|
3
|
+
This reference governs Step 14 (`validate-sample`) of the
|
|
4
4
|
autonomous tail. Load this file before enriching + scoring the sample, and
|
|
5
5
|
on every revision round.
|
|
6
6
|
|
|
@@ -243,9 +243,9 @@ Action: autonomous `update_campaign_brief` with the specific diagnostic
|
|
|
243
243
|
(e.g. "add case-study proof for pain point Y"). Rerun sample. Increment
|
|
244
244
|
revisionRound.
|
|
245
245
|
|
|
246
|
-
#### Worked example — horizontal-SaaS seniority drift
|
|
246
|
+
#### Worked example — horizontal-SaaS seniority drift
|
|
247
247
|
|
|
248
|
-
Symptom observed during
|
|
248
|
+
Symptom observed during an Ambral walkthrough: 14/30 (47%)
|
|
249
249
|
sample was FIT+MAYBE, but the MAYBE cluster was driven by sub-D-round
|
|
250
250
|
"VP Customer Success" titles. These rows match the title whitelist but
|
|
251
251
|
likely don't own budget at that stage.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Sellable Cleanup Rules
|
|
2
2
|
|
|
3
|
-
Use these filters before
|
|
3
|
+
Use these filters before offline message validation is marked `confirmed`.
|
|
4
4
|
|
|
5
5
|
Read "What Good Looks Like" first. These are the positive targets. Use
|
|
6
6
|
"Automatic Revisions" as the rejection backstop, not the primary lens.
|
|
@@ -74,12 +74,18 @@ Revise or reject the sample when any of these happen.
|
|
|
74
74
|
- **actions are implied, not stated** — e.g. "runs that chain as AI agents" when a clearer version would name the specific actions (verb + object, one per line)
|
|
75
75
|
- **category-level opener used when a per-lead signal exists** — if `lead-sample.json` carries any per-lead signal (post, hire, visible tool, topic engagement), the opener must reference it. Category-level openers of shape `"Most [category] teams still do X by hand"` are only acceptable when zero per-lead signal is in the sample. When a category-level opener is used as fallback, Findings must flag it explicitly
|
|
76
76
|
- **mind-reading from engagement signals** — a topic engagement, post, public activity, role, company, or hiring trigger does not prove buyer intent. Reject phrases like `"AI-GTM stack is clearly on your mind"`, `"you're clearly focused on..."`, `"obviously relevant"`, or `"already thinking about..."` unless that exact priority is explicitly present in `lead-sample.json`. Translate to low-certainty buyer context or omit the signal from copy.
|
|
77
|
-
- **source-y signal narration** — reject `"saw you on..."`, `"saw you engaging with..."`, `"you commented on..."`, `"your LinkedIn activity..."`, `"you might not remember the thread..."`, `"found you through [source] and your role looked close..."`, or any line that makes the recipient feel watched unless the chosen archived motion is intentionally self-aware about the signal. For LinkedIn-post-sourced campaigns, a topic-level bridge is allowed when it explains why the note exists and stays apologetically uncertain: `"saw you in a few conversations about [topic], so may be off, but this seemed relevant."
|
|
78
|
-
- **
|
|
77
|
+
- **source-y signal narration** — reject `"saw you on..."`, `"saw you engaging with..."`, `"you commented on..."`, `"your LinkedIn activity..."`, `"you might not remember the thread..."`, `"found you through [source] and your role looked close..."`, or any line that makes the recipient feel watched unless the chosen archived motion is intentionally self-aware about the signal. For sender-owned LinkedIn post sources, a light first-person acknowledgment is allowed when row data proves a reaction/comment: `"appreciate you showing some love on my post about [topic]"` or `"thanks for showing support on my [topic] post"`. Do not name a comment unless comment text is present. Follow the acknowledgment with a soft relevance bridge before broad pain/product copy, e.g. `"figured this might be relevant if LinkedIn is becoming more of a GTM channel for [company]"`. For third-party LinkedIn-post-sourced campaigns, a topic-level bridge is allowed when it explains why the note exists and stays apologetically uncertain: `"saw you in a few conversations about [topic], so may be off, but this seemed relevant."`, `"saw you in a few conversations around [topic], so hope this is relevant."`, or `"found you in a thread about [topic], so may be off, but this seemed relevant."` Reserve `"raise your hand"` language for explicit lead-magnet comments, replies, or opt-ins. Translate the signal into natural buyer context or omit it.
|
|
78
|
+
- **fake line-to-line continuity** — reject line stacks where the source acknowledgment, relevance bridge, product line, and CTA do not actually build on each other. Each line must make the next line feel earned. If two adjacent lines could be swapped, deleted, or joined with `"anyway"` without changing the meaning, the transition is fake. In sender-owned post campaigns, the chain should be: support on my post -> why this topic may matter for the company -> what the product/problem does about that same topic -> low-friction next step.
|
|
79
|
+
- **assumptive title-fit opener** — reject `"Your [role] role at [company] looked close to this problem"` or `"looked close to this outbound campaign problem"`. This asserts fit from title/company. Keep the apologetic uncertainty instead: `"may be off, but if [workflow] is relevant to what you're working on..."`.
|
|
79
80
|
- **internal-metric flex** — reject compute time, token/cache details, model names, agent-counts, orchestration internals, or similar process metrics unless the brief proves the buyer cares about that exact detail. `~5 min of compute per message` is not buyer value by itself.
|
|
80
|
-
- **action lines are parallel
|
|
81
|
+
- **action lines are parallel and harder to scan as paragraphs** — when 3
|
|
82
|
+
adjacent product actions repeat the same subject pattern (e.g. `It drafts...`
|
|
83
|
+
/ `It adapts...` / `It helps...`) and none carries narrative proof context,
|
|
84
|
+
prefer a short bullet stack for mobile readability. Keep one-line paragraphs
|
|
85
|
+
when there are only 1-2 actions, one line needs narrative context, bullets
|
|
86
|
+
feel like a landing page, or the paragraph version is clearly more human.
|
|
81
87
|
- **PS carries a second proof beat that doesn't answer a different objection** — the second beat must open a dimension beat #1 didn't address (e.g. technical reliability when beat #1 was operator empathy; named backing when beat #1 was founder track record). Default PS is ONE beat
|
|
82
|
-
- **apologetic source-thread PS** — reject `p.s. if the source thread was just casual reading, ignore me`, `only reaching out where the role and topic looked close`, or any PS that defends why the recipient was sourced. If the source is too weak, omit the personalization line. A relevance-risk PS such as `p.s. if this is
|
|
88
|
+
- **apologetic source-thread PS** — reject `p.s. if the source thread was just casual reading, ignore me`, `only reaching out where the role and topic looked close`, or any PS that defends why the recipient was sourced. If the source is too weak, omit the personalization line. A relevance-risk PS such as `p.s. if this is not relevant to your outbound workflow, ignore me` is allowed because it lowers pressure without narrating the source.
|
|
83
89
|
- **subject line uses the same banned glue jargon as the body** — any B2B compound noun the buyer wouldn't say naturally in conversation. Subject follows the same jargon rules as the body
|
|
84
90
|
- **jargon that a 5th-grade reader could not parse** — any B2B compound noun the buyer wouldn't say naturally in conversation. Common examples across motions: "handoff", "rip-and-replace", "pane of glass", "single source of truth", "alert fatigue", "top of funnel", "time to hire". Keep product and tool names that the buyer recognizes; cut the glue language around them
|
|
85
91
|
- em dashes in copy that is otherwise plainspoken
|
|
@@ -93,6 +99,7 @@ Revise or reject the sample when any of these happen.
|
|
|
93
99
|
- **full titles in the PS when the bare role word would read more natural** — "our CEO [did X]" reads more natural than "CEO Alex, 2x founder, [did X]". Drop titles unless the title itself is the proof
|
|
94
100
|
- more than two proof beats in the PS (three or more reads as a resume dump)
|
|
95
101
|
- a proof beat that is not tied to the buyer's situation — proof should explain why this sender gets the buyer's pain, not just list credentials
|
|
102
|
+
- **backing proof ends in seller-focus copy** — reject `backed by [X] and focused on [category/problem]`. Keep the backing only if the same line turns into buyer value, e.g. `backed by [X] to help [buyer segment] [buyer outcome]`; otherwise cut the PS
|
|
96
103
|
|
|
97
104
|
**Motion alignment**
|
|
98
105
|
|
|
@@ -364,16 +371,20 @@ who scraped me."
|
|
|
364
371
|
sentence].`
|
|
365
372
|
- `Hey {{first_name}}, hope this is relevant if [buyer context] is
|
|
366
373
|
still on your plate.`
|
|
367
|
-
- `Hey {{first_name}}, may be off, but if [workflow] is
|
|
368
|
-
|
|
374
|
+
- `Hey {{first_name}}, may be off, but if [workflow] is relevant to what
|
|
375
|
+
you're working on, this might be useful.`
|
|
369
376
|
- `Hey {{first_name}}, saw you might be interested in [topic], so hope
|
|
370
377
|
this is relevant.`
|
|
371
378
|
- `Hey {{first_name}}, saw you in a few conversations around [topic],
|
|
372
379
|
so hope this is relevant.`
|
|
380
|
+
- `Hey {{first_name}}, found you in a thread about [topic], so may be
|
|
381
|
+
off, but this seemed relevant.`
|
|
373
382
|
- `Hey {{first_name}}, saw you raise your hand for [topic], so figured
|
|
374
|
-
this was (hopefully) worth sending.`
|
|
383
|
+
this was (hopefully) worth sending.` Only for explicit lead-magnet
|
|
384
|
+
comments, replies, or opt-ins.
|
|
375
385
|
- `Hey {{first_name}}, saw you raise your hand for [topic] (creepy to
|
|
376
386
|
reach out based on that, i know) - but this felt too on the nose to ignore.`
|
|
387
|
+
Only for explicit lead-magnet comments, replies, or opt-ins.
|
|
377
388
|
- `Hey {{first_name}}, quick one. My co-founder and I left [prior
|
|
378
389
|
role] to build [X].`
|
|
379
390
|
- `Hey {{first_name}}, reaching out because [one-line sender
|
|
@@ -443,17 +454,17 @@ Tell #8 hardcoded signoff, Tell #10 vague-proof) overlap with
|
|
|
443
454
|
Filters 3 and 6. This is intentional — the catalog is the canonical
|
|
444
455
|
enumeration; Filter 8 is the catalog-driven check. Filters 3 and 6
|
|
445
456
|
remain as human-readable explanations of specific high-priority
|
|
446
|
-
tell classes, but the actual detection logic in
|
|
457
|
+
tell classes, but the actual detection logic in offline validation reads from
|
|
447
458
|
`ai-tells.md`.
|
|
448
459
|
|
|
449
460
|
**Adding new tells.** When UAT surfaces a new AI-tell pattern, add
|
|
450
461
|
it as `Tell #N` in `ai-tells.md` with Pattern / Why / Allowed
|
|
451
|
-
alternative / Severity. The next
|
|
462
|
+
alternative / Severity. The next offline validation run picks it up
|
|
452
463
|
automatically. Update
|
|
453
464
|
`tests/scripts/skill-references-substance-filters.test.ts` if the
|
|
454
465
|
new tell needs regression coverage.
|
|
455
466
|
|
|
456
|
-
**Example of a violation** (
|
|
467
|
+
**Example of a violation** (Patientdesk regression example, pre-catalog —
|
|
457
468
|
Tell #1 body-level self-introduction):
|
|
458
469
|
|
|
459
470
|
> "Hey Bonnie — Oncel here. My co-founders and I ran our own dental
|
|
@@ -509,7 +520,7 @@ Do not patch a weak message by inventing stronger personalization.
|
|
|
509
520
|
|
|
510
521
|
## Dry-Mode Discipline
|
|
511
522
|
|
|
512
|
-
|
|
523
|
+
Offline dry mode is validation, not production drafting.
|
|
513
524
|
|
|
514
525
|
- use only `brief.md`, `lead-filter.md`, and `lead-sample.json`
|
|
515
526
|
- do not fetch new research
|
|
@@ -520,19 +531,18 @@ Phase 84 dry mode is validation, not production drafting.
|
|
|
520
531
|
- retrieve broadly, but preserve one primary example and borrow from at most one
|
|
521
532
|
narrow secondary influence
|
|
522
533
|
|
|
523
|
-
##
|
|
534
|
+
## Critique Rewrite Addendum
|
|
524
535
|
|
|
525
536
|
These filters are also the gate on any critique rewrite shipped by the
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
on, a rewritten message must still clear:
|
|
537
|
+
parallel critique protocol (see `references/parallel-critique-protocol.md`).
|
|
538
|
+
When the critique flag is on, a rewritten message must still clear:
|
|
529
539
|
|
|
530
540
|
- every "Automatic Revisions" check above (jargon, resume-list PS, stacked
|
|
531
541
|
sentences, weak hooks, etc.)
|
|
532
|
-
- the
|
|
542
|
+
- the offline-validation token contract: only supported tokens from the brief, no
|
|
533
543
|
unresolved `{{token}}`, no invented proof, no personalization that can't
|
|
534
544
|
be traced to `lead-sample.json`
|
|
535
|
-
- the
|
|
545
|
+
- the offline-validation finalizer pass when `synthesis.enforceFinalizerPass` is
|
|
536
546
|
`true` (default)
|
|
537
547
|
|
|
538
548
|
If a rewrite fails any of these, the critique pass falls back to the
|
|
@@ -63,7 +63,7 @@ rows graduated.
|
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
5. re-check token contract on the cascaded subset (strict mode default)
|
|
66
|
-
— see references/
|
|
66
|
+
— see references/sellable-cleanup-rules.md + gold-standard-message-patterns.md
|
|
67
67
|
|
|
68
68
|
6. go back to step 1 until selectedCellCount == 0
|
|
69
69
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Thomas Variant Selection
|
|
2
2
|
|
|
3
|
-
This reference governs which rows in a
|
|
3
|
+
This reference governs which rows in a critique sample earn
|
|
4
4
|
an Opus refinement rewrite. Load this file only when
|
|
5
5
|
`messaging.critique.enabled === true` AND
|
|
6
6
|
`messaging.critique.opus.enabled === true` in
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Validation Criteria
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
goal is to preserve the brief thesis while proving that
|
|
5
|
-
message direction hold up against real preview evidence.
|
|
3
|
+
Offline validation is a chained-artifact validation pass over the approved
|
|
4
|
+
campaign brief. The goal is to preserve the brief thesis while proving that
|
|
5
|
+
leads, filters, and message direction hold up against real preview evidence.
|
|
6
6
|
|
|
7
7
|
## Primary Contract
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ message direction hold up against real preview evidence.
|
|
|
10
10
|
- validation/debug artifacts are optional debug/UAT diagnostics, not durable campaign state.
|
|
11
11
|
- normal customer runs should not expose local draft files.
|
|
12
12
|
- resume and handoff read campaign state before debug files.
|
|
13
|
-
- `CampaignOffer.campaignBrief` is the durable
|
|
13
|
+
- `CampaignOffer.campaignBrief` is the durable campaign thesis input;
|
|
14
14
|
`brief.md` is its debug copy
|
|
15
15
|
- `lead-review.md` and `lead-sample.json` are the required outputs of lead preview
|
|
16
16
|
- `lead-filter.md` is the primary output of the middle step
|
|
@@ -28,7 +28,7 @@ Allowed:
|
|
|
28
28
|
|
|
29
29
|
Not allowed:
|
|
30
30
|
|
|
31
|
-
- rewrite the
|
|
31
|
+
- rewrite the approved campaign thesis in `brief.md`
|
|
32
32
|
- create `lead-filter.md`
|
|
33
33
|
- create `message-validation.md`
|
|
34
34
|
- mutate campaign state
|
|
@@ -87,13 +87,12 @@ Required:
|
|
|
87
87
|
the brief justifies absence with reference to a specific archived winner.
|
|
88
88
|
If a candidate uses `two options:`, option `a)` and option `b)` must be
|
|
89
89
|
separated by a blank line so the CTA scans cleanly on mobile.
|
|
90
|
-
- **All
|
|
91
|
-
PASS per candidate.** A candidate that fails
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
the offending line).
|
|
90
|
+
- **All Sellable cleanup rules, including all 8 substance filters from
|
|
91
|
+
`sellable-cleanup-rules.md`, MUST PASS per candidate.** A candidate that fails
|
|
92
|
+
any cleanup rule or substance filter is BLOCKED. The Finalizer Pass CANNOT
|
|
93
|
+
select a blocked candidate. If all 3 candidates fail, route to
|
|
94
|
+
`revise-message` with the failure reasons enumerated per candidate (cite the
|
|
95
|
+
rule/filter name and the offending line).
|
|
97
96
|
|
|
98
97
|
## Lead Preview Expectations
|
|
99
98
|
|
|
@@ -254,7 +253,7 @@ The sample set must:
|
|
|
254
253
|
- contain no invented proof, metrics, logos, or customer names
|
|
255
254
|
- keep proof claims inside the brief's safe-claims boundary
|
|
256
255
|
- reject personalization that cannot be traced back to `lead-sample.json`
|
|
257
|
-
- apply
|
|
256
|
+
- apply Sellable cleanup rules before the step is marked `confirmed`
|
|
258
257
|
- choose the highest-specificity validated strategy available in this order:
|
|
259
258
|
event-led, signal-led, job-post-led, then proof-led specialist fallback
|
|
260
259
|
- retrieve against the full archived gold-standard library and choose a
|
|
@@ -294,20 +293,23 @@ The sample set must:
|
|
|
294
293
|
multi-sentence paragraphs. Target 5-8 one-line paragraphs total
|
|
295
294
|
- split sentences that are above ~15 words or carry more than one comma
|
|
296
295
|
- do not stack three workflows into one mechanism line or one comma list.
|
|
297
|
-
Give each workflow its own
|
|
298
|
-
|
|
296
|
+
Give each workflow its own line, use a short bullet stack when the three
|
|
297
|
+
actions repeat the same subject pattern, or pick the most painful one and
|
|
298
|
+
drop the others
|
|
299
299
|
- **product clarity is non-negotiable**: a cold reader must be able to state
|
|
300
300
|
in one sentence what the product does. Require a crisp `Product is an X
|
|
301
301
|
that does Y` anchor sentence before any action breakdown, then one action
|
|
302
|
-
per
|
|
303
|
-
|
|
302
|
+
per line. Do not gesture at "that chain" / "the stack" / "that work" in
|
|
303
|
+
place of naming specific actions
|
|
304
304
|
- body flow must follow: opener → pain → what the product IS (one sentence)
|
|
305
305
|
→ what it DOES (one action per line, up to three) → deployment ease →
|
|
306
306
|
CTA → optional PS
|
|
307
307
|
- the "what it DOES" action list may render as one-line paragraphs or as a
|
|
308
308
|
bullet list — whichever reads cleaner. Bullets are acceptable here (the
|
|
309
309
|
rule against bullet points applies to feature/benefit marketing lists,
|
|
310
|
-
not to enumerable product actions).
|
|
310
|
+
not to enumerable product actions). Prefer bullets for 3 repeated-subject
|
|
311
|
+
product actions; keep paragraphs when one line needs narrative context or the
|
|
312
|
+
paragraph version is clearly more human. Never comma-stack three actions into
|
|
311
313
|
one glued sentence
|
|
312
314
|
- **opener must use per-lead signal when any is present in `lead-sample.json`**
|
|
313
315
|
(post, hire, visible tool, topic engagement). Category-level openers are
|
|
@@ -325,6 +327,10 @@ that does Y` anchor sentence before any action breakdown, then one action
|
|
|
325
327
|
with no anchor. Use "I" voice if the sender is the founder; "our CEO",
|
|
326
328
|
"our team", or "we" otherwise. At most two proof beats. No three-credential
|
|
327
329
|
resume lists
|
|
330
|
+
- reject backing PS lines that describe the seller's focus instead of the
|
|
331
|
+
buyer's outcome, such as `backed by [X] and focused on [category/problem]`.
|
|
332
|
+
Backing proof only survives when the same line translates to buyer value,
|
|
333
|
+
e.g. `backed by [X] to help [buyer segment] [buyer outcome]`
|
|
328
334
|
- samples in one set must read like siblings from one campaign, not three
|
|
329
335
|
experiments
|
|
330
336
|
- reject fallback drafts that lead with generic "most teams..." copy without a
|
|
@@ -379,7 +379,7 @@ templateRevision: "current" })` until the first current-revision generated
|
|
|
379
379
|
Generate Message cell, and do not add "one more wait" for a stronger sample.
|
|
380
380
|
Remaining review/process sample rows can continue processing in the background.
|
|
381
381
|
4. Read the first ready generated message back via `get_rows` (full) and
|
|
382
|
-
sanity-check that sample against the
|
|
382
|
+
sanity-check that sample against the offline-validation token contract: no unresolved
|
|
383
383
|
`{{tokens}}`, no invented proof, one sentence per line, etc.
|
|
384
384
|
5. If the sample fails the token contract, diagnose brief-vs-list
|
|
385
385
|
(same revision loop as Step 14) and escalate if over
|
|
@@ -403,17 +403,17 @@ strings, which is why Step 16 requires Step 15 to be complete.
|
|
|
403
403
|
|
|
404
404
|
1. Observe the review-sample messages on the same sample that passed
|
|
405
405
|
validation.
|
|
406
|
-
2. If `messaging.critique.enabled` is true
|
|
406
|
+
2. If `messaging.critique.enabled` is true, run the
|
|
407
407
|
bounded critique pass on the sample output per
|
|
408
408
|
`references/parallel-critique-protocol.md`. The pass runs on at
|
|
409
409
|
most `messaging.critique.sampleSize` rows, sends each row through
|
|
410
410
|
three parallel critics (targeting / copy / voice) that return
|
|
411
411
|
structured JSON, and merges the voices in a synthesis step that
|
|
412
|
-
enforces the
|
|
412
|
+
enforces the offline-validation token contract verbatim and re-runs the
|
|
413
413
|
finalizer pass. Any rewrite that invents proof or uses an
|
|
414
414
|
unsupported token falls back to the plain generated message. A
|
|
415
415
|
trip of `messaging.critique.budgetUsdCap` HALTS critique for the
|
|
416
|
-
remaining sample and continues the plain tail.
|
|
416
|
+
remaining sample and continues the plain tail. The plain campaign tail reads
|
|
417
417
|
the flag but never flips it; critique stays off until the flag is
|
|
418
418
|
deliberately enabled.
|
|
419
419
|
3. If `messaging.critique.opus.enabled` is also true, route the
|
|
@@ -512,7 +512,7 @@ calling any mutating tool; if the campaign is already running, skip
|
|
|
512
512
|
approve-batch / start_campaign / update_campaign and just confirm.
|
|
513
513
|
|
|
514
514
|
Workspace/sender mismatch at greenlight time aborts the start with the
|
|
515
|
-
same invariant
|
|
515
|
+
same invariant offline validation enforces.
|
|
516
516
|
|
|
517
517
|
## Threshold Trips and Logging
|
|
518
518
|
|
|
@@ -546,7 +546,7 @@ runs.
|
|
|
546
546
|
|
|
547
547
|
| File | Load when |
|
|
548
548
|
| ------------------------------------------------ | ------------------------------------------------------------------------- |
|
|
549
|
-
| `references/approval-gate-framing.md` |
|
|
549
|
+
| `references/approval-gate-framing.md` | Approval gate, before showing the approval packet |
|
|
550
550
|
| `references/watch-link-handoff.md` | First brief handoff + explicit link recovery only |
|
|
551
551
|
| `references/post-mint-source-materialization.md` | Step 13, before importing normal-discovery or legacy campaignless sources |
|
|
552
552
|
| `references/sample-validation-loop.md` | Step 14, before enriching + scoring the sample |
|
|
@@ -554,7 +554,7 @@ runs.
|
|
|
554
554
|
| `references/final-handoff-contract.md` | Step 16, and every Claude greenlight turn |
|
|
555
555
|
| `references/parallel-critique-protocol.md` | Step 15 when `messaging.critique.enabled` is true |
|
|
556
556
|
| `references/thomas-variant-selection.md` | Step 15 when `messaging.critique.opus.enabled` is true |
|
|
557
|
-
| `references/
|
|
557
|
+
| `references/sellable-cleanup-rules.md` | Any critique rewrite, before persisting |
|
|
558
558
|
| `core/auto-execute.yaml` | Start of Step 13, load once; all tail steps read parsed values |
|
|
559
559
|
| `core/auto-execute.README.md` | When tuning `auto-execute.yaml` knobs or reviewing threshold-trip logs |
|
|
560
560
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: create-campaign-v2-validation
|
|
3
|
-
description: Validate
|
|
3
|
+
description: Validate an approved `brief.md` through chained offline artifacts before any live campaign state exists.
|
|
4
4
|
visibility: internal
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Create Campaign v2 Validation
|
|
8
8
|
|
|
9
9
|
<role>
|
|
10
|
-
You are the
|
|
11
|
-
is to validate
|
|
10
|
+
You are the offline validation orchestrator for create-campaign-v2. Your job
|
|
11
|
+
is to validate an approved `brief.md` through chained draft artifacts without
|
|
12
12
|
creating live campaign state.
|
|
13
13
|
</role>
|
|
14
14
|
|
|
@@ -28,7 +28,7 @@ Each step writes its own artifact into the draft directory. The original
|
|
|
28
28
|
Validated draft directory:
|
|
29
29
|
|
|
30
30
|
```text
|
|
31
|
-
|
|
31
|
+
~/.sellable/create-campaign-v2/drafts/{workspace-slug}/{campaign-slug}/
|
|
32
32
|
brief.md
|
|
33
33
|
lead-review.md
|
|
34
34
|
lead-sample.json
|
|
@@ -41,7 +41,7 @@ Validated draft directory:
|
|
|
41
41
|
|
|
42
42
|
<rules>
|
|
43
43
|
|
|
44
|
-
- `brief.md` is the stable
|
|
44
|
+
- `brief.md` is the stable approved input and remains the thesis source.
|
|
45
45
|
- `lead-review.md` and `lead-sample.json` are the required outputs of `find leads`.
|
|
46
46
|
- `lead-filter.md` is the primary output of `filter leads`.
|
|
47
47
|
- `rubric.json` is optional and secondary to `lead-filter.md`.
|
|
@@ -49,7 +49,7 @@ Validated draft directory:
|
|
|
49
49
|
- Run validation serially in this order: `find leads`, `filter leads`, `generate message`.
|
|
50
50
|
- Resume state is based on the presence and completeness of the chained artifacts,
|
|
51
51
|
not on inline validation blocks inside `brief.md`.
|
|
52
|
-
- Preserve the
|
|
52
|
+
- Preserve the approved thesis. Do not rewrite product, ICP, offer, or message
|
|
53
53
|
hypothesis sections during preview validation.
|
|
54
54
|
- Every artifact write uses `tmp + rename` so a failed write leaves the prior
|
|
55
55
|
artifact intact.
|
|
@@ -222,7 +222,21 @@ Orchestration requirements:
|
|
|
222
222
|
same company as the brief
|
|
223
223
|
- draft 3 internal candidates and run a Finalizer Pass that combines the
|
|
224
224
|
best opener, proof sentence, bridge, and CTA across them into one winner
|
|
225
|
-
- pass the
|
|
225
|
+
- pass the Sellable cleanup rules before writing findings
|
|
226
|
+
- pass the source-transition gate before writing findings. For sender-owned
|
|
227
|
+
LinkedIn post sources where the sample proves a reaction/comment, a light
|
|
228
|
+
first-person acknowledgment is allowed (`appreciate you showing some love on
|
|
229
|
+
my post about [topic]`), but it must be followed by a soft relevance bridge
|
|
230
|
+
before broad problem or product copy (`figured this might be relevant if
|
|
231
|
+
LinkedIn is becoming more of a GTM channel for [company/team]`). Block drafts
|
|
232
|
+
that jump straight from the acknowledgment into generic `a lot of teams...` or
|
|
233
|
+
`most teams...` pain. For third-party post sources, keep source references
|
|
234
|
+
topic-level and low-certainty.
|
|
235
|
+
- pass the line-continuity gate before writing findings. Each message line must
|
|
236
|
+
make the next line feel earned: source/post signal -> relevance bridge ->
|
|
237
|
+
product/problem -> next step. If two adjacent lines could be swapped, deleted,
|
|
238
|
+
or connected with `anyway` without changing the meaning, the transition is
|
|
239
|
+
fake and the draft must be revised.
|
|
226
240
|
|
|
227
241
|
Do not:
|
|
228
242
|
|
|
@@ -257,6 +271,8 @@ Do not:
|
|
|
257
271
|
- `Finalizer Pass`
|
|
258
272
|
- `Gold-Standard Quality Gate`
|
|
259
273
|
- `Skeptical Prospect Review`
|
|
274
|
+
- `Source Transition Gate`
|
|
275
|
+
- `Line Continuity Gate`
|
|
260
276
|
- `Winner Gate`
|
|
261
277
|
- `Selected Winner`
|
|
262
278
|
- `Findings`
|