--- tags: - work - cpm - tech-design - pixel - web-extension updated: '2026-11-11' status: draft --- # TD: Pixel Definition: CPM Wake Init Detection (macOS/iOS + embedded web extension) **Author:** Alex M **Reviewer:** TBD **Stakeholders:** Michal, Konrad, Russell **Project:** [CPM: root-cause the stuck embedded extension messaging (macOS/iOS)](https://app.asana.com/1/137249556945/task/1216761517055116) ## Background & Requirements The extension's background is unloaded when idle and woken when a page needs it. Failures after such a wake are the largest group of CPM failures with no fix: on macOS 1.214 they are 39% of all failures (0.68% of DAU), on iOS 7.244 22% (0.06% of DAU). For one page, startup has these steps: the page script sends `init`; the background receives it; it reads the configuration; it reads the user setting from the app; it checks the site; it answers the page and sends the app a dashboard refresh. The app sees only the last step, so every failure looks the same: no answer. We need to find where startup stops, without changing what the extension does for the page and without collecting URLs or persistent identifiers. ## Problem Statement For every tab that the permanent breakage metric reports as silent, record the furthest startup step the extension reported. ## Recommended Approach 1. After each step the extension sends the app a short notification ([extension PR #3727](https://github.com/duckduckgo/duckduckgo-privacy-extension/pull/3727)). It does not wait for the app's reply. 2. For each tab the app remembers the furthest step reached. 3. When a tab is reported as silent, `web_extension_cpm_breakage` carries that step as a new parameter, `last_stage`: | `last_stage` | What the app saw last | |---|---| | `none` | no notification (the background may not have run at all) | | `page_init_sent` | the page script sent `init`, the background never processed it | | `received` | the background got `init`, the configuration or storage read did not finish | | `config_read` | the configuration was read, the user setting did not arrive | | `settings_checked` | the user setting arrived, the site check did not finish | | `site_checked` | all checks finished, no answer reached the app | | `response_sent` | the background finished sending the answer to the page, no dashboard refresh followed | | `response_failed` | sending the answer to the page failed | 4. These notifications and the parameter are temporary and are removed when the wake failures are fixed or the investigation is closed. ## Testing Unit tests in the app and in the extension. ## Additional Considerations (if applicable) 1. Privacy 1. New parameter `last_stage` on `web_extension_cpm_breakage`: one of eight fixed values.