# Consolidated findings

Deduplicated across all five review lanes and the orchestrator's own verification. Every finding was
independently re-checked by the orchestrator against the cited artifact before it was admitted here;
where a lane's claim did not survive that check, the corrected version is what appears below and the
correction is stated.

**Severity** = business impact + decision risk + recurrence, never cosmetic weight.
**Type** = defect · inefficiency · UX problem · measurement risk · simplification · out-of-scope idea.

| ID | Severity | Title | Type |
| --- | --- | --- | --- |
| F-01 | Critical | Both platforms optimise on a form start, not an enquiry | measurement risk / defect |
| F-02 | Critical | The `Submit lead form` conversion action points at a 404 | defect |
| F-03 | Critical | A forint-labelled revenue axis exists with no revenue behind it | defect |
| F-04 | Critical | Enquiries cannot be attributed to any traffic source | measurement risk |
| F-05 | Critical | The dimensions Matt asked to compare are never collected | measurement risk |
| F-06 | High | There is nothing to compare: one PMax campaign, one Meta campaign | measurement risk |
| F-07 | High | The comparison Matt wants cannot reach significance at this volume | measurement risk |
| F-08 | High | Children were launched from a branch missing all their inputs | defect |
| F-09 | High | The one dependency gate that passed cites a commit on the wrong branch | defect |
| F-10 | High | A stalled run reports itself as ACTIVE, and nothing was watching | defect |
| F-11 | High | T2's finished work is untracked on disk and its own state file denies it ran | defect |
| F-12 | High | Five source windows do not align, yet feed one funnel | defect |
| F-13 | Medium | Meta's period comparison passes at 11 delivery days out of 30 | defect |
| F-14 | Medium | The Meta creative dashboard is permanently broken as shipped | defect / UX problem |
| F-15 | Medium | The KPC system analyses a paused structure with zero traffic | inefficiency |
| F-16 | Medium | The KPC config ships TODO placeholders and a Mac-only credential path | defect |
| F-17 | Medium | 83% of the run's output is ceremony around 716 lines of evidence | simplification |
| F-18 | Medium | The delivery chain puts all three requested artifacts behind two enablers | simplification |
| F-19 | Low | Three commits share one subject line across three branches | defect |
| F-20 | Low | The report's headline enquiry improvement is not significant and is not caveated | UX problem |
| F-21 | Critical | A cached page serves a previous visitor's UTM and Google click ID | defect / measurement risk |
| F-22 | Critical | Three surfaces convert an honest failure into confident-looking emptiness | defect / UX problem |
| F-23 | High | A closeout page certifies HTTP 200 for a file that exists on no branch | defect |
| F-24 | High | The one creative comparison ever built shows no creatives and hides its decision control | UX problem |
| F-25 | High | "People per funnel step" is unsatisfiable, and the frozen goal contradicts itself about it | defect |
| F-26 | Medium | The closeout tiles omit cost and CPA and imply an attribution that cannot exist | UX problem |
| F-27 | Medium | The council deck renders 198 byte-identical placeholder cards | UX problem |
| F-28 | Medium | A real zero and a never-wired pipe are displayed identically | UX problem |
| F-29 | Medium | Three identical form instances share one page | defect |
| F-30 | Low | A live review URL serves a different client's asset pack | defect |

---

## F-01 · Both platforms optimise on a form start, not an enquiry
**Severity: Critical. Confidence: high. Type: measurement risk plus configuration defect.**
**Actor and flow:** Matt and the client; flows 5, 6, 10, and every budget decision downstream.

- **Expected:** ad platforms bid toward submitted enquiries so that spend moves to what produces
  business.
- **Actual:** of Google's 49 conversions in 2026-07-25..08-23, **46 are `vhk_form_start`** and 3 are
  `VHK_lead`; the other 18 configured actions read 0.0. Meta's Results column is the same event
  (`conversions:offsite_conversion.fb_pixel_custom.VHK_form_start`,
  `client.meta_ads.pixel_lead_event = "VHK_form_start"`). 100% of Google spend runs through one PMax
  campaign on smart bidding, so the bidding model is trained on the proxy.
- **Evidence:** `report_data.json` → `ppc.conversion_actions`, `meta_ads.actions`,
  `meta_ads.lead_generation.measurement_key`, `limitations[0]`. The client's own register records
  **13** enquiries against the platforms' 49 and 14.
- **Impact:** every optimisation the account has made in this window was steered by a signal that
  overstates results roughly 3.8x against the client's own record. Google CPC fell from 64 Ft to
  21 Ft while spend tripled — cheaper traffic bought against a cheaper-to-trigger event. This is the
  "optimised for cheap leads rather than qualified leads" failure in its literal form.
- **Smallest safe fix:** promote a verified submission event to primary and demote the form start to
  secondary, on both platforms. Diagnose why `VHK_lead` reads only 3.0 before switching (see F-02).
- **Dependencies:** F-02. **Owner:** measurement specialist. **Requires Matt's approval** — it is a
  live Ads change.
- **Decisive retest:** in the next 30-day window, Google primary conversions and the lead register
  agree within a stated tolerance, and the 49-versus-13 gap becomes a documented, explainable
  difference.

## F-02 · The `Submit lead form` conversion action points at a 404
**Severity: Critical. Confidence: high (live-verified). Type: defect.**

- **Expected:** the conversion action that represents a submitted enquiry fires when an enquiry is
  submitted.
- **Actual:** it is configured as a page-load action on
  `https://fusiontables.hu/biliard/biliard`. Orchestrator `curl -L` on 2026-08-30: **404**. The
  parent path `https://fusiontables.hu/biliard/` is also **404**. The action is structurally
  incapable of firing, which mechanically explains why it reads 0.0 while 13 real enquiries arrived,
  and why the account falls back to the form-start proxy.
- **Related:** `Purchase (Page load https://fusiontables.hu/billiardasztal/billiardasztal)` — that
  URL returns **200**. It is a live page-load trigger named "Purchase" that has not fired yet. It is
  the more dangerous of the two, because when it fires it will report purchases that did not happen.
- **Correction recorded:** Lane 5 reported both URLs as malformed. Re-tested: one 404s, one 200s.
  The distinction matters — one is dead, one is armed.
- **Smallest safe fix:** repoint the enquiry conversion at a real thank-you URL or a server-side
  event; retire or rename the `Purchase` action.
- **Owner:** measurement specialist. **Requires Matt's approval** (live Ads change).
- **Decisive retest:** a test submission increments the enquiry conversion action within its
  attribution window, and no enabled action has a page-load trigger with a transaction-shaped name.

## F-03 · A forint-labelled revenue axis exists with no revenue behind it
**Severity: Critical. Confidence: high. Type: defect.**

- **Actual:** `ppc.totals.conversion_value` = `{"current": 49.0, "previous": 1.0, "unit": "huf"}` —
  numerically identical to `ppc.totals.conversions` `{"current": 49.0, "previous": 1.0,
  "unit": "count"}`. Every conversion carries a default value of 1, relabelled as forint. The
  pipeline derives `roas` = 0.000532056… and `cpa` = 1,879.50 HUF from it. The same pair sits inside
  `ppc.campaigns` for the PMax campaign.
- **Impact:** the delivered `report.md` does not print ROAS, so nothing has misled a client yet.
  But the field is in the data envelope labelled `huf`, and the dashboard Matt asked for is exactly
  the surface that would pick it up. This is a trap set for the next builder.
- **Smallest safe fix:** set `conversion_value`, `roas` and every revenue-derived field to the `na`
  state the schema already supports.
- **Decisive retest:** no rendered surface can display a ROAS or revenue figure for this client; the
  field reads `UNAVAILABLE`, not `0` and not `49`.

## F-04 · Enquiries cannot be attributed to any traffic source
**Severity: Critical. Confidence: high. Type: measurement risk.**

- **Actual:** `crm.source_column` = `null`. `crm.no_source_column_note`: *"this spreadsheet has no
  source or campaign column, so enquiries cannot be attributed to a traffic source. The breakdown is
  by the form that recorded the enquiry."* The 13 enquiries cannot be joined to Google, to Meta, to a
  campaign or to a creative by any key.
- **Impact:** this is the single break that makes the whole measurement chain non-terminating. Every
  step from impression to form start is measured; the step that matters lands in a spreadsheet with
  no way back to the spend that produced it. No dashboard can repair this — a spreadsheet column can.
- **Smallest safe fix:** hidden `utm_*`, `gclid`, `fbclid` and `wbraid` fields on the form, written
  into four new sheet columns.
- **Decisive retest:** a test submission through a tagged ad URL lands with non-empty source,
  campaign and click ID; the next report attributes at least 80% of enquiries and states the
  unattributed remainder explicitly.

## F-05 · The dimensions Matt asked to compare are never collected
**Severity: Critical. Confidence: high. Type: measurement risk.**

- **Requested, verbatim:** *"how different ad copies / ad creatives / different placements /
  different targeting settings performed"* and *"instead of keywords, we will see the different
  creatives we are using and the targeting options."*
- **Actual:** `report_data.json` has no ad-group, ad, creative, asset-group, placement, device,
  audience or demographic dimension anywhere. `ppc.search_terms` = `[]`. `ppc.change_events` = `[]`.
  The deepest grain is campaign: 5 Google rows, 1 Meta row.
- **Impact:** this is a data-contract gap, not a dashboard gap. Building the dashboard first would
  render a page of one-row tables. It is the reason the T3 dashboard task could not have succeeded
  even if the run had not stalled.
- **Smallest safe fix:** extend collection to Meta adset/ad/creative with placement, age and gender
  breakdowns (Meta reports all of these), and to Google PMax asset-group, search-theme, device and
  geo (the subset PMax exposes).
- **Decisive retest:** a refreshed `report_data.json` carries non-empty creative-level Meta rows and
  asset-group-level Google rows whose totals reconcile to the already-verified account totals.

## F-06 · There is nothing to compare
**Severity: High. Confidence: high. Type: measurement risk.**

- **Actual:** `ppc.campaigns` — `2605-Fusion-Tables_Pmax` [PERFORMANCE_MAX/ENABLED] holds 4,410
  clicks, 92,095.56 Ft and 49 conversions; `2605-Fusion-Tables_Search`, `Keresési - KMO`,
  `Display - KMO` and `Remarketing` are all PAUSED at zero. Meta has exactly one campaign,
  `2505-fusion_tables_biliard_1_Lead`.
- **Impact:** one PMax campaign plus one Meta campaign is not a portfolio, and PMax withholds most of
  the dimensions Matt named by design. Even with F-05 fixed, the Google side of the comparison stays
  shallow.
- **Type note:** this is not a bug in anything built. It is a media-structure fact that determines
  whether the requested dashboard can ever answer the question. **Requires Matt's decision.**
- **Decisive retest:** none available until the account structure changes; this is the content of the
  two strategies that were commissioned and never produced.

## F-07 · The comparison cannot reach significance at this volume
**Severity: High. Confidence: high. Type: measurement risk.**

- **Actual:** Meta delivers about 825 clicks and 14 form starts a month; the register records 13
  enquiries. A creative x placement x age x device cross-tab produces on the order of a thousand
  cells for fourteen events. Lane 5 computes roughly 28 months to detect a +30% Meta creative
  difference at current volume.
- **Orchestrator-verified instance:** the report's headline *"Beérkezett érdeklődők 13 vs 7,
  +85,7%"* is **p = 0.263** two-sided on a binomial test over 20 events. The report presents it
  without a confidence caveat.
- **Impact:** a dashboard that ranks creatives or demographics at this volume will rank noise, and
  budget moved on that ranking is budget moved at random. This is the most likely way the finished
  system would have caused Matt to allocate incorrectly.
- **Smallest safe fix:** every segment row shows its denominator and conversion count; any row below
  a stated threshold renders "insufficient data" and cannot display a rate or a CPA.
- **Decisive retest:** a segment below the threshold is structurally unable to display a rate.

## F-08 · Children were launched from a branch missing all their inputs
**Severity: High. Confidence: high. Type: defect. (ORCH-CORR-1)**

- **Actual:** `git merge-base --is-ancestor 638e7524 round-13-takeover` → false. 41 files exist on
  `origin/codex/fusion-ppc-architecture-orchestrator` and never existed on `round-13-takeover`,
  including all of `ads-control/`, the Meta creative dashboard and the complete
  `2026-08-28-fusiontables-report/` package. All eight child worktrees were based on
  `round-13-takeover`.
- **Mechanism:** `launch_child.py` validates the title contract, worktree validity, prompt marker,
  tmux collision, Codex login, daemon, remote control, trust, branch-not-detached, the runtime
  model/effort pin and the task title/pin readback — and **nothing about inputs**. Ten ARCH
  acceptance rows check model pins, goal hashes, Git blobs and diff hygiene; none asks whether the
  input data is present.
- **Impact:** T1 survived only by reading 131 Git blobs from immutable commits on the other line.
  T3 (dashboard) and T5 (report) need data files present, not merely citable, and would have failed.
- **Smallest safe fix:** each child goal already lists its input paths; stat them in the worktree and
  refuse to launch on a miss.
- **Decisive retest:** launching a child whose goal cites `ads-control/config.yaml` from a
  `round-13-takeover` worktree exits non-zero naming the missing path.

## F-09 · The one dependency gate that passed cites a commit on the wrong branch
**Severity: High. Confidence: high. Type: defect. (ORCH-CORR-4)**

- **Expected, in the ledger's own words:** *"Only a parent-accepted child commit integrated into
  `round-13-takeover` can release its downstream task"* and *"`PASS` requires every cell in a
  transition row to cite an exact immutable receipt."*
- **Actual:** the T1→T2 row is `PASS`, citing `b1013882` as the integration receipt.
  `git branch -a --contains b1013882` returns only `codex/fusion-ppc-t2-audit`.
- **Not lost work:** the T1 content did reach `round-13-takeover` by a different commit (`4459dfe`),
  and `git diff 4459dfe b101388 -- …/artifacts/` is empty. The corpus is intact. What failed is the
  receipt, not the evidence.
- **Impact:** the only dependency transition the architecture ever completed was certified against a
  commit on the wrong branch, and nothing noticed, because branch membership is asserted everywhere
  and verified nowhere — the same root defect as F-08.
- **Smallest safe fix:** one `git branch --contains` assertion in the release path, and the same
  check as an acceptance row.
- **Decisive retest:** the check fails loudly for `b1013882` against `round-13-takeover` and passes
  for `4459dfe`.

## F-10 · A stalled run reports itself as ACTIVE, and nothing was watching
**Severity: High. Confidence: high. Type: defect.**

- **Actual:** the architecture `run-state.md` reads `Status: ACTIVE`, last updated
  2026-08-30T12:14:00Z, while `tmux ls` shows no architecture or child session. Both the T2 child and
  the architecture parent died **mid-turn within 74 seconds of each other** — T2's last event at
  12:32:31.773 and the parent's at 12:33:45.930, each an `AgentMessage` with `phase: "commentary"`
  describing what it would do next, then the rollout file simply ends. No error, no `turn_completed`,
  no rate limit, no context exhaustion. Unrelated Codex threads continued normally past 12:40.
- **Why it was silent:** `~/ops/.codex-direct-mode` disables the AI-supervisor layer and no
  `supervisor.sh tick` exists in crontab, while `launch_child.py:200` stamps `"supervised": true`
  into every child session record. Nothing polls the machine-readable state the children already
  write.
- **Impact:** seven of eight deliverables were never produced and no signal was raised for hours.
  Every downstream trigger depended on a parent process noticing, and the parent was the thing that
  died.
- **Smallest safe fix:** a heartbeat per child and one watcher that flips `run-state.md` to
  `STALLED` and posts a single Mission Control line when no heartbeat advances. `~/ops/status.sh`
  already exists for exactly this.
- **Decisive retest:** kill a child's tmux session; within N minutes `run-state.md` reads `STALLED`
  and Mission Control shows it.

## F-11 · T2's finished work is untracked on disk and its own state file denies it ran
**Severity: High. Confidence: high. Type: defect.**

- **Actual:** T2 ran for about 18 minutes, verified the goal hash, the corpus hash, all 11 artifact
  hashes and Git ancestry, completed six access scouts, and wrote four artifacts totalling **313
  lines** — `current-state-funnel-and-data-flow.md` (82), `event-conversion-taxonomy.md` (149),
  `fresh-evidence-register.md` (60), `edit-manifest.md` (22) — then died before committing. Verified:
  `git -C /home/matt/mirror/Fusion-ppc-children/t2 status --porcelain -uall` shows 2 modified and
  5 untracked.
- **The compounding defect:** `children/t2-measurement-audit/run-state.md` still reads
  `WAITING_DEPENDENCY` and `Started: PENDING`. The one file a recovering agent reads first is the
  one file that was never updated.
- **Correction recorded:** my own first ground-truth pass concluded "T2 produced no artifacts". That
  was true of git and false of the filesystem. Lane 3 caught it.
- **Smallest safe fix:** salvage the 313 lines before any relaunch decision; make the child write its
  own `run-state.md` on transition rather than leaving it to the parent.
- **Decisive retest:** the four artifacts are committed or archived, and a child's `run-state.md`
  reflects a start within seconds of it starting.

## F-12 · Five source windows do not align, yet feed one funnel
**Severity: High. Confidence: high. Type: defect.**

- **Actual:** `windows` — `google_ads` and `meta_ads` 2026-07-25..08-23; `bigquery`
  2026-07-**24**..08-**22**; `crm_sheet` 2026-07-**26**..08-**24**; `work_evidence`
  2026-06-23..08-23 (62 days, `previous: null`).
- **Impact:** the enquiry count that forms the funnel's last step is measured over a different 30
  days than the impressions and clicks above it. Matt's requested chart puts them on one x-axis. A
  funnel whose steps span different windows is not a funnel, and any step-to-step rate computed
  across them is wrong.
- **Smallest safe fix:** align the CRM window to the ad-platform window, or render each step's window
  and refuse to compute cross-step rates across mismatched windows.
- **Decisive retest:** every funnel step displays the same window, or no cross-step rate is computed.

## F-13 · Meta's period comparison passes at 11 delivery days out of 30
**Severity: Medium. Confidence: high. Type: defect.**

- **Actual:** `meta_ads.lead_generation.comparability` reports `comparable: true` while the previous
  window delivered on **11 of 30 days** (`ratio` 0.3667), because `min_delivery_day_ratio` is
  `0.3333`.
- **Impact:** Meta's headline period-over-period growth is partly an artifact of more delivery days,
  presented as performance improvement.
- **Smallest safe fix:** raise the threshold, and always show both delivery-day counts beside a
  change figure.
- **Decisive retest:** the 11-of-30 case renders with an explicit delivery-days caveat or is marked
  not comparable.

## F-14 · The Meta creative dashboard is permanently broken as shipped
**Severity: Medium. Confidence: high. Type: defect and UX problem.**

- **Actual:** `deliverables/fusion-meta-ads-review-2026-08-24/index.html:395` hardcodes
  `const SOURCE_ROOT = '/.tmp/overnight-2026-08-10/data/'` and fetches `meta_ads.json` and
  `meta_ad_insights.json` from it, plus creative images from `${SOURCE_ROOT}meta-creatives/`.
  `.tmp/` is gitignored; neither JSON exists in any commit.
- **Impact:** the one artifact that actually does creative-level comparison — the closest thing ever
  built to what Matt asked for — cannot be reopened by anyone, including Matt.
- **Smallest safe fix:** commit the two JSON files beside the page and make `SOURCE_ROOT` relative.
- **Decisive retest:** open from a clean clone over a local server; the creative table renders and
  the console shows no failed request.

## F-15 · The KPC system analyses a paused structure with zero traffic
**Severity: Medium. Confidence: high. Type: inefficiency. (ORCH-CORR-3)**

- **Actual:** `advice_output-20260824T111713-2aa95a23.json` places **61 of 61** criterion rows in
  `wait_for_evidence`, none approved and none flagged to investigate. `config.yaml` states the reason
  itself: both Search campaigns are paused with zero traffic in the window, and PMax — which carries
  100% of spend — has no keyword criteria and is excluded by design.
- **Credit where due:** the system correctly refuses to invent signal from zero, and it holds the
  only real data contract in the whole stack (a 1,524-row `field_ledger` with per-field
  `evidence_state`, `query_sha256` receipts and an exact reconciliation rule — everything
  `report_data.json` lacks).
- **Impact:** running it monthly against a paused structure produces 61 rows of "wait" and consumes a
  review cycle each time.
- **Smallest safe fix:** repoint it at PMax search themes and asset groups, or shelve it until Search
  is re-enabled. **Requires Matt's decision.**

## F-16 · The KPC config ships TODO placeholders and a Mac-only credential path
**Severity: Medium. Confidence: high. Type: defect.**

- **Actual:** `ads-control/config.yaml` → `conversion_tracking.call_tracking_live_from` = `'TODO: ISO
  date call-conversion tracking went live, e.g. 2026-07-11'`, `reliability` = `'TODO: full | partial
  | none'`, `note` = `'TODO: one paragraph on…'`. Also `monthly_spend_goal_ft: null` and
  `priority_registry.priority_clusters: []`. `credential_source` =
  `/Users/agency/.config/riport-30d/clients/fusiontables-ads-client.json`, a Mac-only path.
- **Impact:** the system cannot refresh from the devbox, which is where Matt explicitly asked the
  work to run (*"also create the new sessions on the ssh devbox cuz i have unstable internet here"*).
  The unfilled conversion-tracking block is the exact metadata that would have surfaced F-01.
- **Smallest safe fix:** fill the three fields, move the credential to a host-neutral location.

## F-17 · 83% of the run's output is ceremony
**Severity: Medium. Confidence: high. Type: simplification.**

- **Actual:** 4,010 lines across 59 files landed with no `CHANGELOG.md` or `PROJECT_STATE.md` entry.
  About 3,500 lines are control documents against 716 lines of actual evidence. Five separate
  documents assert whether T2 is running and disagree. `launch_child.py:41-53` is **byte-identical**
  to `~/ops/run-in-cloud.sh:260-272`; the 291-line launcher re-implements the platform launcher minus
  its Slack post. Seven idle worktrees hold **10.5 GB** for zero commits of work
  (`Fusion-ppc-children/` measures 14 GB total).
- **Against:** Matt's verbatim *"give me a more consice prompt. i need the 80/20. dont overengineer."*
- **Estimate:** −34 of 49 control files, −2,457 lines, −16 stale `~/ops` artifacts, −10.5 GB, roughly
  30 manual bookkeeping steps. **Evidence files removed: 0 of 12.**
- **Smallest safe fix:** one generated status table derived from `git branch --contains` and
  `tmux ls`, which cannot go stale; one goal file per child without the 502 duplicated preamble
  lines; `run-in-cloud.sh --no-slack` instead of a copied launcher.

## F-18 · The delivery chain puts all three requested artifacts behind two enablers
**Severity: Medium. Confidence: high. Type: simplification.**

- **Actual:** `goal-v1.md:44-51` places the dashboard, strategy A and strategy B — the three things
  Matt actually named — at chain positions 3 through 8, behind T1 (evidence corpus) and T2
  (measurement audit), neither of which he asked for. Eight tasks, seven dependency edges, five
  ledger documents each, to deliver three artifacts. One stall at stage 1 produced zero of three.
- **Smaller architecture with the same output:** three parallel children reading the
  already-committed report package, with the evidence corpus as optional enrichment rather than a
  gate. No dependency graph, no handoff ledger, no release protocol, no single point of failure.
- **Of 7 supervision points in the current design, 2 are worth keeping** (the parent's independent
  revalidation before acceptance, and the cherry-pick integration step) **and 5 are operational
  debt** — noticing a child finished, hand-copying four SHAs into a release message, noticing a child
  stopped, updating the child's own run-state, and evaluating the AND-joins, which are pure boolean
  predicates over facts already in files.

## F-19 · Three commits share one subject line across three branches
**Severity: Low. Confidence: high. Type: defect.**

- **Actual:** `638e752` (parent `310758d`, orchestrator branch), `ce93cef` (parent `f427516`,
  `round-13-takeover`) and `975e6c3` (pinned by `children/t1-evidence-corpus/run-state.md:20` as the
  accepted base) all read `plan: freeze Fusion PPC architecture delegation`. The frozen goal blob is
  byte-identical on all of them (`2421c9e`, SHA-256 `547b20a3f9…`).
- **Impact:** a reviewer reading `git log --oneline` cannot tell them apart, which is how the mission
  handoff came to name a fixed point that is not on the branch under review.
- **Smallest safe fix:** one freeze, one commit, cross-referenced; or distinct subjects naming the
  branch.

## F-20 · The headline enquiry improvement is not significant and is not caveated
**Severity: Low. Confidence: high. Type: UX problem.**

- **Actual:** `report.md` leads its enquiry section with *"Beérkezett érdeklődők 13 vs 7, +85,7%"*.
  Two-sided binomial over 20 events: **p = 0.263**. No confidence caveat appears.
- **Impact:** the client reads an 85.7% improvement as real. It is the one number in the report most
  likely to be quoted back, and it is noise-compatible.
- **Smallest safe fix:** print the absolute counts prominently and add one sentence stating that at
  this volume the change is not distinguishable from normal variation.
- **Note:** this is the only place the delivered report falls short of its own standard. Everywhere
  else it is scrupulous — see the credits section below.

---

## What the delivered work gets right

These are load-bearing and must survive any rebuild.

1. **`report.md` refuses to overclaim.** It states that the 49 conversions are *"platformon rögzített
   jelzés, nem igazolt érdeklődő és nem árbevétel"*, that Meta's result column is a form start that
   does not prove submission, that SEO and funnel figures are absent because GSC and GA4 are
   unavailable, and that none of the agent instructions were executed. It excludes 7 QA test rows
   from the enquiry count. It honours Matt's "do not claim attribution" and "missing is not zero"
   rules without being asked twice.
2. **The T1 corpus is genuine and intact.** 716 lines, 12 files, `git diff 4459dfe b101388` over the
   artifacts directory is empty. It marks leads, revenue and GA4 `UNAVAILABLE` rather than zero and
   refuses attribution. Every failure in this review is in the apparatus around it, not in it.
3. **The KPC evidence ledger is the best data contract in the stack** — 1,524 `field_ledger` rows
   with per-field `evidence_state` (`retrieved` 704, `verified_zero` 266, `not_applicable` 488,
   `unavailable` 3, `derived` 63), `query_sha256` receipts and an exact reconciliation status. The
   pattern to copy into `report_data.json` already exists in this repo.
4. **`launch_child.py` verifies its runtime pins properly** — it reads the model and reasoning effort
   back out of Codex's own SQLite and fails the launch on a mismatch, then re-reads the task title
   and pin state. It also ships a passing `--self-check`. The gap is inputs, not rigour.

## F-21 · A cached page serves a previous visitor's UTM and Google click ID
**Severity: Critical. Confidence: high (directly observed by the July auditors, re-read at source).**
**Type: defect plus measurement risk. Flow 2.2.**

- **Actual:** a clean, query-less `GET` of the production `/billiardasztal/` page returned a cache
  `HIT` whose **three CF7 form action URLs carried a previous advertising visitor's UTM parameters
  and Google click ID**. The same non-empty click ID persisted under `Cache-Control: no-cache`. A
  unique audit query produced a `MISS` whose form action contained only the audit query.
- **Evidence:** `deliverables/fusion-ppc-2026-07-30/evidence/tracking-audit.md`, section
  *"Cache és attribúciós kockázat"*. The auditors graded it **P0** themselves and stated the exact
  impact is unproven without a successful submission. It has not been fixed since 2026-07-30.
- **Impact:** an organic visitor can be stamped with a paid click ID. That corrupts attribution in
  the direction that flatters the ads. Worse, it poisons the one repair that would unlock revenue
  measurement: offline conversion import keyed on `gclid`. Uploading offline conversions before this
  is fixed would train Google's bidding on identifiers belonging to the wrong people.
- **Sequencing consequence:** fix F-21 → fix F-04 → add outcome fields → only then offline
  conversions. Any other order actively degrades the account.
- **Smallest safe fix:** exclude the ad-parameter query from the HTML cache key, or populate the
  click-ID fields client-side only.
- **Decisive retest:** re-run the exact three-request probe (clean `GET`, `no-cache` `GET`,
  unique-query `GET`) and assert no form action carries a foreign click ID.
- **Note:** nothing in any dashboard, report or ledger surfaces this. It was found once, written
  down once, and never entered the system's own view of itself.

## F-22 · Three surfaces convert an honest failure into confident-looking emptiness
**Severity: Critical. Confidence: high (two reproduced in-browser, one read at source).**
**Type: defect and UX problem.**

This is one pattern with three instances, which is why it is a single finding.

1. **Meta creative dashboard.** On load it correctly shows *"Meta insights failed to load"* (the
   `catch` at `index.html:519`). **One click on any sort header or the search box** re-renders the
   table body through `index.html:460` and replaces that message with
   *"No creatives match these filters."* and *"0 of 0 rows"*. Reproduced twice, byte-identical. The
   four hero KPI tiles (`total-spend`, `top-share`, `lead-total`, `coverage`, lines 255–270) read
   `Loading` forever, because the catch block never touches them. A user who touches any control
   sees a working dashboard reporting that this client has no creatives.
2. **KPC stage-3 template.** Its seven filters are all live, all functionally identical, and their
   empty state blames the operator — *"Clear search or choose another filter"* — when the actual
   condition is that no snapshot is loaded.
3. **Its test.** `test_dashboard.py` passes on a string match, so it stays green in exactly this
   state.
- **Impact:** the two most consequential failure modes in a measurement system are showing a wrong
  number and showing a confident zero. All three instances produce the second. "No creatives match"
  is a statement about this client's advertising; "failed to load" is a statement about the software.
  The code says the second and displays the first.
- **Smallest safe fix:** set a `loadFailed` flag in the catch, have every render path check it
  first, and blank the tiles to `—` rather than leaving them at `Loading`.
- **Decisive retest:** with the data source removed, click every sort header and type in the search
  box; the failure message survives every interaction and no tile reads `Loading`.

## F-23 · A closeout page certifies HTTP 200 for a file that exists on no branch
**Severity: High. Confidence: high. Type: defect.**

- **Actual:** `20260824T085117Z-fusion-kpc-report-recovery/index.html` is headed *"Complete and
  verified"*. Its primary call to action, *"Open the final report"* (line 94), targets
  `../../../ads-control/reports/stage-3-20260824T111713-2aa95a23.html`. Line 168 of the same page
  states: *"The final report returned HTTP 200 with 893,030 bytes. Playwright ran at 1280 by 900,
  device scale factor 1."*
- **Orchestrator verification:** `git log --all --diff-filter=A` for that path returns **nothing** —
  the file was never committed on any branch, and it is absent from the materialised orchestrator
  tree. Five of the page's six links resolve; the one the page exists to deliver does not.
- **It also certifies QA of export, review and recommendation controls that appear zero times** in
  the only KPC HTML the repository ships.
- **Impact:** the closeout artifact is the thing a reader trusts when they do not have time to check.
  Here it is the least reliable file in the set, and its unreliability is invisible without running
  the link.
- **Smallest safe fix:** the closeout generator resolves every link it emits and fails if one 404s.
- **Decisive retest:** every `href` on a page headed "verified" resolves from a clean clone.

## F-24 · The one creative comparison ever built shows no creatives and hides its decision control
**Severity: High. Confidence: high (fixture-driven; structural, not value-dependent).**
**Type: UX problem.**

- **Actual:** driven with a synthetic fixture so the success path could be seen at all, the Meta
  creative dashboard renders **20 of 20 creative thumbnails broken** — the image assets were never
  shipped, and any ad outside the hardcoded `assetMap` emits `<img src="">`. At 1280 px, the only two
  columns pushed off-screen are **Triage** and **My decision**.
- **Impact:** this artifact is the closest thing anyone has built to what Matt asked for. In its
  success state it shows no creatives, and it hides the control that turns looking into deciding.
  A creative comparison without visible creatives is a table of IDs.
- **Smallest safe fix:** ship the thumbnails beside the page (this is also F-14's fix), and pin the
  decision column left or make it sticky.
- **Decisive retest:** at 1280×900 with real data, 20 of 20 thumbnails render and both decision
  columns are reachable without horizontal scrolling.

## F-25 · "People per funnel step" is unsatisfiable, and the frozen goal contradicts itself about it
**Severity: High. Confidence: high. Type: defect in the specification.**

- **Matt asked for:** *"the number of people reached that funnel step in the last 30 days vs the
  preceding 30 days"* — people.
- **Actual:** every accepted source is event-grain, click-grain or session-grain. No source in the
  stack counts people. The frozen goal then contradicts itself: **T3-04 demands verified people per
  step while T3-03 forbids substituting events for persons.** Both rows are mandatory. No child could
  have satisfied both, and **nobody recorded the conflict** — it survived the freeze, the ARCH
  acceptance rows and the dependency ledger untouched.
- **Impact:** the centrepiece deliverable was specified as impossible before any child started. Had
  T3 run, it would have failed acceptance or quietly substituted events for people — which is
  precisely the false-precision failure the goal was written to prevent.
- **Smallest safe fix:** relabel every axis in units the data actually has (impressions, clicks,
  sessions, form starts, enquiries) and state the unit on the chart. Matt's decision does not need
  people; it needs consistent, honestly-labelled denominators.
- **Requires Matt's confirmation** that unit-labelled event counts answer his question.
- **Decisive retest:** no funnel step is labelled "people" unless a person-grain source exists.

## F-26 · The closeout tiles omit cost and CPA and imply an attribution that cannot exist
**Severity: Medium. Confidence: high. Type: UX problem.**

- **Actual:** every number on `20260828T232516Z-fusiontables-report-closeout/index.html` verifies
  exactly against `report_data.json` (4,410/452 clicks, 825/322, 13/7 enquiries, 6 recommendations).
  But the tile row shows **only clicks and enquiries** — no cost, no conversions, no CPA, no CPL —
  and places *"13 enquiries, up from 7"* directly beside the two channel click counts.
- **Impact:** juxtaposition is a claim. A reader takes the enquiries as coming from those clicks in
  that proportion. `crm.source_column` is `null`, so no enquiry can be attributed to Google or Meta
  at all (F-04). The page is accurate line by line and misleading as a layout.
- **Smallest safe fix:** add cost and CPA tiles, and put a one-line "enquiries cannot be attributed
  to a channel" note inside the tile group rather than further down the page.
- **Decisive retest:** no unattributed total sits adjacent to per-channel figures without an
  in-group caveat.

## F-27 · The council deck renders 198 byte-identical placeholder cards
**Severity: Medium. Confidence: high. Type: UX problem.**

- **Actual:** `deliverables/fusion-ppc-council-2026-07-31/public/deck.js:26-33` renders one feedback
  card per named expert in which **only the name is interpolated**. Every card body is the fixed
  string *"ABSTAIN, candidate snapshot, 0 active/queryable"* with *"tanácsi ellenőrzésre vár"* as the
  position. `deck.html` has 22 `<section>` slides; nine named experts per slide gives **198 identical
  cards**.
- **Impact:** the deck presents as nine expert perspectives (Hormozi, Imperium Meta, Sam Ovens Meta
  and others). It contains zero. The honest version of this page is one sentence.
- **Smallest safe fix:** render the card block only when real per-agent content exists; otherwise one
  line stating the council has not been run.

## F-28 · A real zero and a never-wired pipe are displayed identically
**Severity: Medium. Confidence: high. Type: UX problem.**

- **Actual:** four of the five CRM worksheets read 0/0 in both periods across 5,235 paid clicks. One
  of those is a form that exists and received nothing; the others are forms that were never wired.
  Nothing in the data or the presentation distinguishes them. The same ambiguity appears wherever
  `source_health` is `degraded` but a figure still renders.
- **Impact:** an operator cannot tell a channel that failed from a channel that was never connected,
  which is the difference between "fix it" and "ignore it". This is the same class as F-03 and F-22:
  the system's zeros do not carry their provenance.
- **Smallest safe fix:** adopt the KPC `evidence_state` vocabulary that already exists in this repo —
  `retrieved` / `verified_zero` / `not_applicable` / `unavailable` / `derived` — in
  `report_data.json` and every surface that reads it.
- **Decisive retest:** every zero on every surface can be traced to one of those five states.

## F-29 · Three identical form instances share one page
**Severity: Medium. Confidence: high. Type: defect.**

- **Actual:** `tracking-audit.md` records form ID `3154` present **three times** on the production
  landing page, each with the full hidden click-ID field set and an identical `landing_page` value.
- **Impact:** a duplicate-control smell and a duplicate-event risk. It is also the multiplier on
  F-21: three form actions, three copies of the foreign click ID. And it makes `vhk_form_start`
  (F-01) noisier still, since three instances can each emit a start.
- **Smallest safe fix:** one form instance per page, or three with distinct `form_location` values so
  the events are separable.
- **Decisive retest:** load the page and assert exactly one `#3154`, or three with distinct
  locations.

## F-30 · A live review URL serves a different client's asset pack
**Severity: Low. Confidence: high. Type: defect.**

- **Actual:** `https://b62a73b2.cf-review-9e5.pages.dev/assets-p12/` is reachable and serves a Bali
  holiday asset pack for a different client, with **0 Fusion mentions** and dead section navigation.
- **Impact:** low technically, non-trivial commercially — it is a live URL under the agency's review
  domain that shows one client's material at a path referenced from another client's work.
- **Smallest safe fix:** remove the reference, or repoint it.
