[2026-10-30] eagle: work/projects/CPM Breakage Testing Steps.md work/projects/cpm-post-release-analysis-2026-10-27.md work/projects/cpm-status-2026-10-15.md work/projects/cpm-web-extension-breakage-findings.md work/projects/cpm-web-extension-breakage-validation.md work/projects/cpm-web-extension-code-guide-2026-10-09.md
This commit is contained in:
1 parent
449c867f90
commit
203852d638
6 files changed
+98
-3
No files matched your search
@@ -1,8 +1,47 @@
|
||||
---
|
||||
updated: '2026-10-20'
|
||||
updated: '2026-10-30'
|
||||
---
|
||||
# CPM episode telemetry — testing steps
|
||||
|
||||
## Error-6 restart — PR 7730 (30 October 2026)
|
||||
|
||||
Current production PR: [#7730](https://github.com/duckduckgo/apple-browsers/pull/7730), **`cf668e2938`**, OPEN and not shipped. Review harness: `codex/cpm-error6-restart-harness` at **`5348c7254e`**, production code identical to the PR; its extra fixtures are outside main and production CI. Use a clean, isolated macOS checkout with the repository's Xcode toolchain.
|
||||
|
||||
1. Fetch and select the harness:
|
||||
```sh
|
||||
git fetch origin
|
||||
git switch --detach origin/codex/cpm-error6-restart-harness
|
||||
```
|
||||
2. Disable only retained-view restart:
|
||||
```sh
|
||||
CPM_REPRO=1 CPM_REPRO_RESTART=0 swift test \
|
||||
--package-path SharedPackages/WebExtensions \
|
||||
--filter CPMReproError6RestartTests/testRetainedError6RestartRestoresMessaging
|
||||
```
|
||||
Expected **functional FAIL**: `enabled=false error6=true retained=true`, original document timeout, nonempty `lost`, `restarts=0 responses=0`; existing M4 eventually repairs messaging. Setup errors, skips or absence of the injected real error are not valid negative controls.
|
||||
3. Enable restart on the same binary:
|
||||
```sh
|
||||
CPM_REPRO=1 CPM_REPRO_RESTART=1 swift test \
|
||||
--package-path SharedPackages/WebExtensions \
|
||||
--skip-build \
|
||||
--filter CPMReproError6RestartTests/testRetainedError6RestartRestoresMessaging
|
||||
```
|
||||
Expected **PASS**: `enabled=true error6=true retained=true`, original document gets an attributed dashboard response **and actual page initResp**, `lost=[] restarts=1 responses=1`, two later ordinary idle/wake cycles answer.
|
||||
4. Return to production:
|
||||
```sh
|
||||
git switch --detach origin/alex/cpm-error6-restart
|
||||
```
|
||||
|
||||
The last completed same-binary real-WebKit OFF/ON used **production `d1a2e1de65`**, not the latest head. The fixture branch is now synchronized for reviewers to rerun. This injected worker-start exception validates the retained-view mechanism; it does not establish the natural production trigger or physical iOS suspension behavior.
|
||||
|
||||
Permanent tests in the PR cover new/historical/equal errors, healthy replacements, weak ownership, foreground/wake, runtime kill switches, queued newer errors, automatic cooldown expiry and expiry in background. Telemetry tests cover success vs background_ready, measured/unobserved deadlines, suspension, supersession, reload failure/timeout and embedded upgrades. Same-identifier loaded and another extension type must not supersede an active observation. These tests run in ordinary PR CI; the optional slow fault-injection harness does not.
|
||||
|
||||
Latest local package result: **1064 PASS**; final source review with eight temporary probes: **1072 PASS**, no important findings. The temporary probes were removed. Treat `background_ready` only as a stage, not messaging success. Evaluate `web_extension_cpm_background_load_restart` using **count** rows; daily deduplication is by name. No response by deadline or a missing terminal row after process exit does not prove permanent breakage.
|
||||
|
||||
Full contract and evidence: [[cpm-status-2026-10-15#Error-6 restart — PR 7730]].
|
||||
|
||||
## Historical episode-telemetry scope — 20 October 2026
|
||||
|
||||
Verified against #7376 **`5d1cb4abd2`**, 20 October 2026. These expectations apply to that published branch; the PR is closed without merge. The macOS counterpart #7484 still has the earlier `was_stuck` contract. Full values and limitations: [[cpm-pr0-episode-telemetry-summary-2026-10-16]].
|
||||
|
||||
Use an isolated test profile and filter the Xcode console by `PixelKit` and `CPM Health Monitor`. Finish each episode before starting the next case. In production, the first completed episode per day sends `web_extension_cpm_episode_daily` and `_count` with the same payload; subsequent episodes send count only, across every reason/outcome. PixelKit dry-run logs instead of sending and compresses daily deduplication to two minutes, so a five-minute case may cross that boundary.
|
||||
|
||||
@@ -9,6 +9,20 @@ updated: '2026-10-30'
|
||||
---
|
||||
# CPM: first post-release data, 26 October 2026
|
||||
|
||||
## Error-6 restart — 30 October 2026
|
||||
|
||||
[PR #7730](https://github.com/duckduckgo/apple-browsers/pull/7730) is **OPEN, non-draft, MERGEABLE**, head **`cf668e2938`**, with **privacy review required**. The closed draft described under 28 October is historical. This PR is not merged or shipped; this update does not add a new production data cut.
|
||||
|
||||
The implementation restarts only the current embedded context whose **original failed background view is still retained at execution**. Released views keep the existing P2 retry; WebKit's replacement view is left alone. Deferred errors resume after foreground/wake. The latest pending error survives the 60-second cooldown and is retried after expiry; expiry in background waits for foreground. Equal historical errors are deduplicated, with history reset for a newly created background view so delayed clear/add notifications do not hide a new equal failure.
|
||||
|
||||
A dedicated `web_extension_cpm_background_load_restart` pixel now exists, dailyAndCount on both platforms with no macOS name suffix and bounded `outcome`. Applying the restart, background readiness and an attributable dashboard response are separate stages. Terminal outcomes distinguish measured no-response at the five-active-minute deadline, unobserved, superseded, reload failure and reload timeout. A new embedded identifier loaded by upgrade supersedes the old restart observation; its response cannot claim that the old restart recovered messaging. Count rows are required for outcome rates; daily deduplication usually keeps restart_started.
|
||||
|
||||
Local final validation on `cf668e2938`: **1,064 production package tests passed**, strict lint and both platforms' pixel validators passed. Final review added **8 temporary edge-case probes: 1,072 tests passed**, no important findings; the probes were removed. Permanent regressions remain in normal PR CI. Exact-head CI was not re-read for this documentation update.
|
||||
|
||||
The separate review harness is synchronized at `5348c7254e` and adds only 17 Swift fixture/test files plus its guide. The last actual same-binary macOS OFF/ON was run on **`d1a2e1de65`**: OFF functionally failed with real error 6 and a retained failed view; ON restored the original document's native response and real page initResp, with two later idle/wake cycles healthy. This is controlled worker-start fault injection, not a natural production trigger or physical iOS suspend/wake validation. Later queue/cooldown/attribution changes have regression-test evidence, not a new real-WebKit OFF/ON result.
|
||||
|
||||
Full behavior, flags, outcomes and evidence: [[cpm-status-2026-10-15#Error-6 restart — PR 7730]]. Reviewer commands: [[CPM Breakage Testing Steps#Error-6 restart — PR 7730 (30 October 2026)]]. Historical production percentages below retain their original dates/denominators; the PR does not establish its production causal share or post-rollout effect.
|
||||
|
||||
Internal metrics; keep these figures out of public PRs. Previous analysis: [[cpm-metrics-causes-and-mitigations-2026-10-16]], [[cpm-status-2026-10-15]] (§3–5, 12–14 October cut).
|
||||
|
||||
## Upgrade-before-load — 30 October 2026
|
||||
@@ -375,7 +389,9 @@ Internal metrics; keep these figures out of public PRs. Data: ClickHouse via `~/
|
||||
|
||||
The background page loads with `navigator.serviceWorker.register(...)`; its rejection carries the WebKit error text (`Error: <message>`), obtainable with a `WKUserScript` and `WKScriptMessageHandler` on the background web view delivered by `didCreateBackgroundWebView` (before the page loads). Message only, no file or line. The extension's own `extensionException` messages are not handled by the app (unknown method). Verified once with an injected exception.
|
||||
|
||||
### Proposed fix: restart the context when the failed view is retained (PR #7730, closed)
|
||||
### Historical draft — 28 October 2026: retained-view restart
|
||||
|
||||
> Superseded by [[cpm-post-release-analysis-2026-10-27#Error-6 restart — 30 October 2026]]. PR #7730 is now OPEN at `cf668e2938`; the following closed/no-new-pixel/three-test statements describe the 28 October draft, not the current implementation.
|
||||
|
||||
- **Behavior.** On error 6 (current context, recovery flag on, app in the foreground, no M4 in progress, 60 s cooldown) the manager checks `WKWebExtensionContext._backgroundWebView`. If the failed view is still alive it reloads the embedded extension at once (new reload trigger `cpmBackgroundLoadFailure`) and loads the background. If the view was released it keeps the plain P2 retry, which preserves the failed document's init.
|
||||
- **Why.** WebKit's `loadBackgroundWebViewIfNeeded` returns early while the view exists (`m_backgroundWebView` set), and after a failed `_loadServiceWorker` WebKit records error 6 without an underlying error and does not unload the view. The retry therefore cannot replace it.
|
||||
@@ -391,7 +407,7 @@ The background page loads with `navigator.serviceWorker.register(...)`; its reje
|
||||
- Why 172 permanent episodes of the `interruption` family do not recover, when 2,797 identical-looking ones do.
|
||||
- What makes a start hang longer than 30 s (candidates from earlier notes: origin-change data migration, host main thread stall, process throttling), and why that survives M4.
|
||||
- How often the failed view is retained.
|
||||
- Pixel for the restart (none exists yet).
|
||||
- Historical 28 Oct gap, now implemented in PR #7730: `web_extension_cpm_background_load_restart` with bounded outcomes. Privacy review and release/rollout are separate gates; see the 30 October update above.
|
||||
|
||||
## Idle wake investigation — 28 October 2026
|
||||
|
||||
|
||||
@@ -9,6 +9,28 @@ updated: '2026-10-30'
|
||||
---
|
||||
# CPM Web Extension: единый статус
|
||||
|
||||
## Error-6 restart — PR 7730
|
||||
|
||||
Сверено **30 октября 2026**: [#7730](https://github.com/duckduckgo/apple-browsers/pull/7730) снова **OPEN**, не draft, **MERGEABLE**, head **`cf668e29382df79f1a94961e39067beac85c6128`**, ветка `alex/cpm-error6-restart`. Есть label **privacy review required**. Не merged и не shipped; локальный review и MERGEABLE не заменяют privacy review, CI или rollout. Историческое закрытие draft 28 октября больше не является текущим статусом.
|
||||
|
||||
**Что делает фикс.** Для новой error 6 текущего embedded context manager запоминает исходный failed background view. Если к выполнению recovery WebKit всё ещё держит именно его, выполняется full embedded-context restart с trigger `cpmBackgroundLoadFailure`; при освобождённом view остаётся обычный P2 background-only retry. Новый replacement view, даже ещё загружающийся, не перезапускается. Дополнительного page reload/re-init фикс не добавляет; в контролируемом harness исходный документ получает настоящий `initResp` после restart.
|
||||
|
||||
**Background/wake и очередь.** Попытка хранит context/view слабо. Новая ошибка заменяет pending-попытку также в foreground, если прежняя recovery ещё стоит в очереди. На iOS отложенная recovery получает возможность на `didBecomeActive`, на macOS — на `didWake`; повторные события не воспроизводят завершённую попытку. Cooldown **60 s** отсчитывается от фактически применённой recovery: ошибка сохраняется до истечения срока и запускается таймером без новой навигации/notification. Если срок истёк в background, попытка ждёт foreground. Перед выполнением снова проверяются актуальность context/view, runtime flags и concurrent-recovery guard. Исторические равные errors не запускают restart; история сбрасывается при создании нового background view, чтобы задержанные clear/add notifications не скрыли новую одинаковую error 6.
|
||||
|
||||
**Flags.** `webExtensions.cpmBackgroundLoadRecovery` разрешает P2/recovery целиком; отдельный `cpmBackgroundLoadRestart` — только retained-view restart, code default ON на iOS/macOS, default OFF в manager API. OFF у restart сохраняет plain retry. M4 использует собственный `cpmMessagingHangRecovery`. [Registry task](https://app.asana.com/1/137249556945/project/1211834678943996/task/1219970564251181); [задача PR](https://app.asana.com/1/137249556945/project/72649045549333/task/1219939142983214?focus=true). Live remote config этой работой не менялась и не проверялась.
|
||||
|
||||
**Телеметрия реализована.** Новый `web_extension_cpm_background_load_restart` имеет одно имя на iOS/macOS, **без `_macos`**, частоту dailyAndCount и единственный custom parameter `outcome`. Stages: `restart_started`, `background_ready`; terminal outcomes: `response_received`, `no_response_before_deadline`, `unobserved`, `superseded`, `reload_failed`, `reload_timed_out`. Наблюдение отдельно от failure episode: быстрый restart может завершиться раньше первого navigation timeout. Успех требует атрибутируемого dashboard response нужного поколения; background callback — только промежуточный этап. Deadline — пять активных минут, suspension исключается, после resume остаётся минимум 30 s. Без измеренного timeout/ответа — `unobserved`; другой reload или загрузка новой embedded-версии завершает старое наблюдение как `superseded`. Повторный `loaded` того же identifier и другой extension type его не закрывают. Ошибка reload уже даёт `reload_failed` и существующий reload-error pixel с `cpm_background_load_failed`. URLs, tab IDs и raw errors новым pixel не отправляются. Для outcome rates использовать **count**, не daily: daily dedupe работает по имени и обычно оставляет первый `restart_started`. Отсутствие terminal row после завершения процесса не считать failure.
|
||||
|
||||
**Проверки на текущем head.** **1064 штатных WebExtensions tests PASS**, strict SwiftLint и pixel-schema/format/wide-event checks обеих платформ PASS. Финальный source review: **0 существенных findings**; отдельный полный прогон со **8 временными edge-case probes — 1072 PASS / 0 failures**. Probes проверили burst ошибок, повторный background перед queued recovery, смену context/flags во время cooldown, upgrade после measured failure и позднее завершение прежнего reload. Временные probes удалены; постоянные manager, monitor и platform-adapter regressions входят в обычный PR CI. В unit-регрессии без cooldown timer автоматический retry действительно падает. Exact-head CI заново в этом обновлении документации не запрашивался.
|
||||
|
||||
**Harness отдельно от main.** Production worktree `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-error6-restart`; review harness — `cpm-error6-restart-harness`, ветка [`codex/cpm-error6-restart-harness`](https://github.com/duckduckgo/apple-browsers/tree/codex/cpm-error6-restart-harness), опубликованный head **`5348c7254efb23e44a4f53e5150dc95cc5edd938`**, синхронизирован с `cf668e2938`. Отличия — только **17 fixture/test Swift files + run guide**, production code идентичен. [Инструкции OFF/ON](https://github.com/duckduckgo/apple-browsers/blob/codex/cpm-error6-restart-harness/SharedPackages/WebExtensions/CPMError6RestartHarness.md).
|
||||
|
||||
Последний реальный macOS OFF/ON выполнен **на production `d1a2e1de65`**, а не повторно на финальном `cf668e2938`: одинаковый binary SHA256 `5369bd0105cc8c1f8257db374a631cae0a4f6146ca038e1e0aa4c75da6f2d141`. OFF — ожидаемый functional FAIL: настоящая error 6, retained=true, исходный timeout, потерянный `busy 0`, restarts/responses=0; позднее помогает M4. ON — PASS: настоящий dashboard response и page `initResp`, первый ответ 0.084 s, lost=[], restarts=1, responses=1, два следующих idle/wake цикла здоровы. Более поздние queue/cooldown/upgrade-attribution изменения проверены unit/regression tests, не новым OFF/ON запуском.
|
||||
|
||||
**Границы.** Natural production trigger и доля retained-view failures неизвестны; новые production metrics не запрашивались. Контролируемый worker-start exception доказывает этот механизм, не всю iOS interruption/error-6 когорту. Физический iOS suspend/wake финальным прогоном не проверен. Старый draft использовал full reload шире; нынешний restart ограничен тем же retained failed view. Не переносить прежний отрицательный результат full-context P2 из 16 октября на этот более узкий случай как доказательство неработоспособности; он остаётся историческим ограничением, а положительный harness — отдельным контролируемым доказательством.
|
||||
|
||||
Артефакты: `cpm-error6-verification-2026-10-30/final-review/{verification.json,tests.log}`, `pending-recovery/`, `foreground-publish/` в корне bare repo; финальный штатный run и validators — `/private/tmp/cpm-upgrade-observation-tests.log`, `cpm-upgrade-observation-lint.log`, `cpm-upgrade-{iOS,macOS}-{validate-pixel-defs,check-wide-events}.log`. Карта кода — [[cpm-web-extension-code-guide-2026-10-09#Error-6 restart — PR 7730]]; reviewer steps — [[CPM Breakage Testing Steps#Error-6 restart — PR 7730 (30 October 2026)]].
|
||||
|
||||
## Текущее состояние — 30 октября 2026, 16:48 Бишкек
|
||||
|
||||
### Upgrade-before-load: PR открыт, CI зелёный
|
||||
|
||||
@@ -11,6 +11,8 @@ updated: '2026-10-30'
|
||||
---
|
||||
# CPM Web Extension Breakage Findings
|
||||
|
||||
> **Error-6 restart — 30 октября 2026:** [#7730](https://github.com/duckduckgo/apple-browsers/pull/7730) снова OPEN, head `cf668e2938`, с privacy-review gate; не merged/shipped. Реализованы retained-view restart, отложенная foreground/wake recovery, сохранение ошибки через cooldown и отдельный outcome pixel. Финальный source review не нашёл существенных проблем: 1064 штатных tests + 8 временных probes PASS. Natural trigger и физический iOS suspend/wake не установлены. Текущий контракт, проверенные heads и границы — [[cpm-status-2026-10-15#Error-6 restart — PR 7730]]. Датированные выводы ниже остаются историей.
|
||||
|
||||
> **Актуализация 30 октября 2026:** #7752 / #7753 merged в release 1.214 / 7.244; публикация и эффект ещё не подтверждены. Только rename JSON key, без миграции UUID и OS-version tracking; без нового ключа используется installation UUID. Ошибочное утверждение ниже о том, что extension workers никогда не сохранялись, исправлено. Текущий итог и границы доказательств: [[cpm-post-release-analysis-2026-10-27#Release update — 30 October 2026]]. Остальные датированные разделы сохраняют историю исследования.
|
||||
|
||||
> **Актуальный контекст — 20 октября 2026.** Это исторический журнал source audit, ручных repro и отозванных гипотез. Его «нет фикса», local-only, bundle/OS и CI states относятся к датам записей; текущие heads и gates — [[cpm-status-2026-10-15#2. PR и quality gates]].
|
||||
|
||||
@@ -5,6 +5,8 @@ updated: '2026-10-30'
|
||||
|
||||
## Текущее состояние — 30 октября 2026
|
||||
|
||||
**Error-6 restart:** [#7730](https://github.com/duckduckgo/apple-browsers/pull/7730), head `cf668e2938`, OPEN/MERGEABLE, privacy review required, не merged/shipped. На этом head 1064 штатных WebExtensions tests PASS; финальный review с 8 временными edge-case probes — 1072 PASS, без существенных findings. Реальный macOS OFF/ON подтверждён на более раннем `d1a2e1de65`; физический iOS suspend/wake и natural production trigger не проверены. Полное текущее поведение, flags, pixel outcomes, очередь/cooldown и ссылки на артефакты: [[cpm-status-2026-10-15#Error-6 restart — PR 7730]]. Ниже — отдельный upgrade-before-load PR и исторические validation snapshots.
|
||||
|
||||
Upgrade-before-load реализован в [PR #7767](https://github.com/duckduckgo/apple-browsers/pull/7767), head `45593bbb4e`, main `3046f67631` влит. PR OPEN/MERGEABLE; exact-head CI **43 SUCCESS / 15 SKIPPED / 0 failed/pending**. Не merged и не shipped.
|
||||
|
||||
Подготовка до load применяется только к CPM, без scriptlet downloads. Ошибка upgrade оставляет старую установку для load и последующего retry. `webExtensions.cpmUpgradeBeforeLoad` — default-ON failsafe, применяется при создании manager; OFF возвращает прежний порядок на следующем manager/запуске. Origin reuse дополнительно зависит от stable-origin policy, OS 26.6+, приватного manifest и отсутствия живого старого context.
|
||||
|
||||
@@ -9,6 +9,20 @@ updated: '2026-10-30'
|
||||
---
|
||||
# CPM Web Extension — карта кода по worktree и строкам
|
||||
|
||||
## Error-6 restart — PR 7730
|
||||
|
||||
Карта на **30 октября 2026**, production head **`cf668e29382df79f1a94961e39067beac85c6128`**, [PR #7730](https://github.com/duckduckgo/apple-browsers/pull/7730) OPEN/MERGEABLE, не merged/shipped. Ветка `alex/cpm-error6-restart`, worktree `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-error6-restart`.
|
||||
|
||||
- `SharedPackages/WebExtensions/Sources/WebExtensions/Manager/WebExtensionManager.swift:408` — error notification observer, multiset-diff новых error 6; `:1062` — weak snapshot failed context/view; `:1087` — очередь последней попытки и runtime guards; `:1138` — одноразовый cooldown timer; `:1161` — retained-view context restart. `:1604` сбрасывает историю при создании нового background view. `:1035` отправляет промежуточный background_ready.
|
||||
- `Autoconsent/CPMInterruptionObserver.swift:51` — iOS didBecomeActive для recovery, `:57` — macOS didWake. Health-monitor clocks возобновляются отдельно на iOS willEnterForeground.
|
||||
- `Autoconsent/CPMMessagingHealthMonitor.swift:197` — отдельное restart observation; `:933` — lifecycle attribution, включая superseded на loaded другого embedded identifier; `:979` — единственный terminal outcome и отмена deadline; `:998` — quiet deadline. Same-identifier loaded и другой extension type сохраняют наблюдение.
|
||||
- `Pixels/WebExtensionPixelFiring.swift:261` — bounded outcomes; `:289` — canonical metadata для `web_extension_cpm_background_load_restart`, dailyAndCount, только custom `outcome`, без `_macos`. Platform adapters и JSON5 definitions есть на обеих платформах.
|
||||
- `WebExtensionManagerTests`, `CPMInterruptionObserverTests`, `CPMMessagingHealthMonitorTests` — постоянные queue/cooldown/wake, historical/equal-error и upgrade-attribution regressions; native PixelKit adapter tests находятся в iOS/macOS app test targets. Shared package run: 1064 PASS; final review run с 8 временными probes: 1072 PASS. Это не full-app iOS suspend/wake прогон.
|
||||
|
||||
Review-only worktree `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-error6-restart-harness`, branch `codex/cpm-error6-restart-harness`, head **`5348c7254efb23e44a4f53e5150dc95cc5edd938`**; production code совпадает с `cf668e2938`, diff — ровно 17 Swift fixtures/tests + `SharedPackages/WebExtensions/CPMError6RestartHarness.md`. Последний реально выполненный macOS OFF/ON относится к `d1a2e1de65`; не приписывать его повторный запуск текущему head. Reviewer guide: [CPMError6RestartHarness.md](https://github.com/duckduckgo/apple-browsers/blob/codex/cpm-error6-restart-harness/SharedPackages/WebExtensions/CPMError6RestartHarness.md).
|
||||
|
||||
Флаги, telemetry interpretation, доказательства и ограничения — [[cpm-status-2026-10-15#Error-6 restart — PR 7730]]. Состояние upgrade-before-load #7767 ниже относится к отдельному PR.
|
||||
|
||||
## Upgrade-before-load — PR 7767
|
||||
|
||||
Проверено 30 октября 2026, 16:48 Бишкек: [#7767](https://github.com/duckduckgo/apple-browsers/pull/7767), production worktree **`/Users/admin/DuckDuckGo/apple-browsers.git/cpm-upgrade-before-load`**, branch `codex/cpm-upgrade-before-load`, head **`45593bbb4e`**. Main `3046f67631` влит; PR OPEN/MERGEABLE, exact-head CI 43 SUCCESS / 15 SKIPPED, 0 failed/pending. Не merged и не shipped.
|
||||
|
||||
Reference in new issue
Block a user