diff --git a/work/projects/cpm-web-extension-breakage-findings.md b/work/projects/cpm-web-extension-breakage-findings.md index 71569297..fec11f97 100644 --- a/work/projects/cpm-web-extension-breakage-findings.md +++ b/work/projects/cpm-web-extension-breakage-findings.md @@ -850,3 +850,12 @@ Also covered by the same mechanism: tabs restored at launch before the manager e ### Open question that decides the fix design Is CPM breakage in production reported for **old tabs only** (consistent with this chain) or for **new tabs too**? The stuck/recovered pixel sequence with `tab_controller_matches_context` answers it. Fix design deferred until that is known, per agreement. + + +### Controller-replacement chain: not triggered in production (checked 2026-09-09) + +- `privacy-configuration/overrides/macos-override.json`: `webExtensions` block (`enabled`, `minSupportedVersion 1.183.0`, subfeature `embedded: enabled`) unchanged since June; no commit touched it. +- App flag `.webExtensions` = `remoteReleasable(webExtensions.featureEnabled)`, `defaultValue: .enabled`. `featureEnabled` is absent from the config → `.disabled(.featureMissing)` → default → `true` (`AppPrivacyConfiguration.swift:191-197`, `FeatureFlagger.swift:431-432`). Stable across launches and config reloads; `.removeDuplicates()` suppresses repeats. Only a parent-state change or an internal override can flip it. +- Browser update: bundle swap happens at relaunch; on first launch of the new version the old UUID loads, then `syncEmbeddedExtensions` installs/loads the new UUID into the same controller and unloads the old. Documents holding old-context content scripts lose messaging until their next navigation — transient. Handlers are keyed by UUID; nothing from the previous version lingers. + +Status: memory pressure, Network-process death, lost native handlers and controller replacement are all either not reproducible on shipping WebKit or not triggered by production conditions. Retained-failed-view self-heals. **Next input must be production data**: `cpm_messaging_stuck_` split and recovered-with/without-reload ratio; breakage-report split of `cpmDashboardState=waiting` vs `applied` + `cpmStage ∈ {setting_disabled, config_unavailable, settings_missing}`.