@vruum/skills 0.6.15 → 0.6.16

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vruum",
3
- "version": "0.6.15",
3
+ "version": "0.6.16",
4
4
  "description": "Vruum AI skills + remote MCP server for B2B GTM teams. Slash commands for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis, paired with the full Vruum MCP tool surface over OAuth 2.1.",
5
5
  "author": {
6
6
  "name": "Vruum AI",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vruum",
3
- "version": "0.6.15",
3
+ "version": "0.6.16",
4
4
  "description": "Vruum AI skills + remote MCP server for B2B GTM teams. Skills for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis, paired with the full Vruum MCP tool surface over OAuth 2.1.",
5
5
  "author": {
6
6
  "name": "Vruum AI",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vruum/skills",
3
- "version": "0.6.15",
3
+ "version": "0.6.16",
4
4
  "description": "Vruum AI skills for Claude Code, Claude Desktop, Codex CLI, and any AI assistant with a skill directory. Slash commands for outreach triage, engagement triage, pipeline filling, prospect enrichment, and reply diagnosis. Pairs with the Vruum MCP server at https://api.vruum.ai/mcp.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,5 +42,5 @@
42
42
  "outreach",
43
43
  "gtm"
44
44
  ],
45
- "contentHash": "b2f0ddac2806baa9a94b8f6e0bcbd7a31f7f6195cc1b4928c9e7bd09914c11a5"
45
+ "contentHash": "b8c87fc8fa92db1b14f993e7797fe6d7bd69ec24fec5fafa3256d346f7d0a0f9"
46
46
  }
@@ -15,7 +15,7 @@ You are the CSV harness-mode source for `/pipeline-fill`. You read a CSV the ope
15
15
  ## Inputs
16
16
 
17
17
  - `file_path`: absolute path to the CSV. If not provided, ask for it. Common locations: `~/Downloads/`, `.context/attachments/` in the workspace.
18
- - `segment`: target segment (single)
18
+ - `campaign`: target campaign (single)
19
19
  - `column_mapping` (optional): explicit `{header_name: canonical_field}` mapping if headers don't auto-resolve. Default: auto-detect.
20
20
 
21
21
  ## Workflow
@@ -97,7 +97,7 @@ Emit the canonical handoff prompt (defined in `pipeline-fill/RESEARCH-ENGINE.md`
97
97
  ```
98
98
  Candidate list ready: {N} prospects from csv (after {dedup_count} dedup).
99
99
 
100
- NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and segment {segment_id}.
100
+ NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and campaign {campaign_id}.
101
101
 
102
102
  Continue automatically? (y/n)
103
103
  ```
@@ -28,7 +28,7 @@ From the person_360 response, read the full conversation thread. Identify:
28
28
 
29
29
  ## Step 3: Diagnose
30
30
 
31
- Call `get_performance_metrics` with `view='funnel'` and the segment_id to get segment-level reply rates by channel.
31
+ Call `get_performance_metrics` with `view='funnel'` and the campaign_id to get campaign-level reply rates by channel.
32
32
 
33
33
  Synthesize a diagnosis:
34
34
 
@@ -37,13 +37,13 @@ Synthesize a diagnosis:
37
37
  **The message that got the reply:** T3 via LinkedIn DM, 'workflow_pain' angle, referenced their recent job posting for DevOps engineer (specific signal), ended with a question about their current tooling.
38
38
 
39
39
  **Why it likely worked:**
40
- - Channel: LinkedIn DM has [X]% reply rate in this segment (vs [Y]% email)
41
- - Angle: 'workflow_pain' converts at [X]% in this segment ([Z]x above average)
40
+ - Channel: LinkedIn DM has [X]% reply rate in this campaign (vs [Y]% email)
41
+ - Angle: 'workflow_pain' converts at [X]% in this campaign ([Z]x above average)
42
42
  - Signal: Referenced a specific, verifiable company signal (job posting)
43
43
  - CTA: Question CTA has [X]x lift over statement CTAs
44
44
 
45
45
  **What's different from the ghosted messages:**
46
- - T1 and T2 used 'cost_replacement' angle (segment average: [X]%)
46
+ - T1 and T2 used 'cost_replacement' angle (campaign average: [X]%)
47
47
  - T1 had surface-level personalization (company name only)
48
48
  - T2 had no question CTA
49
49
 
@@ -52,10 +52,10 @@ Synthesize a diagnosis:
52
52
  ## Step 4: Suggest action
53
53
 
54
54
  **If positive reply** (interested, wants to learn more, asks a question):
55
- - "This combination is worth repeating: [angle + specific signal + CTA style]. Note it in your segment's strategy so the next batch follows the same shape."
55
+ - "This combination is worth repeating: [angle + specific signal + CTA style]. Note it in your campaign's strategy so the next batch follows the same shape."
56
56
 
57
57
  **If negative reply** (not interested, wrong person, bad timing):
58
- - "This is the [N]th rejection using the '[angle]' strategy in this segment. If the pattern holds, consider deprioritizing this angle for the segment."
58
+ - "This is the [N]th rejection using the '[angle]' strategy in this campaign. If the pattern holds, consider deprioritizing this angle for the campaign."
59
59
 
60
60
  **If objection or question** (pricing, timing, skepticism):
61
61
  - "This is a live conversation. The reply response draft should address [specific objection]. Check the outreach queue — there may be a draft pending."
@@ -64,5 +64,5 @@ Synthesize a diagnosis:
64
64
 
65
65
  - This skill is diagnostic, not prescriptive. It explains what happened; acting on the pattern (deprioritizing an angle, repeating a winning combination) is a separate, deliberate decision.
66
66
  - When the conversation has many touches, focus on the touch that triggered the reply, not the full sequence.
67
- - Always compare against segment averages to distinguish signal from noise. One data point doesn't make a pattern.
68
- - If `get_performance_metrics` doesn't have enough data for the segment, say so: "Not enough segment data to compare against. This is a single data point."
67
+ - Always compare against campaign averages to distinguish signal from noise. One data point doesn't make a pattern.
68
+ - If `get_performance_metrics` doesn't have enough data for the campaign, say so: "Not enough campaign data to compare against. This is a single data point."
@@ -194,7 +194,7 @@ After the first batch returns for any engagement type:
194
194
 
195
195
  - **All reactions clean:** "First batch of reactions all approved. N more look similar — approve the rest?" Apply without more agents.
196
196
  - **All comments have the same issue** (e.g., all too generic, all missing sender voice): Flag the pattern to the user. "First 8 comments are all generic 'great post' style — likely a prompt issue. Want me to edit them all with the same fix, or skip the batch?"
197
- - **Systematic voice mismatch:** If comments consistently don't sound like the sender, flag it as a segment/prompt config issue rather than fixing each one individually.
197
+ - **Systematic voice mismatch:** If comments consistently don't sound like the sender, flag it as a campaign/prompt config issue rather than fixing each one individually.
198
198
 
199
199
  ### Step 8: Summary
200
200
 
@@ -21,7 +21,7 @@ Call `get_engagement_review` with your assigned `engagement_ids`, `content_lengt
21
21
  - `polish_provenance.polished_floor.regressed` — true means the backend's floor rewrite was worse than first_draft and was reverted (signal that the rules are hard for this draft)
22
22
  - `validator_failures` — structural failures recorded by the backend (e.g. `["banned_opener:Yep","no_specific_marker:0/1"]`). Treat as a checklist.
23
23
  - `target_post_text` — what the prospect actually posted
24
- - `person_id`, `person_name`, `person_title`, `match_score`, `segment_name` — person context
24
+ - `person_id`, `person_name`, `person_title`, `match_score`, `campaign_name` — person context
25
25
  - `source` — `warming` / `nurture` / `marketing`
26
26
  - `budget_status` — sender daily quota
27
27
  - `schema_version` + `rules_version` — backward-compat signals
@@ -64,7 +64,7 @@ For each row, include a one-line "hook" — a specific recent observation from `
64
64
 
65
65
  Step 6 — Hand off to outreach. Two options:
66
66
  - **Option A (recommended)**: Approve the ranked list, then for each account: run `/pipeline-fill` with that prospect_list — same Sales Nav harness flow, just sourced from the expansion cohort instead of cold. Tag the resulting `outreach_plans.tag` with `bowtie_pilot:expansion` so success-tracking finds them.
67
- - **Option B**: Direct `manage_outreach` action=start with an expansion-flavored segment (pre-create an `expansion_<your-tenant>` segment with the right tone — formal, ROI-focused, no opener-hooks since the customer already knows you).
67
+ - **Option B**: Direct `manage_outreach` action=start with an expansion-flavored campaign (pre-create an `expansion_<your-tenant>` campaign with the right tone — formal, ROI-focused, no opener-hooks since the customer already knows you).
68
68
 
69
69
  Step 7 — Success tracking (auto). When a calendar webhook fires a `meeting_booked` event on an outreach plan tagged `bowtie_pilot:expansion`, the webhook handler in `backend/app/domains/calendar/` auto-records the impact event, equivalent to:
70
70
  ```
@@ -11,7 +11,7 @@ You are an outreach queue orchestrator. Your job is to efficiently process pendi
11
11
 
12
12
  ## Why this skill exists
13
13
 
14
- Reviewing outreach messages is context-expensive. Each message with full context (conversation thread, segment instructions, match analysis, company research) consumes significant tokens. This skill solves that by dispatching messages to independent subagents, each with their own context window, who do the deep review work and return compact summaries.
14
+ Reviewing outreach messages is context-expensive. Each message with full context (conversation thread, campaign instructions, match analysis, company research) consumes significant tokens. This skill solves that by dispatching messages to independent subagents, each with their own context window, who do the deep review work and return compact summaries.
15
15
 
16
16
  ## Subagent architecture
17
17
 
@@ -116,7 +116,7 @@ Prospect: {person_name}, {title} at {company}
116
116
  Message type: T{sequence_number} follow-up
117
117
 
118
118
  Steps:
119
- 1. Call get_outreach_review with message_ids="{message_id}" and content_length="full" to get the current message, thread context, segment instructions, and match analysis.
119
+ 1. Call get_outreach_review with message_ids="{message_id}" and content_length="full" to get the current message, thread context, campaign instructions, and match analysis.
120
120
  2. Call fetch with type=person_research plus get_person_360 for this person to get everything we know.
121
121
  3. Call fetch with type=company_research to understand the company's product, positioning, and what problems it solves.
122
122
  4. Search the web for this prospect and their company to understand what they actually do, what challenges they face, what they post about.
@@ -8,7 +8,7 @@ Every outreach message must pass one test: "Would the person sending this actual
8
8
 
9
9
  ## Tone and Voice
10
10
 
11
- The sender's identity and tone vary by company. Some senders are founders, some are AEs, some are BDRs. The segment's tone instructions define the specific voice. Always follow them.
11
+ The sender's identity and tone vary by company. Some senders are founders, some are AEs, some are BDRs. The campaign's tone instructions define the specific voice. Always follow them.
12
12
 
13
13
  **Universal rules that apply to every sender:**
14
14
 
@@ -53,16 +53,16 @@ This matters more as touch count increases. A 5-touch sequence has fewer angles
53
53
 
54
54
  ## Touch Sequence Compliance
55
55
 
56
- Each segment defines its own touch sequence with per-touch instructions, channel, timing, and format constraints. These are the source of truth for what each touch should do.
56
+ Each campaign defines its own touch sequence with per-touch instructions, channel, timing, and format constraints. These are the source of truth for what each touch should do.
57
57
 
58
58
  When reviewing a message:
59
- - Check the touch_number against the segment's touch_sequence
59
+ - Check the touch_number against the campaign's touch_sequence
60
60
  - Read the per-touch instructions (these are one-sentence intents the writer interprets)
61
61
  - Verify the message follows the intent (e.g., "No pitch, no product mention" means exactly that)
62
62
  - Check word/character limits specified for that touch
63
63
  - Verify the CTA approach matches the touch stage (early touches typically use questions, later touches may include calendar links, breakup touches have no ask)
64
64
 
65
- Do NOT apply hardcoded assumptions about what any touch number should do. A T4 might be a breakup in a 5-touch sequence but a mid-funnel touch in a 15-touch sequence. Always read the segment's specific instructions.
65
+ Do NOT apply hardcoded assumptions about what any touch number should do. A T4 might be a breakup in a 5-touch sequence but a mid-funnel touch in a 15-touch sequence. Always read the campaign's specific instructions.
66
66
 
67
67
  ## Personalization Standards
68
68
 
@@ -83,22 +83,22 @@ If personalization is surface-level and better data exists in the review context
83
83
 
84
84
  ## Vertical and Industry Language
85
85
 
86
- Each segment's selling strategy includes vertical context with industry-native terminology. Messages should use the language the prospect uses, not generic sales language.
86
+ Each campaign's selling strategy includes vertical context with industry-native terminology. Messages should use the language the prospect uses, not generic sales language.
87
87
 
88
88
  When reviewing:
89
- - Check if the message uses terms from the segment's vertical context
90
- - Flag messages that use generic business language when the segment specifies industry terminology
89
+ - Check if the message uses terms from the campaign's vertical context
90
+ - Flag messages that use generic business language when the campaign specifies industry terminology
91
91
  - The selling strategy's role adaptation section tells you how to frame things differently for different titles (CEO vs VP vs Director, etc.)
92
92
 
93
- Do NOT hardcode vertical knowledge. Always pull it from the segment instructions for that specific message.
93
+ Do NOT hardcode vertical knowledge. Always pull it from the campaign instructions for that specific message.
94
94
 
95
95
  ## Channel-Specific Rules
96
96
 
97
97
  **LinkedIn connection requests**: Hard 280 character limit. No exceptions. Count characters, not words.
98
98
 
99
- **LinkedIn DMs**: Keep within the word limit specified per touch in the segment's touch sequence. No bullet points or numbered lists. Write like a chat message, not an email.
99
+ **LinkedIn DMs**: Keep within the word limit specified per touch in the campaign's touch sequence. No bullet points or numbered lists. Write like a chat message, not an email.
100
100
 
101
- **Email**: Subject line matters. Can be longer and more structured than LinkedIn. Follow the segment's email formatting rules if specified.
101
+ **Email**: Subject line matters. Can be longer and more structured than LinkedIn. Follow the campaign's email formatting rules if specified.
102
102
 
103
103
  ## Real Examples of Common Failures
104
104
 
@@ -113,7 +113,7 @@ Do NOT hardcode vertical knowledge. Always pull it from the segment instructions
113
113
 
114
114
  **Bad:** "Worth 15 min to see how it works?" / "Worth a quick call?" / "Open to a brief chat?"
115
115
  **Why it fails:** Every automated outreach tool uses this pattern. It's the single biggest AI tell in 2026.
116
- **Fix:** Follow the segment's CTA rules for that touch number. Early touches end with questions. Later touches with calendar links should frame them conversationally, not as a close.
116
+ **Fix:** Follow the campaign's CTA rules for that touch number. Early touches end with questions. Later touches with calendar links should frame them conversationally, not as a close.
117
117
 
118
118
  ### Failure: Surface personalization
119
119
 
@@ -12,8 +12,8 @@ Call `get_outreach_review` with your assigned `message_ids`, `content_length="fu
12
12
 
13
13
  - The draft message content
14
14
  - Person info (name, title, company, match score)
15
- - Segment tone instructions (including anti-AI-tell rules)
16
- - Segment selling strategy and touch sequence
15
+ - Campaign tone instructions (including anti-AI-tell rules)
16
+ - Campaign selling strategy and touch sequence
17
17
  - Match analysis with alignment points and recommended approach
18
18
  - Company research summary
19
19
  - Recent LinkedIn posts from the prospect
@@ -45,7 +45,7 @@ If ANY repetition is found, the message needs a rewrite. This is the most common
45
45
 
46
46
  ### 2c. AI tell detection
47
47
 
48
- Scan the message against the anti-AI-tell rules in the segment tone instructions. Also check for:
48
+ Scan the message against the anti-AI-tell rules in the campaign tone instructions. Also check for:
49
49
  - Uniform sentence length (every sentence roughly the same word count)
50
50
  - Generic opener patterns ("I noticed that...", "I came across your...")
51
51
  - Fake personalization (mentioning something vague rather than specific)
@@ -97,7 +97,7 @@ If the message needs changes, rewrite it and apply the edit using `manage_messag
97
97
 
98
98
  When rewriting:
99
99
  - Keep the same strategic intent (don't change a T2 into a T4)
100
- - Follow the segment tone instructions exactly
100
+ - Follow the campaign tone instructions exactly
101
101
  - Stay within word/character limits
102
102
  - Make it sound like something a real person would actually type in a LinkedIn DM
103
103
  - Use the selling strategy's role adaptation for this person's title
@@ -147,7 +147,7 @@ RESEARCH_DONE: {list of extra research you did, or "none"}
147
147
  - You flagged the message for human review
148
148
  - The conversation thread suggests strategic complexity (pricing discussions, objections, competitor mentions)
149
149
  - You couldn't find enough context to personalize well
150
- - The segment instructions conflict with what seems like the right approach
150
+ - The campaign instructions conflict with what seems like the right approach
151
151
 
152
152
  ## Decision Framework
153
153
 
@@ -4,7 +4,7 @@ This is the canonical research-engine doc referenced by `/pipeline-fill` (orches
4
4
 
5
5
  When a source skill produces a candidate list, it hands off to this engine via the canonical handoff prompt at the bottom of this doc. The engine then runs Steps 3–8: pre-flight → Phase A → Phase B → harness gate → save → report.
6
6
 
7
- The orchestrator's SKILL.md owns the front-of-flow: segment picker (Step 1), source picker (Step 2), and the inline manual-list parser. Everything from Step 3 onward is defined here. **Don't duplicate this doc in source skills** — link to it.
7
+ The orchestrator's SKILL.md owns the front-of-flow: campaign picker (Step 1), source picker (Step 2), and the inline manual-list parser. Everything from Step 3 onward is defined here. **Don't duplicate this doc in source skills** — link to it.
8
8
 
9
9
  ---
10
10
 
@@ -37,7 +37,7 @@ All harness source skills produce candidate lists matching this shape exactly. T
37
37
 
38
38
  ## MCP-availability precheck (load-bearing — runs before Step 3)
39
39
 
40
- Before any other Step 3 work, call `fetch(type="research_playbook", id=<segment_id>)`. If this fails with "tool not found" / 404 / connection error, abort the run with this exact message:
40
+ Before any other Step 3 work, call `fetch(type="research_playbook", id=<campaign_id>)`. If this fails with "tool not found" / 404 / connection error, abort the run with this exact message:
41
41
 
42
42
  > Vruum MCP not configured as a user-scoped server. Run:
43
43
  >
@@ -53,7 +53,7 @@ The research_playbook fetch also doubles as the ICP load — capture target_titl
53
53
 
54
54
  ## Step 3 — Pre-flight
55
55
 
56
- Per segment's candidate list:
56
+ Per campaign's candidate list:
57
57
 
58
58
  1. **MCP precheck + ICP load** (above) — abort run on failure.
59
59
  2. **Batch dedup against existing pipeline.** Call `search(type="people", query=[{name, company, linkedin_url} for each candidate])`. Returns one match record per candidate (in input order). Drop candidates with non-null `match` — they're already in pipeline.
@@ -75,11 +75,11 @@ Dispatch one `vruum-company-deep-researcher` per unique uncached company. Subage
75
75
  Dispatch prompt template (fill in placeholders):
76
76
 
77
77
  ```
78
- You are vruum-company-deep-researcher. Research this company against segment "{segment_name}".
78
+ You are vruum-company-deep-researcher. Research this company against campaign "{campaign_name}".
79
79
 
80
80
  company_name: {name}
81
81
  domain: {domain}
82
- segment_icp_summary: {one paragraph from the research_playbook fetch}
82
+ campaign_icp_summary: {one paragraph from the research_playbook fetch}
83
83
  acv_floor: {dollars or default $10K}
84
84
 
85
85
  Run your workflow (a–i) and return the structured output block.
@@ -108,7 +108,7 @@ Dispatch one `vruum-prospect-deep-researcher` per surviving candidate. Subagent
108
108
  Dispatch prompt template:
109
109
 
110
110
  ```
111
- You are vruum-prospect-deep-researcher. Research this prospect against segment "{segment_name}".
111
+ You are vruum-prospect-deep-researcher. Research this prospect against campaign "{campaign_name}".
112
112
 
113
113
  full_name: {name}
114
114
  first_name: {first_name or null}
@@ -122,7 +122,7 @@ phase_a_signals:
122
122
  outbound_motion_score: {0|1|2 or null}
123
123
  triggers: [list or null]
124
124
 
125
- segment_icp_summary: {one paragraph from the research_playbook fetch}
125
+ campaign_icp_summary: {one paragraph from the research_playbook fetch}
126
126
  acv_floor: {dollars}
127
127
 
128
128
  Run your workflow (a–k) and return the structured output block. Note: do NOT call manage_person action=save_discovered or manage_outreach action=start — those are orchestrator-only and not in your tools list.
@@ -141,19 +141,19 @@ Each subagent returns: `topics_of_interest`, `recent_posts`, `opening_hooks[]` (
141
141
 
142
142
  This is a **coarse pre-filter** — its job is to avoid wasted backend save calls (`manage_person` action=save_discovered) on obvious dismisses. The **authoritative** gate is server-side `MatchAnalysisAgent.match_score >= 70` and runs inside that save call. The harness gate cannot override the backend gate; it can only dismiss before reaching it.
143
143
 
144
- Per surviving prospect, evaluate four criteria using the segment's playbook ICP and the Phase A + Phase B signals:
144
+ Per surviving prospect, evaluate four criteria using the campaign's playbook ICP and the Phase A + Phase B signals:
145
145
 
146
- ### 1. ACV class meets segment threshold?
147
- - `acv_class >= acv_floor_class` → pass this criterion (smb=$5K, mid=$5–50K, ent=$50K+; segment's `acv_floor` from playbook maps to a class)
146
+ ### 1. ACV class meets campaign threshold?
147
+ - `acv_class >= acv_floor_class` → pass this criterion (smb=$5K, mid=$5–50K, ent=$50K+; campaign's `acv_floor` from playbook maps to a class)
148
148
  - If no → dismiss `acv_too_low`. Don't call `manage_person` action=save_discovered.
149
149
 
150
150
  ### 2. Outbound motion or hiring signal?
151
151
  - `outbound_motion_score > 0` OR explicit hiring trigger present → pass
152
- - If no → flag `warming_candidate` (still call `manage_person` action=save_discovered — operator may want to warm-track them; backend match analysis tells us if the segment fit is real)
152
+ - If no → flag `warming_candidate` (still call `manage_person` action=save_discovered — operator may want to warm-track them; backend match analysis tells us if the campaign fit is real)
153
153
 
154
154
  ### 3. Decision-maker level senior?
155
155
  - `decision_maker_level == senior` → pass
156
- - If `mid` → pass with a note (segment owner decides if mid is acceptable)
156
+ - If `mid` → pass with a note (campaign owner decides if mid is acceptable)
157
157
  - If `junior` → look for a more-senior person at the same `company_id` in the Phase B output set. If found, swap and rerun. If not, dismiss `decision_maker_junior`.
158
158
 
159
159
  ### 4. Trigger event in last 90d?
@@ -217,18 +217,18 @@ If the prospect's company isn't already cached and Phase A produced fresh resear
217
217
 
218
218
  ### c. Save discovered person (the backend authoritative gate runs here)
219
219
 
220
- Call `manage_person(action="save_discovered", payload={person_id: <from b>, segment_id: ...})`. This:
220
+ Call `manage_person(action="save_discovered", payload={person_id: <from b>, campaign_id: ...})`. This:
221
221
  - Runs server-side `analyze_person_match` + signal eval
222
222
  - Returns `match_score` (0–100) and `quality_gate_pass` (bool, true iff `match_score >= 70`)
223
- - Writes the `company_people` row that puts the prospect into the segment
223
+ - Writes the `company_people` row that puts the prospect into the campaign
224
224
 
225
225
  **Distinguish two failure modes (Codex Finding #9):**
226
226
  - **Request failure (5xx, timeout, network):** retry once with 2s backoff. If still failing, leave the prospect in `discovery_failed` status and surface in the final report. **Don't** claim "saved as gate-fail" — the row was never written.
227
- - **Request success + low score (`quality_gate_pass: false`):** the prospect IS saved with research; backend marks gate-fail; surface for operator review. This is a soft-fail. The prospect is on file with full research, useful for future segments.
227
+ - **Request success + low score (`quality_gate_pass: false`):** the prospect IS saved with research; backend marks gate-fail; surface for operator review. This is a soft-fail. The prospect is on file with full research, useful for future campaigns.
228
228
 
229
229
  ### d. Bulk enrollment (only after all prospects saved)
230
230
 
231
- Collect all `person_id`s where `harness_gate_status == pass` AND backend `quality_gate_pass == true` AND `mode == save-and-enroll`. Then call `manage_outreach(action="start", id=[those person_ids], payload={segment_id: ...})` ONCE at the end of Step 7.
231
+ Collect all `person_id`s where `harness_gate_status == pass` AND backend `quality_gate_pass == true` AND `mode == save-and-enroll`. Then call `manage_outreach(action="start", id=[those person_ids], payload={campaign_id: ...})` ONCE at the end of Step 7.
232
232
 
233
233
  - Per-prospect outcomes are returned (enrolled | skipped | failed). Surface per-prospect failures in the report.
234
234
  - If `harness_gate_status` is `warming` or `low_priority`, exclude from the bulk enroll list. Operator decides on review.
@@ -241,7 +241,7 @@ Collect all `person_id`s where `harness_gate_status == pass` AND backend `qualit
241
241
  Print to chat AND write to `.context/runs/pipeline-fill-{ISO-timestamp}.md` (workspace-local; `.context/` is gitignored per CLAUDE.md). Format identical for both surfaces.
242
242
 
243
243
  ```
244
- Pipeline fill complete: {segment_name} (source: {source}, mode: {harness|platform})
244
+ Pipeline fill complete: {campaign_name} (source: {source}, mode: {harness|platform})
245
245
 
246
246
  Candidates flow:
247
247
  source : {N from source skill output}
@@ -274,14 +274,14 @@ Pool status: healthy | drying up | exhausted ⚠️
274
274
  Audit log written: .context/runs/pipeline-fill-{timestamp}.md
275
275
  ```
276
276
 
277
- For multi-segment runs, group the report by segment and include a totals summary at the bottom.
277
+ For multi-campaign runs, group the report by campaign and include a totals summary at the bottom.
278
278
 
279
279
  ---
280
280
 
281
281
  ## Edge cases + failure handling reference
282
282
 
283
283
  - **Source returns empty after dedup** — orchestrator says "All {N} candidates already in pipeline, nothing to research" and exits cleanly.
284
- - **Mid-flight cancellation** (operator Ctrl+C between Phase A and Phase B) — Phase A research is saved server-side. Re-running `/pipeline-fill` for the same segment + source picks up via batch dedup; no re-research of cached companies. Note this in the cancellation message.
284
+ - **Mid-flight cancellation** (operator Ctrl+C between Phase A and Phase B) — Phase A research is saved server-side. Re-running `/pipeline-fill` for the same campaign + source picks up via batch dedup; no re-research of cached companies. Note this in the cancellation message.
285
285
  - **Subagent timeout cascade** — Phase A failed for a company → Phase B runs degraded → harness gate marks `gate_inconclusive` → backend decides via cached company research. See Step 4.
286
286
  - **Two-gate disagreement** — harness pass + backend fail (or vice versa) → see Step 7c. Stricter outcome wins for enrollment; both states surfaced in the report.
287
287
  - **Cached company research >90 days old** — Phase A re-runs the company subagent. Don't trust stale signals for an active fill.
@@ -299,7 +299,7 @@ When a HARNESS source skill completes its sourcing flow and has a candidate list
299
299
  ```
300
300
  Candidate list ready: {N} prospects from {source}.
301
301
 
302
- NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and segment {segment_id}.
302
+ NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and campaign {campaign_id}.
303
303
 
304
304
  Continue automatically? (y/n)
305
305
  ```
@@ -9,19 +9,19 @@ description: >-
9
9
  ---
10
10
  # Pipeline Fill
11
11
 
12
- You are a source-agnostic pipeline filler. You pick segments to fill, pick a source per segment (Sales Nav / YC / CSV / discovery), and orchestrate harness deep research that gates against the segment ICP before saving prospects into the backend pipeline.
12
+ You are a source-agnostic pipeline filler. You pick campaigns to fill, pick a source per campaign (Sales Nav / YC / CSV / discovery), and orchestrate harness deep research that gates against the campaign ICP before saving prospects into the backend pipeline.
13
13
 
14
14
  ## Why this skill exists
15
15
 
16
- Filling your pipeline by source-of-the-day is normal. Sales Nav drying up doesn't mean you're stuck — pick YC, paste a CSV, or run discovery (paste candidates OR describe an ICP and the harness sources them via WebSearch + Vruum MCP + LinkedIn search). This skill orchestrates deep research per prospect in your IDE (your compute), pre-filters against segment ICP, then saves the qualified ones into the segment via the backend's canonical gate.
16
+ Filling your pipeline by source-of-the-day is normal. Sales Nav drying up doesn't mean you're stuck — pick YC, paste a CSV, or run discovery (paste candidates OR describe an ICP and the harness sources them via WebSearch + Vruum MCP + LinkedIn search). This skill orchestrates deep research per prospect in your IDE (your compute), pre-filters against campaign ICP, then saves the qualified ones into the campaign via the backend's canonical gate.
17
17
 
18
18
  ## Where the heavy logic lives
19
19
 
20
20
  Steps 3–8 (pre-flight, Phase A research, Phase B research, harness gate, save chain, audit-log report) are defined in `RESEARCH-ENGINE.md` (in this same skill directory). This skill owns:
21
- - Step 1: segment picker (with ETA)
21
+ - Step 1: campaign picker (with ETA)
22
22
  - Step 2: source picker (conditional PLATFORM block + always-visible HARNESS block)
23
23
  - The discovery-mode handler (paste candidates inline OR describe an ICP and source via harness tools)
24
- - The multi-segment grammar
24
+ - The multi-campaign grammar
25
25
 
26
26
  When you reach Step 3, **stop and read** `RESEARCH-ENGINE.md`. That doc is the canonical source for the candidate-list shape, the harness gate criteria, the identity-resolution save chain, and the canonical handoff prompt that source skills use.
27
27
 
@@ -50,13 +50,13 @@ The orchestrator's MCP precheck at the top of Step 3 (the `fetch` type=research_
50
50
  ## Inputs
51
51
 
52
52
  - `prospect_list` (optional): pre-built candidate list matching the canonical shape in `RESEARCH-ENGINE.md`. If provided, skip the source-picker step and go straight to Step 3 (pre-flight). This is how source skills hand off.
53
- - `segment(s)`: target segment(s); multi-segment supported.
53
+ - `campaign(s)`: target campaign(s); multi-campaign supported.
54
54
  - `mode`: `research-only` | `save` | `save-and-enroll` (default: `save-and-enroll`).
55
- - `gate_threshold`: minimum backend `match_score` to enroll (default: segment's existing quality_gate).
55
+ - `gate_threshold`: minimum backend `match_score` to enroll (default: campaign's existing quality_gate).
56
56
 
57
- ## Workflow — Step 1: Show pipeline status & pick segments
57
+ ## Workflow — Step 1: Show pipeline status & pick campaigns
58
58
 
59
- Call `import_prospects(action="sales_nav_searches", payload={action: "list"})` + `fetch(type="stats", subtype="outreach")` for queue depth + `search(type="campaigns")` for non-Sales-Nav segments. Present a numbered table with **per-segment ETA**:
59
+ Call `import_prospects(action="sales_nav_searches", payload={action: "list"})` + `fetch(type="stats", subtype="outreach")` for queue depth + `search(type="campaigns")` for non-Sales-Nav campaigns. Present a numbered table with **per-campaign ETA**:
60
60
 
61
61
  ```
62
62
  Pipeline status:
@@ -66,29 +66,29 @@ Pipeline status:
66
66
  3. Houston CTOs — 0/20 (20 needed) — harness ETA: ~18m
67
67
  4. NYC Partners — 40/40 ✓
68
68
 
69
- Which segments to fill? (all / 1,3 / skip 2)
69
+ Which campaigns to fill? (all / 1,3 / skip 2)
70
70
  Total if all needing fill: ~37m sequential.
71
71
  ```
72
72
 
73
- ETA estimates: ~2s for batch Step 3 dedup + ~30s/wave Phase A + ~60s/wave Phase B (5-parallel cap on Phase B). Multi-segment ETAs are sequential.
73
+ ETA estimates: ~2s for batch Step 3 dedup + ~30s/wave Phase A + ~60s/wave Phase B (5-parallel cap on Phase B). Multi-campaign ETAs are sequential.
74
74
 
75
75
  **Table rules:**
76
- - One row per segment, numbered sequentially
76
+ - One row per campaign, numbered sequentially
77
77
  - Show current/target counts and how many are needed
78
78
  - Flag searches that are drying up (⚠️) or accounts near capacity
79
- - Mark segments already at target with ✓ and don't number them
80
- - Show per-segment ETA so operator can budget time
79
+ - Mark campaigns already at target with ✓ and don't number them
80
+ - Show per-campaign ETA so operator can budget time
81
81
 
82
- **Wait for the user's response.** Parse: "all", "1, 3", "skip 2", "just the CFO ones", etc. Only proceed with the selected segments.
82
+ **Wait for the user's response.** Parse: "all", "1, 3", "skip 2", "just the CFO ones", etc. Only proceed with the selected campaigns.
83
83
 
84
- ## Workflow — Step 2: Pick source per segment (only if `prospect_list` not provided)
84
+ ## Workflow — Step 2: Pick source per campaign (only if `prospect_list` not provided)
85
85
 
86
- Per selected segment, prompt:
86
+ Per selected campaign, prompt:
87
87
 
88
88
  In **public mode** (the package builder strips the PLATFORM block from this skill before publishing), the picker shows only HARNESS modes, renumbered 1–4:
89
89
 
90
90
  ```
91
- Source for {segment_name}?
91
+ Source for {campaign_name}?
92
92
  HARNESS mode (your compute, in-chat deep research, visible & interruptible):
93
93
  1. sales-nav-deep — Sales Nav profiles + harness deep research
94
94
  2. yc — scrape YC directory with filters you provide
@@ -107,7 +107,7 @@ Per source pick, dispatch:
107
107
  - `csv` → invoke `/csv-pipeline-fill` to produce a candidate list, then continue to Step 3 with it.
108
108
  - `discovery` → use the discovery-mode handler below to produce a candidate list (handler branches: paste-shaped input → parse, prose ICP brief → harness sources via WebSearch + Vruum MCP + LinkedIn search), then continue to Step 3 with it.
109
109
 
110
- **Multi-segment behavior:** segments run sequentially. Segment 1's Step 7 (save chain + bulk enroll) completes before segment 2's Step 3 starts. Predictable rate-limit behavior, simple progress narrative. Trade-off: 3-segment fills are ~37min wall-clock vs ~22min if Phase A/B were overlapped across segments. Cross-segment overlap is a v2.
110
+ **Multi-campaign behavior:** campaigns run sequentially. Campaign 1's Step 7 (save chain + bulk enroll) completes before campaign 2's Step 3 starts. Predictable rate-limit behavior, simple progress narrative. Trade-off: 3-campaign fills are ~37min wall-clock vs ~22min if Phase A/B were overlapped across campaigns. Cross-campaign overlap is a v2.
111
111
 
112
112
  ## Discovery-mode handler (for `discovery` source)
113
113
 
@@ -127,13 +127,13 @@ Drop blank lines and lines starting with `#` (treat as comments).
127
127
  **Path B — operator describes an ICP** (you want the harness to discover candidates)
128
128
  Operator gives a brief like "Series A-C SaaS founders, US, 50-500 ppl" or "directors of operations at MSPs in DFW, recently posted about hiring". Harness sources candidates from scratch:
129
129
 
130
- 1. **Anchor on segment ICP** — read the segment's existing ICP/company profile (via `fetch` type=campaign and `fetch` type=settings subtype=profile) and merge with the operator's brief. Show a one-line synthesis ("OK so: Series A-C SaaS, US, 50-500 ppl, founder/CEO/CTO titles") and confirm before sourcing.
130
+ 1. **Anchor on campaign ICP** — read the campaign's existing ICP/company profile (via `fetch` type=campaign and `fetch` type=settings subtype=profile) and merge with the operator's brief. Show a one-line synthesis ("OK so: Series A-C SaaS, US, 50-500 ppl, founder/CEO/CTO titles") and confirm before sourcing.
131
131
  2. **Source companies first** — use harness tools to find candidate companies matching the brief:
132
132
  - `WebSearch` for funding announcements, news, lists ("Series A SaaS 2026", "TechCrunch Series B SaaS announcements")
133
133
  - `WebFetch` on Crunchbase / PitchBook / company directories
134
134
  - `mcp__vruum__import_prospects` with action=sales_nav_search (payload={keywords, title, limit}) for company-fitting roles when the brief is people-shaped (e.g. "VPs of Eng at Series A SaaS")
135
- 3. **Source people from each company** — for each candidate company, use `mcp__vruum__search` with type=companies and filters={domain, seniority} (Unipile-backed; respects LinkedIn rate limits) to find titles matching the segment ICP. Cap at ~5 people per company to spread the discovery surface.
136
- 4. **Dedup against existing pipeline** — for each discovered person, check `mcp__vruum__search` with type=people and a name/company keyword query so you don't research someone the segment already has.
135
+ 3. **Source people from each company** — for each candidate company, use `mcp__vruum__search` with type=companies and filters={domain, seniority} (Unipile-backed; respects LinkedIn rate limits) to find titles matching the campaign ICP. Cap at ~5 people per company to spread the discovery surface.
136
+ 4. **Dedup against existing pipeline** — for each discovered person, check `mcp__vruum__search` with type=people and a name/company keyword query so you don't research someone the campaign already has.
137
137
  5. **Show the discovered list to the operator** before handoff. Format: `Name (title) — Company [linkedin]`. Cap the surface at 2x daily_target so we don't over-source. Get a "go" / "drop X" before continuing.
138
138
 
139
139
  Discovery-path candidates produced in either path use the canonical shape in `RESEARCH-ENGINE.md` and feed into Step 3 the same way.
@@ -14,18 +14,18 @@ You are the Sales Nav harness-mode source for `/pipeline-fill`. You produce a ca
14
14
 
15
15
  ## Inputs
16
16
 
17
- - `segment`: target segment (single — multi-segment lives in `/pipeline-fill`)
17
+ - `campaign`: target campaign (single — multi-campaign lives in `/pipeline-fill`)
18
18
  - `count`: how many profiles to pre-filter (default 30)
19
19
 
20
20
  ## Workflow
21
21
 
22
22
  ### Step 1: Preview Sales Nav profiles
23
23
 
24
- Call `import_prospects(action="sales_nav_preview", payload={segment: ..., count: ...})`. Returns profile data + segment ICP context (target_titles, target_industries, value_proposition, positioning_angle, differentiators).
24
+ Call `import_prospects(action="sales_nav_preview", payload={campaign: ..., count: ...})`. Returns profile data + campaign ICP context (target_titles, target_industries, value_proposition, positioning_angle, differentiators).
25
25
 
26
26
  ### Step 2: Dispatch `vruum-pipeline-filter` for ICP pre-filter
27
27
 
28
- Spawn the existing `vruum-pipeline-filter` subagent (defined at `.claude/agents/vruum-pipeline-filter.md`). It evaluates each profile against the segment ICP using cheap title/company matching — no LinkedIn API calls, no deep research. APPROVE / DISMISS per profile.
28
+ Spawn the existing `vruum-pipeline-filter` subagent (defined at `.claude/agents/vruum-pipeline-filter.md`). It evaluates each profile against the campaign ICP using cheap title/company matching — no LinkedIn API calls, no deep research. APPROVE / DISMISS per profile.
29
29
 
30
30
  This is the cheap pre-filter — it removes obvious mismatches (titled-wrong, industry-wrong) before they enter Phase A/B deep research. Saves ~8 minutes per fill on a 30-profile preview that has 10 mismatches.
31
31
 
@@ -47,7 +47,7 @@ Emit the canonical handoff prompt (defined in `pipeline-fill/RESEARCH-ENGINE.md`
47
47
  ```
48
48
  Candidate list ready: {N} prospects from sales-nav-deep.
49
49
 
50
- NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and segment {segment_id}.
50
+ NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and campaign {campaign_id}.
51
51
 
52
52
  Continue automatically? (y/n)
53
53
  ```
@@ -84,7 +84,7 @@ If no hook can be generated → defer the row. Warm via marketing/content first,
84
84
 
85
85
  Step 6 — Hand off. Two options:
86
86
  - **Option A (recommended)**: Approve the list; run `/pipeline-fill` with the prospect_list for harness deep research + outreach. Plans get `outreach_plans.tag = bowtie_pilot:winback`.
87
- - **Option B**: Direct `manage_outreach` action=start with a winback-flavored segment (pre-create a `winback_<your-tenant>` segment — tone: empathetic, no apology, lead with what changed since last conversation).
87
+ - **Option B**: Direct `manage_outreach` action=start with a winback-flavored campaign (pre-create a `winback_<your-tenant>` campaign — tone: empathetic, no apology, lead with what changed since last conversation).
88
88
 
89
89
  Step 7 — Success tracking (auto). The calendar webhook records the impact event, equivalent to:
90
90
  ```
@@ -10,11 +10,11 @@ description: >-
10
10
 
11
11
  You are the YCombinator harness-mode source for `/pipeline-fill`. You scrape YC's public directory, extract founder LinkedIn URLs, dedup, and hand a candidate list to the orchestrator. No deep research, no harness gate, no save chain in this skill — that's all in `pipeline-fill/RESEARCH-ENGINE.md`.
12
12
 
13
- This is the answer to "DFW CFOs Sales Nav is dead, what now?" — pivot to YC, get 30 founders into the segment in ~15 minutes.
13
+ This is the answer to "DFW CFOs Sales Nav is dead, what now?" — pivot to YC, get 30 founders into the campaign in ~15 minutes.
14
14
 
15
15
  ## Inputs
16
16
 
17
- - `segment`: target segment (single)
17
+ - `campaign`: target campaign (single)
18
18
  - `count`: target number of imports (default 50)
19
19
  - `filters` (REQUIRED — no defaults; operator must specify at least one):
20
20
  - `team_size_min` / `team_size_max` (proxy for funding stage)
@@ -27,9 +27,9 @@ If the operator runs the skill without filters, prompt: "YC has 5K+ companies
27
27
 
28
28
  ## Workflow
29
29
 
30
- ### Step 1: Load segment ICP
30
+ ### Step 1: Load campaign ICP
31
31
 
32
- Call `fetch` type=research_playbook id=<segment_id> to load ICP context. The downstream subagents need it for classification; capture it now to pass forward.
32
+ Call `fetch` type=research_playbook id=<campaign_id> to load ICP context. The downstream subagents need it for classification; capture it now to pass forward.
33
33
 
34
34
  ### Step 2: Algolia connectivity precheck
35
35
 
@@ -149,7 +149,7 @@ Emit the canonical handoff prompt (defined in `pipeline-fill/RESEARCH-ENGINE.md`
149
149
  ```
150
150
  Candidate list ready: {N} prospects from yc.
151
151
 
152
- NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and segment {segment_id}.
152
+ NEXT: invoke /pipeline-fill Step 3 onward (deep research → harness gate → save) with this list and campaign {campaign_id}.
153
153
 
154
154
  Continue automatically? (y/n)
155
155
  ```