[2026-10-05] eagle: work/projects/cpm-web-extension-breakage-validation.md
This commit is contained in:
1 parent
daf6747057
commit
d136dba735
1 file changed
+86
@@ -24,6 +24,92 @@
|
||||
|
||||
**Следующая проверка:** на public macOS 1.210 / iOS 7.240 с 2026-10-06 раздельно считать affected daily users (recovered и permanent) против DAU той же версии; разбирать ordered `bg_events` и tab-поля по каждой сигнатуре. Воспроизвести на macOS 1.210 update/session restore и off→on Web Extensions с уже открытой вкладкой: сравнить старую и новую вкладки по controller, scripts и CPM outcome. До этого не ранжировать причины по internal `.count`.
|
||||
|
||||
## Как получить и проверить attribution data
|
||||
|
||||
**Источник:** Grafana ClickHouse datasource `dekdbd6bqq1hcd` (`grafana-clickhouse-datasource`), таблица `metrics.pixels`. Использовался API через `/Users/admin/DuckDuckGo/grafana-dashboards/tools/grafana-query/read-dashboard.py`, **не** браузер и не локальный Apple worktree. Авторизация этого helper — `grafana-auth`/SSO либо `GS_GRAFANA_API_KEY`; токены в документ не записывать. [Board](https://grafana.duckduckgo.com/d/dfon7whlilnggb/cpm-weird-error-investigation?orgId=1) — визуальная сверка, SQL ниже — источник приведённых чисел.
|
||||
|
||||
1. Сохранить нужный SQL-блок ниже в `/tmp/cpm-query.sql`. Для исторической проверки оставить UTC-окно `[2026-09-28, 2026-10-05)`; для public заменить начало на фактический день публикации и указать **только завершённые UTC-дни**. Сверять `date`, `agent`, `appVersion`, суффикс `.count`/`.daily` и наличие `context_loaded` с Kibana.
|
||||
2. Из `/Users/admin/DuckDuckGo/grafana-dashboards` выполнить этот read-only API-запрос. Заменить `FROM`/`TO` вместе с датами SQL; пустой Grafana frame без ошибки перепроверить повторным запросом, а не трактовать как ноль:
|
||||
|
||||
```bash
|
||||
uv run --with requests python3 - /tmp/cpm-query.sql 2026-09-28T00:00:00Z 2026-10-05T00:00:00Z <<'PY'
|
||||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
path = Path('tools/grafana-query/read-dashboard.py').resolve()
|
||||
spec = importlib.util.spec_from_file_location('grafana_reader', path)
|
||||
reader = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(reader)
|
||||
target = {'refId': 'A', 'rawSql': Path(sys.argv[1]).read_text(),
|
||||
'editorType': 'sql', 'queryType': 'table', 'format': 1}
|
||||
raw = reader.query_ds_query('dekdbd6bqq1hcd', 'grafana-clickhouse-datasource',
|
||||
[target], reader.parse_time(sys.argv[2]), reader.parse_time(sys.argv[3]))
|
||||
result = raw.get('results', {}).get('A', {})
|
||||
if result.get('error'):
|
||||
raise SystemExit(result['error'])
|
||||
if not result.get('frames'):
|
||||
raise SystemExit('No data frame returned; retry/inspect Grafana response')
|
||||
for frame in result['frames']:
|
||||
print('\t'.join(f['name'] for f in frame['schema']['fields']))
|
||||
for row in zip(*frame['data']['values']):
|
||||
print('\t'.join(map(str, row)))
|
||||
PY
|
||||
```
|
||||
|
||||
**SQL 1 — покрытие по всем версиям, включая пиксели без attribution.** Не фильтровать версии заранее: так обнаруживаются 1.211/7.241 и большой legacy iOS-поток без новых полей. `attributed` — строки с live-параметром `context_loaded`; `rows` — все stuck-пиксели. `.count` и `.daily` не складывать.
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toString(date) AS day,
|
||||
agent,
|
||||
arrayStringConcat(arraySlice(splitByChar('.', extractURLParameter(request, 'appVersion')), 1, 3), '.') AS app_version,
|
||||
multiIf(match(pixel, '\\.daily(\\.ios\\.(phone|tablet))?$'), 'daily',
|
||||
match(pixel, '\\.count(\\.ios\\.(phone|tablet))?$'), 'count', 'other') AS frequency,
|
||||
count() AS rows,
|
||||
countIf(extractURLParameter(request, 'context_loaded') != '') AS attributed,
|
||||
countIf(extractURLParameter(request, 'bg_events') != '') AS chain_present
|
||||
FROM metrics.pixels
|
||||
WHERE date >= toDate('2026-09-28') AND date < toDate('2026-10-05')
|
||||
AND agent IN ('ddg_ios', 'ddg_mac_desktop')
|
||||
AND pixel_id = 'debug'
|
||||
AND pixel LIKE 'debug.web.extension.cpm.messaging.stuck.%'
|
||||
GROUP BY day, agent, app_version, frequency
|
||||
ORDER BY day, agent, app_version, frequency;
|
||||
```
|
||||
|
||||
**SQL 2 — macOS 1.210 tab-сигнатуры и предшествующие события.** Только attributed `.count` stuck; каждое число — репорты, не люди. `bg_events` упорядочены oldest→newest, но содержат лишь ограниченный хвост и грубые age buckets; `dealloc` не равен доказанному process death. Проверить эту же выборку с `.daily` для чувствительности к повторным репортам.
|
||||
|
||||
```sql
|
||||
WITH events AS (
|
||||
SELECT
|
||||
extractURLParameter(request, 'tab_in_context') AS tab_in_context,
|
||||
extractURLParameter(request, 'tab_controller_match') AS controller_match,
|
||||
extractURLParameter(request, 'tab_has_ext_scripts') AS scripts_present,
|
||||
extractURLParameter(request, 'bg_view_creations') AS view_creations,
|
||||
extractURLParameter(request, 'app_version_change') AS version_change,
|
||||
splitByChar(',', decodeURLComponent(extractURLParameter(request, 'bg_events'))) AS chain
|
||||
FROM metrics.pixels
|
||||
WHERE date >= toDate('2026-09-28') AND date < toDate('2026-10-05')
|
||||
AND agent = 'ddg_mac_desktop' AND pixel_id = 'debug'
|
||||
AND pixel LIKE 'debug.web.extension.cpm.messaging.stuck.%'
|
||||
AND match(pixel, '\\.count$')
|
||||
AND extractURLParameter(request, 'appVersion') LIKE '1.210.%'
|
||||
AND extractURLParameter(request, 'context_loaded') != ''
|
||||
)
|
||||
SELECT
|
||||
count() AS reports,
|
||||
countIf(arrayCount(x -> startsWith(x, 'dealloc@'), chain) >= 2) AS repeated_dealloc,
|
||||
countIf(scripts_present = 'false') AS scripts_absent,
|
||||
countIf(scripts_present = 'false' AND controller_match = 'false' AND tab_in_context = 'true') AS controller_mismatch,
|
||||
countIf(scripts_present = 'false' AND controller_match = 'false' AND version_change = 'updated') AS mismatch_after_update,
|
||||
countIf(scripts_present = 'false' AND controller_match = 'true' AND view_creations = '0') AS same_controller_zero_views,
|
||||
countIf(scripts_present = 'false' AND controller_match = 'true' AND view_creations = '0' AND version_change = 'updated') AS zero_views_after_update
|
||||
FROM events;
|
||||
```
|
||||
|
||||
**Методика интерпретации:** сначала SQL 1 проверяет покрытие версии/платформы и отсутствие attribution; затем SQL 2 группирует совместные признаки вместо чтения одиночного поля как root cause. Для конкретной сигнатуры дополнительно сгруппировать `bg_events` с сохранением порядка, reason из имени pixel, `app_version_change` и `bg_view_alive`; сверить с исходным кодом `CPMMessagingDiagnosticsRecorder` и созданием `WebExtensionManager` на `apple-browsers.git/main`. Internal forced-failure testing, app update и повторные `.count` могут смещать выборку. Public user-rate и recovered/permanent требуют отдельного user-level числителя и DAU **той же версии**; эти SQL их не вычисляют.
|
||||
|
||||
## Исторический статус и PR-план (2026-09-23—09-25)
|
||||
|
||||
> Ниже сохранён прежний план. Его формулировки о shipped status, готовности PR и дизайне graveyard A/B не являются текущим release/experiment contract; сверять с `apple-browsers.git/main` и актуальной privacy config.
|
||||
|
||||
Reference in new issue
Block a user