86 lines
5.8 KiB
Markdown
86 lines
5.8 KiB
Markdown
# CPM Web Extension Breakage — статус и PR-план
|
||
|
||
> Актуально на 2026-09-22. Полная трассировка: [[cpm-web-extension-breakage-findings]].
|
||
> Experiment Definition: [[cpm-background-graveyard-experiment-definition]].
|
||
|
||
## Решение
|
||
|
||
Есть два независимых класса проблем:
|
||
|
||
- **Per-tab lifecycle** исправлен в M1 и уже merged.
|
||
- **All-tabs CPM outage** идёт stack: M3 telemetry → M5 bounded graveyard → M6 A/B.
|
||
|
||
M4 как отдельной ветки/PR нет: production validation — rollout gate после M3. Старый M4 worktree удалён и из topology исключён.
|
||
|
||
## Статус проблем
|
||
|
||
| Проблема | Статус | Что делаем |
|
||
|---|---|---|
|
||
| Forced background-process death → persistent all-tabs CPM outage | **Подтверждено** | M3 измеряет production incidence; M5 лечит; M6 сравнивает control/treatment. |
|
||
| Natural crash/memory/CPU termination → production outage | **Не проверено в production** | Один production release M3 до включения M5/M6. |
|
||
| Close Other Tabs, popup duplicate, pin/unpin/reorder/move/merge/window close | **Исправлено, merged** | M1 PR #6827. |
|
||
| Нестабильный Web Extension base URL | **Исправлено локально** | M2 задаёт deterministic base URL до load/reload и отвергает malformed identifier без crash. |
|
||
| Startup/session-restore content-script miss | **Подтверждено как transient** | Не объясняет persistent all-tabs outage. |
|
||
| Failed background load навсегда блокирует WebKit | **Отвергнуто** | WebKit повторяет load; нужна повторяемая причина/traffic. |
|
||
| Critical memory pressure как root cause | **Не воспроизведено** | Остаётся diagnostic correlation M3. |
|
||
| Event starvation / JSC hang / native messaging stall | **Не проверено** | Остаётся в M3 diagnostic buckets. |
|
||
| Network process restart | **Отвергнуто** | На проверенной сборке CPM восстановился. |
|
||
| removeAllUserScripts / flag transition / scriptlet reload / page JS как all-tabs cause | **Отвергнуто** | Это не persistent global failure mode. |
|
||
|
||
## Milestones
|
||
|
||
| Milestone | Branch / worktree | Готовность |
|
||
|---|---|---|
|
||
| M1 tab lifecycle | `codex/cpm-tab-lifecycle-fixes` | **Merged:** [PR #6827](https://github.com/duckduckgo/apple-browsers/pull/6827), CI green. |
|
||
| M2 stable base URL | `alex/cpm-stable-base-url` — `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-stable-base-url` | **Production-ready:** 2 files; 11/11 targeted tests. Добавлена safe URL construction и negative validation вместо force-unwrap. |
|
||
| M3 attribution telemetry | `alex/cpm-failure-telemetry` — `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-failure-telemetry` | **Production-ready code:** passive PII-free buckets, app-update/launch attribution, stable-base-URL transition fact, iOS/macOS schema validation green. Privacy triage: [[cpm-m3-telemetry-privacy-triage]]. |
|
||
| M5 graveyard mitigation | `alex/cpm-graveyard-mitigation` — `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-graveyard-mitigation` | **Production-ready, default off:** one retained view maximum, 3-second bounded hold, stale release cancellation, unload/reload/runtime kill-switch cleanup. 24/24 targeted tests; earlier real forced-kill iOS E2E recovered with release at ≈3.15 s. |
|
||
| M6 graveyard A/B | `alex/cpm-graveyard-ab` — `/Users/admin/DuckDuckGo/apple-browsers.git/cpm-graveyard-ab` | **Production-ready code:** lazy exposure enrollment, stable cohorts, control/treatment isolation, bounded pending queue, operational pixels and standard `experiment_metrics` outcome. 421/421 WebExtensions tests; iOS/macOS app builds; iOS/macOS pixel validators. |
|
||
|
||
All milestone diffs pass `git diff --check`; changed Swift lines are within 150 columns.
|
||
|
||
## Stack and Git state
|
||
|
||
Independent PRs:
|
||
|
||
1. M2 — stable base URL.
|
||
2. M3 — production telemetry.
|
||
|
||
Stacked PRs:
|
||
|
||
```
|
||
M3 telemetry
|
||
└── M5 graveyard mitigation
|
||
└── M6 A/B experiment
|
||
```
|
||
|
||
Current refs intentionally preserve the earlier no-commit workflow:
|
||
|
||
- M3 and M5 branch refs: `814bce5d11`; their milestone changes are unstaged.
|
||
- M5 ghost commit used only as M6 base: `cefad244c5`.
|
||
- M6 branch ref: `cefad244c5`; M6 changes are unstaged above it.
|
||
- M5’s final combined pixel description has been pulled into M6.
|
||
- Local `origin/main` advanced from the M3 merge base by one unrelated pixel-definition commit (`67a2f2b7b2`); it does not overlap CPM files.
|
||
|
||
Before opening PRs: commit M2 and M3, update them onto current `origin/main`, recreate/rebase the M5 commit onto M3, then rebase M6 onto that M5 commit. Do not include generated `Package.resolved` churn; Cursor currently regenerates it in the open M3 workspace.
|
||
|
||
## Experiment contract
|
||
|
||
- Experiment: `cpmBackgroundGraveyardExperiment`.
|
||
- Cohorts: `control`, `treatment`.
|
||
- Enrollment: only on an actual eligible CPM background-process termination.
|
||
- Primary framework metric: `cpmBackgroundGraveyardOutcome`, window `0...1`, values `healthy`, `initialization_failed`, `not_measured`.
|
||
- Rollback: disable both `cpmBackgroundGraveyardExperiment` and `cpmBackgroundGraveyard`.
|
||
|
||
Full definition and config draft: [[cpm-background-graveyard-experiment-definition]].
|
||
|
||
## Remaining gates
|
||
|
||
1. Open M2/M3/M5/M6 PRs in the topology above.
|
||
2. Create separate iOS and macOS experiment-log tasks.
|
||
3. Create Privacy Configuration + privacy/schema review tasks.
|
||
4. Create Data Science sample-size/design and Native Apps Experiment Analysis task.
|
||
5. Ship M3 first; enable M5/M6 only if production telemetry confirms the process-death hypothesis.
|
||
|
||
No Asana tasks, comments, or configuration were created during this review.
|