From 10166cbd8878e99cacc182828a5ee7163260107d Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Tue, 6 Oct 2026 11:03:53 +0600 Subject: [PATCH] [2026-10-06] eagle: work/projects/cpm-web-extension-breakage-validation.md work/projects/cpm-web-extension-public-attribution-2026-10-05.md --- .../cpm-web-extension-breakage-validation.md | 11 ++-- ...extension-public-attribution-2026-10-05.md | 54 ++++++++++--------- 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/work/projects/cpm-web-extension-breakage-validation.md b/work/projects/cpm-web-extension-breakage-validation.md index fbcaadf5..cbb7d68c 100755 --- a/work/projects/cpm-web-extension-breakage-validation.md +++ b/work/projects/cpm-web-extension-breakage-validation.md @@ -2,12 +2,13 @@ > **Актуальный отчёт за завершённый 5 октября 2026 UTC:** [[cpm-web-extension-public-attribution-2026-10-05]]. Он сверяет все `init failure.daily`, диагностические группы, соседние события, тренды до релиза и восстановление после stuck. Исторические internal-testing проверки и PR-план ниже сохранены как архив. -## Текущий статус +## Текущий статус — только после публикации release tag -- Основной сигнал: 6 624 iOS и 1 405 macOS `initialization.failed.after.*.daily`; эксклюзивные группы и контрольные суммы приведены в актуальном отчёте. -- Session restoration failure сохраняется: 952 iOS / 71 macOS за 5 октября. На iOS 604 имеют scripts absent + zero background views. Долю временно восстановившихся по этому reason без связывания событий посчитать нельзя. -- M4 reload после confirmed stuck даёт 916 iOS / 354 macOS `recovered.after.extension.reload.daily` от `messaging_stuck`; это подтверждает реальные успешные ответы после reload, но не success rate всех эпизодов. -- Старые версии не содержат controller/scripts attribution. По общему тренду после macOS M1 существенный эффект tab lifecycle не выделяется. +- Основной сигнал: 6 624 iOS и 1 377 macOS `initialization.failed.after.*.daily`; группы и контрольные суммы — в [[cpm-web-extension-public-attribution-2026-10-05]]. +- На macOS есть 77 `init failure.daily` и 35 `stuck.daily` с controller mismatch и отсутствующими scripts **после** публикации tag; **до** публикации таких строк нет. Пиксели не содержат channel, поэтому отдельное событие нельзя строго назвать public-user report. +- Session restoration failure сохраняется: 952 iOS / 68 macOS после tag. Долю временно восстановившихся по этому reason без связывания событий посчитать нельзя. +- M4 reload после confirmed stuck дал 916 iOS / 354 macOS `recovered.after.extension.reload.daily` от `messaging_stuck`; это успешные ответы, но не success rate всех эпизодов. +- До публикации macOS tag 5 октября было 28 init и 2 stuck; они вынесены в отдельный раздел отчёта вместе со ссылкой на более ранний internal-testing архив. ## Исторические проверки и планы diff --git a/work/projects/cpm-web-extension-public-attribution-2026-10-05.md b/work/projects/cpm-web-extension-public-attribution-2026-10-05.md index 1c7c5846..01e67c50 100755 --- a/work/projects/cpm-web-extension-public-attribution-2026-10-05.md +++ b/work/projects/cpm-web-extension-public-attribution-2026-10-05.md @@ -1,64 +1,68 @@ # CPM Web Extension: attribution и сравнение релизов — 5 октября 2026 -**Статус:** первый завершённый UTC-день с данными версий iOS 7.240.0 и macOS 1.210.0. Главный сигнал — `initialization.failed.after.*.daily`; `messaging.stuck.*.daily` проверен отдельно как более поздний, менее точный сигнал. Выгрузка сделана 6 октября из Grafana ClickHouse `metrics.pixels`, интервал `[2026-10-05 00:00, 2026-10-06 00:00) UTC`, `agent` и `appVersion` зафиксированы. [Dashboard](https://grafana.duckduckgo.com/d/dfon7whlilnggb/cpm-weird-error-investigation?orgId=1). +**Статус:** первый завершённый UTC-день с данными версий iOS 7.240.0 и macOS 1.210.0. Главный сигнал — `initialization.failed.after.*.daily`; `messaging.stuck.*.daily` проверен отдельно как более поздний, менее точный сигнал. Выгрузка сделана 6 октября из Grafana ClickHouse `metrics.pixels`, интервал `[2026-10-05 00:00, 2026-10-06 00:00) UTC`, `agent` и `appVersion` зафиксированы. **Основные таблицы ниже включают только события после публикации release tag каждой платформы**; отдельный раздел сохраняет всё попавшее в выгрузку до публикации. [Dashboard](https://grafana.duckduckgo.com/d/dfon7whlilnggb/cpm-weird-error-investigation?orgId=1). -**Вывод:** iOS session restoration по-прежнему даёт 952 первых сбоя, из них 604 со совпадающим контроллером вкладки, но без extension scripts и без созданного background view. По macOS таких первых сбоев 71, из них 12 с той же сигнатурой. Восстановление после reload наблюдается гораздо чаще, чем в предыдущих релизах; оно реально достигает успешного CPM-ответа, но долю успешных попыток эти пиксели не измеряют. Эффект исправлений tab lifecycle в совокупном тренде не выделяется. +**Вывод:** после публикации macOS tag есть **77** первых init failures и **35** stuck с несовпадающим controller вкладки и отсутствующими extension scripts; **до публикации таких строк нет**. iOS session restoration по-прежнему даёт 952 первых сбоя, из них 604 со совпадающим controller, но без scripts и background view; у macOS после публикации таких session-restoration сбоев 68, из них 12 с той же сигнатурой. Восстановление после reload наблюдается гораздо чаще, чем в предыдущих релизах; оно реально достигает успешного CPM-ответа, но долю успешных попыток эти пиксели не измеряют. Эффект исправлений tab lifecycle в совокупном тренде не выделяется. ## 1. Охват и контрольные суммы -| Независимые имена `.daily` пикселей | iOS 7.240 | macOS 1.210 | +| После release tag: независимые имена `.daily` пикселей | iOS 7.240 | macOS 1.210 | |---|---:|---:| -| Первое `initialization.failed.after.*` | **6 624** | **1 405** | -| Позднее `messaging.stuck.*` | 1 440 | 489 | -| Первый неудачный post-reload CPM probe | 670 | 234 | +| Первое `initialization.failed.after.*` | **6 624** | **1 377** | +| Позднее `messaging.stuck.*` | 1 440 | 487 | +| Первый неудачный post-reload CPM probe | 670 | 232 | | CPM ответ после reload, оба `recovery_from` | 963 = 916 stuck + 47 init | 362 = 354 stuck + 8 init | -| CPM ответ без reload, `initialization_failed` | 1 555 | 353 | -| **Сумма записей CPM daily по именам пикселей** | **11 252** | **2 843** | +| CPM ответ без reload, `initialization_failed` | 1 555 | 346 | +| **Сумма записей CPM daily по именам пикселей** | **11 252** | **2 804** | -Контроль: первичные события `6 624 + 1 405 = 8 029` строк в `initialization_daily.tsv`; вторичные `1 440 + 489 = 1 929` строк в `events_daily.tsv`. Суммы всех CPM daily `11 252 + 2 843 = 14 095` совпадают между `inventory.tsv` и независимым `release_cpm_daily_trends.tsv` **по каждому имени пикселя**. Включать `debug.web.extension.reload.failed.daily` в эту сумму нельзя: это отдельное семейство операций Web Extensions. Внутри CPM `initialization.failed.after.extension.reload.daily` и `messaging.extension.reload.failed.daily` обычно посылаются вместе на одной неудачной post-reload проверке: их суммы не обозначают разные эпизоды. `.daily` ограничен одним событием **на имя пикселя** за UTC-день на установку; разные имена могут относиться к одному пользователю и эпизоду. Переход версии внутри дня тоже меняет наблюдаемые суммы. Здесь нет числа уникальных пользователей, DAU той же версии и идентификатора для связывания событий. +Контроль после release tag: `6 624 + 1 377 = 8 001` первичных строк; `1 440 + 487 = 1 927` вторичных строк; `11 252 + 2 804 = 14 056` CPM daily записей по именам пикселей. До tag есть ещё 28 init, 2 stuck и 39 CPM daily записей, все на macOS; полные файлы поэтому содержат `8 029` init, `1 929` stuck и `14 095` CPM daily. Разделение по времени и pixel name воспроизводит `release_cutover_daily.tsv`, полный день сходится с `inventory.tsv` и `release_cpm_daily_trends.tsv`. Включать `debug.web.extension.reload.failed.daily` в сумму CPM нельзя: это отдельное семейство операций Web Extensions. Внутри CPM `initialization.failed.after.extension.reload.daily` и `messaging.extension.reload.failed.daily` обычно посылаются вместе на одной неудачной post-reload проверке: их суммы не обозначают разные эпизоды. `.daily` ограничен одним событием **на имя пикселя** за UTC-день на установку; разные имена могут относиться к одному пользователю и эпизоду. Переход версии внутри дня тоже меняет наблюдаемые суммы. Здесь нет числа уникальных пользователей, DAU той же версии и идентификатора для связывания событий. -Публикация release tag состоялась 5 октября в 15:18 UTC для [iOS 7.240](https://github.com/duckduckgo/apple-browsers/releases/tag/7.240.0%2Bios) и 09:46 UTC для [macOS 1.210](https://github.com/duckduckgo/apple-browsers/releases/tag/1.210.0%2Bmacos). Все 6 624/1 440 iOS атрибутированных init/stuck пришли после iOS tag; у macOS 28/1 405 init и 2/489 stuck пришли до macOS tag. Пиксель не содержит канала распространения, поэтому оставшиеся записи нельзя строго отделить от internal testing. +Публикация release tag состоялась 5 октября в 15:18 UTC для [iOS 7.240](https://github.com/duckduckgo/apple-browsers/releases/tag/7.240.0%2Bios) и 09:46 UTC для [macOS 1.210](https://github.com/duckduckgo/apple-browsers/releases/tag/1.210.0%2Bmacos). Время после tag — доступная граница, **не доказательство public-канала у каждого отправителя**: пиксель не содержит channel/rollout cohort, и internal testing могло продолжаться после публикации. + +### До публикации release tag: отдельный срез + +В пределах выгрузки за 5 октября до публикации iOS tag нет CPM daily событий версии 7.240. До публикации macOS tag у версии 1.210 есть **28 init failure.daily, 2 stuck.daily, 2 post-reload failed.daily, 7 recovered.without.reload.daily, 0 recovered.after.reload.daily** — всего **39 CPM daily**. В этих 28 init: 12 native snapshot без видимой ошибки, 7 background state, 5 только context error history, 3 tab attachment/injection (2 без scripts/zero views и 1 tab-not-in-context), 1 с неполными tab facts. В двух stuck нет отсутствующих scripts или controller mismatch. `debug.web.extension.reload.failed.daily` до tag нет. Более ранние internal-testing данные 28 сентября – 4 октября сохранены в [[cpm-web-extension-breakage-validation]] как архив и **не смешиваются** с таблицами после публикации. ## 2. Первичный сигнал: группы и события рядом с `init failure.daily` Каждая строка попадает ровно в одну диагностическую группу по приоритету: tab scripts/controller → явные признаки background → история ошибок → неполные поля → видимо исправный native snapshot. Это **классификация снимка**, а не доказательство первопричины. Полные пересекающиеся признаки сохранены отдельно. -| Диагностическая группа | iOS init, из 6 624 | macOS init, из 1 405 | iOS stuck, из 1 440 | macOS stuck, из 489 | +| После release tag: диагностическая группа | iOS init, из 6 624 | macOS init, из 1 377 | iOS stuck, из 1 440 | macOS stuck, из 487 | |---|---:|---:|---:|---:| -| Native snapshot без видимой ошибки | 3 717 (56,1%) | 923 (65,7%) | 789 (54,8%) | 336 (68,7%) | -| Tab attachment / injection | 931 (14,1%) | 119 (8,5%) | 53 (3,7%) | 38 (7,8%) | -| Background state | 768 (11,6%) | 165 (11,7%) | 457 (31,7%) | 35 (7,2%) | -| Только история ошибок context | 343 (5,2%) | 163 (11,6%) | 87 (6,0%) | 80 (16,4%) | -| Недостаточно tab facts | 865 (13,1%) | 35 (2,5%) | 54 (3,8%) | 0 | +| Native snapshot без видимой ошибки | 3 717 (56,1%) | 911 (66,2%) | 789 (54,8%) | 335 (68,8%) | +| Tab attachment / injection | 931 (14,1%) | 116 (8,4%) | 53 (3,7%) | 38 (7,8%) | +| Background state | 768 (11,6%) | 158 (11,5%) | 457 (31,7%) | 35 (7,2%) | +| Только история ошибок context | 343 (5,2%) | 158 (11,5%) | 87 (6,0%) | 79 (16,2%) | +| Недостаточно tab facts | 865 (13,1%) | 34 (2,5%) | 54 (3,8%) | 0 | -Контроль групп: iOS init `3717+931+768+343+865=6624`; macOS init `923+119+165+163+35=1405`; iOS stuck `789+53+457+87+54=1440`; macOS stuck `336+38+35+80=489`. Контроль причин первого сбоя: iOS `other 4803 + session.restoration 952 + extension.reload 670 + tab.crash 199 = 6624`; macOS `1073+71+234+27=1405`. Это `reason` навигации/эпизода, **не причина поломки**. +Контроль групп после tag: iOS init `3717+931+768+343+865=6624`; macOS init `911+116+158+158+34=1377`; iOS stuck `789+53+457+87+54=1440`; macOS stuck `335+38+35+79=487`. Контроль причин первого сбоя: iOS `other 4803 + session.restoration 952 + extension.reload 670 + tab.crash 199 = 6624`; macOS `1050+68+232+27=1377`. Это `reason` навигации/эпизода, **не причина поломки**. **Окружающие события по главным цепочкам:** 1. **iOS session restoration, 952.** У 604 (63,4%) `tab_controller_match=true`, scripts отсутствуют, `bg_view_creations=0`; у 607 хвост `bg_events` содержит только `load`, ещё у 283 — `load → view → proxy_on`. 754 первых сбоя попали в bucket первых 30 секунд запуска. Код ожидает начальный `loadAndSync` и загрузку background content перед первой HTTP(S)-навигацией restored tab, но общий дедлайн ожидания — 5 секунд; неоконченная загрузка и более позднее внедрение script всё ещё способны дать временный timeout. 260 снимков уже выглядят исправно и требуют timings сообщения, а не ещё одного снимка состояния. 2. **iOS `other`, 4 803.** 2 921 выглядят исправно; 831 имеют неполные tab facts; 334 содержат background load error code 6; 239 — scripts отсутствуют при нулевом числе background views. Частые хвосты `load → view → proxy_on` (1 450) и `load → view → proxy_on → dealloc → view → proxy_on` (934). `dealloc` фиксирует освобождение background view, не падение процесса; только 85 первичных iOS строк имеют явный `died_*` в доступном хвосте. -3. **Повторная проверка после extension reload, iOS 670 / macOS 234.** Это именно первый CPM init timeout после reload, вместе с `messaging.extension.reload.failed.daily`. Типичный хвост iOS `load → base_url_changed → view → proxy_on` (483); macOS `load → base_url_changed → view → proxy_on → dealloc → view → proxy_on` (87). `base_url_changed` здесь совпадает с reload и сам по себе не доказывает ошибку URL. Native snapshot уже выглядит исправно у 470 iOS / 126 macOS; причина отсутствия ответа там не локализована. -4. **macOS `other`, 1 073.** 722 выглядят исправно, 138 не имеют живого background view, 115 имеют только историческую context error, 47 — неверный controller без scripts. За все причины init неверный controller без scripts есть у 77/1 405; в stuck — у 35/489. App update сам по себе не сохраняет старый `WKWebView`; эти строки не доказывают сценарий «вкладка осталась у старого контроллера после обновления». Требуется событие смены manager/controller при живой вкладке. +3. **Повторная проверка после extension reload, iOS 670 / macOS 232.** Это именно первый CPM init timeout после reload, вместе с `messaging.extension.reload.failed.daily`. Типичный хвост iOS `load → base_url_changed → view → proxy_on` (483); macOS `load → base_url_changed → view → proxy_on → dealloc → view → proxy_on` (87). `base_url_changed` здесь совпадает с reload и сам по себе не доказывает ошибку URL. Native snapshot уже выглядит исправно у 470 iOS / 125 macOS; причина отсутствия ответа там не локализована. +4. **macOS `other`, 1 050.** 713 выглядят исправно, 132 не имеют живого background view, 110 имеют только историческую context error, 47 — неверный controller без scripts. За все причины init неверный controller без scripts есть у **77/1 377 после tag и 0/28 до tag**; в stuck — **35/487 после tag и 0/2 до tag**. Init-сигнатура встречается с 10:34 до 23:21 UTC, а не только сразу после публикации в 09:46. Из 77 после tag 45 имеют `app_version_change=updated`. App update сам по себе не сохраняет старый `WKWebView`; эти строки не доказывают сценарий «вкладка осталась у старого контроллера после обновления». Требуется событие смены manager/controller при живой вкладке. 5. **iOS `tab.crash`, 199.** 47 имеют code 6, 37 — явную смерть background процесса, 35 — scripts отсутствуют и background view не создан. Название reason означает навигацию после crash вкладки, а не установленную смерть CPM worker. Вторичный stuck сдвигает iOS-картину: background state 768/6 624 (11,6%) на первом сбое против 457/1 440 (31,7%) на stuck; no-scripts/zero-view 917/6 624 против 52/1 440. Это согласуется с временными startup misses и более устойчивой background-проблемой, **но это не переходная вероятность**: имена `.daily` считаются независимо. У iOS code 6 находится в 364 stuck снимках (в 363 `dealloc` раньше первой ошибки); WebKit регистрирует code 6 как `BackgroundContentFailedToLoad` после неудачной загрузки service worker. Причина отказа регистрации из пикселя неизвестна. Хвост `bg_events` ограничен 12 событиями и может обрезать старые события. «Native snapshot без видимой ошибки» означает, что текущих полей недостаточно для локализации content script → worker → native → page ответа, а не что пользовательского сбоя не было. ## 3. Session restoration: ушли ли временные сбои? -**Нет.** В новых версиях есть 952 iOS и 71 macOS первых `session.restoration` failures. Соответствующий поздний `stuck.session.restoration.daily` встречается 118 / 8 раз, но без связи событий нельзя сказать, какие именно первые сбои восстановились. `recovered.without.extension.reload.daily` (1 555 iOS / 353 macOS) не содержит `reason`, поэтому доля временных session-restoration эпизодов также неизвестна. +**Нет.** После release tag есть 952 iOS и 68 macOS первых `session.restoration` failures. Соответствующий поздний `stuck.session.restoration.daily` встречается 118 / 8 раз, но без связи событий нельзя сказать, какие именно первые сбои восстановились. `recovered.without.extension.reload.daily` (1 555 iOS / 346 macOS) не содержит `reason`, поэтому доля временных session-restoration эпизодов также неизвестна. -Сравнение по имени пикселя на одинаковых пятидневных окнах после предыдущих release tags: iOS 7.238 (23–27 сентября) — 3 372 386 session restoration из 5 821 858 init daily (57,9%); iOS 7.239 (30 сентября – 4 октября) — 3 014 131 из 5 390 550 (55,9%). У iOS 7.240 за **первый неполный день** — 952 из 6 624 (14,4%). Это сильное изменение состава сигналов, совместимое с readiness gate, вошедшим в 7.240, но не оценка снижения риска на пользователя: новая версия имеет иной ранний cohort и нет DAU. macOS 1.208 (23–27 сентября) — 4 531/76 336 (5,94%); 1.209 (30 сентября – 4 октября) — 7 425/114 075 (6,51%); 1.210 за первый день — 71/1 405 (5,05%). На macOS явного снижения по этому proxy пока нет. Gate входит в macOS 1.210 / iOS 7.240 и по умолчанию включён, но фактическое состояние remote flag у отправителей не передано. +Сравнение по имени пикселя на одинаковых пятидневных окнах после предыдущих release tags: iOS 7.238 (23–27 сентября) — 3 372 386 session restoration из 5 821 858 init daily (57,9%); iOS 7.239 (30 сентября – 4 октября) — 3 014 131 из 5 390 550 (55,9%). У iOS 7.240 за **первый неполный день** — 952 из 6 624 (14,4%). Это сильное изменение состава сигналов, совместимое с readiness gate, вошедшим в 7.240, но не оценка снижения риска на пользователя: новая версия имеет иной ранний cohort и нет DAU. macOS 1.208 (23–27 сентября) — 4 531/76 336 (5,94%); 1.209 (30 сентября – 4 октября) — 7 425/114 075 (6,51%); 1.210 после публикации — 68/1 377 (4,94%). На macOS явного снижения по этому proxy пока нет. Gate входит в macOS 1.210 / iOS 7.240 и по умолчанию включён, но фактическое состояние remote flag у отправителей не передано. ## 4. Исправления tab lifecycle: виден ли эффект? -[M1 tab identity fix](https://github.com/duckduckgo/apple-browsers/pull/6827) вошёл в macOS 1.209, а в 1.208 его нет; PR менял только macOS. Старые версии не посылали новые поля controller/scripts, поэтому сравним лишь общий proxy `stuck.other.daily / initialization.failed.after.other.daily`, **не частоту tab bugs**. В сопоставимых пятидневных окнах он равен 27 493/69 565 = **39,52%** на macOS 1.208 и 40 030/103 135 = **38,81%** на 1.209. Изменение на 0,71 процентного пункта мало и может отражать состав cohort/нагрузки; это не измеренный эффект фикса. Новый 1.210 за один день даёт 420/1 073 = **39,14%**. Следовательно, по агрегатному тренду исчезновение tab breakage не подтверждено и не опровергнуто; именно относящиеся к нему события старых версий нельзя выделить без attribution. +[M1 tab identity fix](https://github.com/duckduckgo/apple-browsers/pull/6827) вошёл в macOS 1.209, а в 1.208 его нет; PR менял только macOS. Старые версии не посылали новые поля controller/scripts, поэтому сравним лишь общий proxy `stuck.other.daily / initialization.failed.after.other.daily`, **не частоту tab bugs**. В сопоставимых пятидневных окнах он равен 27 493/69 565 = **39,52%** на macOS 1.208 и 40 030/103 135 = **38,81%** на 1.209. Изменение на 0,71 процентного пункта мало и может отражать состав cohort/нагрузки; это не измеренный эффект фикса. Новый 1.210 после публикации даёт 418/1 050 = **39,81%**. Следовательно, по агрегатному тренду исчезновение tab breakage не подтверждено и не опровергнуто; именно относящиеся к нему события старых версий нельзя выделить без attribution. ## 5. After-stuck recovery mitigation: работает ли? -**Функциональный сигнал есть.** [M4](https://github.com/duckduckgo/apple-browsers/commit/41656f8d17) входит в macOS 1.210 / iOS 7.240 и при подтверждённом hang пытается reload embedded extension (remote flag по умолчанию enabled). `recovered.after.extension.reload.daily` отправляется только после реального успешного CPM-ответа текущего поколения extension. В релизный день таких событий от `messaging_stuck` — **916 iOS / 354 macOS**. Все `recovered.after` вместе дают 963/1 440 = **66,9%** от числа stuck daily на iOS и 362/489 = **74,0%** на macOS, тогда как в предшествующих пятидневных окнах число пикселей этого имени относительно stuck daily составляло **3,23%** (iOS 7.239) и **2,70%** (macOS 1.209). Это большой скачок, согласующийся с автоматическим reload. Эти отношения **не success rate**: имена пикселей независимо throttled, эпизоды не соединены, одни установки могли дать несколько разных сигналов. +**Функциональный сигнал есть.** [M4](https://github.com/duckduckgo/apple-browsers/commit/41656f8d17) входит в macOS 1.210 / iOS 7.240 и при подтверждённом hang пытается reload embedded extension (remote flag по умолчанию enabled). `recovered.after.extension.reload.daily` отправляется только после реального успешного CPM-ответа текущего поколения extension. После публикации таких событий от `messaging_stuck` — **916 iOS / 354 macOS**. Все `recovered.after` вместе дают 963/1 440 = **66,9%** от числа stuck daily на iOS и 362/487 = **74,3%** на macOS, тогда как в предшествующих пятидневных окнах число пикселей этого имени относительно stuck daily составляло **3,23%** (iOS 7.239) и **2,70%** (macOS 1.209). Это большой скачок, согласующийся с автоматическим reload. Эти отношения **не success rate**: имена пикселей независимо throttled, эпизоды не соединены, одни установки могли дать несколько разных сигналов. -**Ограничение эффекта:** первый post-reload CPM probe всё ещё завершился timeout 670 раз на iOS и 234 на macOS, поэтому reload не гарантирует немедленного восстановления. Это не сбой самого API reload. Отдельный `debug.web.extension.reload.failed.daily` содержит один macOS error для `embedded / cpm_messaging_hung / load` и 223 iOS errors для **другого** `adBlocking / scriptlet_update / unload` extension. На текущих данных M4 действительно возвращает ответы после stuck у части установок; нельзя вычислить долю всех stuck-эпизодов, которые остались невосстановленными, или изменение общей частоты init failures. +**Ограничение эффекта:** после публикации первый post-reload CPM probe всё ещё завершился timeout 670 раз на iOS и 232 на macOS, поэтому reload не гарантирует немедленного восстановления. Это не сбой самого API reload. Отдельный `debug.web.extension.reload.failed.daily` после публикации содержит один macOS error для `embedded / cpm_messaging_hung / load` и 223 iOS errors для **другого** `adBlocking / scriptlet_update / unload` extension; до публикации этих operation errors нет. На текущих данных M4 действительно возвращает ответы после stuck у части установок; нельзя вычислить долю всех stuck-эпизодов, которые остались невосстановленными, или изменение общей частоты init failures. ## Источники и воспроизведение сверки -Локальная выгрузка и код подсчёта: `cpm-public-attribution-2026-10-06/` в `/Users/admin/DuckDuckGo/apple-browsers.git`. `inventory.tsv` — полный CPM daily/count перечень и actual reload errors; `initialization_daily.tsv` и `events_daily.tsv` — PII-free строки attribution; `daily_groups_exclusive.tsv`, `daily_families.tsv`, `daily_reasons.tsv`, `daily_signatures.tsv` — сводки; `release_cpm_daily_trends.tsv` — 982 строки дневных трендов шести версий. `analyze_daily.py` воспроизводит эксклюзивные группы. Код поведения: `CPMMessagingHealthMonitor.swift` (`reportFailure`, `reportSuccess`), `WebExtensionManager.swift` (`onConfirmedHang`, `reloadEmbeddedExtensionAfterCPMMessagingHang`), `WebExtensionLifecycleCoordinator.swift` (navigation gate), `PixelKit.swift` (лимит `.daily` по имени и UTC). Снимок законченного дня; для вывода о динамике incidence нужен следующий полный UTC-день новой версии и знаменатель активных установок той же версии. +Локальная выгрузка и код подсчёта: `cpm-public-attribution-2026-10-06/` в `/Users/admin/DuckDuckGo/apple-browsers.git`. `inventory.tsv` — полный CPM daily/count перечень и actual reload errors; `release_cutover_daily.tsv` — все CPM daily и actual reload daily по обе стороны release-tag timestamp; `initialization_daily.tsv` и `events_daily.tsv` — PII-free строки attribution с точным timestamp; `release_cutover_groups.tsv` и `release_cutover_reasons.tsv` — группы и причины по обе стороны tag, воспроизводятся `analyze_cutover.py`; `daily_groups_exclusive.tsv`, `daily_families.tsv`, `daily_reasons.tsv`, `daily_signatures.tsv` — сводки **полного дня, включая pre-tag**; `release_cpm_daily_trends.tsv` — 982 строки дневных трендов шести версий. Код поведения: `CPMMessagingHealthMonitor.swift` (`reportFailure`, `reportSuccess`), `WebExtensionManager.swift` (`onConfirmedHang`, `reloadEmbeddedExtensionAfterCPMMessagingHang`), `WebExtensionLifecycleCoordinator.swift` (navigation gate), `PixelKit.swift` (лимит `.daily` по имени и UTC). Снимок законченного дня; для вывода о динамике incidence нужен следующий полный UTC-день новой версии и знаменатель активных установок той же версии.