From ef1b44e2e041d970b86d15513b81de536810c558 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 8 Oct 2026 16:54:27 +0600 Subject: [PATCH] [2026-10-08] eagle: work/projects/cpm-web-extension-breakage-session-summary-2026-10-07.md work/projects/cpm-web-extension-repro-and-fix-2026-10-08.md --- ...ion-breakage-session-summary-2026-10-07.md | 2 + ...-web-extension-repro-and-fix-2026-10-08.md | 49 ++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/work/projects/cpm-web-extension-breakage-session-summary-2026-10-07.md b/work/projects/cpm-web-extension-breakage-session-summary-2026-10-07.md index 3eb0148d..c1fc4b1b 100644 --- a/work/projects/cpm-web-extension-breakage-session-summary-2026-10-07.md +++ b/work/projects/cpm-web-extension-breakage-session-summary-2026-10-07.md @@ -258,6 +258,8 @@ Error 6 частично ложится на путь `refreshCpmDashboardState` - **Полный отказ:** падение Network-процесса оставляет background живым, а worker мёртвым; ломаются все вкладки и уже открытые документы; M4 чинит только новые навигации. Закрыто watchdog'ом, который перезапускает только background-процесс. - **Смерть worker'а при живом Network-процессе** (SPI или удаление SW-регистраций) из приложения не обнаружить; закрыто перезапуском background по первому сбою (стоит одну навигацию). - Сверка с данными 5 октября: смена Network-процесса заметно чаще в группе «без видимой ошибки» (iOS 17–21%, macOS 30–45% против ~10% и 1–3% в остальных группах), но это не доказательство — нужен параметр `network_replaced_since_view`. Error 6 на iOS (~1/3 строк), привязка вкладок и большая часть «здоровых» сбоев фиксами не покрыты. +- **Error 6 (iOS):** механизм воспроизведён на macOS — процесс нового background'а не выполняется ≥30 с во время загрузки → таймаут SW → error 6 с продовой сигнатурой. Вероятный iOS-путь: будильник CPM `cpm-summary` будит background, пока приложение в фоне и процессы приостановлены. Ждёт подтверждения на устройстве с iOS 26 (подключённый iPhone на 18.1). +- **Привязка вкладок (macOS):** гипотеза «флаг мигает → новый менеджер» отброшена — флаг всегда `enabled`; проверяются popup-вкладки и пересборка user scripts. - Фикс не закоммичен; открытые вопросы (feature flag, телеметрия, SPI, сборка приложений, ping в extension) — в заметке по ссылке. --- diff --git a/work/projects/cpm-web-extension-repro-and-fix-2026-10-08.md b/work/projects/cpm-web-extension-repro-and-fix-2026-10-08.md index 2d85bcc0..1fe9d59a 100644 --- a/work/projects/cpm-web-extension-repro-and-fix-2026-10-08.md +++ b/work/projects/cpm-web-extension-repro-and-fix-2026-10-08.md @@ -20,6 +20,7 @@ tags: - Оба класса отказа воспроизведены, причины найдены, фикс на стороне app написан, тесты зелёные. - Сверка с данными 5 октября: механизм краша Network-процесса подкреплён лишь частично (20–45% «здоровых» `stuck`); error 6 на iOS (~1/3 строк), привязка вкладок и большая часть «здоровых» сбоев фиксами не покрыты. Нужна телеметрия до или вместе с фиксами (раздел «Телеметрия для валидации»). - Весь пакет: 490 тестов, 0 падений (repro-тесты без env пропускаются). SwiftLint `--strict` чистый. +- **8 октября:** разбор непокрытых групп ведётся в отдельном worktree `alex/cpm-web-extension-remaining-failures` (без фиксов, как в проде) — см. раздел «Непокрытые группы: расследование». Error 6 воспроизведён на macOS, найден естественный iOS-путь (будильник CPM будит background, пока приложение в фоне); ждёт подтверждения на устройстве с iOS 26. ## Что нашли @@ -96,6 +97,50 @@ tags: - **Нет background view** — WebKit не пересоздал background; обоим механизмам нужен живой view. - **«Здоровые» без смены Network-процесса — крупнейший необъяснённый остаток** (1 170 iOS / 497 macOS). Кандидаты: другая смерть worker'а (поймает перезапуск по сбою), поздний или несопоставленный `refreshCpmDashboardState` при живом worker'е (перезапуск — ложное срабатывание), первая загрузка вне gate. Без `native_seen` не разделить. +## Непокрытые группы: расследование (8 октября) + +Worktree `alex/cpm-web-extension-remaining-failures`, ветка от того же коммита `a0717cf098`, **без фиксов** — чтобы воспроизводить на коде как в проде. Фиксы остаются незакоммиченными в `alex/cpm-web-extension-ready-handshake`. + +- В harness перенесена инфраструктура (без watchdog/recovery) и подключён production `CPMMessagingDiagnosticsRecorder`: воспроизведённые сбои дают те же параметры пикселей, что и прод (`bg_events`, `context_errors`, `network_restarted`, …). Watcher логирует `context.errors`. +- Новый набор `CPMReproBackgroundLoadFailureTests`: idle-выгрузка (~32 с), затем пробуждение навигацией при заданном условии. + +### Error 6 (`BackgroundContentFailedToLoad`, ~1/3 строк `stuck` на iOS) + +WebKit (`WebExtensionContextCocoa.mm`): error 6 ставится, когда `_loadServiceWorker` вернул `success=false` (`:2796`) или упала навигация background-страницы (`:3052`). **Код 7 — внутренний `ScriptExecutionError`** (`didEncounterScriptError`, `:284`): JS-ошибка в скрипте extension во время работы. В проде: `7,6` — 283, только `6` — 259, `6,7` — 103 из 645 строк iOS с error 6. + +| Условие при пробуждении (macOS) | Результат | +|---|---| +| Без помех | доставлено | +| Network-процесс заморожен 5/10/60 с | пробуждение потеряно, error 6 нет, потом всё работает | +| Network-процесс убит перед пробуждением | доставлено | +| Background убит во время загрузки | пробуждение потеряно (`died_client`), error 6 нет | +| Файлы extension отсутствуют | error 6 + `WKWebExtensionErrorDomain:2` — **в проде кода 2 нет, не причина** | +| Background-скрипт бросает на верхнем уровне / нет `browser`/`chrome` | error 6 **без** кода 7 — точная продовая сигнатура «только 6», но продовой причины падения скрипта не нашлось | +| **Новый процесс background заморожен ≥30 с во время загрузки** | **таймаут загрузки SW → `background none` + error 6**, цепочка `view, proxy_on, unresponsive, error:6, dealloc`; 10 с — error 6 нет; после разморозки работает | + +**Естественный путь на iOS (гипотеза):** в настоящем приложении в iOS Simulator видно, что CPM сам будит background будильником `cpm-summary` (через 2 мин после активности, шлёт `autoconsent_summary`) — **в том числе когда приложение в фоне**. На устройстве RunningBoard не даёт фоновому приложению держать новый WebContent-процесс активным → процесс приостанавливается посреди загрузки SW → таймаут ~30 с → error 6. Объясняет, почему error 6 почти только на iOS (579 против 3). + +Ограничения проверки: +- Тесты пакета в iOS Simulator непоказательны: процесс `xctest` не получает RunningBoard assertions (`Failed to acquire RBS assertion`), background не работает с самого начала. +- В приложении в симуляторе фоновое приложение не приостанавливается (background живёт 40–50 с и грузится), поэтому сам error 6 там не появляется. +- **Нужно устройство с iOS 18.4+ (лучше 26.x).** Подключённый iPhone 12 mini — на iOS 18.1: CPM-extension там не включается (`@available(iOS 18.4)`). Сборка DDG iOS (Debug), локальный HTTP-сервер со страницами и сценарии через `simctl`/`devicectl` готовы. + +Сценарий для устройства: открыть страницу → свернуть приложение → ждать 2–3 мин (будильник `cpm-summary`) → вернуться → навигация; снимать логи `WebExtensions` (`[CPM Diagnostics]`, `Context error`). + +Возможный фикс, если подтвердится: при возврате приложения на передний план, если `context.errors` содержит error 6 или background мёртв, — перезапустить background; либо не давать будильнику будить background, пока приложение в фоне (изменение extension или WebKit). + +### Привязка вкладок на macOS (`tab_controller_match=false` + нет scripts, ~100 строк) + +- **Гипотеза атрибуции не подтвердилась.** Путь в коде есть: выключение флага `webExtensions` вызывает `uninstallAllExtensions()` и обнуляет менеджер, включение создаёт новый с новым controller, а `WKWebViewConfiguration` старых вкладок не меняется. Но флаг `.webExtensions` = `remoteReleasable(WebExtensionsSubfeature.featureEnabled)` с `defaultValue: .enabled`, а подфичи `featureEnabled` нет ни во встроенном, ни в текущем удалённом `macos-config.json` → флаг всегда `enabled` (отсутствующая подфича возвращает `defaultValue`). Мигать нечему. +- **Порядок запуска не объясняет:** `setupWebExtensions()` (`AppDelegate.swift:1509`) вызывается до восстановления сессии (`:1526`), раньше вкладки не создаются. +- `tab_controller_match` считается как `tabController != nil && tabController === context.webExtensionController` (`CPMMessagingDiagnosticsRecorder.swift:378`) — `false` и при **отсутствующем** controller у вкладки, и при устаревшей ссылке на контекст. +- Следующие кандидаты: вкладки из `createWebViewWith` (popup / `target=_blank`) и кэш закреплённых вкладок; пересборка user scripts в `UserContentController` приложения при обновлении правил content blocking — может стирать скрипты extension из вкладки (на iOS есть группа «скриптов нет при верном controller»). + +### Ещё не начато + +- **Нет background view** (158 iOS / 35 macOS). +- **«Здоровые» сбои без смены Network-процесса** (1 170 iOS / 497 macOS) — разделять после `native_seen`. + ## Телеметрия для валидации Выпустить раньше фиксов или вместе с ними в A/B — иначе эффект фиксов не отделить. Все значения — bool/enum/bucket, без URL и идентификаторов; оформить через `ddg-add-pixel`, privacy triage (прецедент — [[cpm-m3-telemetry-privacy-triage]]). @@ -131,7 +176,9 @@ tags: - [ ] **Риск перезапуска по первому сбою.** Первых сбоев много (~6.6k установок/день на iOS); часть — не мёртвый worker (нет инъекции, медленный native). Перезапуск дешевле M4, но рвёт незавершённую работу background для других вкладок. Решить: включать сразу или через эксперимент. - [ ] **Телеметрия.** Восстановление после перезапуска сейчас попадает в `recovered_without_extension_reload` и неотличимо. Реализовать план из раздела «Телеметрия для валидации»; минимум — `network_replaced_since_view`, `native_seen` и пиксель `background_restarted`. - [ ] **Порядок выкатки.** Телеметрия раньше фиксов или вместе с ними в A/B-эксперименте с когортой в CPM-пикселях. -- [ ] **Error 6 на iOS** (~1/3 строк `stuck`) не покрыт фиксами. Следующий шаг — воспроизвести в harness (цепочка `dealloc → error:6 → view`). +- [ ] **Error 6 на iOS** (~1/3 строк `stuck`) не покрыт фиксами. Механизм воспроизведён на macOS (заморозка нового background ≥30 с во время загрузки). **Обновить iPhone до iOS 26.x** и подтвердить сценарий с будильником `cpm-summary` в фоне; затем решить про фикс. +- [ ] **Привязка вкладок на macOS:** гипотеза мигания флага отброшена; проверить popup-вкладки, кэш закреплённых вкладок и пересборку user scripts. +- [ ] Телеметрия для error 6: причина в `context_errors` (описание ошибки, хотя бы категория) и состояние приложения в момент ошибки (foreground/background). - [ ] **Остаток «здоровых» сбоев без смены Network-процесса** (1 170 iOS / 497 macOS) не объяснён; разделить после `native_seen`. - [ ] **SPI.** Перезапуск через `_killWebContentProcessAndResetState`, детекция через `_networkProcessIdentifier`; есть `responds(to:)`. Согласовать с командой (приложение уже использует SPI WebKit в этом месте). - [ ] **Сборка приложений.** iOS и macOS не собирал; изменения обратно совместимы (дефолтная реализация нового метода протокола, дефолтный параметр init). Проверить сборку и прогнать на iOS Simulator.