Campaign Strategy (pre-flight)
SkillFiles & storagePre-flight strategy advisor for a new campaign. Analyses every past campaign in the local YALC DB (HeyReach campaigns auto-sync on each run), their real outbound copy, where in the sequence each conversation first replied, every prior retro brief, and the validated/proven intelligence file. Then it proposes angle, audience, batch size, channel choice, and concrete testable hypotheses for the campaign you are about to launch. Does NOT draft outbound copy — that is refine-outbound-copy's job. Use when someone says 'I want to launch a campaign for X', 'how should we approach this campaign', 'what should we test next', 'strategy for the next campaign', or 'campaign manager' in the context of building a new campaign.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Campaign Strategy (pre-flight) skill
What this skill tells your AI
The instructions your AI receives, as published by othmane-khadri/yalc-the-gtm-operating-system in .claude/skills/campaign-strategy/SKILL.md and read by ahel’s review.
The forward-looking sibling of improve-campaign. Where improve-campaign asks "what should we change after this campaign?", strategy asks "what should we do for the next campaign, given everything we know?"
Goal (per David's standing direction): "Improve our campaigns constantly. The goal is not execution and completion — it's performance and results." The skill exists at the moment a new campaign is being built, because that is when analysis is most useful.
Key idea: the reasoning happens in chat — not via a duplicate API call. The CLI helpers load the raw data and persist the output; the strategic thinking happens between them.
When this skill applies
- "I want to launch a campaign for X" / "how should we approach this campaign"
- "What should the next campaign test?"
- "Campaign manager" — when invoked while building (not after) a campaign
- "What did we learn from previous campaigns that's worth testing next?"
Not this skill:
- "Retro on the last campaign" / "what didn't work" →
improve-campaign - "Draft / rewrite the outbound copy" →
refine-outbound-copy - "Create the campaign now in the DB" →
campaign:create-sequence
Inputs
Just one: concept — a short description of the campaign the user wants to launch. e.g. "Reddit GEO Specialists hire", "datascalehr CHRO Tier-1 follow-up". Don't ask anything else up front.
Procedure
Step 0 — Guard
test ! -e ~/.gtm-os/.in-flight-setup
If the file exists, stop and tell the user setup is in progress.
Step 1 — Auto-sync HeyReach (proactive — do not ask)
Per David's standing rule: if the user doesn't need to do something because you have access, do it. Before pulling data, refresh the local DB so the strategy reasons against the latest funnel + copy + reply attribution:
npx tsx src/cli/index.ts campaign:import-heyreach
This is idempotent and cached (5-min TTL on stats, 1-hour TTL on chatrooms), so it's cheap on re-runs. It auto-extracts the real DM copy and reply-step attribution from chatrooms via the HeyReach MCP. If the user has other senders besides David, repeat with --sender-account-id <id>.
Surface a one-line note ("Synced N HeyReach campaigns") so the user sees the refresh happened — don't dump the full output.
Step 2 — Pull the strategy data block
npx tsx src/cli/index.ts campaign:strategy --data-only --concept "<one-line concept>"
Emits JSON with three top-level arrays plus the concept:
{
"concept": "...",
"tenantId": "default",
"intelligenceDir": ".../data/intelligence",
"outputDir": ".../data/intelligence",
"pastCampaigns": [
{
"id": "heyreach:412427",
"title": "GEO/SEO Talents Batch #1",
"hypothesis": "...",
"funnel": { "leads": 43, "connectsSent": 42, "connectsAccepted": 24, "dmsSent": 18, "replies": 15, "acceptRate": 0.57, "replyRate": 0.83 },
"replyAttribution": [ { "after_step": 1, "replies": 11 }, { "after_step": 2, "replies": 10 } ],
"conversationsSampled": 18,
"variants": [ { "name": "...", "connectNote": "...", "dm1Template": "<the real DM1 text>", "dm2Template": "<the real DM2 text>", "sends": 42, "accepts": 24, "acceptRate": 0.57, "dmsSent": 18, "replies": 15, "replyRate": 0.83 } ]
}
],
"retroBriefs": [ /* every campaign_improvement_*.json */ ],
"intelligence": [ /* every validated/proven entry in data/intelligence/ */ ]
}
dm1Template / dm2Template are the real outbound messages David sent, extracted from chatrooms. replyAttribution shows where in the sequence each conversation first replied (after_step: 1 = after DM1, after_step: 2 = after DM2, etc.). The connect-request note is NOT recoverable via LinkedIn's API — if the user wants it factored in, ask them to paste it via campaign:annotate --connect-note "..." before continuing. Otherwise, proceed using DM1+ data only.
Step 3 — Reason in chat (this is the work)
Read the data block and write a strategy brief that matches this shape:
{
"proposed_campaign_concept": "<echo back the concept>",
"summary": "one-line strategic take",
"closest_past_campaigns": [
{ "id": "heyreach:412427", "name": "...", "why_similar": "...", "headline_metric": "57% accept / 83% reply on 43 leads" }
],
"what_worked_before": [
{ "observation": "...", "evidence": "...", "confidence": "hypothesis|validated|proven" }
],
"what_to_carry_forward": [
{ "decision": "...", "rationale": "...", "confidence": "..." }
],
"copy_devices_to_test": [
{ "device": "...", "seen_in": "<campaign id or '(new)'>", "why_might_work": "...", "confidence": "..." }
],
"what_to_test": [
{ "hypothesis": "...", "test_design": "...", "rationale": "..." }
],
"open_strategic_questions": [
"one-line question the user must answer before launch"
]
}
Reasoning rules:
- 2–4 items in
closest_past_campaigns. Each row needs a one-second headline metric (e.g.57% accept / 83% reply on 43 leads). - 3–5 items in
what_worked_before, anchored infunnelnumbers,variants[*]metrics, andreplyAttribution. Quote actual phrases from the extracted copy when they support the observation. - 2–5 items in
what_to_carry_forward. Concrete decisions only — "Use the GEO/SEO Talents DM1 device stack" not "keep the messaging similar." - 2–5 items in
copy_devices_to_test. This is the highest-value output. Identify specific phrases or structural moves in past copy whose performance is suspected (e.g. authority signal, exclusivity language, specific compensation anchor, permission-to-decline). Anchor each device to the campaign you saw it in, or mark(new)if proposing fresh. - 2–4 items in
what_to_test. Each must include a realtest_design— "A/B variant A=all 4 devices vs B=2 devices, 50/50 split, >20pt reply-rate gap = stacking confirmed" beats "test the copy." - 1–3
open_strategic_questions. Things the user must decide before launch (e.g. "hire or warm pool?"). One should always be the channel question if no cross-channel data exists. - Reply-step attribution is first-class. When step-1 catches most replies (e.g. GTM Engineers at 22/28), DM1 is the workhorse — the next campaign's DM1 should preserve that load. When step-2 catches near-step-1 volume (e.g. GEO/SEO at 11/10), DM2 has its own devices doing work — call those out separately.
- Confidence tagging is mandatory.
hypothesisis the default.validated/provenonly when anchored in retro entries, multiple cross-campaign signal, or a validated/proven intelligence entry. - Do not draft outbound copy. Identify devices, not lines.
- No invented metrics. If a number isn't in the data block, don't cite it.
Step 4 — Save the brief
echo "$STRATEGY_JSON" > /tmp/campaign_strategy_<slug>.json
npx tsx src/cli/index.ts campaign:strategy --from-file /tmp/campaign_strategy_<slug>.json
The CLI validates the schema and writes data/intelligence/campaign_strategy_<slug>_<YYYYMMDD>.json.
Step 5 — Render the result in chat
Show the user six sections:
- Concept — the one-line concept being advised on
- Summary — strategic take in one line
- Closest past campaigns — table with id, name, headline metric, why similar
- What to carry forward — bullets tagged
[confidence] - Copy devices worth testing — bullets:
device — seen in <campaign id> — why might work - Hypotheses to test in this campaign —
hypothesis → test design - Open questions before launch — bullets
When relevant, include a small reply-attribution table showing which step caught replies for each closest-past campaign — it's load-bearing data the user will want to see.
Then tell the user where the file landed.
Step 6 — Follow-up offer
After rendering, offer:
Want me to draft outbound copy for this strategy now? For a YALC tenant (client) campaign I'd route to
refine-outbound-copy. For an Earleads-internal campaign I'll draft in chat directly against this brief and your voice rules.
If yes: chain forward. If they want to refine the strategy first, iterate in chat and re-write the file.
Step 7 — Surface CLI failures verbatim
Print stderr unchanged. Common failure modes:
Strategy brief is missing field: ...— step-3 JSON didn't match the schema.--concept is required with --data-only.— pass a concept.
Hard rules
- Auto-sync HeyReach before reasoning. Proactivity is the baseline — don't ask the user to run import first.
- Strategy never drafts the outbound copy. That's
refine-outbound-copy(for tenant campaigns) or in-chat drafting against voice rules (for Earleads-internal campaigns). - Copy-device hypotheses are first-class output. Per the user's standing rule: surface what's worth testing next, with confidence tags, anchored to specific phrases observed in past copy.
- Reply-step attribution is first-class. Each closest past campaign's
replyAttributioninforms whether DM1 or DM2 is the workhorse — propagate that into the next campaign's architecture. - Confidence tagging is mandatory on every observation, decision, and copy-device.
- One brief per concept per day. Same-day re-runs overwrite the prior file.
Reference
- Strategy library:
src/lib/campaign/strategy.ts(runStrategyData,runStrategyWrite) - HeyReach importer:
src/lib/campaign/import-heyreach.ts+src/lib/services/heyreach.ts(REST + MCP wrapper, auto-extracts copy + reply attribution) - Backfill / annotate:
src/lib/campaign/annotate.ts+campaign:annotateCLI (for connect-note backfill or hypothesis override) - Past retros:
data/intelligence/campaign_improvement_*.json - Past strategy briefs:
data/intelligence/campaign_strategy_*.json - Validated intelligence:
data/intelligence/*.json(excludingcampaign_*prefixes) - Sibling skills:
improve-campaign(retro),refine-outbound-copy(copy rewrite),campaign-dashboard(visual)
Signals
- GitHub stars
- 301
- Forks
- 90
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
campaign-strategy- Source
- github.com/othmane-khadri/yalc-the-gtm-operating-system