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:
- Attribution fixes (tracking must be correct first)
- Negative keyword removals (unblock traffic before adding keywords)
- Active keyword additions
- Active keyword pauses / match type changes
- Negative keyword additions
- Ad copy changes
- Asset changes
- Bid modifier changes
- Bid strategy / budget changes (last, affects everything)
- 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