From 203852d6385ae13bd3d06eccd5157f93f87c1783 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Fri, 30 Oct 2026 16:59:25 +0600 Subject: [PATCH] [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 --- work/projects/CPM Breakage Testing Steps.md | 41 ++++++++++++++++++- .../cpm-post-release-analysis-2026-10-27.md | 20 ++++++++- work/projects/cpm-status-2026-10-15.md | 22 ++++++++++ .../cpm-web-extension-breakage-findings.md | 2 + .../cpm-web-extension-breakage-validation.md | 2 + ...cpm-web-extension-code-guide-2026-10-09.md | 14 +++++++ 6 files changed, 98 insertions(+), 3 deletions(-) diff --git a/work/projects/CPM Breakage Testing Steps.md b/work/projects/CPM Breakage Testing Steps.md index 51f72308..d77ed94d 100755 --- a/work/projects/CPM Breakage Testing Steps.md +++ b/work/projects/CPM Breakage Testing Steps.md @@ -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. diff --git a/work/projects/cpm-post-release-analysis-2026-10-27.md b/work/projects/cpm-post-release-analysis-2026-10-27.md index f6c587cc..576800cb 100644 --- a/work/projects/cpm-post-release-analysis-2026-10-27.md +++ b/work/projects/cpm-post-release-analysis-2026-10-27.md @@ -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: `), 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 diff --git a/work/projects/cpm-status-2026-10-15.md b/work/projects/cpm-status-2026-10-15.md index 5f5ce62a..71494c5e 100755 --- a/work/projects/cpm-status-2026-10-15.md +++ b/work/projects/cpm-status-2026-10-15.md @@ -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 зелёный diff --git a/work/projects/cpm-web-extension-breakage-findings.md b/work/projects/cpm-web-extension-breakage-findings.md index d54184c4..9b6b2f5b 100755 --- a/work/projects/cpm-web-extension-breakage-findings.md +++ b/work/projects/cpm-web-extension-breakage-findings.md @@ -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]]. diff --git a/work/projects/cpm-web-extension-breakage-validation.md b/work/projects/cpm-web-extension-breakage-validation.md index eddae757..5613e420 100755 --- a/work/projects/cpm-web-extension-breakage-validation.md +++ b/work/projects/cpm-web-extension-breakage-validation.md @@ -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. diff --git a/work/projects/cpm-web-extension-code-guide-2026-10-09.md b/work/projects/cpm-web-extension-code-guide-2026-10-09.md index cf61d56b..0db9c737 100755 --- a/work/projects/cpm-web-extension-code-guide-2026-10-09.md +++ b/work/projects/cpm-web-extension-code-guide-2026-10-09.md @@ -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.