---
name: investigate-performance-anomalies
description: >-
  A time-boxed, read-only root-cause investigation for an unexpected Google Ads performance change:
  confirm the move is real (volume, magnitude, persistence), rule out internal changes via
  gads_get_change_history, decompose the affected KPI down its component metrics with
  gads_run_gaql_query, isolate the one segment (device, geo, campaign, search terms) that explains
  it, then check competitive and tracking explanations before proposing a fix. Use it when a health
  check, alert, or stakeholder flags a specific metric jump or drop. Do not use it for scheduled
  reviews with no specific anomaly (run-a-daily-account-health-check or the weekly review), for
  known disapproval problems (resolve-ad-disapprovals), or right after a seasonal peak where query
  decay is the expected cause (run-post-peak-season-normalization).
---
# Root-Cause an Unexpected Performance Change

## Purpose
When a KPI moves and nobody knows why, the expensive failure modes are chasing noise, stopping at
the first correlated metric, or "fixing" a change that was intentional. This skill walks a strict
elimination order, is it real, did we cause it, which component metric broke, which segment
carries it, what external force remains, and produces a documented cause with a proposed
resolution. It makes no account changes itself; fixes route to the appropriate skill.

## When to run
- The daily health check or an automated alert flagged a spend, conversion, CPA, or delivery
  anomaly.
- A weekly review confirmed a trend that needs explanation before action.
- A stakeholder reports performance "suddenly looks wrong" on any account KPI.

## When NOT to run
- No specific anomaly exists, routine scanning is run-a-daily-account-health-check.
- The cause is already visible as disapproved ads, go directly to resolve-ad-disapprovals.
- A seasonal event just ended and the symptom is decaying seasonal traffic, run
  run-post-peak-season-normalization first.
- You want to change bids/budgets in response, this skill only diagnoses; execution belongs to
  the relevant bidding or budget skill.

## Prerequisites
- A concrete anomaly statement: which metric, which direction, roughly what magnitude, since when,
  and at what scope (account / campaign / ad group).
- Read access to the account via VigilDog.
- If conversions are involved: some reference for backend truth (CRM or analytics numbers the user
  can supply).

## Procedure
Time-box the whole investigation to about 60 minutes. If no cause survives scrutiny by then,
document what was eliminated and schedule a re-check with fresh data.

1. Confirm the anomaly is real. Use `gads_run_gaql_query` to pull the metric daily for the last
   4-8 weeks at the affected scope, and check three things: enough data volume to judge (not a
   3-click keyword), a move that exceeds the entity's normal week-to-week variance, and
   persistence across at least two consecutive periods. Sudden total failures (zero conversions,
   zero impressions) are exempt from the persistence test, treat those as breakage immediately.
   If the tests fail, stop and report "noise, no action", that is a valid outcome.
2. Classify the shape: hard breakage (binary, sudden), gradual erosion (multi-week drift), a spike
   (sudden cost/volume surge), or a step change to a new baseline. The shape constrains the cause:
   breakage is almost always tracking or policy; erosion is competition, fatigue, or slow internal
   drift; step changes follow discrete events.
3. Rule out self-inflicted causes. Call `gads_get_change_history` for a window starting ~7 days
   before the anomaly began, scoped to affected campaigns. Look specifically for: bid strategy or
   target edits, budget changes, keyword adds/pauses/match-type changes, ad edits, targeting
   changes, conversion-action modifications, and anything applied automatically rather than by a
   named user. A change that immediately precedes the anomaly and plausibly drives the metric is
   your prime suspect, confirm with the user whether it was intentional.
4. Decompose the metric. With `gads_run_gaql_query`, walk from the headline KPI down its
   components until you find the deepest metric that actually moved:
   - Value-based KPIs (ROAS/revenue): did conversion count move, or value per conversion?
   - CPA: did cost move, or conversions? Cost splits into clicks × CPC; conversions split into
     clicks × conversion rate.
   - Traffic: clicks split into impressions × CTR; impressions trace to budget caps, rank/quality,
     competitor pressure, or search-demand shifts (check impression-share-lost columns).
   The deepest moved metric, not the headline, is what you diagnose.
5. Localize it. Segment the root metric one dimension at a time:
   - `gads_get_device_performance` for device concentration.
   - `gads_get_geo_performance` for location concentration.
   - `gads_run_gaql_query` segmented by campaign, network, or day-of-week.
   - `gads_get_search_terms_report` to see whether new/unfamiliar queries started absorbing spend
     (typical after match-type loosening or automated expansion).
   Stop at the first single dimension that explains most of the movement. Do not cross three
   dimensions, tiny intersections always "explain" anything.
6. Check external forces. Pull `gads_get_auction_insights` for the affected campaigns and compare
   overlap, outranking, and impression share against the pre-anomaly period, a new or newly
   aggressive competitor shows up here. Compare against the same calendar period last year for
   seasonality. HUMAN STEP (outside VigilDog): market news, Google product/system updates, and
   industry events need a human's context.
7. If conversions moved while clicks and impressions did not, treat it as a tracking suspect:
   compare Google Ads conversions (by conversion time) against the user's backend numbers for the
   same window, and check whether an attribution or conversion-action change appears in the change
   history. HUMAN STEP (outside VigilDog): live tag testing on the site.
8. Conclude and route. Write up: the anomaly, its classification, what was eliminated, the root
   cause with evidence, and a confidence level. Propose the fix and hand off:
   - Unintentional internal change → revert via the owning skill (any revert is a write:
     preview first, apply only after user approval, guardrail consulted before the session's
     first write).
   - Tracking fault → set-up-google-ads-conversion-tracking territory; treat as same-day urgent.
   - Competitive squeeze → decide with analyze-auction-insights; do not reflexively chase rank.
   - Seasonal/external → usually adjust expectations, not settings.
   - Unknown → monitor one more period, then escalate.

## Decision rules
- Three gates before investigating: sufficient volume, beyond normal variance, persisted 2+
  periods (persistence waived for binary breakage). Fail any gate → declare noise.
- Change history before metric math, always, most anomalies are something someone did.
- Diagnose the deepest metric that moved, not the first correlated one: "CPC rose" is a symptom
  if quality or competition drove it.
- One segmentation dimension at a time; a segment must carry the bulk of the delta to count.
- Zero conversions with healthy traffic = tracking until proven otherwise.
- 60-minute cap; past it, additional staring produces conclusions, not evidence.

## Common failure modes
- Investigating normal variance because a stakeholder sounded alarmed, the three gates exist to
  protect you from this.
- Blaming the market before reading the change history; auto-applied recommendations and teammate
  edits cause a disproportionate share of "mysteries".
- Declaring victory on correlation ("CTR fell, so it's the ads") without walking down to why CTR
  fell (rank? new queries? competitor copy?).
- Fixing without documenting: the same anomaly reappears in three months and the investigation
  starts from zero. Keep the write-up.
- Overcorrecting external causes, bidding up into a competitor spike or a seasonal trough
  converts a temporary problem into a permanent cost increase.

## Related skills
- run-a-daily-account-health-check, the upstream triage that flags candidates for this skill.
- configure-account-alerts, automated detection that triggers this skill.
- resolve-ad-disapprovals, downstream fix when policy status is the cause.
- analyze-auction-insights, deeper competitive readout when step 6 implicates competitors.
- run-post-peak-season-normalization, downstream when the cause is post-event query decay.
