# Executive review — Fusion Tables PPC measurement, reporting and decision system

**Date:** 2026-08-30 · **Branch reviewed:** `round-13-takeover` · **Scope:** review and planning only,
no fixes implemented · **Spend:** USD 0

---

## The verdict in one paragraph

The system you commissioned does not exist yet, and the part that does exist measures the wrong
thing. Of the eight tasks that were supposed to build it, one finished and seven did not — the run
died in silence on 2026-08-30 at 12:33 and nothing was watching. So the dashboard, both PPC
strategies, the client report, the owner action review and the targeting pack were never produced.
Separately, and more importantly, the measurement underneath them is not ready to answer your
question even once the dashboard is built: both ad platforms are optimising on a *form start* rather
than a submitted enquiry, the conversion action that represents a real enquiry points at a page that
returns 404, enquiries carry no source column so they cannot be traced back to any ad, the
dimensions you specifically asked to compare — creatives, placements, targeting, demographics — are
not collected at all, and a cached page has been serving one visitor's Google click ID to the next
visitor since July. **Recommendation: do not resume the stalled build. Fix five measurement defects
first, then build a much smaller dashboard directly.**

---

## Your five questions, answered

### 1. Is it logically correct?

**No, in one decisive place.** The chain from ad impression to enquiry is logically sound right up to
the last step, where it breaks completely: `crm.source_column` is `null`, so an enquiry cannot be
joined back to the campaign that produced it. Everything upstream is measured; the thing that matters
lands in a spreadsheet with no way home.

Two further logic defects compound it. The revenue axis is fabricated — `conversion_value` carries
the conversion *count* relabelled as forint (49.0 "huf" beside 49.0 "count"), which produces a ROAS
of 0.0005 that nothing currently prints but any new dashboard would pick up. And the five data
sources cover five different date windows: your ad platforms report 25 July to 23 August, the CRM
reports 26 July to 24 August, BigQuery reports 24 July to 22 August. A funnel whose last step is
measured over different days than its first step is not a funnel.

### 2. Is it measurable end to end?

**No. About 18% of the way.** Two and a half of fourteen funnel steps are both measured and
attributable. Impressions, clicks, link clicks, landing-page views and form starts are all real and
verified. Then it stops.

The single most consequential fact in this review: **46 of your 49 Google conversions are
`vhk_form_start`**, and Meta's entire result count is the same pixel event. The conversion action
that represents an actual enquiry, `Submit lead form`, is configured as a page-load trigger on
`https://fusiontables.hu/biliard/biliard` — which returns **404**. It is structurally incapable of
firing, which is why it reads zero while your own register shows 13 real enquiries. So Google's smart
bidding, which spends 100% of your Google budget through one Performance Max campaign, has spent the
last 30 days learning to buy people who *start* a form. Your cost per click fell from 64 Ft to 21 Ft
while spend tripled. That is not a win; that is cheaper traffic bought against a cheaper-to-trigger
event, at a signal roughly 3.8x inflated against your own record of 13 enquiries.

There is also a conversion action named **`Purchase`** pointed at a URL that returns **200**. It has
not fired yet. When it does, it will report purchases that did not happen.

### 3. Is it efficient?

**No — but the inefficiency is in the machinery, not the analysis.** The stalled build produced 4,010
lines across 59 files. About 3,500 of those are control documents; 716 are actual evidence. Five
separate files assert whether one task is running, and they disagree with each other. The 291-line
task launcher contains a block byte-identical to the platform launcher it replaced. Seven idle
worktrees hold **10.5 GB** for zero commits of work.

You asked for the 80/20 and said not to overengineer. The architecture put the three things you
actually named — the dashboard and the two strategies — at positions 3 through 8 of an eight-task
dependency chain, behind two tasks you never asked for. One stall at stage 1 delivered zero of three.

### 4. Is it understandable?

**The written report is. The dashboards are actively misleading.** `report.md` is genuinely good: it
states plainly that the 49 conversions are a platform signal and not verified enquiries or revenue,
it refuses to claim attribution, it excludes 7 QA test rows from the enquiry count, and it says which
sources were unavailable rather than printing zero. That discipline is the most valuable thing the
system currently has and it must survive whatever gets rebuilt.

The browser surfaces are the opposite. The Meta creative dashboard — the closest thing anyone has
built to what you asked for — shows *"Meta insights failed to load"* on arrival, and then **one click
on any column header replaces that with "No creatives match these filters — 0 of 0 rows."** The
software says it is broken; the screen says your account has no creatives. Four headline tiles read
`Loading` forever. A closeout page headed *"Complete and verified"* offers *"Open the final report"*
as its main link, and that file exists on no branch — while the same page states the report returned
HTTP 200 at 893,030 bytes. A council deck presents nine named expert opinions that are 198
byte-identical copies of the word `ABSTAIN`.

### 5. Is it useful for allocating budget?

**Not yet, and it would not have been even if the build had finished.** You asked to compare ad
copies, creatives, placements and targeting settings. **None of those dimensions exist in the data.**
There is no ad-group, ad, creative, asset-group, placement, device, audience or demographic breakdown
anywhere in the collected data; search terms and change events are empty arrays. The deepest available
grain is the campaign — and you have exactly one active Google campaign (Performance Max, which
withholds most of those dimensions by design) and one Meta campaign. Building the dashboard on
today's data would produce a page of one-row tables.

There is a second, quieter problem. Meta delivers roughly 825 clicks and 14 form starts a month
against 13 recorded enquiries. Splitting fourteen events across creative × placement × age × device
produces about a thousand cells. At that volume, detecting a genuine 30% difference between two
creatives takes **roughly 28 months**. A dashboard that ranks creatives on this data ranks noise, and
budget moved on that ranking is budget moved at random.

Concretely: your report's headline *"13 enquiries versus 7, +85.7%"* has a two-sided p-value of
**0.263**. It is not distinguishable from normal variation, and the report does not say so.

---

## What actually happened to the build

Eight tasks were planned. **T1 finished** and produced a genuine 716-line evidence corpus that is
intact and correct. **T2 ran for 18 minutes and died mid-turn**, leaving 313 lines of real audit work
uncommitted on disk — its own status file still says it never started. **T3 through T7 never
started.** The dashboard, strategy A, strategy B, the client report, the owner action review and the
targeting pack are all **UNAVAILABLE — never produced**.

Three things made that failure invisible and unrecoverable:

1. **The children were launched from a branch that did not contain their inputs.** Forty-one files —
   all of `ads-control/`, the Meta creative dashboard, the entire report package — exist on a
   different branch and never existed on the one the workers used. T1 survived only because it read
   files by their Git hash, which a dashboard build cannot do. The launcher validates eleven things
   about models, sessions and Git state and **nothing about whether the inputs are present**.
2. **Branch identity is asserted everywhere and verified nowhere.** The one dependency gate that ever
   passed cites a commit that exists only on a different branch than the one it claims. The content
   did arrive by another route, so nothing was lost — but the check that was supposed to catch this
   is the check that failed.
3. **Nothing was watching.** Every task record is stamped `"supervised": true`, but the supervisor is
   switched off by a flag file and no scheduled job ever runs it. Both processes died within 74
   seconds of each other with no error, no rate limit and no memory exhaustion, and the run's own
   status file still reads `ACTIVE` hours later.

---

## What to do — the short version

**Do not resume the stalled build.** Resuming it would rebuild the same dependency chain on top of
measurement that cannot answer your question.

**Five fixes, strictly in this order.** Order matters more than usual here, because doing them out of
order makes the account worse rather than better.

| # | Fix | Why it is at this position |
| --- | --- | --- |
| 1 | Fix the page cache so it stops serving a previous visitor's Google click ID | Adding a source column while the cache is poisoned writes *wrong* IDs instead of *no* IDs — a known gap becomes a confident error. Found and graded P0 on 2026-07-30, never fixed. |
| 2 | Repoint the enquiry conversion at a URL that exists; make it primary; demote the form start; retire the `Purchase` action | Until this is done, both platforms optimise on the wrong event and nothing downstream can be trusted. |
| 3 | Add `source`, `gclid_or_fbclid`, `landing_page` columns to the enquiry sheet | This is the single break that makes "where should the budget go" unanswerable. It is a spreadsheet change, not a software project. |
| 4 | Collect the dimensions you asked for: Meta creative/placement/age/gender, Google asset-group/search-theme/device | Meta reports all of these today. Without this the dashboard has nothing to put on its axes. |
| 5 | Only then build the dashboard — with a minimum-volume rule that refuses to show a rate for any segment below threshold | Prevents the dashboard from ranking noise, which is the most likely way it would cause a wrong allocation. |

**Then build the dashboard directly**, not through an eight-task delegation chain. A four-step Meta
funnel with last-30 versus preceding-30 is constructible **today, with zero new collection**:
impressions 63,461 → clicks 825 → link clicks 727 → landing-page views 626 → form starts 14, each
with its prior-period twin already present in the data. What is missing is the rendering, not the
measurement. That is a small piece of work, and it is worth doing before the collection changes land
so you can see the shape of the thing you are asking for.

---

## Three decisions only you can make

1. **The units question.** You asked for "the number of *people* reaching each funnel step." No source
   in this stack counts people — everything is events, clicks or sessions. The frozen build goal
   demanded verified people per step *and* forbade substituting events for people, which is why that
   task could never have passed. **Recommendation: label every axis in the units the data actually
   has and print the unit on the chart.** Your allocation decision does not need people; it needs
   consistent, honestly-labelled denominators. Confirm this and the contradiction disappears.
2. **The account structure.** One Performance Max campaign carrying 100% of Google spend, with four
   paused campaigns at zero, cannot support the comparison you want — PMax withholds most of those
   dimensions by design. Comparing creatives and targeting requires a structure built to be compared.
   That is the substance of the two strategies that were commissioned and never delivered.
3. **The KPC keyword system.** It currently returns "wait for evidence" on **61 of 61** rows, because
   it analyses keyword criteria on two paused Search campaigns while PMax carries all the spend.
   Either repoint it at PMax search themes and asset groups, or shelve it until Search is re-enabled.
   Worth knowing: its evidence ledger is the best data contract in the whole stack, and the pattern is
   worth copying into the main report pipeline regardless of what happens to the tool itself.

---

## What is already good and must not be lost

- **`report.md` refuses to overclaim.** It labels the 49 conversions as a platform signal, not
  verified enquiries and not revenue. It states the Meta result column is a form start. It excludes
  QA test rows. It reports unavailable sources as unavailable rather than as zero. This is the
  standard everything else should be raised to.
- **The T1 evidence corpus is genuine and intact** — 716 lines, verified byte-identical to its
  accepted form. Every failure in this review is in the machinery around it, not in it.
- **The KPC evidence ledger** — 1,524 fields, each with a state, a query hash and a reconciliation
  status — is a working implementation of exactly the discipline the main pipeline lacks.
- **The launcher verifies its model pins properly**, reading them back out of the runtime and failing
  on mismatch. The gap is inputs, not rigour.

---

## How much of what you asked for exists today

Of sixteen substantive things you asked for, **zero are delivered** by the commissioned system. Seven
are partly covered by artifacts that pre-date this run. Nine have no artifact at all. Your three
constraint requirements — do not claim unproven attribution, do not act on live accounts without
approval, do not overengineer — were honoured, though partly because seven of the eight tasks never
ran.

Nothing in this review changed any account, any campaign, any budget or any live page. No credentials
were read.
