Skip to content

War Room Orchestrator

The orchestrator is the top-level Claude Code session that coordinates all 8 specialist agents. It runs daily on weekdays.

Execution Flow

Phase 1: Pre-fetch shared data (sequential, ~2 min)
  Orchestrator pulls data all agents need via GAQL

Phase 2: Foundation agents (parallel, no dependencies)
  [Attribution] [Bid Structure] [Offline Conversions]
  + also in parallel: [Ad Copy] [Assets] [Bid Adjustments]

Phase 3: Dependent agents (sequential, after Phase 2)
  [Active Keywords]    -- needs Bid Structure output
  [Negative Keywords]  -- needs Active Keywords output

Phase 4: Conflict resolution (sequential)
  Orchestrator cross-checks all manifests

Phase 5: Slack report + approval (async, human-gated)

Phase 6: Execute approved changes (sequential)

Phase 7: Log to SAIL Knowledge Base via Notion

Shared Data Pre-fetch

Before dispatching agents, the orchestrator pulls data that multiple agents need. This avoids redundant API calls and saves rate-limit quota.

GAQL Queries

-- campaign_performance_30d
SELECT campaign.id, campaign.name, campaign.status,
       campaign.bidding_strategy_type,
       campaign.target_cpa.target_cpa_micros,
       metrics.impressions, metrics.clicks, metrics.cost_micros,
       metrics.conversions, metrics.conversions_value,
       metrics.all_conversions, metrics.search_impression_share,
       metrics.search_budget_lost_impression_share,
       metrics.search_rank_lost_impression_share
FROM campaign
WHERE segments.date DURING LAST_30_DAYS
  AND campaign.status != 'REMOVED'

-- search_terms_30d
SELECT search_term_view.search_term, search_term_view.status,
       campaign.id, campaign.name,
       ad_group.id, ad_group.name,
       metrics.impressions, metrics.clicks, metrics.cost_micros,
       metrics.conversions, metrics.all_conversions
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS

-- all_keywords_with_metrics
SELECT ad_group_criterion.keyword.text,
       ad_group_criterion.keyword.match_type,
       ad_group_criterion.status,
       ad_group_criterion.quality_info.quality_score,
       campaign.id, ad_group.id,
       metrics.impressions, metrics.clicks, metrics.cost_micros,
       metrics.conversions, metrics.average_cpc
FROM keyword_view
WHERE segments.date DURING LAST_30_DAYS

-- all_negative_keywords
SELECT campaign_criterion.keyword.text,
       campaign_criterion.keyword.match_type,
       campaign_criterion.criterion_id,
       campaign.id, campaign.name
FROM campaign_criterion
WHERE campaign_criterion.type = 'KEYWORD'
  AND campaign_criterion.negative = TRUE

-- all_ads_with_metrics
SELECT ad_group_ad.ad.id, ad_group_ad.ad.type,
       ad_group_ad.ad.responsive_search_ad.headlines,
       ad_group_ad.ad.responsive_search_ad.descriptions,
       ad_group_ad.ad_strength,
       campaign.id, ad_group.id,
       metrics.impressions, metrics.clicks, metrics.cost_micros,
       metrics.conversions
FROM ad_group_ad
WHERE segments.date DURING LAST_30_DAYS
  AND ad_group_ad.status != 'REMOVED'

-- all_conversion_actions
SELECT conversion_action.id, conversion_action.name,
       conversion_action.type, conversion_action.status,
       conversion_action.category,
       conversion_action.primary_for_goal,
       conversion_action.attribution_model_settings.attribution_model,
       conversion_action.click_through_lookback_window_days,
       metrics.conversions, metrics.all_conversions
FROM conversion_action
WHERE segments.date DURING LAST_30_DAYS

-- device_location_schedule_segments
SELECT campaign.id, segments.device, segments.day_of_week,
       segments.hour,
       metrics.impressions, metrics.clicks, metrics.cost_micros,
       metrics.conversions
FROM campaign
WHERE segments.date DURING LAST_30_DAYS

Conflict Detection (Phase 4)

The orchestrator cross-checks all manifests before consolidating:

Agent A Agent B Conflict Type Resolution
Active Keywords Negative Keywords New keyword matches existing negative Flag both for review
Active Keywords Negative Keywords New negative matches existing keyword Flag both for review
Bid Structure Bid Adjustments Strategy change invalidates modifiers Defer Bid Adjustment changes
Ad Copy Assets Copy references sitelink Assets wants to remove Flag both for review
Attribution All Conversion data unreliable Add warning header to Slack report

Rule: if two agents contradict, flag both for human review rather than picking a winner.

Execution Order (Phase 6)

After approval, changes deploy in this order:

  1. Attribution fixes (tracking must be correct first)
  2. Negative keyword removals (unblock traffic before adding keywords)
  3. Active keyword additions
  4. Active keyword pauses / match type changes
  5. Negative keyword additions
  6. Ad copy changes
  7. Asset changes
  8. Bid modifier changes
  9. Bid strategy / budget changes (last, affects everything)
  10. Offline conversion uploads

Each mutation is wrapped in error handling with the rollback action from the manifest. If any fails, log it and continue with the rest.

Slack Approval Timeout

If Sam doesn't respond within 4 hours: - No "Needs Review" changes are applied - Auto-approved items that already executed stay (all are reversible) - A follow-up message: "War Room timed out. N items deferred to tomorrow." - Stale recommendations (>24 hours old) are re-analyzed before execution

Logging

Every War Room run creates a Notion entry in the SAIL Knowledge Base: - Type: Workflow - Project: Google Ads - Status: Complete (or Needs Follow-up if items were deferred) - Content: summary of what each agent found, what was approved, what deployed