88 KiB
Executable File
title, date, tags
| title | date | tags | |||
|---|---|---|---|---|---|
| CPM Web Extension — карта кода по worktree и строкам | 2026-10-09 |
|
Актуально — 16 октября 2026, PR review fixes. В #7379 проверены оба inline замечания: cancellation уже покрыта, повторные 5 секунд на каждую navigation исправлены общим deadline на startup. Production
08866c7eda, 3 commits / 21 paths; review-only harness3f4d755511, 12 test-only paths, вне main. Проверки: red-before-fix 2 FAIL, после исправления 182 unit PASS, signed macOS build и iOS shared-module build PASS, strict lint 8 / 0; на одних app/XCTest binaries ON 8 PASS → OFF 6 ожидаемых functional FAIL → ON 8 PASS, без skips. Оба review threads resolved; Danger 0 failures, только PR-size advisory; flag tracking links добавлены, defaults не менялись. Пользовательские правки и reviewer steps сохранены. Подробности этого review — в конце. Более ранние heads/results ниже сохранены как история.
Актуально — 16 октября 2026, reviewer ON → OFF → ON. В #7379 восстановлена проверка выключенных production flags. Review-only branch
codex/cpm-fix-init-loss-integration-tests/543e37164bсодержит два schemes: CPM Integration Tests → 8 PASS; CPM Integration Tests - Fixes Disabled → ровно 6 functional FAIL; затем normal scheme → снова 8 PASS. Проверено на одних подписанных app/XCTest binaries, без пересборки и изменения Swift code. Production PRda126120a9, 2 commits / 21 files, не менялся; harness остаётся вне main (2 test-only commits / 12 paths). Пользовательские правки PR сохранены. Подробные результаты и artifacts — в конце; прежние односхемные steps и harness head6e4e39e67cотносятся к истории.
Актуально — 16 октября 2026, harness вынесен из PR. #7379:
alex/cpm-fix-init-loss/da126120a9, база #7376, 2 коммита / 21 файл, production fixes + 18 новых shared unit regressions. Все local-only app tests, Xcode entries и DEBUG app hooks — только вcodex/cpm-fix-init-loss-integration-tests/6e4e39e67c, один дочерний commit от PR head; эта ветка не идёт в main. Проверено: production app build PASS, unit 179 PASS, harness app 8/8 PASS, strict lint 19+8 / 0. Reviewer steps в PR обновлены и пользовательские правки сохранены. Ниже сохранена датированная история; прежние 3 commits / 32 files и app harness в PR больше не актуальны.
Актуальный итог — 16 октября 2026, после force push. PR #7379 теперь поверх #7376 (
alex/cpm-messaging-readiness-telemetry), headaec5be9a83, ровно 3 коммита / 32 файла. Старый worktreecpm-fix-init-lossудалён; текущая директорияalex/cpm-fix-p1-p2теперь на веткеalex/cpm-fix-init-loss. Checkpoint367759cbc1и backup старой истории сохранены. Проверка через production feature flags без создания/переключения коммитов: signed app 8/8 PASS ON, 6/6 функциональных FAIL OFF, unit 179 PASS, strict lint 27 / 0, pixel validators обеих платформ PASS. Новый late-reload flag default disabled. Описание PR/шаги и local-onlyto-be-disabled before mergeannotations обновлены; GitHub CI ещё не объявляется green. Подробная финальная сверка — в конце документа. Ниже сохранена датированная история: прежние «не закоммичено», старые head/base и over-budget limitation не являются текущим статусом.
App integration update — 16 октября 2026, 01:48 Бишкек. В
cpm-e2e-initдобавлены 20 методов настоящего app-hosted CPM suite: финальные 20/20 PASS, 0 failures/skips/expected failures, группы 18+1+1 на одной signed build. СхемаCPM Integration Tests; файлы/guards/запуск/ограничения — §5 ниже, полный реестр и история — cpm-status-2026-10-15#Финальный app-hosted итог — 16 октября 2026. Без commits. Карта остальных worktree/PR ниже сохраняет свою датированную сверку 15 октября.
CPM Web Extension — карта кода по worktree и строкам
Актуальная карта — 15 октября 2026. Текущий статус PR/CI, данные и все 14 новых P5/P6 результатов: cpm-status-2026-10-15 (§2, §5, §10–12). Датированные исходные разделы 1–4 ниже сохранены; их «ничего не закоммичено», номера строк и общий worktree описывают 9 октября, а не текущее состояние.
0. Текущая карта worktree и запусков
Корень: /Users/admin/DuckDuckGo/apple-browsers.git/. Проверены git worktree list, HEAD и наличие тестовых файлов. Единого worktree со всеми suites нет. Общая база в истории не включает local dirty/untracked файлы; особенно это относится к remaining-failures и scratch init-progress E2E.
| Worktree | Ветка / текущий HEAD | Назначение и границы |
|---|---|---|
alex/cpm-web-extension-remaining-failures |
та же; a0717cf098cd |
Основное расследование без A/B watchdog: P1 (3 wake), P2 (9 load failure), P3 (2 cache/cleanup), новые P5/P6 (12 lifecycle + 2 flag). Все 28 repro opt-in; CPMRepro/ untracked. Production dirty telemetry — прежняя копия, не переносить вместе с тестами |
cpm-repro-harness |
alex/cpm-repro-harness; dfb96279196d |
PR #7378: базовый harness, быстрые CI-контроли, медленные сценарии и raw WebKit characterization; без новых P5/P6 |
cpm-fix-init-loss — историческая строка; worktree удалён 16 Oct |
alex/cpm-fix-init-loss; 7ad771e227bb |
PR #7379: A, первые init при install/upgrade mid-session; красное/зелёное доказательство отдельно от remaining-failures |
alex/cpm-fix-p1-p2 — актуально 16 Oct |
alex/cpm-fix-init-loss; 08866c7eda |
PR #7379: база #7376 / 713d67419a; 3 commits / 21 files, production fixes/pixels + 21 новый shared unit method; один navigation deadline на startup; local-only app harness и hooks исключены |
| — (отдельная ветка, без своего worktree) | codex/cpm-fix-init-loss-integration-tests; 3f4d755511 |
Два harness commits + sync merge нового production head 08866c7eda + README correction: 8 app methods, ON/OFF schemes, PBX + 3 DEBUG app hooks; 12 paths, не идут в main; reviewer steps включают ON → OFF → ON |
cpm-fix-network-crash |
alex/cpm-fix-network-crash; local f1085846e7ff |
B поверх A; 5 network/termination сценариев в FullFailure + 11 watchdog unit tests. Remote PR #7381 остаётся на 39f94e12eaa4, красный Non-Sandbox; локальный fix не запушен |
cpm-fix-pixels |
alex/cpm-fix-pixels; d6d800846d1f |
A/B + PR0, измерение first_load_wait/background_restart; отдельный PR не зарегистрирован в текущем статусе |
alex/cpm-messaging-readiness-telemetry |
та же; 619869ee84c6 |
PR0 #7376: readiness/failure/recovery параметры, CI без failure/pending, review required |
cpm-readiness-baseline |
alex/cpm-readiness-baseline; 99ecf8b12787 |
#7384 поверх PR0: baseline readiness; Danger=FAILURE |
cpm-init-progress-native |
alex/cpm-init-progress-native; 46f25175c7c4 |
#7385 поверх baseline: init_stage, 11 CPMInitProgress unit tests; Danger=FAILURE. Нужен JS privacy-extension#3727 |
cpm-e2e-init |
scratch/cpm-e2e-init; 46f25175c7c4 (HEAD сохранён, без новых commits) |
Прежний scratch native init-progress/SPM harness плюс новые 20 app-hosted XCTest methods в macOS/IntegrationTests/CPM/ и схема CPM Integration Tests; результаты и ограничения — §13 status. Наличие HEAD, совпадающего с #7385, не означает наличие untracked suites в PR |
alex/cpm-web-extension-ready-handshake |
та же; a0717cf098cd |
Старый объединённый локальный A/B harness и slow-wake-with-fixes; архив сравнения. Текущие PR A/B нарезаны в worktree выше |
cpm-stable-base-url |
alex/cpm-stable-base-url; 570c2f8ef479 |
Старый M2 experiment: меняет baseURL всем extensions, не доведён и не прогнан через нужный integration harness. Прежнее «production-ready» в старых планах не является актуальным итогом |
CI статусы — read-only snapshot GitHub 15 октября, 17:26 UTC. Подробные head/base/checks и все оговорки — основной статус; локальные воспроизведения не дают зелёного CI незапушенному коду.
0.1. Файлы remaining-failures и полный охват
Путь тестов — SharedPackages/WebExtensions/Tests/WebExtensionsTests/CPMRepro/.
| Файл | Что искать |
|---|---|
CPMReproLifecycleHypothesisTests.swift:30 |
12 методов: nil/previous controller, startup healthy control, source-linked shared-window close + unrelated-window control, forgotten live tab, listener metadata, long documents/dashboard loss, host main-actor stall |
CPMReproProductionFlagTests.swift:30 |
2 метода: главный flag true→false→true даёт P6; true→true не меняет manager; embedded-only cycle сохраняет controller и работает после explicit ready wait |
CPMReproBackgroundLoadFailureTests.swift:31 |
9 методов P2: ≥30-секундный медленный запуск, 10-секундный контроль, file/script/bindings ошибки и четыре отрицательных process/load проверки |
CPMReproExtensionLoadCleanupTests.swift:36 |
2 метода P3: relaunch и reload при большом Network cache и смене baseURL |
CPMReproWakeExperimentTests.swift:25 |
3 метода P1: 5/12-секундный wake и сравнение readiness signals |
CPMReproTestCase.swift:37 |
Базовый opt-in CPM_REPRO=1, Options, cleanup. existingTabs (68) предоставляет сохранённые view до load нового context |
CPMReproHarness.swift:258,269,296 |
open/close additional window через production eventsListener; adopt existing view. :175 watcher без strong reference через await; :365 content marks |
CPMReproTabs.swift:29,148,165 |
Реальные WKWebView, navigation gate/monitor callbacks, window/tab delegates и multiple-window provider |
CPMReproDelayedResource.swift:26 |
Реальный 35-секундный image subresource; URL уникален на каждую навигацию |
CPMReproPrelude.swift |
DOM init/initResp marks, trace всех autoconsent payloads, startup/listener test seams |
CPMReproSupport.swift:43,92,175,213 |
Pixel recorder; optional native-method suppression; temporary instrumented extension copy; WebKit process SPI |
Результаты: все 14 новых методов P5/P6 имеют pass по нескольким запускам; последние обычные tests — 478 XCTest / 28 skipped / 0 failures (10.469 с), strict SwiftLint восьми изменённых файлов — 0. P1/P2/P3 в этом продолжении заново не запускались. Таблица всех 14, начальные красные результаты, log paths и SHA-256 — основной статус §12.
0.2. Browser → WebKit paths
P5: MainWindowController.windowWillClose (611–640) фильтрует сохраняемые tabs только для явных didCloseTab, затем unregister и didCloseWindow. MainWindowController+WKWebExtensionWindow.tabs(for:) (31) всё ещё возвращает loaded pinned + regular tabs. WindowControllersManager.unregister (178) не очищает closing-window collections. WebKit внутри WebExtensionContext::didCloseWindow сам вызывает didCloseTab для каждого delegate tab; тот попадает в forgetTab. runtimeSendMessage возвращает tab-not-found до wake. Проверены текущий browser worktree и macOS tag 1.210.0+macos; shared-window effect исполнен на системном WebKit.
P6: AppDelegate.setupWebExtensions/initializeWebExtensions (2153–2166, 2209–2221) и shared FeatureFlag/WebExtensionFeatureFlagHandler.swift: main disable → uninstall + clear references; enable при manager=nil → новый manager/controller без пересоздания старых WKWebView. WebExtensionTab::webView отвергает неправильный controller. Только test-controlled main-flag cycle доказан; исторические данные не подтверждают такой production transition. Default main flag enabled; повторный true и embedded-only toggle не заменяют controller.
WebKit source checkout: /Users/admin/Downloads/WebKit_sparse, HEAD 99051d5d08cd9f19ec76ce599f7539d070b1ae09:
Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionContextCocoa.mm:1351,1419;Source/WebKit/UIProcess/Extensions/Cocoa/API/WebExtensionContextAPIRuntimeCocoa.mm:129;Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionTabCocoa.mm:339.
Это карта source contract и system-WebKit проверки, не утверждение о полном совпадении checkout с shipped binary. В SPM исполняются production shared classes и WebKit, а app-side host callbacks/delegates реализованы harness.
0.3. Команды и предусловия
Из alex/cpm-web-extension-remaining-failures/SharedPackages/WebExtensions:
CPM_REPRO=1 CPM_REPRO_P5_P6=1 swift test --disable-automatic-resolution --filter 'CPMReproLifecycleHypothesisTests|CPMReproProductionFlagTests'
CPM_REPRO=1 CPM_REPRO_P5_P6=1 swift test --disable-automatic-resolution --filter 'CPMReproProductionFlagTests|CPMReproLifecycleHypothesisTests/testClosing'
CPM_REPRO=1 swift test --disable-automatic-resolution --filter CPMReproWakeExperimentTests
CPM_REPRO=1 swift test --disable-automatic-resolution --filter CPMReproBackgroundLoadFailureTests
swift test --disable-automatic-resolution --skip-build
Первая команда всех 14 дана для повторения: в текущей сессии 14 методов проверялись раздельными группами. --skip-build применим после актуальной сборки. Для P3 нужны CPM_REPRO_CACHE_URL (server /fill.html?n=N) и CPM_REPRO_CACHE_ENTRIES (default 20000; заполнение порядка 10 минут), затем filter CPMReproExtensionLoadCleanupTests.
Выделенный PR-harness в cpm-repro-harness имеет быстрые tests без общего opt-in и requireLocalRun для тяжёлых; raw WebKit characterization требует также CPM_REPRO_WEBKIT=1. Новые P5/P6 живут только в remaining-failures и в PR-harness ещё не переносились.
Environment P5/P6: macOS 26.7.1 (25G241), Xcode 27.1 (27A9275), embedded bundle 2026.9.29. M4 в этих 14 tests выключен, gate включён, Network PID прогрет до context-load; production bundle zip не правился, temporary copy содержит trace/DOM instrumentation. Нативные flags в production не переключались.
Архив карты на 9 октября. Все следующие разделы сохранены для старых source line references и истории экспериментов; текущие точки входа и статус — выше.
Контекст: cpm-web-extension-breakage-session-summary-2026-10-07 (раздел 10), cpm-web-extension-repro-and-fix-2026-10-08. Номера строк — на 9 октября. Ничего не закоммичено. Корень всех worktree — /Users/admin/DuckDuckGo/apple-browsers.git/; пути ниже даны от корня worktree. SP = SharedPackages/WebExtensions/Sources/WebExtensions, TP = SharedPackages/WebExtensions/Tests/WebExtensionsTests.
| Worktree | Ветка, база | Что внутри |
|---|---|---|
alex/cpm-web-extension-ready-handshake |
та же, a0717cf098 |
Фиксы + основной harness |
alex/cpm-web-extension-remaining-failures |
та же, a0717cf098 |
Прод-код без фиксов, error 6 телеметрия (старая копия), репро error 6, очистки, медленного пробуждения |
alex/cpm-messaging-readiness-telemetry |
та же, main 92e09cdbbc |
Телеметрия фазы 1 (включает error 6) — кандидат на первый PR |
cpm-stable-base-url |
alex/cpm-stable-base-url, старая база 570c2f8ef4 |
Эксперимент со стабильным baseURL |
1. Фиксы — alex/cpm-web-extension-ready-handshake
Цепочка: навигация → coordinator спрашивает менеджер → менеджер проверяет watchdog и незавершённый первый старт background → при сбое монитор зовёт перезапуск.
SP/Lifecycle/WebExtensionLifecycleCoordinator.swift:79-93—initialLoadWaiter, его вызывают обе платформы на каждой main-frame навигации. Было: после открытия стартового gate →nil. Стало::89зовётmanager.prepareEmbeddedBackgroundForNavigation()и ждёт его не дольшеinitialLoadTimeout(5 с,:91-92).SP/Manager/WebExtensionManager+EmbeddedBackground.swift(новый)::35prepareEmbeddedBackgroundForNavigation()— сначалаwatchdog.restartBackgroundIfStale()(:36), потом возвращает waiter, если идёт первый старт background только что установленного extension.:45trackEmbeddedBackgroundStartup(identifier:)— запускаетcontext.loadBackgroundContent()(:49) какTaskи держит его вembeddedBackgroundStartup, пока не завершится. Зачем: WebKit при первой загрузке нового идентификатора грузит background сразу и теряетinit, пришедший до выполнения скрипта (317981).
SP/Manager/WebExtensionManager+EmbeddedExtensions.swift:178-180— послеinstallationStore.addдля.embeddedвызываетсяtrackEmbeddedBackgroundStartup. Покрывает установку и обновление посреди сессии (на запуске это уже делал стартовый gate).SP/Manager/WebExtensionManager.swift::134-139— свойстваembeddedBackgroundWatchdogиembeddedBackgroundStartup.:167— параметр initisEmbeddedBackgroundRecoveryEnabled(по умолчанию{ true }, к удалённому флагу не подключён).:186— создание watchdog.:217-221—healthMonitor.onEpisodeStarted→restartBackgroundIfResponsive(reason:): перезапуск по первому сбою.:757— в делегатеdidCreateBackgroundWebViewwatchdog получает новую background view.
SP/Lifecycle/EmbeddedBackgroundLivenessWatchdog.swift(новый)::63init — все зависимости подменяемые (PID, перезапуск, проба отзывчивости).:76backgroundWebViewDidChange— запоминает view и PID Network-процесса, запускает периодическую проверку.:85restartBackgroundIfStale— PID Network-процесса сменился (или исчез) → перезапуск. Это и есть детектор «Network-процесс упал, worker мёртв».:107restartBackgroundIfResponsive— перезапуск по сбою, только если процесс ответил наreturn 1за 1 с (:166-170). Замороженный не трогаем: убийство остановленного процесса давало глухой новый worker.:137периодическая проверка раз в 1 с;:156_networkProcessIdentifier(SPI через KVC);:173-180перезапуск через_killWebContentProcessAndResetState— WebKit поднимает новый worker, и чинятся даже уже открытые документы.
SP/Autoconsent/CPMMessagingHealthMonitor.swift:96-100— колбэкonEpisodeStarted;:656-658— вызывается на первом сбое нового эпизода, только дляfailureReason == .other(не session restoration).SP/Manager/WebExtensionManaging.swift:164-168— требование протокола;:176-178— реализация по умолчанию{ nil }, чтобы моки и платформы не ломались.
Тесты:
TP/EmbeddedBackgroundLivenessWatchdogTests.swift— 11 unit-тестов (:48–:150): смена PID, исчезновение Network-процесса, отзывчивый и неотзывчивый процесс, выключатель,stop(), периодическая проверка.TP/WebExtensionLifecycleCoordinatorTests.swift:193, :217, :227, :243— навигация ждёт первый старт; не ждёт, если готов; ожидание ограничено 5 с; при выключенном gate ничего не готовится. Мок —:667.TP/CPMMessagingHealthMonitorTests.swift:50, :61, :71—onEpisodeStartedна первом сбое; не на session restoration; снова для нового эпизода.- Harness
TP/CPMRepro/(запуск:CPM_REPRO=1 swift test --filter CPMReproизSharedPackages/WebExtensions):CPMReproSingleTabTests.swift— 10 тестов одной вкладки: холодный старт:32, обновление на запуске:46, установка/обновление посреди сессии:64,:87(до фикса терялись), перезапуск:111,:128, после reload:146,:165, пробуждение:187, падение background:206.CPMReproFullFailureTests.swift— краш Network-процесса:33,:38,:55(без M4); смерть worker'а через SPI:76и удаление регистраций:85(стоит одну навигацию); не-триггеры:124,:129,:136.CPMReproWebKitTests.swift— 7 тестов, нуженCPM_REPRO_WEBKIT=1: защиты выключены, утверждают, что баги WebKit ещё есть (:45потеряinitпри первой загрузке,:80/:87/:151мёртвый worker,:97только перезапуск background чинит открытые документы,:133сообщение из страницы background не доходит до worker'а).CPMReproWakeExperimentTests.swift:27-28— эксперимент, не для коммита: медленное пробуждение 5 и 12 с с фиксами. Для него вCPMReproHarness.swiftсвойствоstorageсделано неprivate.
2. Расследование без фиксов — alex/cpm-web-extension-remaining-failures
Прод-код как в релизе; harness перенесён без watchdog, с production-recorder'ом, поэтому сбои дают те же параметры пикселей, что в проде.
TP/CPMRepro/CPMReproHarness.swift::51recorder диагностики;:191contextErrorCodes;:196папка установленного extension;:203prependToBackgroundScript— дописывает код в начало background-скрипта на диске (WebKit читает его заново на каждом пробуждении);:212PID Network-процесса;:262loadRealPage(для наполнения кэша).TP/CPMRepro/CPMReproBackgroundLoadFailureTests.swift— error 6, 9 тестов, все с проверками::59новый процесс background заморожен на 45 с при пробуждении → только:6,bg_load_error_after=25s_to_35s. Это таймер выгрузки WebKit.:7010 с → error 6 нет.:79,:89,:96— другие пути к error 6 (нет файлов, скрипт бросает, нетbrowser) — быстрые,under_5s; в проде их сигнатур нет.:104,:111,:118,:125— условия, которые error 6 не дают.
TP/CPMRepro/CPMReproExtensionLoadCleanupTests.swift:49, :69— задержка очистки при сменеbaseURLна перезапуске и reload. Нужен локальный сервер:CPM_REPRO_CACHE_URL,CPM_REPRO_CACHE_ENTRIES(наполнение ~10 мин).TP/CPMRepro/CPMReproWakeExperimentTests.swift— эксперимент, не для коммита::27старт worker'а 5 с на пробуждении →initialization_failedс сигнатурой группы 1, затем поздний ответ.:2812 с + навигация →stuck→ M4.:31сигналы готовности:isLoading=falseчерез 0,1 с (бесполезен), completionloadBackgroundContentи первое нативное сообщение — ровно на старте worker'а.
- Продовые изменения здесь (
CPMMessagingDiagnostics*, JSON5,WebExtensionManager+iOS.swift,AppDelegate.swift) — старая копия телеметрии error 6, она целиком перенесена в worktree телеметрии. Отсюда не коммитить.
3. Телеметрия фазы 1 — alex/cpm-messaging-readiness-telemetry
Только параметры пикселей, поведение детектора не меняется.
SP/Autoconsent/CPMMessagingDiagnostics.swift::29ApplicationState,:38провайдер состояния приложения вCPMAppSessionDiagnostics.:50CPMBackgroundReadiness:noBackground/pending/loaded(seconds)/failed.:109-123новые поля снимка (error 6,applicationState, возраст view, готовность, вкладки).:182-188имена параметров (bg_load_error_*,app_state,bg_view_age,bg_ready_after,open_tabs,loading_tabs).:217-231сериализация: error 6 —none, если ошибки не было, и опускается, если неизвестно; остальные опускаются приnil.- Бакеты:
:248error 6 (вокруг таймера 30 с),:258возраст view,:269готовность (вокруг 4 с монитора и 30 с WebKit),:285число вкладок.
SP/Autoconsent/CPMBackgroundReadinessObserver.swift(новый) — откуда берётсяbg_ready_after::52observeна создании view: ставитpendingи на следующем шаге run loop (:56) зовётloadBackgroundContent. View уже есть, поэтому вызов лишь присоединяется к идущей загрузке и ничего не будит.- completion →
loaded(секунды от создания view)илиfailed; ответ для заменённой view игнорируется. :34загрузчик подменяется в тестах;:72readiness(of:)— только для текущей view.
SP/Autoconsent/CPMMessagingDiagnosticsRecorder.swift::125,:141наблюдатель;:223сброс при новом контексте.:311-316наблюдение включается тем же флагом, что и delegate proxy (cpmBackgroundDelegateProxy).:413-415поля error 6;:426состояние приложения;:430-431возраст view и готовность;:435-438open_tabs/loading_tabsизcontext.openTabsиwebView(for:).isLoading.:503-517recordContextErrors— при error 6 фиксирует состояние приложения и секунды от создания view.
SP/Pixels/WebExtensionPixelFiring.swift::71,:73— у recovery-событий появилсяdetails(по умолчаниюnil, старые вызовы не ломаются).:85CPMMessagingRecoveryDetails:failed_navigation(опоздавший ответ) /later_navigation/unattributed+:108бакетыrecovery_after.:181-188параметры пикселя.
SP/Autoconsent/CPMMessagingHealthMonitor.swift::451-452неатрибутированный ответ закрывает stuck →unattributed.:712-716обычное восстановление: тот же упавший замер →failed_navigation, иначеlater_navigation.:722recoveryDetails— секунды от первого сбоя эпизода.
- Приложения:
iOS/DuckDuckGo/WebExtensions/WebExtensionManager+iOS.swift:107-114(UIApplication.applicationState),macOS/DuckDuckGo/Application/AppDelegate.swift:122-123(NSApp.isActive). - JSON5:
- словари
iOS/PixelDefinitions/pixels/params_dictionary.json5(:602recovery,:619error 6,:643готовность и вкладки) иmacOS/.../params_dictionary.json5(:677,:694,:718); - определения — iOS
debug_pixels.json5, macOSweb_extensions.json5: по 8 пикселям сбоя и 2 пикселям восстановления.
- словари
Тесты:
TP/CPMMessagingDiagnosticsTests.swift:- бакеты
:135,:144,:149; полный набор параметров:154; - error 6
:279,:417; - готовность: загрузилась
:304, упала:327, заменённая view:343, наблюдение выключено:360; - состояние приложения
:377; вкладки на реальном контроллере с незавершающейся загрузкой:384.
- бакеты
TP/CPMMessagingHealthMonitorTests.swift: опоздавший ответ:1061, следующая навигация:1081,unattributed:1095, бакеты:1112, обновлённый тест параметров:1119.- Проверка на реальном WebKit (harness временно копировался): медленное пробуждение 5 с →
bg_ready_after=pending,bg_view_age=4s_to_8s, затемrecovery_document=failed_navigation,recovery_after=under_4s.
4. Стабильный baseURL — cpm-stable-base-url
SP/Loading/WebExtensionLoader.swift:56,:93,:134,:154,:158-165— вmakeContextвыставляетсяcontext.baseURL = webkit-extension://<uniqueIdentifier>/; если из идентификатора не собрать URL — ошибкаinvalidIdentifier.TP/WebExtensionLoaderDelegateTests.swift:61-94— 2 теста: URL выставлен до загрузки; неверный идентификатор → загрузка не начинается.- Открыто: сейчас меняет URL всем extension (нужно — только встроенным без
web_accessible_resources); не прогнан через harness (M4, краш Network-процесса, обновление); старая база.
5. App-hosted CPM integration tests — 16 октября 2026
Worktree /Users/admin/DuckDuckGo/apple-browsers.git/cpm-e2e-init, branch scratch/cpm-e2e-init, HEAD 46f25175c7c42766cab23ea39f447f075c7bdd24, без commits. Новая схема macOS/DuckDuckGo-macOS.xcodeproj/xcshareddata/xcschemes/CPM Integration Tests.xcscheme выбирает только две CPM classes, отключает parallel testing и включает CPM_APP_INTEGRATION=1. В ней нет Review-profile wipe/pre-action или killall tests-server.
Файл в macOS/IntegrationTests/CPM/ |
Роль |
|---|---|
CPMAppIntegrationTests.swift |
10 deterministic baseline/diagnostics/scope/recovery tests: slow HTTP/native, одна навигация, одна таба, несколько табов одного окна, все окна, M4, dashboard transport, proxy flag |
CPMAppKnownFailureIntegrationTests.swift |
10 characterization methods: actual AppDelegate flags, shared-pin window closure, Network/background crashes, first install, slow idle wake, frozen WebKit load timeout, 20k persistent-cache reload |
CPMAppIntegrationHarness.swift |
Реальные AppDelegate/WindowsManager/MainWindowController/Tab, production navigation/monitor/recorder, JSON attachments, owned windows/data stores, bounded cleanup |
CPMAppIntegrationSupport.swift |
Реальный macOS native handler/provider/delegate с fault boundary; recorder transport before daily dedup; extraction через production storage; in-memory installation store; test-only PID/background SPI |
CPMAppIntegrationBridge.swift |
Instrumentation только распакованной временной extension copy: page initResp mark, реальные runtime messages и scoped drop/release controls |
CPMAppFixtureServer.swift |
Owned HTTP loopback, eight-second resource delay, cacheable 2KiB resources with unique URLs |
README.md |
Повторение, signing, flags, все сценарии, ограничения причинной интерпретации |
Все 6 Swift files включены в Integration Tests и Integration Tests App Store. Минимальные production seams: optional manager controllerConfiguration с прежним default; DEBUG AppDelegate factory с двумя guards; отдельный ConfigurationStore directory для CPM test host; разрешён только loopback HTTP в opted-in integration Tab; macOS diagnostics flag adapter доступен через @testable без изменения поведения. SecureVault/AppMain bypass отсутствует. Существующие dirty ZIP/SPM files сохранены.
Запускать с project signing defaults, как в Xcode; unsigned override оказался ошибкой bootstrap и удалён. CLI run recipe находится в README. Для реального 30s WebKit timeout нужен test-host env CPM_APP_INTEGRATION_EXPENSIVE=1; для persistent cache — CPM_APP_INTEGRATION_CACHE=1, при необходимости CPM_APP_INTEGRATION_CACHE_ENTRIES, execution allowance 2400 s. Cache case лучше выбирать отдельно; этот opt-in включает fresh persistent UUID configuration в harness. Обычные запуски используют nonpersistent stores.
Артефакты /private/tmp/cpm-app-integration-20261015/: signed .xcresult, logs, exported JSON, app-test-results.json (история результатов и hashes исходников). Финальные результаты сверять с §13 cpm-status-2026-10-15, не считать каждый characterization test доказательством воспроизведения причины. P3 может пройти с отрицательным outcome; background crash может самоизлечиться. App P5 ограничен одной потерянной навигацией и контролями: более длинная попытка прерывалась DEBUG guard закрытого окна в XCTest. Persistent P5/stuck доказан отдельно SPM, что не превращает app attempt в green. iOS/device-only причины и естественная потеря listener metadata этим suite не доказаны.
App harness isolation follow-up: extension resources now use an owned UUID directory under unswizzled NSTemporaryDirectory(), outside com.duckduckgo.macos.tests. The latter is a shared FileManager swizzle target that TestRunHelper removes on host initialization/bundle completion. A preceding joint run passed 16/18 but lost its Network-test extension resource before reload (extensionNotFound), then the next wake test hit INT. The deleter was not identified; latest status must include that red run and the resource-isolation recheck, rather than treating prior isolated passes as a green combined suite. CPMAppExtensionStorage.resolveInstalledExtension still delegates to production and adds only missing-folder/root logging.
Финальная сверка §5: signed-isolated-regression 18/18, signed-isolated-pinned 1/1 (72.644 s), signed-isolated-cache 1/1 (43.053 s). Все summaries: 0 failures, 0 skipped, 0 expected failures. В последнем cache run 20k ресурсов за 39.113 s, post-reload probe 0.900 s, P3 не воспроизведён, UUID store удалён. Все 20 JSON exported в одноимённые *-evidence/ directories; /private/tmp/cpm-app-integration-20261015/app-test-results.json содержит текущие hashes исходников и всю per-method историю. HEAD 46f25175c7c42766cab23ea39f447f075c7bdd24 сохранён, исходный dirty ZIP не менялся. Финальный strict lint: 11 Swift files, 0 violations; PBX и scheme XML валидны. Предыдущие red attempts сохранены, не превращены в pass; единый invocation всех 20 не выполнялся.
16 Oct clarification/rerun: all 20 current app methods passed again in 18+1+1 groups, same signed build and source hashes; /private/tmp/cpm-app-integration-20261015/rerun-failed-20261016-042858/rerun-summary.json. This is an instrumented app-test environment, not an unchanged shipping binary. P1/P2 delay/SIGSTOP and message/native/dashboard loss are imposed faults; P5/P6/Network use real lifecycle paths but their production occurrence/causal attribution is a separate claim. Old long P5 is still outside the verified app scope; P3 remains unreproduced. Cache teardown has a recorded nonfatal SQLite warning. Submodules are not required by these CPM cases: privacy-reference-tests resources map to Unit Tests targets, SnapshotReferences to snapshot testing support, not XCUI accessibility snapshots. Neither submodule was initialized or modified by this rerun.
Локальный кандидат P1/P2 — 16 октября 2026 (без commits)
Worktree cpm-e2e-init, HEAD всё ещё 46f25175c7c42766cab23ea39f447f075c7bdd24. Эта секция дополняет прежнюю карту: #7379 не изменялся, новая работа пока только локальная.
WebExtensionLifecycleCoordinator.initialLoadWaiter: после launch gate проверяет подготовку background на каждом HTTP(S) main-frame navigation. Await ограничен прежними 5 s и отменой navigation; AsyncStream позволяет освободить navigation даже при callback WebKit, игнорирующем cancellation. Жизненный цикл load/sync этим не блокируется.WebExtensionManaging.prepareEmbeddedBackgroundForNavigation: новый protocol hook с no-op default для лёгких conformers. Реализация —WebExtensionManager.swift, без нового project file.WebExtensionManager.loadEmbeddedExtensionBackgroundContent: публичный callback API + одна shared startup task на текущий context. Error notification завершает/очищает старую readiness task, чтобы новая попытка не приклеилась к завершённому старому startup.WebExtensionManager.recoverEmbeddedBackgroundLoadFailure: собственный текущий embedded context, настоящий domain/code 6, существующий recovery kill switch, known app_state != background, отсутствие M4 in-progress и cooldown 60 s. Повторяется только background load; context/Tab/controller не заменяются. Полный M4 reload остаётся при confirmed stuck. Старый full-context P2 prototype отброшен: он терял page initResp в existing tab при повторе.CPMAppKnownFailureIntegrationTests.testSlowBackgroundWakeKeepsFirstNavigationHealthy: actual idle + 8 s worker delay, первый документ получает native+page без detector failure....testFrozenBackgroundRecoversAutomaticallyForNextNavigation: actual one-tab idle wake, owned SIGSTOP 45 s, настоящий error 6. Требует native+page на том же failed document до новой navigation, тот же объект context и recovery_document=failed_navigation; затем healthy existing/new-window/new-tab.- Raw P1 и P3 characterization отключают navigation gate; P5 остаётся с gate включённым и ожидает bucket bg_view_creations=3_to_5: подготовка P1 создаёт дополнительный background перед rejected unknown-tab message. P5 tab-registration loss и healthy controls по-прежнему проверяются.
Артефакты и snapshots: /private/tmp/cpm-p1-p2-fixes-20261016/. before-changes.tar.gz сохраняет прежние dirty changes; point-fixes.diff предназначен для delta этой работы. Начальный background-only result — 2/2 PASS, пакет 806/14 skipped/0 failures. Общий run/negative controls/P5/cache ещё выполняются; окончательный исход — в cpm-status-2026-10-15. Зелёный случай относится к macOS с imposed timing/process faults; natural iOS cause по-прежнему не доказан.
Финальная сверка P1/P2, 16 октября 12:30 UTC: работа завершена без commits. validation-summary.json: 22/22 уникальных app methods PASS, positive groups 2+19+1+1 (P2 повторён), 0 failures/skips/expected failures; оба disabled-fix controls functional FAIL. unit-package-background-retry.log: 806 / 14 skipped / 0 failures; strict lint 6 файлов — 0 violations. Source hashes после сборки не менялись, прежние dirty files/ZIP сохранены. Окончательный P2 — background-only retry и same-document native+page recovery, не context replacement. Предыдущая full-reset реализация отвергнута после повторной потери page initResp. Current patch — /private/tmp/cpm-p1-p2-fixes-20261016/point-fixes.diff; P5 ожидает дополнительный view от P1, P3 остаётся отрицательным на 20,000 resources. Cache assertions прошли, но teardown снова имеет известный SQLite vnode warning для owned UUID. Подробная проверенная матрица/ограничения и весь red-history — cpm-status-2026-10-15.
Отдельный worktree P1/P2 — 16 октября 2026
/Users/admin/DuckDuckGo/apple-browsers.git/alex/cpm-fix-p1-p2, branch alex/cpm-fix-p1-p2, от alex/cpm-messaging-readiness-telemetry (01d4a0ec22), без коммитов. Отличается от полного scratch research-набора:
WebExtensionLifecycleCoordinator.initialLoadWaiter: после launch открывает ограниченное 5 s ожидание background wake; cancellation-safe AsyncStream, существующий gate flag.WebExtensionManager.prepareEmbeddedBackgroundForNavigation/loadEmbeddedExtensionBackgroundContent: один startup job на конкретный context object, public WK callback, release pending callers при error/reload.- Observer
WKWebExtensionContext.errorsDidUpdateNotification/recoverEmbeddedBackgroundLoadFailure: error 6 только своего embedded context, существующий recovery flag, current background guard, throttle 60 s; повтор background load без context replacement. M4 reload остаётся fallback. - Recorder
isApplicationInBackground: читает уже существующий appSession lifecycle provider, не добавляет telemetry dimension. macOS/IntegrationTests/CPM/: пять Swift-файлов, ровно два app-тестаCPMBackgroundRecoveryIntegrationTests, сокращённая инфраструктура; схемаCPM Integration Tests. Реальные app windows/tabs/native handlers/WebKit, неизменный bundled ZIP, extracted startup-delay и page initResp observation, SIGSTOP только своего background PID. Scoped drop/cache/Network/P3/P5 сценарии остались в research worktree.- Четыре новых метода
WebExtensionLifecycleCoordinatorTests: wake после launch, bounded non-cancellable callback, cancellation, disabled flag. Всего 6 новых test methods; 22 — весь прежний app-набор.
Текущая база уже перешла на episode contract. Test-only diagnostics proxy фиксирует реальный first-failure вызов, не синтезируя monitor events. P2 требует terminal failed_measurement_response / reload_state=none плюс page initResp исходного документа до другой навигации и ту же context identity. Signed app 2/2 PASS; unit 31+134=165 PASS; strict lint 14 files / 0 violations. Оба disabled-flag контроля на той же сборке функционально FAIL. Test autorelease pools исправили deallocation guard без отключения проверок. Source hashes и исходный scratch неизменны; schemas/ZIP/dependencies в diff не менялись. Артефакты и полная история: /private/tmp/cpm-p1-p2-clean-20261016/validation-summary.json, cpm-status-2026-10-15. Границы P1 cap / macOS injection / неустановленного natural iOS trigger сохраняются.
Объединение #7379 с P1/P2 и независимый lifecycle guard — 16 октября 2026
Текущий alex/cpm-fix-p1-p2 семантически заменяет #7379 в пределах прежнего navigation timeout 5 s:
WebExtensionManager+EmbeddedExtensions.installEmbeddedExtensionвызываетtrackEmbeddedBackgroundStartup(identifier:)именно для вновь установленного embedded context.- Manager сохраняет preferred context, а
prepareEmbeddedBackgroundForNavigationзахватывает конкретный context object. Fallback учитывает append-порядок installation store и не выбирает произвольный context при неизвестном порядке нескольких версий.loadEmbeddedExtensionBackgroundContent(in:)coalesces job на тот же object. recoverEmbeddedBackgroundLoadFailureигнорирует superseded context. Состояние background приходит через самостоятельныйisApplicationInBackgroundprovider; iOS factory читаетUIApplication.shared.applicationStateнезависимо от diagnostics flag. Старый diagnostics getter удалён. Перед queued retry повторно проверяются flag/background.- Два install/upgrade-теста #7379 адаптированы в
CPMBackgroundRecoveryIntegrationTestsрядом с P1/P2. Реальный upgrade даёт context sets[0,1,2,1]; assertions требуют native dashboard + page initResp первого документа, а не просто загрузку context. Default delay 4500 ms. - Пять новых manager unit tests проверяют coexistence/newest selection, fallback после удаления replacement, diagnostics=nil + background→foreground, runtime kill switch и отказ retry старого context. Вместе с четырьмя lifecycle tests в ветке 9 новых unit methods.
Финальная валидация: общий signed app 4/4 PASS; install/upgrade 10/10 + 10/10 PASS на той же сборке; targeted unit 170 PASS, strict lint 16 files / 0 violations; WebExtensions generic iOS Simulator module BUILD SUCCEEDED. Все 4 disabled-flag controls функционально FAIL без teardown errors. Коммитов и изменений scratch/ZIP/schema/dependencies нет.
Локальные [CPM Background] logs показывают медленный WK callback (>=1 s) и release gate по deadline. Они подтвердили предел: fixture 5000 ms даёт фактическую готовность после 5 s cap и может потерять первый upgrade document (6/10 ранее). Этот over-budget режим не исправлен и сохраняется через CPM_APP_INTEGRATION_INSTALL_DELAY_MS=5000; здоровые contract regression cases проверяют 4500 ms. Это не доказательство всех natural production causes и не реальный iOS suspension/resume run. Артефакты и история: /private/tmp/cpm-p1-p2-replacement-20261016/validation-summary.json, cpm-status-2026-10-15.
Дополнение: late background recovery — 16 октября 2026, работа продолжается
По запросу сначала сохранён прежний проверенный стейт: commit dff29dfb1e (Fix CPM background wake and installation readiness) в alex/cpm-fix-p1-p2. Предыдущие утверждения «коммитов нет» относятся к проверке до этого checkpoint. Новые изменения пока не закоммичены.
Добавлен кандидат восстановления потерянного первого документа при startup за пределами 5 s: отдельный remote flag webExtensions.cpmLateBackgroundDocumentRecovery, default disabled. Navigation cap остаётся 5 s. Кандидат привязывает документ к конкретному unfinished startup, требует настоящий missing-dashboard timeout и успешный public WK background callback; после этого допускает одну GET-перезагрузку в пределах 30 s от старта. Смена/закрытие/ошибка документа, context replacement, background app state, выключение flag, изменённые form fields/contenteditable/loading document отменяют reload. Логика независима от diagnostics flag.
Пять новых dailyAndCount pixels различают install readiness, upgrade readiness, idle background wake, error-6 background retry и late document reload. background_ready — факт успешного WK callback после использованного navigation wait (для error-6 retry — любого успешного retry), не доказательство initResp; reload_started — принятый WK reload; response_received — однозначно атрибутированный dashboard response после reload, не ACK content script. App tests отдельно требуют настоящий page initResp. macOS names заканчиваются _macos, iOS — стандартные platform/form-factor suffixes. Только outcome, appVersion и стандартные platform parameters, без URL/tab ID/form values/raw error.
На данном этапе: targeted unit suite 178 PASS, strict lint 17 Swift / 0 violations, pixel definitions + wide-event consistency/immutability validators обеих платформ PASS. Подписанная app-сборка и реальные install/upgrade 8000 ms regression runs ещё не завершены; over-budget failure пока НЕ объявлен исправленным. Новые артефакты: /private/tmp/cpm-late-recovery-20261016/.
Итог late background recovery и fix instrumentation — 16 октября 2026
Актуальный стейт: checkpoint dff29dfb1e сохранён до новых изменений; новый код/tests/pixels в alex/cpm-fix-p1-p2 остаются незакоммиченными. Новый flag webExtensions.cpmLateBackgroundDocumentRecovery default disabled, динамически проверяется до попытки и после async safety check; remote config не менялась. Navigation cap по-прежнему 5 s.
Новый CPMBackgroundReadinessRecovery.swift в shared Autoconsent получает startup UUID manager, commit/failure/response/navigation events monitor и зарегистрированный GET WKWebView от platform tabs. Документ должен commit во время известного unfinished startup; только genuine missing-response timeout вместе с successful public background callback допускают одну GET-перезагрузку в пределах 30 s startup. Изменённый/loading/closed/failed document, main-document form edits/contenteditable, background app state, flag OFF и context replacement запрещают reload. Идентичность проверяется после async JS. Результат — replacement document на том же URL, сохранённый extension context; P2 background-only recovery исходного документа остаётся отдельным механизмом. Safety check использует настоящий async WK API label contentWorld:; ранние красные app runs поймали ошибочный callback overload с Void, и вся история сохранена.
Пять отдельных dailyAndCount pixels с prefix web_extension_cpm_: install_readiness, upgrade_readiness, background_wake, background_load_retry, late_document_reload. macOS suffix _macos, iOS standard suffixes. Первые четыре: background_ready после использованного slow navigation wait (для P2 любого successful retry), без page-ACK claim; последний: reload_started и однозначный dashboard response_received после replacement navigation. Ответ исходного документа во время safety check не получает credit. Только outcome и стандартные параметры, без URL/tab IDs/field values/raw errors. Injection + PixelKitMock adapter test, definitions/validators обеих платформ PASS. Existing episode contract сохранён; document reload даёт failed_tab_response, extension reload_state=none.
Проверено на одной финальной подписанной сборке: общий набор 8/8 PASS (7 app/WebKit scenarios + adapter test); новые 8-second install/upgrade 2/2 PASS, затем 10/10 repetitions PASS; новый flag OFF 2/2 функционально FAIL, 0 skips/expected failures/teardown errors. Во всех 14 positive over-budget executions первая загрузка 5.085–5.328 s, затем ровно один reload, настоящий page initResp + native dashboard, URL/context сохранены. Edit-veto app test PASS; прежние P1/P2/install/upgrade PASS. Targeted units 179 PASS (9 новых recovery; всего 18 новых unit methods в ветке), lint 17 files / 0 violations, новый recovery без compiler warnings. Shared iOS Simulator и FeatureFlags-iOS builds PASS; полный iOS app/runtime не запускался.
Code entry points: manager background startup callback/typed fix marker; monitor backgroundReadinessRecovery и registerReadinessRecoveryDocument; macOS PrivacyDashboardTabExtension weak view + real initiating request method; iOS TabViewController main-frame GET tracking; platform factories dedicated provider; PixelFiring adapters + platform JSON5 definitions. Все 8 app methods остаются в существующем CPM file/scheme; SharedPackages files подхватывает SwiftPM без pbxproj изменений.
Все facts/history/guards/pixel semantics: cpm-status-2026-10-15, /private/tmp/cpm-late-recovery-20261016/validation-summary.json. Source/app/test binary hashes стабильны; bundled ZIP равен checkpoint; package pin side effect убран; scratch/#7379 не менялись. Это opt-in bounded GET recovery, не универсальное исправление permanent background failures/unsafe documents. Прежние P3/P5 и natural-production/iOS suspension ограничения не сняты; 22 historical research methods отдельно.
Перенос в PR #7379 поверх #7376 — 16 октября 2026
Git и состав PR
По запросу до переноса сохранён checkpoint 367759cbc17d717b05e53ab30792c077ff103a8b в alex/cpm-fix-p1-p2 (предыдущий checkpoint dff29dfb1e также сохранён). Старый чистый worktree /Users/admin/DuckDuckGo/apple-browsers.git/cpm-fix-init-loss удалён штатно; локальные ignored settings сохранены в /private/tmp/cpm-pr7379-port-20261016/retired-worktree-local-settings.tar.gz. Research worktree cpm-e2e-init и его незакоммиченные данные не менялись.
Рабочая директория остаётся /Users/admin/DuckDuckGo/apple-browsers.git/alex/cpm-fix-p1-p2, но её текущая ветка теперь alex/cpm-fix-init-loss. Финальный HEAD aec5be9a834e97984d4cbbee01a207548222427c, ровно 3 коммита / 32 изменённых файла поверх #7376, base branch alex/cpm-messaging-readiness-telemetry, base SHA 713d67419a776b235b66210b1c594ce39da6fe03:
05b499e355— P1/P2, ожидание нового install/upgrade context и необходимые app/unit tests.c661f805b1— late GET document recovery, независимый flag, пять fix pixels, регрессии.aec5be9a83— маркировка local-only fault-injection suite/scheme/README какto-be-disabled before merge.
PR #7379 обновлён разрешённым force-with-lease с точным ожидаемым старым head 7ad771e227bbd68348ed7b719684783575dd7c9f; новый head/base проверены через GitHub. Старый head и промежуточная история сохранены в backup branch alex/cpm-fix-init-loss-before-force-20261016 (70869f5c69). Зависимость от #7378/research SPM harness убрана из diff; episode contract #7376 сохранён. Промежуточный перенос на прежнюю базу с 167 unit tests — историческая попытка, окончательный результат относится к новой базе и 179 tests.
PR title/description/Testing Steps переписаны под окончательный код. Коммитить или переключать test-only/fix commits для проверки не требуется. Удалены старые инструкции и placeholder GREEN_RUN_URL; используется одна подписанная сборка с переключением production flags в test fixture.
Feature flags
| Механизм | Remote flag | Default |
|---|---|---|
| Install/upgrade readiness + P1 navigation wake wait | webExtensions.stateRestorationGate |
Enabled, существующий |
| P2 background-only error-6 retry | webExtensions.cpmMessagingHangRecovery |
Enabled, существующий |
| Late first-document GET reload | webExtensions.cpmLateBackgroundDocumentRecovery |
Disabled, новый независимый |
Флаги явно задаются fixture; ENV CPM_APP_INTEGRATION_DISABLE_P1_P2_FIXES=1 и CPM_APP_INTEGRATION_DISABLE_LATE_RECOVERY=1 выбирают соответствующие negative controls без изменения исходников или binary. В двух over-budget controls отключается late recovery при сохранённом 5 s navigation gate, чтобы изолировать новый механизм. Remote configuration не изменялась.
Финальная проверка запушенного head aec5be9a83
Новый прогон на базе #7376, macOS 26.7.1, Xcode 27.1, нормальная подпись Apple Development: Alexey Martemyanov (9SAT8X9S84) / team HKE973VLUW. Проверены identity подписи app и strict signatures app debug dylib / XCTest bundle; это не заявление о distribution signing/notarization или полной deep-проверке вложенных продуктов.
| Проверка | Результат |
|---|---|
| Все восемь методов dedicated app suite, соответствующие flags ON | 8/8 PASS, 0 failures/skips/expected failures |
| Шесть recovery controls, соответствующие flags OFF, те же бинарники | 0/6 PASS, 6 функциональных FAIL, 0 skips/expected failures, без teardown/deallocation errors |
| Targeted shared suites | 179 PASS, 0 failures/skips (13 diagnostics + 9 recovery + 78 monitor + 31 lifecycle + 48 manager) |
| Strict lint относительно новой PR base | 27 Swift files, 0 violations |
| Pixel schemas/formatting + wide-event consistency/immutability | macOS и iOS PASS |
| Source/binary integrity | Все 32 source hashes и 2 app/test binary hashes неизменны; git status чистый |
Положительный набор: P1 slow idle wake, P2 реальная WK error 6 с background-only retry и ответом исходному документу без навигации, install, upgrade при coexistence contexts, late install, late upgrade, edited-document veto и PixelKitMock adapter. При 8000 ms startup в новых late install/upgrade runs первый документ завершился за 5.159 / 5.093 s, затем ровно один automatic reload (итого два finish), настоящий page initResp и native dashboard, URL/context сохранены. Navigation cap остаётся 5 s. Отдельные десять stress repetitions и более ранние iOS module/flags builds относятся к предыдущему checkpoint/проверке, не объявляются новым stress/iOS runtime run на этом head.
Красные controls на той же сборке: install/upgrade теряют первый native/page ответ; P1 получает response timeout; P2 достигает реальной error 6, но без flag не получает same-document recovery; оба over-budget случая не получают automatic document recovery. Это намеренные функциональные FAIL, не инфраструктурные crashes и не XCTExpectFailure. У controls и positive runs отдельные .xcresult / summaries / JSON attachments.
Local app suite, setup и dedicated scheme/README помечены to-be-disabled before merge. Они уже требуют CPM_APP_INTEGRATION=1 и пропускаются обычным CI без opt-in. Сценарии используют GUI-host и 45 s SIGSTOP только собственного background PID; deterministic unit regressions оставлены включёнными. General macOS UI Tests scheme локально не запускалась из-за её profile-clearing preaction.
Артефакты нового прогона: /private/tmp/cpm-pr7379-final-20261016/validation-summary.json, рядом enabled.xcresult, disabled.xcresult, JSON evidence, logs, signature/hash snapshots, pr-after.json, финальный PR body и CI snapshots. Bundled extension ZIP неизменён относительно base/checkpoint: SHA256 ff98a2b0c07819b2ee5ee6de67d6dd8d28696363c08c9fbc2c32255e9d9efa94; package pin side effect убран. Прежние red runs и расследовательские данные сохранены.
Новый remote CI после push запущен; локальный PASS не выдаётся за завершённый зелёный GitHub CI. Контракт fix pixels остаётся прежним: background_ready — callback readiness, response_received — dashboard correlation после reload; page ACK проверяет app assertion отдельно. Default-disabled late flag не включался в remote config. Natural production attribution, unreproduced P3, прежние P5 app ограничения и реальный iOS suspension/resume этой работой не закрыты.
GitHub checks после push
Финальная сверка CI для aec5be9a83: основные jobs ещё IN_PROGRESS/QUEUED; Danger — FAILURE, точная причина — новые pixels требуют label privacy review required, который создаёт privacy-review task в Asana. Label в этой работе не менялся. Дополнительно Danger предупреждает об отсутствующем Asana Feature Flags project task link для cpmLateBackgroundDocumentRecovery в macOS/iOS enum comments и размере PR; это warnings, не причина функциональных app failures. Значения flags и локальные ON/OFF результаты выше подтверждены независимо. Evidence: /private/tmp/cpm-pr7379-final-20261016/danger-comment.md, ci-final.json.
Вынос app harness из PR #7379 — 16 октября 2026
По запросу весь local-only app harness вынесен в отдельную review-only ветку codex/cpm-fix-init-loss-integration-tests, основанную непосредственно на очищенном alex/cpm-fix-init-loss. Тестовая ветка не предназначена для merge в main, отдельный PR на неё не создавался.
- Production PR #7379: head
da126120a94b625cf1d9705302c29099b4dbc62d, база #7376 /713d67419a, 2 коммита, 21 файл.7dbe2a25bb— P1/P2/install/upgrade;da126120a9— late recovery + flags/pixels. Все 21 production/unit/schema файла побайтово совпадают с прежнимaec5be9a83; поведение и defaults не менялись. - Harness branch: head
6e4e39e67c64907127bd17197a932b0117a4cb09, parent ровно production headda126120a9, один дополнительный commit, 11 test-only paths. Это пять Swift app-test files + README, CPM scheme и PBX registrations, DEBUG manager factory/config storage/loopback navigation hooks в AppDelegate, ConfigurationStore, Tab. - Все app hooks и Xcode project changes исключены не только из финального diff PR, но и из его двух новых коммитов. 18 новых deterministic shared unit methods остаются в production PR; восемь app methods — только в harness branch.
- В harness комментариях прежнее
to-be-disabled before mergeзаменено на ясное review-only назначение: эта ветка не идёт в main. Explicit scheme opt-in сохранён. Старые checkpoints и исходная история сохранены; дополнительный backupcodex/cpm-fix-init-loss-before-harness-split-20261016->aec5be9a83. - Reviewer instructions в PR: unit suites на PR branch;
git fetch origin,git switch --detach origin/codex/cpm-fix-init-loss-integration-tests; открыть workspace, выбрать CPM Integration Tests / My Mac, ⌘U, ожидать 8 PASS / 0 skips; затем вернутьсяgit switch --detach origin/alex/cpm-fix-init-loss. Production description и пользовательские правки сохранены. Исторические intentional-red controls не возвращены в reviewer steps.
Артефакты разделения: /private/tmp/cpm-harness-split-20261016/: manifest с production/harness paths и исходными SHA256, раздельные patches, build/unit/lint/signing logs и snapshots PR description. Точные окончательные результаты новой проверки и remote SHA — ниже.
Проверка после разделения
- Production
da126120a9: обычная macOS Browser Debug app build PASS без harness; нормальная Apple Development подпись, teamHKE973VLUW; strict app dylib verification PASS. - Production shared regressions: 179/179 PASS, 0 failures/skips; 18 новых unit methods сохранены в PR.
- Review-only harness
6e4e39e67c: полныйxcodebuild test(эквивалент Product → Test), 8/8 PASS, 0 failures/skips/expected failures, отдельная подписанная app/XCTest сборка. Все 32 source hashes неизменны во время run; strict dylib/XCTest signature checks PASS. - Strict lint: 19 production Swift files / 0 violations, 8 harness Swift files / 0 violations. PBX syntax и scheme XML валидны; каждый из пяти harness Swift files зарегистрирован ровно по одному разу в обоих native Integration Tests targets. Выполнен normal signed target, не отдельный App Store runtime run.
- Подтверждены remote SHA обоих branches и GitHub PR diff: production
da126120a94b625cf1d9705302c29099b4dbc62d, harness6e4e39e67c64907127bd17197a932b0117a4cb09; parent harness совпадает с production head. Production PR остаётся на базе #7376. В рабочей директории сноваalex/cpm-fix-init-loss, git status чистый. validation-summary.json,pr-after.json,remote-heads.txt,harness-enabled.xcresultи JSON evidence находятся в/private/tmp/cpm-harness-split-20261016/. Generated Package.resolved side effect сохранён и убран из рабочей копии; production dependencies/ZIP не менялись.- Новые шесть disabled controls после branch-only split не повторялись: предыдущие 6/6 functional FAIL на эквивалентном production/harness code остаются историческим evidence в
/private/tmp/cpm-pr7379-final-20261016/. Нового stress/iOS runtime run не заявляется. P3, прежние P5 app и natural-production/iOS ограничения сохраняются. Remote CI нового head — отдельная незавершённая проверка, snapshotci-after-split.json.
Ранние формулировки о local-only suite внутри production PR и необходимости disable перед merge описывают прежнюю структуру. В актуальном PR этих файлов и hooks нет; review-only branch целиком остаётся вне main.
Возврат проверки production feature flags OFF → failures — 16 октября 2026
При упрощении reviewer instructions ошибочно удалён необходимый negative-control шаг. В PR #7379 восстановлен полный ON → OFF → ON workflow с конкретными Xcode schemes; остальные пользовательские правки сохранены.
В review-only branch codex/cpm-fix-init-loss-integration-tests добавлен commit 543e37164b369c8da8b6734e500af4a203944943, только два файла: новый shared scheme CPM Integration Tests - Fixes Disabled и README с точными cases/flags/ожидаемыми failures. Эта ветка теперь содержит 2 test-only commits / 12 paths сверх production da126120a9; в main она не идёт. Production PR остаётся 2 commits / 21 files, его head/code/unit regressions не менялись.
- CPM Integration Tests → 8 tests должны PASS.
- CPM Integration Tests - Fixes Disabled → автоматически выбирает ровно 6 recovery methods и задаёт обе fixture ENV variables
CPM_APP_INTEGRATION_DISABLE_P1_P2_FIXES=1/CPM_APP_INTEGRATION_DISABLE_LATE_RECOVERY=1. Ожидаются 6 functional FAIL / 0 PASS / 0 skips. - Снова CPM Integration Tests → все 8 должны PASS.
Ручное редактирование ENV или выбор отдельных tests reviewer больше не нужны. OFF scheme через fixture отключает реальные production flags: webExtensions.stateRestorationGate для install/upgrade/slow wake, webExtensions.cpmMessagingHangRecovery для error-6 retry, webExtensions.cpmLateBackgroundDocumentRecovery для late GET recovery. Late recovery выключен и в ранних controls, чтобы не маскировать их; в двух over-budget controls navigation gate сохраняется ON.
Ожидаемые причины FAIL: потерянный native/page first response после install/upgrade; CPM timeout после slow wake; timeout same-document recovery после реальной WK error 6; timeout automatic first-document recovery в late install/upgrade. Setup failures, host crashes или skips не подтверждают работу флага. Полные test names и mapping находятся в README тестовой ветки. В PR сохранены checkout/test/return commands и добавлен возврат к ON scheme.
Артефакты этой проверки: /private/tmp/cpm-flag-controls-20261016/; compiler/test Swift sources и production ref не менялись. Предыдущие 179 unit PASS / production build PASS остаются предыдущей проверкой, не объявляются новым unit/build run.
Финальная проверка ON → OFF → ON
Baseline normal scheme на 6e4e39e67c ранее дал 8/8 PASS. После добавления только OFF scheme/README на 543e37164b выполнены оба shared schemes через xcodebuild test-without-building -workspace DuckDuckGo.xcworkspace -scheme … на тех же подписанных app/XCTest binaries:
| Run | Результат |
|---|---|
| CPM Integration Tests - Fixes Disabled | 6 failed / 0 passed / 0 skipped / 0 expected failures, exit 65 |
| CPM Integration Tests после OFF | 8 passed / 0 failed / 0 skipped / 0 expected failures, exit 0 |
У OFF все шесть failure records сопоставлены точным test names и ожидаемым функциональным причинам; никаких deallocation/setup failures или подмены через XCTExpectFailure. Возврат ON восстанавливает PASS для прежних P1/P2/install/upgrade, обоих late cases, edit veto и pixel adapter. SHA256 app debug dylib и XCTest binary неизменны до/после обоих runs, Swift sources не менялись относительно baseline harness. Remote config и production defaults не редактировались.
Artifacts: /private/tmp/cpm-flag-controls-20261016/validation-summary.json, off.xcresult, on.xcresult, summaries, exported JSON evidence, binary-hashes-before.json, pr-after.json, source/branch verification. Это новая runtime-проверка переключения flags, без нового production build/unit run. Reviewer теперь выбирает два готовых schemes: не редактирует ENV вручную, не выбирает шесть methods и не переключает commits. Production PR и прежние P3/P5/natural-production/iOS ограничения сохраняются.
16 октября 2026 — исправления замечаний review #7379
Production head: 08866c7eda9b1395f7c0baf9887c827bd3f59ec5, branch alex/cpm-fix-init-loss, PR #7379, база #7376 / alex/cpm-messaging-readiness-telemetry / 713d67419a. Три commits / 21 changed paths. Новый commit Share CPM startup deadline across navigations изменяет 8 существующих Swift files; app fixture/hooks в production diff не возвращены. Production и review-only branch обновлены обычным push без переписывания истории.
Что проверено и исправлено
- Замечание о неотменяемом
Task.value: исходное замечание уже было закрыто реализацией cancellable AsyncStream bridge и regressiontestBackgroundWakeWaitIsBoundedWhenWebKitIgnoresCancellation. Проверено повторно на текущем коде: timeout освобождает navigation, даже когда реальный startup task не реагирует на cancellation; физический WebKit startup не отменяется. - Повторные пять секунд на каждом navigation: замечание оказалось актуальным по поведению, несмотря на устаревшее имя файла в тексте. Раньше каждый waiter имел отдельный deadline. Теперь manager возвращает стабильный
Taskтекущего startup, а coordinator хранит один bounded wait для его identity. Оба уже подготовленных waiter и последующие navigation после timeout используют завершившийся wait и не платят ещё по 5 секунд. - Новый startup/replacement получает собственный deadline.
cancelAll()отменяет только navigation wait и очищает его cache. Startup completion очищается при matching uninstall/unload/reload/error-6 retry или замене context; поздний callback старого task не может очистить текущий startup. Timeout сам по себе не отменяет background: поздний успешный callback по-прежнему может запустить отдельный late-document recovery. - В Mac
PrivacyDashboardTabExtensionи iOSTabViewControllerвызов provider ограничен main-frame HTTP(S), поскольку получение task теперь сразу запускает подготовку background. Iframes и другие URL schemes не начинают этот startup через navigation gate. - Добавлены три CI unit regressions:
testTimedOutBackgroundStartupDoesNotDelayLaterNavigations(включая waiter, подготовленный до истечения deadline),testNewBackgroundStartupCanWaitAfterEarlierStartupTimesOut,testCancelAllReleasesPendingBackgroundNavigation. Test double сохраняет identity pending startup; зависший callback моделируется неотменяемым task, затем continuation явно освобождается при cleanup.
Feature flag tracking и review status
Default/config flags не менялись: stateRestorationGate и cpmMessagingHangRecovery сохраняют прежние default; отдельный cpmLateBackgroundDocumentRecovery остаётся false. Remote configuration не редактировалась. Для нового flag добавлены реальные per-platform задачи в Apple Feature Flags Registry и ссылки непосредственно над enum case:
Оба review threads проверены и resolved; открытых inline threads после readback — 0. Danger на 08866c7eda: 0 failures / 1 warning, только advisory о размере PR (1090 added lines); предупреждение об отсутствующих flag tracking links исчезло. Отдельная Privacy Review task уже существовала, дубликат не создавался.
Проверки и отдельная test branch
- До исправления две новые проверки дали 2/2 functional FAIL, после успешной компиляции: повторный navigation wait и освобождение через
cancelAll. - После исправления пять выбранных shared suites: 182 PASS / 0 failures (13 diagnostics + 9 readiness recovery + 78 monitor + 34 lifecycle + 48 manager). Относительно базы PR теперь 21 новый shared unit method.
- Strict SwiftLint: 8 changed Swift files / 0 violations.
- Production macOS Browser Debug, обычная Apple Development signing, build PASS. Подпись app debug dylib проверена. Shared WebExtensions module для iOS Simulator build PASS; это не full iOS app build и не runtime validation iOS suspension/resume.
- Review-only
codex/cpm-fix-init-loss-integration-tests/3f4d7555113d547797b45ff6b2c7b883efedd520синхронизирована merge нового production head; отдельный doc-only commit актуализировал README (7 новых coordinator regressions, 21 shared regression суммарно). Над production — два прежних harness commits + sync merge + README correction; diff всё ещё ровно 12 test-only paths, 8 app methods и два shared schemes. Эта ветка не идёт в main. - Description #7379 изменена только в двух местах для shared deadline и риска зависшего callback. Пользовательские правки и понятные Xcode steps ON → OFF → ON, названия schemes и ожидаемые 8 PASS / 6 FAIL / 8 PASS сохранены. Коммитить или редактировать Swift для reviewer run не нужно.
Финальный runtime cycle на одном наборе подписанных app/XCTest binaries:
| Scheme / запуск | Passed | Failed | Skipped | Результат |
|---|---|---|---|---|
| CPM Integration Tests — ON | 8 | 0 | 0 | PASS |
| CPM Integration Tests - Fixes Disabled — OFF | 0 | 6 | 0 | Все шесть functional failures совпали с ожидаемыми симптомами |
| CPM Integration Tests — ON повторно, без сборки | 8 | 0 | 0 | PASS |
OFF действительно отключает production flag для соответствующего сценария: install/upgrade/slow-wake потеряли первый ответ, P2 не дождался same-document recovery после фактического error 6, late install/upgrade не дождались automatic first-document recovery. expectedFailures в XCTest — 0: OFF остаётся явным красным контрольным запуском, а не ignored CI failure. Fixture setup/host crash/skips не засчитаны как воспроизведение. SHA256 app dylib и XCTest executable совпали до OFF, после OFF и после повторного ON. Бинарники собраны на sync head d0922bb277; финальный test-branch commit 3f4d755511 меняет только README.
CI snapshot 08866c7eda на 16:19 UTC: 31 SUCCESS, 12 SKIPPED, 3 QUEUED, 5 IN_PROGRESS; failures отсутствуют. SwiftLint, macOS/iOS pixel validation и Danger — SUCCESS. Полный CI ещё не объявлен зелёным: оставшиеся unit/UI/release jobs были pending/running.
Артефакты этого прогона: /private/tmp/cpm-pr7379-review-fixes-20261016/. red-tests.log — red-before-fix; unit-final.log, lint-final.log, production-build-final.log, ios-module.log — final validation. Отдельные app-on*, app-off*, app-on-restored* содержат xcresult summaries и exported evidence. SHA256 app/XCTest сохранены до OFF и после каждого последующего run; review/PR/Danger/CI snapshots и validation-summary.json находятся там же.
Это не новая декларация воспроизведения всех production причин. Ограничения прежнего исследования P3/P5 и iOS runtime сохраняются. Точные два новых navigation/cancellation failures сначала воспроизведены deterministic shared tests; восемь app methods проверяют реальные WebKit/app пути существующих install/upgrade, P1/P2 и late recovery сценариев. В ON evidence P2 снова записан фактический WKWebExtensionContextErrorDomain:6; late install/upgrade завершили первый navigation примерно за 5.18 / 5.10 секунды, затем получили отдельный recovery reload, без увеличения navigation timeout.