Files
obsidian-vault/work/projects/cpm-pr0-episode-telemetry-summary-2026-10-16.md
T

122 lines
7.6 KiB
Markdown
Executable File

---
title: CPM PR0 — complete telemetry change
date: '2026-10-16'
tags:
- work
- cpm
- telemetry
---
# CPM PR0: one terminal report per failure episode
**Proposed change:**
Replace separate `init_failed`, `stuck`, `recovery[with/without reload]` and CPM post-reload-failure events with `web_extension_cpm_episode`. Each report contains the initial failure and its observed outcome, so diagnosis no longer requires joining separate failure, stuck and recovery events.
**When it fires:**
The first `4s` timeout **opens** an episode and captures one diagnostic snapshot.
The pixel is **submitted when the episode is closed** (a qualifying dashboard response or a 5-minute deadline closes).
Further failures or extension reloads are recorded in the same episode and included in its final report. If no qualifying response arrives, the report is sent 5min after the first failure, even if the user does not open or reload another page (with `outcome=no_response_before_deadline`). The existing rules for confirming a persistent failure and automatically reloading the extension stay the same.
A dashboard response tells us the extension answered the app. It does not confirm that the page received its initialization reply (`initResp`). For example, tab B may answer while the original failing tab A is still broken.
Deadline expiry does not prove permanent failure; unfinished episodes can be lost if the monitor or process is destroyed.
**Reporting frequency:**
Both platforms use `daily+count` (`.dailyAndCount`). The first completed episode each day sends `_daily` and `_count` with the same summary; every later completed episode sends `_count` only. Daily deduplication is by event name, across all outcomes. `_daily` estimates affected installations per day; `_count` counts completed episodes.
**Attribution:**
**Five added summary parameters:**
- `reason`: the first timeout's context — `session_restoration`, `tab_crash`, `extension_reload` or `other`. [Previously](https://app.asana.com/1/137249556945/project/481882893211075/task/1218619301158188?focus=true) encoded in failure pixel names.
- `was_stuck`: whether a later eligible non-restoration navigation, begun after the first failure, also timed out.
- `outcome`: `failed_measurement_response` for the measurement that timed out; `failed_tab_response` for a later measurement on a failing tab; `other_tab_response` for another tab; `unattributed_response` for an ambiguous current-document match; or `no_response_before_deadline`.
- `reload_state`: `none` (no reload observed), `pending` (replacement started), `failed` (replacement failed), `loaded` (replacement loaded), or `response_timed_out` (its first eligible messaging measurement timed out). Loaded alone does not prove messaging recovery.
- `response_after`: elapsed time since the first failure, bucketed as `under_30s`, `30s_to_1m` or `1m_to_deadline`. Omitted for the no-response outcome.
**Four added background-load parameters:**
Ported and adapted from `alex/cpm-messaging-readiness-telemetry`:
- `bg_ready_after` — whether background loading is pending, failed or complete. Values: `none` (no background view), `pending`, `failed`, or completion-time buckets `under_1s`, `1s_to_4s`, `4s_to_10s`, `10s_to_30s`, `over_30s`. Separates a background still starting from one already ready.
- `bg_view_age` — age of the current background view: `under_4s`, `4s_to_8s`, `8s_to_30s`, `30s_to_2m`, `over_2m`. Distinguishes a fresh wake from a failure long after view creation; omitted when no current view exists.
- `bg_load_error_after` — time from the affected view's creation to WebKit error 6: `under_5s`, `5s_to_25s`, `25s_to_35s`, `over_35s`. Tests whether the failure coincides with the 30-second background-load timer.
- `bg_load_error_app_state` — app state when that error occurred: `active`, `inactive` or `background` (macOS: active/inactive). Helps distinguish foreground failures from background suspension conditions.
These values are captured in the first-failure snapshot and sent in the same terminal episode report, retaining `daily+count`. Unavailable values are omitted. The two error fields describe only the first newly observed error 6 for the corresponding background-load attempt. Repeated error-list notifications preserve its original time and app state; a replacement view/context clears that attribution. Errors seen before any view was created do not qualify.
Readiness observation shares the existing `cpmBackgroundDelegateProxy` switch. It calls the public `loadBackgroundContent` API on the next main-queue turn after a new view is created. Disabling observation invalidates pending callbacks; reenabling on an existing view leaves readiness unknown until the next view creation. Error 6 also marks the observed load failed if WebKit never completes its load callback. Later readiness changes and errors do not replace the episode's first-failure snapshot.
The added fields' combined distinguishability with the retained `bg_events` still needs checking.
`app_state` and `open_tabs` remain deferred to targeted startup/no-view diagnostics; `loading_tabs` is not planned for this change. These additions do not change the four-second detector or add page-side `initResp` acknowledgement.
**Eight existing diagnostic booleans** from [✓ TD: CPM failure pixels attribution](https://app.asana.com/1/137249556945/project/481882893211075/task/1218619301158188?focus=true): all are captured at the first failure; unavailable facts are omitted.
- `context_loaded` — extension context loaded; `bg_view_alive` — current background view exists.
- `bg_process_alive` — its process is alive; `bg_process_responsive` — WebKit considers it responsive.
- `tab_in_context` — failing tab registered in WebKit; `handler_registered` — autoconsent native handler registered.
- `tab_controller_match` — tab and context controllers match; `tab_has_ext_scripts` — extension scripts remain registered.
`bg_events` is kept included, using the existing encoder: the latest 12 events at the first failure, oldest first, as sanitized `token@age` entries. Ages use `30s`, `1m`, `2m`, `5m`, `15m` and `over_15` buckets; older entries are dropped to keep the value within 255 characters. The timeline can contain error descriptors. Later failures and recovery do not replace or append to this snapshot.
Standard metadata remains: `appVersion` on both platforms, plus `pixelSource` and `channel` on macOS.
**Remove retired pixels from** [✓ TD: CPM failure pixels attribution](https://app.asana.com/1/137249556945/task/1218619301158188)**:**
- `debug_web_extension_cpm_initialization_failed_after_session_restoration`
- `debug_web_extension_cpm_initialization_failed_after_other`
- `debug_web_extension_cpm_initialization_failed_after_tab_crash`
- `debug_web_extension_cpm_initialization_failed_after_extension_reload`
- `debug_web_extension_cpm_messaging_stuck_session_restoration`
- `debug_web_extension_cpm_messaging_stuck_tab_crash`
- `debug_web_extension_cpm_messaging_stuck_extension_reload`
- `debug_web_extension_cpm_messaging_stuck_other`
- `debug_web_extension_cpm_messaging_recovered_without_extension_reload`
- `debug_web_extension_cpm_messaging_recovered_after_extension_reload`
- `debug_web_extension_cpm_messaging_extension_reload_failed`
**Parameters removed from transmission:**
`context_errors`, `network_restarted`, `critical_memory_age`, `bg_view_creations`, `bg_view_leaked_count`, `app_version_change`, `app_launch_age`, `background_graveyard_enabled` and `recovery_from`. Episode state and response attribution replace `recovery_from`. Graveyard attribution is also removed from the diagnostic model and monitor.