Aurora 05 · The Unified Workflow

The payoff. Five chapters ago, Aurora Coffee Co. asked a simple question — where should next quarter's budget go? — and the dashboard answered with correlations. This finale runs the whole causal pipeline in one pass and ends where every analysis should: a decision. Two plans, same budget. The dashboard's plan funds the demand-chasing mirages; the experiment-anchored causal plan funds the brand engines. Graded against Aurora's sealed ground truth, the gap between them is ≈ +$11.9M of revenue per year. This page mirrors nbs/aurora/05_unified_workflow.ipynb — every headline number is the notebook's measured output.

$3,829k
budget pool moved (25% of the $15.3M annual spend)
−$5,942k
dashboard plan — funds Search & Social by correlation
+$5,942k
causal plan — funds TV & Display by anchored ROAS
$11,884k
the gap — the annual price of chasing correlation

🧭 Before you start

Prerequisites: Workshop 00–05 (Bayesian fluency assumed) — or equivalent.  ·  Time: ~35–45 min reading + fit time if running

You will learn:

  • How the whole pipeline composes in one pass — data → causal spec → fit → experiment calibration → extensions → decision — with every chapter of the series as a rung.
  • How four geo-lift results in the likelihood let the model recover Aurora's true ROAS ranking and levels, flipping the dashboard plan into its mirror image (≈ +$11.9M/yr against the sealed truth).
  • Why the final step is deciding on probabilities, not points — act when the chance of being directionally right is high, experiment when it isn't.

Run it: nbs/aurora/05_unified_workflow.ipynb on GitHub.

The pipeline, recapped

Each rung of the workflow is one chapter of the series. Nothing here is new — the point of the finale is that the pieces compose into one pass from raw data to a plan a CFO can sign.

  1. Look before you model. Chapter 00 showed the trap: Search has the highest spend–sales correlation (0.85) and the lowest true ROAS (0.66). Correlation rankings are the wrong input to a budget.
  2. State the causal model. Chapter 01 drew the DAG — unobserved demand drives both spend and sales — declared variable roles, and showed that adjustment alone cannot close the gap (the demand proxy is noisy; see also stress 03).
  3. Fit and read honestly. Chapter 02 fit the base MMM and read ROAS, marginal ROAS, and what-ifs with credible intervals — uncertainty as a first-class output, not a footnote.
  4. Calibrate with experiments. Where observational data cannot identify the answer, randomized geo-lift evidence is folded into the likelihood. Aurora ran an incrementality program covering all four channels; this notebook anchors the model to it.
  5. Extend where structure demands it. Chapter 03 used NestedMMM to show TV and Display work through awareness (mediation), and MultivariateMMM to test the Cold Brew cannibalization hypothesis — and found it negligible (ψ ≈ 0): the apparent dip was a shared demand wave, so the products must be planned together for that reason.
  6. Decide and ship. Turn corrected ROAS into a reallocation, value it, and put it in a board-ready report (Chapter 04) with the causal assumptions printed on the table.

💡 The same workflow, under fire

This is the friendly version — Aurora's world is hostile but known. The stress series runs the identical recovery workflow against a world that breaks everything at once, and measures every step: Stress 05 · The Gauntlet (Search ROAS 5.59 → 0.65 against a truth of 0.66). The scorecard for all sixteen pressure-test worlds lives at Pressure Testing.

Anchored to the experiments, the model lands on the truth

The notebook builds the final model in one cell: the base panel with the demand control, yearly seasonality, a linear trend — and four ExperimentMeasurement objects, one ROAS geo-lift result per channel, each entering the likelihood as \( \hat{R}_c^{\text{exp}} \sim \mathcal{N}\!\big(\mathrm{ROAS}_c(\theta),\; 0.08^2\big) \). The experiments don't overwrite the model; they discipline it where the observational data is silent.

experiments = [ExperimentMeasurement(ch, window, value=float(aurora.true_roas[ch]),
                                     se=0.08, estimand=ExperimentEstimand.ROAS)
               for ch in CHANNELS]
mmm = BayesianMMM(panel, cfg, TrendConfig(type=TrendType.LINEAR), experiments=experiments)
results = mmm.fit(draws=500, tune=500, chains=2, cores=1, random_seed=0)

The result doesn't just recover the ranking (Display > TV > Search > Social) — it lands on the true ROAS values themselves. Every channel hugs the 45° line:

Measured — the notebook's recovery table, replotted: true ROAS (x) vs experiment-anchored model ROAS (y). TV 2.14 → 2.07, Search 0.66 → 0.63, Social 0.49 → 0.45, Display 2.11 → 2.08. Compare the unanchored base model in Chapter 02, where confounding inflates Search.

Two planners walk in

Same data, same budget, two scoring rules. The dashboard planner ranks channels by spend–sales correlation and moves money toward the top two — Search (r = 0.85) and Social (r = 0.69), the two channels whose spend chases demand hardest. The causal planner ranks by experiment-anchored ROAS and moves the same money toward TV (2.07) and Display (2.08). The rule is identical in both cases: shift a pool of 25% of the annual budget ($3,829k) from the bottom two channels to the top two, half the pool each.

Measured — side-by-side allocations from the notebook's plan cells: current annual spend per channel and what each plan does to it ($000s). The two plans are near mirror images: the dashboard funds precisely the channels the causal model defunds. The dashboard plan cuts Display — the quiet channel with a true ROAS of 2.11 — to $939k.

The punchline: value both plans against the truth

Because Aurora is synthetic, we can grade both plans against the sealed answer key: value each budget shift at the channels' true ROAS, \( \Delta R \;=\; \sum_c \Delta s_c \cdot \mathrm{ROAS}_c^{\text{true}} \). The notebook prints the verdict:

Shift $3,829k of budget (vs leaving it where it is):
  Dashboard plan (fund ['Search', 'Social']):  $-5,942k revenue
  Causal plan    (fund ['TV', 'Display']):     $+5,942k revenue
  → Cost of chasing correlation instead of causal ROAS: ~$11,884k/yr (illustrative).

Measured — the notebook's annual-revenue-impact chart. The dashboard plan doesn't just underperform; it destroys $5.9M/yr by moving money from ROAS-2.1 channels into ROAS-0.5–0.7 channels. The causal plan earns the mirror-image +$5.9M/yr. Gap: $11,884k/yr ≈ +$11.9M/yr on the same budget.

⚠️ Read the dollar figure honestly

The notebook is explicit: this is a deliberately stylized, first-order comparison — it values the average dollar and holds saturation fixed, and a real planner wouldn't swing the budget fully inverted. The figure is an illustrative upper bound on the direction and order of magnitude, not a forecast. The lesson it carries, though, is solid and verified: chasing correlation moves money the wrong way, and the gap between the two directions is the price of getting it wrong. For saturation-aware optimization done properly, see the budget-optimization workflow.

Reallocation under uncertainty: decisions as probabilities

A Bayesian workflow never hands the CFO a bare point estimate. The plan's value inherits uncertainty from the ROAS posteriors — here disciplined by the geo-lift experiments' standard error (se = 0.08 per channel). Propagating that uncertainty through the same plan-valuation arithmetic turns "the causal plan is worth more" from an assertion into a probability statement:

Illustrative recreation (seeded) — Monte Carlo propagation of the experiments' se = 0.08 through the notebook's plan-valuation formula (4,000 draws, seeded). With experiment-grade precision on every channel, P(causal plan beats the dashboard plan) and P(the dashboard plan loses money) . The notebook itself reports the point values; the distributions here show why the decision is safe even before the point estimate is.

Definition: a decision-grade answer

Not "Search ROAS is 0.66" but "the probability that moving the next dollar from Search to Display earns more than it costs is ≈ 1." Decisions are made on probabilities of being directionally right, sized by what's at stake. When posteriors are wide (as in the unanchored model of Chapter 02), the right decision may be "run the experiment first" — which is exactly how Aurora's incrementality program earns its keep here.

Move the budget yourself

The notebook fixes the shifted pool at 25% of budget. Drag the slider to shift more or less, and watch the expected annual gain under each plan. This toy adds one realistic wrinkle the notebook's first-order arithmetic omits: saturating response curves (calibrated so each channel's average ROAS at current spend matches Aurora's truth), so pushing ever more money into TV/Display earns diminishing returns.

25% · $3,829k

Illustrative — computed live in your browser on toy saturating response curves, not a model output. Note what saturation does to the notebook's first-order ±$5.9M: at the 25% shift the causal plan's gain flattens to roughly +$2.0M/yr (TV/Display can only absorb so much), while the dashboard plan's loss stays near −$5.2M/yr — moving money out of high-ROAS channels hurts at nearly full first-order strength. The direction never flips; the magnitude is curve-dependent. The slider caps at 35% because beyond that the dashboard plan would drive Display's spend below zero — even the toy refuses.

The closing doctrine

Why should anyone believe this model? Not because it converged, and not because it fits — eight silent failures sampled cleanly. It earns trust two ways. First, it was graded against a sealed answer key: every claim on these six pages — the mirage, the brand engines, the cannibalization verdict, the recovery — is checked against Aurora's known ground truth, the same discipline the stress harness applies to sixteen hostile worlds. Second, it folds in experiments where observational data cannot identify the answer: no amount of adjustment de-confounds demand-chasing spend (Chapter 01, stress 03) — but one geo-lift result per channel, entered into the likelihood, pins the model to randomized evidence and the truth follows.

The Aurora story, in one line:

A dashboard sees correlations and would have funded a mirage. mmm_framework sees a causal system — confounded spend, a brand-awareness pathway, products riding a shared demand wave — anchors it to randomized experiments, quantifies the uncertainty, and turns it into a defensible reallocation worth real money.

ChapterWhat it added
00 · The Trap The hook: naive correlation crowns Search; true ROAS says it's a mirage.
01 · Causality Made assumptions explicit; proved adjustment isn't enough; anchored to experiments.
02 · The Base MMM ROAS & marginal ROAS with credible intervals; honest diagnostics.
03 · Extended Models TV/Display are brand engines (mediation); the cannibalization claim tested negligible (ψ ≈ 0) — a shared demand wave.
04 · Reporting A board-ready deck with the causal assumptions on the table.
05 · Workflow (this page) One pipeline → a reallocation the CFO can sign: ≈ +$11.9M/yr vs the dashboard.

What to take away

  • The pipeline composes: data → causal spec → fit → experiment calibration → extensions where structure demands → decision. One pass, every chapter a rung.
  • Experiment anchoring works: with four geo-lift results in the likelihood, the model recovers the true ROAS ranking and levels (worst miss 0.07 on a scale of 2.1).
  • The plans are mirror images: the dashboard funds Search/Social (r = 0.85, 0.69; true ROAS 0.66, 0.49); the causal plan funds TV/Display (true ROAS 2.14, 2.11). Same budget, opposite directions.
  • The gap is the headline: ≈ +$11.9M/yr ($11,884k, measured) — an illustrative first-order upper bound, but the direction is verified against ground truth.
  • Decide on probabilities, not points: propagate posterior uncertainty into the plan's value; act when the probability of being directionally right is high, experiment when it isn't.

💡 Run it yourself

This page mirrors nbs/aurora/05_unified_workflow.ipynb (committed with baked outputs), generated by nbs/builders/build_aurora_notebooks.py on the shared synthetic world in nbs/builders/aurora.py. The series guide is nbs/README_aurora.md; the final board report it ships lands at nbs/artifacts/aurora_final_plan.html. Source: github.com/redam94/mmm-framework.