Version: 1.0 Date: 2026-02-07 Applies to: SKYMOD & Maad House GTM Engines
Both GTM engines currently support a single campaign with one ICP, one outreach sequence, and one scoring model. As we expand to new ICPs (UK Long-Service, NL Anniversaries, Professional Services for SKYMOD; Legal, DTC, Lifestyle for Maad House), each needs its own pipeline, messaging, and tracking — while sharing infrastructure and avoiding duplicate contacts.
A campaign encapsulates everything needed to run an independent outbound motion:
| Component | What It Defines |
|---|---|
| ICP | Who to target (firmographic + intent signals + scoring weights) |
| Scoring | How to score (criteria and weights specific to this ICP) |
| Sequences | What to say (touch templates, tone, CTA, cadence) |
| Collateral | Supporting materials (1-pagers, pitch decks, case studies) |
| Geography | Where to target (country/region filters) |
| Stages | Pipeline stages (can vary per campaign) |
| Timing | Cadence rules (days between touches, send windows) |
New file at Marketing/GTM/campaigns.json:
{
"version": "2.0",
"campaigns": [
{
"id": "retirement-archive",
"name": "Retirement Archive (EU Manufacturing)",
"status": "active",
"priority": 1,
"icpFile": "campaigns/retirement-archive/icp-definition.md",
"positioningFile": "campaigns/retirement-archive/positioning.md",
"sequencesDir": "campaigns/retirement-archive/outreach-sequences/",
"collateralDir": "campaigns/retirement-archive/collateral/",
"geography": ["DE", "NL", "CH", "AT", "BE"],
"stages": [
"sourced",
"recognition_qualified",
"contacted",
"replied",
"interested",
"invoiceSent",
"paid",
"shipped",
"closed"
],
"touchCount": 4,
"cadence": {
"t1_to_t2": 3,
"t2_to_t3": 7,
"t3_to_t4": 14
},
"scoring": {
"model": "recognition-first",
"weights": {
"firmographic": 30,
"recognition": 45,
"accessibility": 25
}
},
"created": "2026-02-03",
"metrics": {
"prospectCount": 20,
"contacted": 14,
"replied": 0,
"converted": 0
}
},
{
"id": "uk-longservice",
"name": "UK Long-Service Awards (HMRC Tax Advantage)",
"status": "planned",
"priority": 2,
"icpFile": "campaigns/uk-longservice/icp-definition.md",
"positioningFile": "campaigns/uk-longservice/positioning.md",
"sequencesDir": "campaigns/uk-longservice/outreach-sequences/",
"collateralDir": "campaigns/uk-longservice/collateral/",
"geography": ["GB"],
"stages": [
"sourced",
"recognition_qualified",
"contacted",
"replied",
"interested",
"invoiceSent",
"paid",
"shipped",
"closed"
],
"touchCount": 4,
"cadence": {
"t1_to_t2": 3,
"t2_to_t3": 7,
"t3_to_t4": 14
},
"scoring": {
"model": "recognition-first",
"weights": {
"firmographic": 30,
"recognition": 40,
"accessibility": 30
}
},
"created": "2026-02-07",
"metrics": {
"prospectCount": 0,
"contacted": 0,
"replied": 0,
"converted": 0
}
}
]
}
Marketing/GTM/
├── README.md # Engine overview (updated)
├── campaigns.json # Campaign registry
├── research-process.md # Shared research methodology
├── log.md # Activity log (all campaigns)
│
├── campaigns/
│ ├── retirement-archive/ # EXISTING (migrated from root)
│ │ ├── icp-definition.md
│ │ ├── positioning.md
│ │ ├── outreach-sequences/
│ │ │ ├── t1-cold-intro.md
│ │ │ ├── t2-follow-up.md
│ │ │ ├── t3-value-add.md
│ │ │ └── t4-breakup.md
│ │ └── collateral/
│ │ └── retirement-batch-1pager.md
│ │
│ ├── uk-longservice/ # NEW
│ │ ├── icp-definition.md # UK manufacturing, HMRC angle
│ │ ├── positioning.md # Tax-advantage framing
│ │ ├── outreach-sequences/
│ │ │ ├── t1-cold-intro.md # HMRC hook
│ │ │ ├── t2-follow-up.md
│ │ │ ├── t3-value-add.md
│ │ │ └── t4-breakup.md
│ │ └── collateral/
│ │ └── hmrc-tax-guide.md
│ │
│ ├── nl-anniversaries/ # NEW
│ │ ├── icp-definition.md # NL companies with jubileum culture
│ │ ├── positioning.md # 12.5-year tradition angle
│ │ ├── outreach-sequences/
│ │ └── collateral/
│ │
│ └── prof-services/ # NEW
│ ├── icp-definition.md # UK/EU law & accounting firms
│ ├── positioning.md # Partner gifting angle
│ ├── outreach-sequences/
│ └── collateral/
│
Sales/
├── pipeline/
│ ├── index.json # SINGLE pipeline (all campaigns)
│ └── SCHEMA.md # Updated schema
├── prospects/ # Per-prospect folders (unchanged)
│ ├── _template/
│ ├── miele/
│ └── ...
Design decision: One index.json with a campaign field on each prospect — NOT separate files per campaign.
Why single file:
{
"id": "SKY-2026-021",
"campaign": "uk-longservice", // ← NEW: which campaign
"company": {
"name": "Rolls-Royce plc",
"website": "https://rolls-royce.com",
"industry": "Manufacturing",
"size": "5000+",
"country": "GB",
"city": "Derby"
},
"contact": { ... },
"scoring": {
"total": 88,
"firmographic": 28,
"recognition": 35,
"accessibility": 25,
"notes": "HMRC long-service eligible. 25+ year award program."
},
"tier": "A",
"stage": "sourced",
"recognitionSignal": "...",
"source": "firecrawl",
"personalization": { ... },
"dates": { ... },
"outreach": { ... },
"notes": [],
"folderPath": "prospects/rolls-royce/"
}
{
"version": "2.0",
"lastUpdated": "2026-02-07T12:00:00Z",
"stats": {
"total": 35,
"byCampaign": {
"retirement-archive": {
"total": 20,
"byTier": { "A": 5, "B": 15 },
"byStage": { "sourced": 1, "contacted": 14, "recognition_qualified": 5 },
"byCountry": { "DE": 14, "NL": 1, "CH": 1, "AT": 2, "BE": 2 }
},
"uk-longservice": {
"total": 15,
"byTier": { "A": 5, "B": 10 },
"byStage": { "sourced": 15 },
"byCountry": { "GB": 15 }
}
}
},
"campaigns": ["retirement-archive", "uk-longservice"],
"prospects": [ ... ]
}
Before adding ANY prospect to ANY campaign:
index.json for matching company.website or company.nameA single contact should NEVER receive emails from two campaigns at the same time. Rules:
| Scenario | Action |
|---|---|
| Same person, same company, different campaign | Choose highest-priority campaign. Pause the other. |
| Different person, same company, different campaign | OK — proceed with both (different decision-makers) |
| Same person moved to new company | OK — new company context |
When conflicts arise, defer to campaign priority in campaigns.json. Lower number = higher priority.
"Source SKYMOD prospects for [campaign]"
→ Load ICP from campaigns/{campaign}/icp-definition.md
→ Run Firecrawl Agent with campaign-specific query
→ Dedupe against FULL pipeline (all campaigns)
→ Score using campaign-specific weights
→ Add to index.json with campaign field
"Draft T1 for [company] in [campaign]"
→ Load T1 template from campaigns/{campaign}/outreach-sequences/t1-cold-intro.md
→ Read prospect research + persona
→ Generate personalized email
→ Save to prospects/{company}/outreach/t1.md
"Show SKYMOD pipeline status"
→ Read campaigns.json → list all campaigns
→ For each: show prospect count, stage breakdown, next actions"Show SKYMOD pipeline for [campaign]"
→ Filter index.json by campaign
→ Show that campaign's metrics and upcoming actions
"Show all SKYMOD next actions"
→ Scan ALL campaigns for nextActionDate ≤ today
→ Group by campaign, sorted by date
"Create SKYMOD campaign [name]"
→ Add entry to campaigns.json
→ Create campaign folder structure
→ Generate ICP definition template
→ Generate outreach sequence templates
→ Status: "planned""Activate SKYMOD campaign [name]"
→ Set status: "active"
→ Run first prospecting batch
"Pause SKYMOD campaign [name]"
→ Set status: "paused"
→ Skip all scheduled outreach for that campaign
"Archive SKYMOD campaign [name]"
→ Set status: "archived"
→ Move stats to archive, keep data for reference
Marketing/GTM/icp-definition.md → campaigns/retirement-archive/icp-definition.md
- Marketing/GTM/positioning.md → campaigns/retirement-archive/positioning.md
- Marketing/GTM/outreach-sequences/ → campaigns/retirement-archive/outreach-sequences/
- Sales/collateral/retirement-batch-1pager.md → campaigns/retirement-archive/collateral/campaign field to each existing prospect in index.json: "campaign": "retirement-archive"
byCampaign structurecampaigns.json with retirement-archive as first entrycampaigns.json with hospitality as first entrycampaign: "hospitality" field to each existing prospectcampaigns/hospitality/Maad House follows the same architecture with different campaign definitions:
Maad House/Marketing/GTM/
├── campaigns.json
├── campaigns/
│ ├── hospitality/ # EXISTING (migrated)
│ │ ├── icp-definition.md
│ │ ├── outreach-sequences/
│ │ └── collateral/
│ ├── legal-lawtech/ # NEW (Priority #1 expansion)
│ │ ├── icp-definition.md # Linkilaw as proof point
│ │ ├── outreach-sequences/
│ │ └── collateral/
│ │ └── linkilaw-case-study.md
│ ├── ecommerce-dtc/ # NEW (Priority #2)
│ │ ├── icp-definition.md # SKYMOD as proof point
│ │ ├── outreach-sequences/
│ │ └── collateral/
│ │ └── skymod-case-study.md
│ └── lifestyle-wellness/ # NEW (Priority #3)
│ ├── icp-definition.md
│ ├── outreach-sequences/
│ └── collateral/
Same pipeline rules: single index.json, campaign field per prospect, cross-campaign deduplication.
After migration, the portfolio dashboard supports:
"Show SKYMOD pipeline status"
→ All campaigns summary:
retirement-archive: 20 prospects (14 contacted, 0 replies)
uk-longservice: 0 prospects (planned)
nl-anniversaries: 0 prospects (planned)
prof-services: 0 prospects (planned)"Execute SKYMOD ICP expansion (UK → NL → Prof Services)"
→ Creates campaign entries
→ Generates ICP + sequence templates
→ Sets priority order
→ Ready for prospecting
| Step | Action | Effort |
|---|---|---|
| 1 | Create campaigns.json for both businesses | 10 min |
| 2 | Add campaign field to existing prospects | 5 min |
| 3 | Restructure folders (move existing files to campaign subfolders) | 15 min |
| 4 | Update README files | 10 min |
| 5 | Update SCHEMA.md with campaign field | 5 min |
| 6 | Create first new campaign (UK Long-Service) | 30 min |
| 7 | Run first prospecting batch for new campaign | 15 min |
Total: ~90 minutes to go from single-campaign to multi-campaign for both businesses.