What we proved
Evidence from a full production compute chain — runtimes, artifacts, and the stakeholder moment where a 2.5-hour green run was mistaken for 'done.'
Part 1 was the problem. Part 2 was the design. This post is evidence — what I proved in production batch before asking the business to trust the full loop.
My bar for Layer C was explicit: one orchestrated job, all model families represented, every routine in the chain, every expected artifact written, a success marker, and a latest mirror — on real infrastructure, not a laptop.
One job, full chain, production batch
In mid-2026 we ran the complete HROAS compute chain in production batch for a live client configuration — national MMM, geo MMM, and brand-equity slots all resolved into a single standardized input, then executed sequentially:
Spend/effect summary → model overview → response curves → efficient frontier → marginal decision data.
The marginal-decision stage reads outputs from the spend/effect and response-curve stages — the chain is ordered, not embarrassingly parallel. One task row per client; one JSON contract in.
All routines merged; efficient frontier closed out June 2026.
Full-chain run, all model types — dominated by curve and frontier work.
CSVs, inputs manifest, success marker, and latest mirror written.
National, geo, and brand-equity slots in one run.
That run answered the question I cared about first: given a frozen, correct input, does the compute layer hold? Yes.
It did not answer whether Layer B's resolver is production-ready — that orchestration is still gated. I was careful not to conflate the two.
Where the time actually goes
Stage duration from the full-chain run — rounded, anonymized:
Response-curve generation and efficient-frontier optimization dominate. The frontier stage alone ran dozens of solver iterations. The lightweight summary routines are cheap — which is good, because they'll run every time. If you're optimizing wall clock, target curve and frontier; if you're optimizing trust, still run the cheap stages every time so the bundle is complete and comparable run to run.
Artifact volume followed the same story: weekly attribution rows numbered in the thousands; budget and marginal-decision tables in the hundreds per model family split. The run produced a bundle — not a single CSV — meant for different readers (planners vs economists vs frontend charts).
What the proof does not show
I want three limitations visible upfront — the way a good internal memo names them before a stakeholder does.
Runtime ≠ ROI.
A two-and-a-half-hour batch job proves the chain executes. It does not prove the business acted on the output, or that the output changed a budget decision. Wall clock is an operational metric, not a value metric.
One client configuration ≠ all edge cases.
Mixed regional scopes, sparse brand-equity history, feature-branch models mistakenly promoted — the resolver guards exist because these cases are real. E2E on a happy path is necessary, not sufficient.
Opacity is the industry default; audit is the countermeasure.
MMM vendors often hide model internals; stakeholders make high-stakes calls anyway. Our answer is not "trust the black box" — it is trace every HROAS output to the promoted model versions that fed it. Layer B's audit table is how we make that promise credible. Compute proof without audit proof is half a product.
(Update: the Layer D read-side — consolidated results endpoint and frontend cut-over onto the latest/ layout — shipped 2026-06-22, still separate from resolver readiness at the time of this post.)
Upstream models refresh monthly or bi-monthly — they should. HROAS between those refreshes used to be a manual stitch. Proving Layer C means: when models do change, recompute can be push-button instead of a half-day engineering task. That's the velocity win — not running HROAS daily.
What I got wrong: I communicated the technical bar clearly but not the product bar. After the 2.5-hour green run, a stakeholder asked when the self-serve button would ship. I had to walk back the room — compute proof is not resolver readiness, and I should have said that before anyone saw a duration number. Lesson learned: name what your metrics don't prove before the demo, not after.
Part 4 is the honest inventory: what's decided, what's still open, and which failure modes keep me up at night.
Hindsight
I'd publish a "what this run does not prove" memo alongside every E2E demo. Stakeholders anchor on wall clock — 2.5 hours reads as "done" even when Layer B is still gated. The sequencing was right; my comms timing wasn't. I'm also still deciding whether to parallelize curve and frontier stages — the runtime profile screams for it, but partial failure modes get uglier when stages share inputs.