[2026-10-15] eagle: work/projects/cpm-status-2026-10-15.md

This commit is contained in:
Alexey Martemyanov committed 2026-10-15 23:21:26 +06:00
1 parent 7c5ce2dc10
commit 7d13bdaaaa
1 file changed
+32
+32
View File
@@ -332,3 +332,35 @@ CPM_REPRO=1 CPM_REPRO_P5_P6=1 swift test --disable-automatic-resolution --filter
Начат эксперимент на системном WebKit: один и тот же живой tab в двух windows; закрыть одну через production `WebExtensionEventsListener.didCloseWindow`, сохранить tab в другой, без прямого `didCloseTab`, изменения listener или выгрузки context. До выполнения это **кандидат**, не подтверждённое воспроизведение.
Проверка истории также отсекла старые объяснения: исправление `Close Other Tabs` и фильтр shared pinned tabs уже находятся в `1.210.0+macos`; синхронное создание manager до state restoration существует с февраля 2026. Их прежние версии нельзя выдавать за текущий production-триггер.
### P5: production callback → WebKit side effect подтверждены
Два новых теста зелёные, 0 failures:
- `testClosingWindowForgetsSharedPinnedTabThroughWebKitAndMatchesP5` — **73.033 с**. Один живой tab предоставлен двумя window delegates, как shared pinned tab в macOS. Две успешные инициализации и две штатные idle-выгрузки. Затем только unregister закрываемого окна и production `eventsListener.didCloseWindow` — без явного `didCloseTab`, изменения listeners, ручной выгрузки context или замены manager. Сразу после callback `tab_in_context` меняется true → false, WKWebView остаётся тем же и tab сохраняется в другом окне.
- Две последующие навигации дали actual initialization failures и stuck: `load>view>proxy_on>dealloc>view>proxy_on>dealloc`, creations=2, view=false, context=true, tab=false, controller/scripts=true, errors=none, network_restarted=false. Content script получает init-error. Новая вкладка работает; `didOpenTab` восстанавливает исходную.
- `testClosingUnrelatedWindowPreservesRegisteredTab` — **1.205 с**: закрытие окна, не возвращающего эту вкладку, сохраняет tab_in_context=true, initResp и 0 failures.
Лог: `/private/tmp/cpm-p5-p6-20261015/production-window-close.log`. Это **source-linked воспроизведение на системном WebKit 26.7.1** через production listener и неизменённую логику CPM, а не произвольное закрытие живого tab. Harness использует window/tab delegates, повторяющие контракт macOS; сам MainWindowController/AppKit целиком в SPM-тест не загружен. Следовательно, browser call chain подтверждён чтением исходников, внутренний эффект WebKit и P5 — исполнением теста.
Область объяснения: **P5/tab_in_context=false** (в выбранном Mac-срезе 68 событий). Это не доказательство, что все эти события были caused by shared pinned windows, и не объяснение P5/tab_in_context=true либо iOS.
Тесты WindowsManagerPopupTests в macOS проверяют только список явных didCloseTab и поэтому не проверяют повторное закрытие tabs внутри системного didCloseWindow.
### P6: найден условный production-путь, начата проверка
В `AppDelegate.setupWebExtensions` главная `webExtensions` flag подключена к production `WebExtensionFeatureFlagHandler`. Disable вызывает `uninstallAllExtensions`, затем callback очищает coordinator/manager. Enable вызывает `initializeWebExtensions`: если manager отсутствует, создаётся новый controller, а существующие WKWebView не пересоздаются. WebKit `WebExtensionTab::webView` отвергает view, чей controller не равен controller контекста.
Добавлены отдельные source-linked тесты `CPMReproProductionFlagTests`:
- явное true → false → true главного flag через **реальный handler**, с host callbacks по AppDelegate и существующей вкладкой, предоставленной WebKit при загрузке replacement context;
- negative control: цикл только embedded flag, при неизменном главном, должен сохранить controller и initResp;
- внутри первого теста есть контроль true → true: повторный одинаковый флаг не должен заменять manager.
Это проверка достижимости механизма через production flag handler, **не утверждение, что flag переключался у пользователей**. И macOS, и iOS имеют defaultValue enabled для главного flag; подтверждения реального false → true в рассматриваемой выборке нет. Обычная задержка скачивания config сама по себе не доказывает этот путь.
### Первый прогон flag-путей: P6 получен, контроль обнаружил известную startup race
`production-flag-cycle.log`: главный flag-тест **зелёный, 9.244 с**. Реальный handler по false удалил contexts и host references; по true создан новый manager при сохранённом старом WKWebView/controller. Получены два actual failures и stuck с точным `load>view>proxy_on`, context/tab/view=true, controller/scripts=false, creations=1, errors=none, network_restarted=false. true → true manager не заменил; новая вкладка replacement manager работает. Это подтверждает **условный production-путь P6 при реальном переключении главного flag**.
Embedded-контроль **красный, 6.119 с, 3 assertions**: controller/scripts/tab=true, но первая навигация в 0.704 с ушла до sw activate в 0.747 с и потеряла init. Таким образом, «embedded cycle всегда здоровый сразу после sync» — неверное ожидание: здесь воспроизводится уже известный механизм **A / P4**, а не P6. Не считаю красный результат ошибкой постановки.
Для изоляции именно controller-binding уточняю контроль: после sync явно дождаться `loadEmbeddedExtensionBackgroundContent`, затем требовать initResp без failures при прежнем controller. Этот readiness wait — контрольное условие теста; production fix A данной работой не добавляется.