[2026-10-16] eagle: work/projects/cpm-pr0-episode-telemetry-summary-2026-10-16.md work/projects/cpm-status-2026-10-15.md

This commit is contained in:
Alexey Martemyanov committed 2026-10-16 17:44:43 +06:00
1 parent ec56849012
commit 1b32b92829
2 files changed
+39

No files matched your search

@@ -0,0 +1,31 @@
---
title: CPM PR0 — один итоговый отчёт о сбое
date: '2026-10-16'
tags:
- work
- cpm
- telemetry
---
# CPM PR0: один итоговый отчёт о сбое
Описание локальной правки для [PR0 #7376](https://github.com/duckduckgo/apple-browsers/pull/7376). Изменения находятся в `alex/cpm-telemetry-pr0`, без коммита.
**Что и зачем.** Вместо отдельных `init_failed`, `stuck`, `recovery` и CPM reload-failed отправляем один `web_extension_cpm_episode`. Причина и итог сбоя оказываются в одном отчёте: для диагностики больше не нужно соединять последовательность пикселей с повторяющимися признаками.
**Когда отправляем.** Первый таймаут открывает эпизод и сохраняет один снимок состояния. Последующие сбои и попытки reload учитываются локально. Эпизод завершается при допустимом dashboard-ответе или через пять минут без ответа. Таймер работает и без новых навигаций. Используется существующий monitor; правила подтверждения stuck и запуска автоматического reload сохранены.
**Что получаем.** Отчёт содержит причину первого таймаута, был ли подтверждён stuck, последнее состояние reload и итог наблюдения. Для ответа различаем исходное измерение, последующее измерение на сбойной вкладке, другую вкладку и ответ без однозначной привязки. Время до ответа передаём тремя диапазонами: менее 30 секунд, 30–60 секунд, от минуты до конца наблюдения.
Снимок первого сбоя содержит только фиксированные признаки: состояние контекста и background-процесса, регистрация вкладки и native-handler, соответствие controller, наличие extension scripts и состояние graveyard treatment.
**Приватность и подсчёт.** Из отправки убраны `bg_events`, сырые ошибки, счётчики и временные характеристики приложения и memory pressure. Идентификаторы вкладок и документов не передаются. Это убирает цепочку переходов между отдельными событиями, но не гарантирует отсутствие корреляции редких сочетаний параметров.
Сохраняем `daily+count`: daily оценивает число установок с завершившимся эпизодом за день, count считает завершённые эпизоды. Первый итог за день отправляется в обеих ветках с одинаковыми данными, последующие — только в count.
**Границы результата.** Dashboard-ответ не доказывает доставку `initResp` конкретному документу или восстановление всех вкладок. Отсутствие ответа за пять минут означает только отсутствие наблюдаемого ответа. При завершении процесса незавершённый эпизод может потеряться.
Удалены старые определения пикселей и их неиспользуемые параметры на iOS/macOS. Общий `debug_web_extension_reload_failed` остаётся: менеджер расширений продолжает его отправлять.
Проверено: 82 профильных теста, macOS-пиксель через PixelKitMock, определения обеих платформ и SwiftLint.
Контекст: [[cpm-status-2026-10-15]], [[cpm-readiness-telemetry-tech-design-2026-10-15]].
+8
View File
@@ -744,3 +744,11 @@ Interpretation unchanged: this rerun demonstrates test repeatability in the inst
Локально добавлен кандидат P1: перед каждой HTTP(S) main-frame navigation подготовка background через публичный `loadBackgroundContent`, совместная задача для параллельных навигаций одного context; ожидание ограничено прежними 5 s и отменяется независимо от WebKit. При этом прямой `withTimeout { await Task.value }` не годится для неотменяемого callback: task group ждёт завершения дочерней операции. Использован отменяемый AsyncStream, добавлены отдельные unit tests deadline/cancellation. Старый P1 characterization сохранён с `webExtensionStateRestorationGate=false`.
Кандидат P2: текущий, а не уже заменённый context при настоящем `backgroundContentFailedToLoad` запускает штатный context reload через существующий recovery kill switch. Общий in-progress guard с M4 и 60 s cooldown для load-error recovery; после reload явно запускается background. При известном app_state=background восстановление не выполняется. Приватные process SPI в production-фикс не добавлены; SIGSTOP остаётся только способом воспроизведения. Оба кандидата ещё собираются/проверяются; зелёный результат пока не заявляется. Добавлен disabled-fix режим только новых app-tests для сравнения того же бинарника с явно заданными флагами.
### Проверка кандидата: P1 зелёный, P2 fixture пока не воспроизводит ошибку
`fixed-initial.xcresult`: **новый функциональный P1 PASS (49.628 s)**, первый документ после idle + 8 s busy worker получил page initResp/native confirmation без timeout. P2 в том же прогоне **FAIL на ожидании реального error 6**, не на проверке recovery. После учёта 5 s navigation gate пробовались отключение P1 gate и 45 s SIGSTOP (`fixed-p2-observer.xcresult`): снова healthy late wake без error 6. Этот расширенный fixture имел два окна/два baseline-документа; он **не считается воспроизведением P2 и не подтверждает его фикс**. Запущен исходный одновкладочный `testFrozenBackgroundHitsWebKitLoadTimeout` для сравнения с прежним зелёным сценарием. Все отрицательные результаты сохранены.
P2 реализация уточнена: manager наблюдает публичное `WKWebExtensionContext.errorsDidUpdateNotification`, независимо от navigation gate и пассивного recorder. В прочитанном WebKit source (`WebExtensionContextCocoa.mm:2793–2802`) service-worker failure записывает error 6 и возвращается без выполнения ожидающих `loadBackgroundContent` callbacks. Поэтому callback-ожидание дополнительно завершается по error notification и при `willReload`; recovery guard не удерживается бесконечным ожиданием нового startup. Автоматическая обработка ошибок чужого/старого/не-embedded context исключена. Восстановление пока не объявляется проверенным на app P2.
Пакет после текущих изменений: **806 XCTest, 14 skipped, 0 failures** (`unit-package-callback.log`); strict SwiftLint шести Swift-файлов — **0 violations**. Перегенерированные SPM resolver изменения версий CSS/privacy-dashboard сохраняются только в артефактах и будут исключены из итогового diff; это не часть фикса.