Auto-rollback safety

Every change the agent makes captures a pre-execution snapshot before mutation. The agent then measures whether the change actually improved the campaign. If it made things worse, the change is automatically rolled back to the pre-execution state.

How it works

At execution time, the executor captures the relevant Google Ads state into pre_execution_state on the optimization session row. After mutation, measure-outcomes cron checks the campaign's metrics at fixed time windows relative to executed_at:

  • Surgical changes: T+24h and T+7d
  • Meaningful changes: T+24h, T+7d, and T+14d

Each window compares the post-change metrics against the pre-change baseline (sum of the 7 days before execution). Verdict is computed per window.

Measurement windows

The windows match Smart Bidding's settling curve. Bidding algorithms can produce noisy 24-hour data, so T+24h is a sanity check only. T+7d is where surgical changes settle. T+14d is where meaningful changes (bidding strategy switches, device bid modifiers) settle.

The user-level circuit breaker (3 auto-rollbacks in 30 days) only counts rollbacks from FINAL windows (T+7d for surgical, T+14d for meaningful). T+24h false positives never trip the breaker.

Verdicts

Three outcomes:

  • Improved. Metrics moved in the expected direction by more than the noise threshold. Recorded as a win in diagnostic_rule_outcomes.
  • Unchanged. Metrics moved within the noise band. Neither win nor loss. Recorded as neutral.
  • Worsened. Metrics dropped by more than the threshold. Auto-rollback fires.

Worsened thresholds vary by blast radius:

  • Surgical: 2-of-4 negative signals (cost up 25%, conversions down 20%, impressions down 40%, CPC up 35%). Small scale = more noise tolerance.
  • Meaningful: single strong negative signal (any of the 4 above). Larger scale = tighter threshold.

Rollback mechanics

When a worsened verdict triggers, measure-outcomes invokes agent-optimize with action="rollback". The rollback executor:

  1. Loads pre_execution_state from the session row.
  2. Constructs inverse operations (PAUSED → ENABLED, new bid → old bid, added negative → remove, etc.).
  3. Mutates Google Ads to restore the pre-change state.
  4. Marks the session rolled_back_at = NOW with a reason.
  5. Inserts a real-time notification: "Agent reverted [action] on [campaign] because metrics worsened in the [window]."
  6. Feeds the failure into diagnostic_rule_outcomes for fleet-wide rule learning.
Rollback is non-destructive on the Google Ads side. We never delete data that was not added by VibeAds. The original campaign state is what gets restored.

Manual undo

For changes that the agent thinks are fine but you disagree with, every executed session has an "Undo Changes" button in the Optimize tab. Available for 7 days (surgical) or 14 days (meaningful) after execution. Same rollback machinery, triggered by you instead of the cron.

Max users also get a one-click "Undo this change" link in the weekly digest email for every executed session.

Feeding fleet-wide learning

Every verdict (improved, unchanged, worsened) writes a row to the PII-free diagnostic_rule_outcomes table. Nightly, agent-aggregate refreshes a materialized view diagnostic_rule_success_rates grouped by (rule_action × category × tier).

This view drives the meaningful auto-execute gate: a rule needs over 80% success across at least 10 samples in your category before it can auto-fire at the meaningful blast radius. New rules start manual-only and graduate to auto as evidence accumulates.

Below 40% success in a category with 50+ samples, the rule is auto-downgraded fleet-wide to manual until it recovers.