43 KiB
Executable File
title, date, tags
| title | date | tags | |||
|---|---|---|---|---|---|
| CPM Web Extension — карта кода по worktree и строкам | 2026-10-09 |
|
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 |
alex/cpm-fix-init-loss; 7ad771e227bb |
PR #7379: A, первые init при install/upgrade mid-session; красное/зелёное доказательство отдельно от remaining-failures |
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 сохраняются.