GTM Orchestrator · Team Overview
LeadGrow Internal
GTM
Orchestrator
Brief to launch. Every step visible.
v1
Speaker Notes
This deck covers what the orchestrator is, how the pipeline works, and how operators interact with it — from writing a brief to approving a Bison launch.
01
What It Does
One command. Campaign brief → Bison-ready copy.
Speaker Notes
The key value prop: you write a brief, run one command, and the system handles discovery through copy generation — surfacing at checkpoints where operator judgment is required. Nothing launches automatically.
02
The Pipeline
9 Stages. Brief in. Bison out.
01DiscoverPull leads from DiscoLike or Google Mapsautomated
02–04Format · Enrich · PeopleClay normalize → ICP qualify → AI Ark people findautomated
05EnrichOptional enrichments (news, funding, tech stack, buying signals)⚑ checkpoint
06SegmentClassify leads into campaign segments⚑ checkpoint
07CopyDual-agent copy generation (Braun → secondary) · 2 variants each⚑ checkpoint
08QARendered semantic QA · mechanical spam check · convert variablesautomated
09LaunchBison campaign create → copy → inboxes → leads → route → standards → gate⚑ launch gate
Speaker Notes
Checkpoints (⚑) are the stages where the system pauses and surfaces a file for operator review. Everything else runs fully automated. Stage 9 has a mandatory human launch gate — operator must set operator_confirms: true with a signature before anything goes live.
Chapter 1
Setup
Writing
the Brief
1
Speaker Notes
The brief is the single source of truth for the entire campaign. It's frozen at init — you can't change it after the pipeline starts. Plan carefully.
03
Campaign Setup
One folder.
One brief.
Each campaign lives at a fixed path. The brief is frozen once the pipeline initializes — you cannot modify it mid-run.
Brief is Immutable
Stage 1 freezes the brief. All downstream stages read from that frozen snapshot. Edit before you run, not after.
# Fixed path convention clients/ gtm-client-[slug]/ campaigns/ [campaign-slug]/ brief.md ← frozen at init subcampaigns/ ← per-segment leads stages/ 01-discover/ 02a-clay-format/ ... 07-copy/ 08-qa/ 09-launch/ manifest.sqlite ← truth store
Speaker Notes
The manifest.sqlite is the source of truth — every stage writes its state there. The stages/ directories contain the observable artifacts (CSVs, YAMLs) that mirror the SQLite state.
04
The Brief
Frontmatter
drives everything.
  • client_name — who the campaign is for
  • campaign_slug — unique identifier
  • list_source — discolike or google_maps
  • ## Segments — define named segments
  • ## EDPs — one block per segment (required)
  • ## Market — ICP context for copy
  • ## Angles — messaging hooks
--- client_name: Acme Corp campaign_slug: acme-smb-q2 list_source: discolike qa_sample_size: 10 --- ## Segments - owner-reachable: owners/founders - ops-leader: COOs, ops directors ## EDPs ### owner-reachable - I'm losing 3hrs/day to manual follow-up - My team can't see what's in the pipeline ### ops-leader - Reporting takes a full day every week
Speaker Notes
The EDP contract is strict: every segment listed under ## Segments MUST have a matching ### segment-slug block under ## EDPs. The pipeline validates this at brief-freeze and will hard-fail if a segment is missing its EDPs.
Chapter 2
Running the Pipeline
Commands
& Flow
2
Speaker Notes
Five commands cover everything. Run, resume, status, score-replies, and the dry-run flag. Use dry-run first on any new campaign.
05
The 5 Commands
# Start or resume from last completed stage $ gtm-orchestrator run clients/gtm-client-acme/campaigns/q2-smb # Simulate all Bison calls — skips launch gate (use this first) $ gtm-orchestrator run clients/gtm-client-acme/campaigns/q2-smb --dry-run # Resume after editing a checkpoint file (exit code 5) $ gtm-orchestrator resume clients/gtm-client-acme/campaigns/q2-smb # Per-stage token counts + cost totals $ gtm-orchestrator status clients/gtm-client-acme/campaigns/q2-smb # Classify reply emails post-launch (run after Bison starts getting replies) $ gtm-orchestrator score-replies clients/gtm-client-acme/campaigns/q2-smb
Rule of Thumb
Always dry-run a new campaign first. Dry-run validates the full pipeline with synthetic Bison IDs — no real sends, no real cost on Bison.
Speaker Notes
score-replies is standalone — it doesn't run inside the main pipeline. You run it separately after the campaign has been live and replies are coming in.
06
Exit Codes
What the pipeline
is telling you.
CodeMeaningWhat to do
0Success — stage or full pipeline completeNothing. Move on.
5CheckpointPending — operator action requiredEdit the surfaced file → resume
6StandardsVerificationFailed — Bison settings mismatchFix settings in Bison UI → rerun
7Scorecard hard-block — list quality grade FFix list quality or override (rare)
The Resume Loop
run → exit 5 → edit checkpoint file → resume → exit 5 → edit → resume → … → exit 0
Speaker Notes
Exit code 5 is normal — it's the system asking for operator judgment. Not an error. Exit code 1 is an unexpected error and will include an error message pointing to the failed stage.
Chapter 3
Operator Workflow
Check­points
3
Speaker Notes
There are 5 checkpoint moments in the pipeline. Each one surfaces a specific file to edit. After editing, run resume and the pipeline continues from exactly where it stopped.
07
5 Checkpoints
What the pipeline surfaces and why.
Stage 5 Edit stages/05-enrich/checkpoint.json — resolve flagged enrichment rows idempotent
Stage 6 Edit stages/06-segment/tiebreak.csv — manually assign ambiguous leads to a segment idempotent
Stage 7 Edit stages/07-copy/selection.yaml — pick the winning copy variant per segment required
Stage 9c Edit stages/09-launch/inbox_selection.yaml — uncheck inboxes you don't want used required
Stage 9g Edit stages/09-launch/launch_confirmation.yaml — sign off before anything sends launch gate
Speaker Notes
Stages 5 and 6 are idempotent — you can partially resolve them and resume. Unfilled rows resurface on the next run. Stage 7, 9c, and 9g require full resolution before the pipeline continues.
08
Checkpoint · Stage 5
Enrichment
Review
Optional enrichments run against each lead: recent news, funding signals, tech stack, buying signals. If any fail or need review, the pipeline surfaces them.
Partial Resolution OK
You don't have to fix everything at once. Resolve what you can, resume — unfilled rows will resurface next time.
6 Available Enrichments
linkedin_scrapeLinkedIn profile data
team_headcountCompany size signals
recent_newsLast 90 days coverage
fundingFunding rounds
tech_stackTechnologies in use
buying_signalHiring / intent signals
Speaker Notes
Enrichments are optional per campaign — they're listed in the brief frontmatter. A campaign with no enrichments listed skips Stage 5 entirely. The 6 enrichment slugs are fixed; adding a new one requires a code change to the registry.
09
Checkpoint · Stage 6
Segment
Tiebreak
The pipeline classifies each lead into a segment based on title, seniority, and company signals. Leads where confidence falls below the brief's threshold surface in a tiebreak CSV.
  • Add the correct segment_slug to each flagged row
  • Rows you resolve stay resolved on next resume
  • Blank rows resurface — don't have to fix all at once
# File to edit after Stage 6 checkpoint stages/06-segment/tiebreak.csv # Format row_id,company,title,segment_slug abc123,Acme Inc,Director of Ops, ← fill this def456,Beta Co,VP Operations, ← fill this # Valid slugs match your brief's ## Segments # e.g.: owner-reachable, ops-leader # Then resume $ gtm-orchestrator resume <campaign_dir>
Speaker Notes
The confidence threshold is configurable in the brief via segmentation_confidence_threshold (default 0.7). Lower it to reduce tiebreak volume; raise it to surface more leads for manual review.
Chapter 4
Copy + QA
Stage 7
& Stage 8
4
Speaker Notes
Stage 7 is the creative heart of the pipeline. Two AI agents write copy. The operator picks the winner. Stage 8 QA gates it before anything goes to Bison.
10
Stage 7 · Copy Generation
Two agents write.
You pick the winner.
① Braun runs first
Prospect-voice, EDP-grounded · Writes 2 variants (email 1/2/3 each)
Braun output feeds as context
② campaign-copywriting runs second
Uses Braun output as grounding · Writes 2 more variants
4 total variants written to candidates YAML
③ Checkpoint — pick winner per segment
Edit selection.yaml · Choose braun.variant_01/02 or secondary.variant_01/02
Resume → winners locked into state
Stage 8 QA →
Winning copy goes through semantic + mechanical checks
Speaker Notes
Both agents write a full 3-email sequence. The checkpoint surfaces all 4 candidates in selection.yaml. You can also provide a manual override inline — set manual: {subject, body} instead of picking a slot ID.
11
Checkpoint · Stage 7
Editing
selection.yaml
  • One block per segment in the file
  • Set email_1_winner: to the slot ID you prefer
  • Emails 2 and 3 are pre-filled from the winning agent's variants
  • Override any email inline with a manual: {subject, body} block
  • Pre-fill is braun.variant_01 — just resume if Braun is good
# stages/07-copy/selection.yaml - segment_slug: owner-reachable email_1_winner: braun.variant_01 ← change this email_2: subject: "" body: | ← pre-filled from winner Hey {{first_name}}, following up... email_3: subject: "" body: | Last one from me... # Valid slot IDs: # braun.variant_01 / braun.variant_02 # secondary.variant_01 / secondary.variant_02 # OR provide manual: {subject, body}
Speaker Notes
The candidates_braun.yaml and candidates_secondary.yaml files contain the full text of all 4 variants. Read those to compare before picking a winner in selection.yaml.
12
Stage 8 · QA
Three passes before
copy goes to Bison.
8a · Semantic QA LLM reviews rendered emails (variables substituted) — flags broken variables, AI slop, tone mismatches, spam phrases, em-dashes sample of 10 leads
8b · Mechanical Spam word checker + variable syntax validator — catches formatting issues the LLM might miss all leads
8c · Convert Deterministic pass: {{DOUBLE_BRACE}}{SINGLE_BRACE} · Writes final_copy.yaml in Bison-native format automated · no checkpoint
Semantic QA Only Runs on Rendered Copy
Stage 8a substitutes real lead data into the template, then checks the output. It catches "Hey , I noticed" — blank where {{first_name}} was missing.
Speaker Notes
If Stage 8a or 8b finds HIGH-severity issues, it raises a checkpoint. You edit the copy back in selection.yaml (or fix the template) and resume. The convert step (8c) is fully automated — it just does the variable format swap for Bison compatibility.
Chapter 5
Bison Launch
Stage 9
5
Speaker Notes
Stage 9 has 7 substages. Most are automated. Two require operator action: 9c inbox selection and 9g the launch gate. Nothing goes live until you sign the gate.
13
Stage 9 · Launch Substages
7 steps to Bison-ready.
SubWhat HappensOperator?
9aCreate one Bison campaign per segment in workspace 3automated
9bUpload 3-email sequence from final_copy.yaml · auto-creates missing variablesautomated
9cList connected inboxes → write inbox_selection.yaml⚑ uncheck inboxes
9dUpload leads in 500-lead batchesautomated
9eRoute uploaded leads to their segment's campaignautomated
9fApply campaign standards · verify settings match specautomated
9gWrite launch_confirmation.yaml · full pre-launch summary⚑ sign off to launch
Speaker Notes
Each segment = a separate Bison campaign. Bison has no sub-campaign primitive, so the orchestrator creates independent campaigns and tracks them in stage_09_launch state table. If 9f fails (StandardsVerificationFailed, exit 6), fix the settings in the Bison UI and rerun.
14
Checkpoint · Stage 9g
The Launch
Gate
The final checkpoint before anything goes live. The pipeline writes a full pre-launch summary — campaigns, lead counts, copy preview, inbox assignments.
  • Review the full summary in the YAML
  • Set operator_confirms: true
  • Add a non-empty operator_signature
  • Decline logs and exits cleanly — no partial launch
Dry-Run Skips This
--dry-run uses synthetic Bison IDs and skips Stage 9g entirely. Safe to test the full pipeline without hitting the gate.
# stages/09-launch/launch_confirmation.yaml summary: campaigns_created: 2 total_leads: 847 segments: - owner-reachable: 412 leads - ops-leader: 435 leads inboxes_selected: 3 copy_preview: subject: "Quick question, {{first_name}}" body_preview: "Noticed Acme just..." # To launch: operator_confirms: true operator_signature: "Mitch — 2026-05-04" # To decline: # operator_confirms: false
Speaker Notes
The signature field must be non-empty string — just your name and date is fine. If operator_confirms is false or missing, the pipeline logs the decline and exits cleanly. No partial state written.
15
Bison Campaign Standards
Default settings applied
to every campaign.
1,000
max total sends per campaign
800
max sends per inbox
3
email sequence length
3
Bison workspace (LeadGrow)
Override via Brief Frontmatter
Add bison_standards_override: block to the brief to change max_total_sends, max_per_inbox_sends, sequence_length, or preset_name on a per-campaign basis.
Speaker Notes
Stage 9f verifies these settings after applying them — if there's a mismatch (Bison returned different values than what was set), the pipeline exits with code 6. Fix in the Bison UI and rerun.
Chapter 6
Visibility
Status
& Cost
6
Speaker Notes
The status command gives you per-stage token counts and USD cost at any point in the run. No need to wait until the end to know what you're spending.
16
Cost Visibility
Status tells you
exactly what you spent.
  • Run at any point — mid-pipeline or post-completion
  • Per-stage token counts (in + out) and USD cost
  • TOTAL row shows cumulative spend across all LLM stages
  • Cost tracking accumulates automatically on every LLM call
$ gtm-orchestrator status campaigns/q2-smb Stage Tokens In Tokens Out Cost USD ───────────────────────────────────────────── 03-qualify 48,230 2,140 $0.0212 06-segment 12,800 890 $0.0058 07-copy/seg-1 91,400 8,200 $0.0623 07-copy/seg-2 89,100 7,950 $0.0604 08-qa/rendered 6,200 480 $0.0028 ───────────────────────────────────────────── TOTAL 247,730 19,660 $0.1525
Speaker Notes
The full LIVE-01 dryrun cost $0.23 for 140 API calls and 214K tokens. A real run will vary based on list size and enrichments. Stage 7 (copy) is typically the biggest cost driver.
17
Model Routing
Right model for
the right job.
Task TypeModelWhy
Search / Tool-Use
news summary, website find, scrape, buying signals
gpt-4o-mini Cheap + fast for tool-augmented lookup
Classification / Distillation
ICP qualify, segment classify, semantic QA
gpt-4.1-mini Higher reasoning for judgment calls
Copy Writing
Braun, campaign-copywriting, personalization
claude-haiku-4-5 Anthropic voice quality at Haiku cost
Distillation fallback
Optional — when cost optimization needed
deepseek-* Optional provider — use when available
Speaker Notes
Model routing is defined in the prompt frontmatter (target_model field). The lg-llm-runtime routes automatically based on the model prefix — gpt-* goes to OpenAI, claude-* to Anthropic, deepseek-* to DeepSeek's OpenAI-compatible API.
18
Post-Launch
Scoring
Replies
After the campaign is live and replies come in, run score-replies to classify them and generate a retrospective.
  • Classifies replies into 9 categories (interested, not now, wrong person, OOO, etc.)
  • SHA-256 dedup — safe to re-run as more replies arrive
  • Writes outcomes.md with per-segment breakdown
  • Compares against 1% baseline to surface what's working
# Run after replies start coming in $ gtm-orchestrator score-replies \ clients/gtm-client-acme/campaigns/q2-smb # Output written to: stages/score-replies/outcomes.md # Contents: ## Reply Summary Total replies: 47 Interested: 12 (25.5%) ← 1% baseline = 1.0% Not Now: 18 (38.3%) Wrong Person: 8 (17.0%) OOO: 6 (12.8%) Unsubscribe: 3 (6.4%) ## By Segment owner-reachable: 31.2% interested ops-leader: 18.4% interested
Speaker Notes
score-replies is a standalone CLI command — not part of the main pipeline run. You can run it multiple times as more replies accumulate. The retrospective compares against a 1% interested-rate baseline to contextualize performance.
19
Gotchas
Things that will bite you
if you skip them.
  • 1
    Dry-run first, always. Validates the full pipeline including Bison wiring with synthetic IDs. Takes the same path but costs nothing on Bison. Skip it and you may discover a brief misconfiguration at Stage 9.
  • 2
    The brief is frozen. Stage 1 locks it. If you realize a segment is missing or an EDP is wrong, you have to start a new campaign. Plan the brief carefully before running.
  • 3
    Checkpoints are idempotent. You can partially fill a tiebreak CSV or checkpoint.json and resume — the pipeline won't re-process rows already resolved. Safe to iterate.
  • 4
    score-replies is post-launch only. It reads Bison reply data. Run it after the campaign has been live — not before.
  • 5
    Each segment = a separate Bison campaign. A 3-segment brief creates 3 Bison campaigns. Inbox selection and lead routing happen per campaign, not globally.
Speaker Notes
Point 2 trips people up most often. The brief immutability is intentional — it ensures the pipeline state always traces back to a single, auditable source. If you need to change the brief, it's a new campaign slug.
20
Quick Reference
Operator cheatsheet.
Commands
runStart or resume pipeline
run --dry-runSimulate without Bison sends
resumeContinue after checkpoint edit
statusToken counts + cost per stage
score-repliesClassify replies post-launch
Checkpoint Files
5stages/05-enrich/checkpoint.json
6stages/06-segment/tiebreak.csv
7stages/07-copy/selection.yaml
9cstages/09-launch/inbox_selection.yaml
9gstages/09-launch/launch_confirmation.yaml
0
Success
5
Edit → Resume
6
Fix Bison UI
7
List quality F
Speaker Notes
This is the page operators should keep open while running a campaign. All the checkpoint files are listed in order. Print or bookmark it.
LeadGrow GTM
Brief in.
Pipeline runs.
You approve.
Questions → hello@leadgrow.ai
Speaker Notes
The core promise: the operator's job is judgment, not plumbing. Write the brief, review the checkpoints, approve the launch. The pipeline handles everything in between.