[QA-trace][#120 4/7] Процесс-отчёт web-test-orchestrator (offline) — дедуп-провал: 6 находок = 1 корень #238

Closed
opened 2026-06-27 15:44:57 +03:00 by Ghost · 0 comments

Прогон 4/7 · эпик PR #120 (offline-sync / PWA) · web-test-orchestrator · 14 сырых → 6 подтв / 2 ложных / 2 WIP.
Процесс-отчёт. Сравни с прогоном 3 (#237).

Process-trace QA отчёт — PR #120 feature/offline-sync (gitmost / Docmost fork)

Фокус — НЕ на коде, а на ПРОЦЕССЕ: как отработали агенты web-test-orchestrator, кто как применил офлайн-технику, кто фолс-позитивит, как verifier отсеивал. Сырьё: 14 находок от 7 ролей + 13 вердиктов verifier (1 — TIMED_OUT).


1. Сводка прогона

Стадии: recon → mapping → charters → execution (персоны-туры) → oracle eval → Doer–Verifier → отчёт. Все офлайн-агенты дошли до execution с реальным Playwright-прогоном; root-cause-агенты дополнительно делали grep/Read исходников клиента.

Агенты (7 ролей): recon, pwa-sw-shell, offline-read tester, offline-edit-body, offline-structural-outbox, update-prompt-install slice, online-sanity-regression.

Воронка 14 сырых находок → после verifier:

Итог Кол-во Что это
Подтверждённые РЕАЛЬНЫЕ дефекты 6 один корень (blank-screen/crash офлайн), переоткрыт 5 агентами
Не-реализовано / WIP (корректно классиф.) 2 offline create без навигации; cold-boot read-path не подключён
Ложные (verifier: speculative / not-a-bug) 2 оба от recon
Verified-но-НЕ-дефект (вне трёх корзин) 4 контур-A работает (positive); console-401 baseline; LAN-IP collab (env); мусор тест-данных (hygiene)
Из них verifier НЕ смог перепроверить (TIMED_OUT) 1 pwa-sw-shell blank-shell — но подтверждён 5 «соседями»

Ключевой факт процесса: 6 из 6 «реальных дефектов» — это ОДИН баг (auth-query.tsx:27, незащищённый error.response.status в retry-предикате useCollabToken). Дедупликации между ролями не было — каждый офлайн-агент пришёл к нему сам.


2. Какие агенты/инструменты отработали

recon — карта приложения, SW/cache/IndexedDB-интроспекция, сетевой/консольный шум. Инструменты: Playwright launch_persistent_context (чтобы SW+IndexedDB жили между навигациями), page.on(console/response/requestfailed), page.evaluate (serviceWorker.getRegistration/ready/controller, caches.keys(), indexedDB.databases()), eval_on_selector_all, скриншоты, curl /sw.js /manifest.json. Офлайн-технику толком НЕ применял (остался в онлайне), зато нашёл SW-lifecycle-нюансы — и именно тут перегенерил шум (см. §4). Самый фолс-позитивный.

pwa-sw-shell — персона «установленный PWA, потерял сеть». Техника образцовая: один контекст, дождался controller != null + 237 precache, ТОЛЬКО потом set_offline(True) + reload. Главное — дисконфирм-контроль: офлайн БЕЗ reload отрисовал полный /home (1279 символов), что изолировало дефект на cold-boot, а не на tooling/офлайн вообще. Нашёл blank-shell + проксимальный TypeError. sync_api. На tooling НЕ свалил.

offline-read tester — «тётя Люба читает закэшированное в поезде». Один launch_persistent_context online→offline→online. Оракул out-of-band: Postgres text_content через docker exec psql. Дисконфирм-контроль: офлайн без reload — контент жив (bodyLen 976); reload — bodyLen 0 + тот самый pageerror. Grep .status по apps/client/src → точное место. Чисто, надёжно.

offline-edit-body — контур-A (тело Yjs). Самый строгий: триангуляция ТРЁХ оракулов (Postgres pages.text_content out-of-band, online hard-reload, indexedDB.databases()). Корректно отделил «правка в открытой вкладке переживает reconnect» (positive, НЕ баг) от «reload офлайн = white-screen» (дефект), и довёл до строки auth-query.tsx:27, отметив, что соседний api-client.ts:25 защищён if (error.response). Надёжный.

offline-structural-outbox — контур-B (REST→кэш+outbox). Проверил IndexedDB-аутбокс (gitmost-rq-cacheclientState.mutations), второй браузер-контекст как независимый оракул, from_service_worker на навигации. Лучшая дисциплина WIP-vs-bug: blank-shell классифицировал как РЕАЛЬНЫЙ дефект, а «create без навигации» — как not-implemented-wip, явно зафиксировав «мутации НЕ теряются, реплеются на reconnect». SW-активацию проверил до offline. Надёжный.

update-prompt-install slice — персона install/update + глубокое чтение исходников (vite.config, pwa-update-prompt, query-persister, user-provider, auth-query). add_init_script со слушателем unhandledrejection поймал стек at retry(...), однозначно указавший на retry-предикат useCollabToken. Нашёл ВТОРОЙ механизм того же blank-screen (gate-on-live-auth + исключение currentUser из OFFLINE_PERSIST_ROOTS) и корректно пометил его WIP. Надёжный.

online-sanity-regression — базлайн/регрессия онлайна. Fresh-profile cold-install контроль, capture websocket-фреймов. Обе находки — корректно как НЕ-регрессии (console-401 baseline; LAN-IP collab = env-portability). Дисциплина framing'а образцовая.

Вывод по технике: все 5 офлайн-агентов применили SW-технику ПРАВИЛЬНО — один persistent-контекст, ожидание ready+controller до set_offline, дисконфирм-контроли. Никто не свалил дефект на tooling. Единая трением-точка у всех — chromium-1148 вместо ожидаемого пакетом 1223 (нужен executable_path-override) и auth-rate-limit 429 (внешне = «логин не прошёл»). Оба — френдли-огонь скилла/окружения, и агенты корректно НЕ обвинили приложение.


3. Баги по КЛАССУ (как проявлялся / как и кем найден)

A. blank-shell-offline / white-screen-of-death (rendering ⨯ unhandled-exception) — ДОМИНИРУЮЩИЙ класс.
Проявление: офлайн reload/cold-boot — SW отдаёт index.html shell (HTTP 200, from_service_worker, title выставлен), но body.innerText.length=0, в #root только Mantine <style>, ни лоадера, ни «вы офлайн», ни редиректа, ни авто-восстановления на reconnect (нужен ручной reload). Закэшированный контент (IndexedDB keyval-store + Yjs page.*) существует, но не рендерится.
Найден: на стадии execution, первым — pwa-sw-shell (online→ждать SW→set_offlinereload, с дисконфирм-контролем). Затем НЕЗАВИСИМО переоткрыт offline-read, offline-edit-body, offline-structural-outbox, update-prompt-install (6 сырых находок).

B. unguarded-property-access / uncaught-exception (проксимальный код-дефект под A).
Проявление: TypeError: Cannot read properties of undefined (reading 'status'), 3/3 на каждый офлайн cold-boot. Офлайн bootstrap-запрос (/api/auth/collab-token, /api/users/me, NetworkOnly) падает ERR_INTERNET_DISCONNECTED без response, обработчик читает .status → throw до монтирования React.
Найден: pageerror/unhandledrejection-слушателями; кадр стека at retry сматчен с retry-предикатом useCollabToken; добит grep'ом .status по исходникам (одно незащищённое место против защищённого соседа).

C. partial-offline / degraded-UX (WIP, БЕЗ потери данных).
Проявление: офлайн «Create page» ставит мутацию в очередь (clientState.mutations {spaceId}), но НЕ навигирует и не даёт редактируемую цель; на reconnect реплеется как Untitled (title=null). Данные не теряются.
Найден: offline-structural-outbox — сверка online (NAVIGATED=True) vs offline (False, 0 редакторов) + дамп IndexedDB-аутбокса + /api/pages/recent после reconnect.

D. offline-read-path-not-wired (WIP).
Проявление: тот же белый экран на cold-boot, но другой механизм — UserProvider отдаёт <></> на любую ошибку useCurrentUser, а currentUser намеренно исключён из OFFLINE_PERSIST_ROOTS, поэтому persisted-кэш недостижим через relaunch.
Найден: update-prompt-install — чтением user-provider.tsx + query-persister.ts.

E. sw-activation-race (cosmetic, FP). active.state='activating' при уже не-null controller — штатное W3C-поведение clientsClaim. recon.

F. benign-load-noise (FP/benign). Pre-login 401 на /api/users/me и /api/auth/collab-token — ожидаемые анон-пробы. recon + online-sanity.

G. config/portability (env). Collab WS на захардкоженный ws://10.20.30.227:3001. В этом стенде работает. online-sanity.

H. residual-test-data (hygiene). Мусорные заметки прошлых QA в General. recon.

Важно: классы data-loss-on-reconnect и silent-optimistic-loss (успех→тихая потеря) были ЦЕЛЕНАПРАВЛЕННО проверены и ДИСКОНФИРМИРОВАНЫ: контур-A переживает reconnect (Postgres-оракул), аутбокс-мутации персистятся и реплеются. То есть «страшных» молчаливых потерь данных не нашли — нашли «громкий» краш.


3b. Кто что нашёл

# Находка Агент Класс Вердикт
1 Pre-login 401 (как «находка») recon benign-load-noise false (speculative)
2 SW 'activating' при non-null controller recon sw-race-cosmetic false (speculative)
3 Мусор тест-данных в General recon residual-test-data verified (не дефект)
4 Blank shell на офлайн cold-start pwa-sw-shell blank-shell TIMED_OUT (корроборирован)
5 TypeError reading status (bootstrap) pwa-sw-shell unhandled-exc verified-defect
6 White-screen на всех роутах офлайн offline-read blank-shell/WSOD verified-defect
7 Контур-A правка переживает reconnect offline-edit-body none/working verified (POSITIVE, не баг)
8 Reload офлайн = white-screen SPA offline-edit-body WSOD verified-defect
9 Cold-start PWA blank offline-structural-outbox unhandled-exc verified-defect
10 Create офлайн без навигации offline-structural-outbox partial-offline verified-WIP
11 TypeError в useCollabToken retry update-prompt-install unguarded-access verified-defect
12 Cold-boot read-path gated on live-auth update-prompt-install read-path-not-wired verified-WIP
13 Pre-login 401 (как baseline-nit) online-sanity console-error verified (benign)
14 Collab WS захардкоженный LAN IP online-sanity config/env verified (env)

4. ФОЛС-ПОЗИТИВЫ — кто и насколько (ключевой раздел)

recon — единственный систематический источник фолс-позитива. 3 находки, 2 убиты verifier'ом как speculative (~66% FP среди его «находок»). Чём фолсит: штатное поведение платформы → выдаёт за дефект. SW activating — это спецификация W3C clients.claim(); pre-login 401 — ожидаемые анон-пробы. Обе воспроизводятся детерминированно, поэтому «verified» по факту репро — но это not-a-bug. Урок: recon-роли нужен жёсткий гейт «нашёл странность ≠ нашёл дефект».

Контраст framing'а (важно для отладки скилла): одно и то же явление — pre-login 401 — у recon (#1, заявлено КАК находка-проба) убито в speculative, а у online-sanity (#13, заявлено КАК «benign baseline, не SW-регрессия») прошло verified. Вердикт verifier'а трекает ФОРМУЛИРОВКУ/скромность претензии, а не само явление. Скромный framing «это базлайн, не наш регресс» проходит; претензия «это дефект» — режется.

Все 5 офлайн-агентов — 0 фолс-позитивов по дефектам. 100% их defect-claims подтвердились (5 verified + 1 timed-out-но-корроборирован). Это очень здоровый сигнал: тяжёлая офлайн-техника + дисконфирм-контроли = почти нулевой FP.

Путаница «не реализовано» vs «баг» — НЕ обнаружена. Ни один агент не назвал WIP-пробел «багом». Оба WIP-кейса (#10, #12) явно помечены not-implemented-wip с правильным дискриминатором: «нет потери данных, нет ложного success-тоста — просто пусто/деградировано». А blank-shell, наоборот, верно классифицирован как РЕАЛЬНЫЙ дефект (это краш/тихий lockout, а не «фича не дописана»). Дискриминация между WIP и дефектом — сильная сторона прогона.

Покрытие verifier'а — 1 дыра. Находка #4 (pwa-sw-shell blank-shell) — TIMED_OUT, независимо не переперепроверена. Риск низкий: тот же корень подтверждён 5 соседними находками. Но это сигнал, что verifier'у нужен бюджет/таймаут-политика (см. §6).

Надёжность (от лучшего): offline-edit-bodyoffline-structural-outboxupdate-prompt-install (root-cause до строки, оракулы out-of-band, WIP-дисциплина) > pwa-sw-shell / offline-read (отличная техника, без глубокого root-cause) > online-sanity (корректно, но низкоценные базлайн/env находки) > recon (нужен FP-гейт).


5. Где скилл сработал/провалился на ОФЛАЙНЕ

Сработал:

  • Поймал главный офлайн-дефект (blank-shell/WSOD на cold-boot) — причём 5 независимыми путями, с root-cause до конкретной строки и до соседнего ЗАЩИЩЁННОГО места (доказывает, что это аутлайер, а не общий паттерн).
  • SW-lifecycle-техника применена верно ВЕЗДЕ, где нужна: один launch_persistent_context, ожидание ready + controller != null ДО set_offline, переключение online↔offline↔online в одном контексте. Ни одного «свежий контекст / SW не активирован».
  • Дисконфирм-контроли как норма: «офлайн БЕЗ reload → UI цел» против «reload → пусто» — именно это отделило app-дефект от tooling/общей офлайн-невозможности. Это и спасло от ложного обвинения инструментов.
  • WIP-гейт отработал: silent-optimistic-loss и data-loss-on-reconnect были проверены оракулами (Postgres out-of-band, IndexedDB-аутбокс, второй контекст) и ДИСКОНФИРМИРОВАНЫ — агенты не выдали «деградацию UX» за «потерю данных».

Провалился / шероховатости:

  • recon тащит SW-lifecycle-косметику в дефекты (activation race) — на офлайн-стенде это особенно зашумляет, т.к. SW-состояния выглядят «подозрительно», но штатны.
  • Массовая недедупликация: 6 сырых находок = 1 баг. Пять ролей сожгли бюджет на переоткрытие одного и того же auth-query.tsx:27. Скилл не свёл их до прогона verifier'а.
  • Классификационное наложение: #12 (gate-on-live-auth, помечен WIP) и #5/#6/#8/#9/#11 (тот же белый экран, помечены defect) — это ДВА разных механизма одного симптома. Без явной сшивки «один симптом — два корня» отчёт выглядит противоречиво (баг это или WIP?). Ответ: и то, и то, но скилл это не свёл.
  • Френдли-трения окружения (chromium-1148 vs 1223; auth 429 как ложный «логин не прошёл») каждый агент переоткрывал заново — это надо вынести в пресет скилла, а не оставлять на переоткрытие каждой роли.
  • Verifier-таймаут (#4) — самый ценный, дорогой репро (blank-shell) остался без независимой переперепроверки.

6. Предложения по улучшению скилла (упор на PWA/offline)

  1. SW-lifecycle-чеклист как жёсткий пресет (а не на усмотрение роли): (a) launch_persistent_context обязателен; (b) ассерт serviceWorker.ready И controller != null ДО set_offline; (c) обязательный дисконфирм-контроль «офлайн без reload»; (d) проверка response.from_service_worker на навигации. Все офлайн-роли это сделали — закрепить, чтобы и recon не выпадал.

  2. FP-гейт «штатное поведение ≠ дефект» для recon/sanity-ролей. Явный стоп-лист: SW activation race (clientsClaim), pre-auth 401-пробы, cross-origin WS не перехватывается SW — это НЕ дефекты по умолчанию. Снимет ~2/3 шума recon.

  3. WIP-vs-bug-гейт как формальный оракул-вопрос: «есть ли (a) потеря данных, (b) ложный success-тост/тихий успех? Если нет, а функция просто отсутствует/пуста → not-implemented-wip; если краш/lockout/тихая потеря → defect». Прогон уже это делал интуитивно — кодифицировать.

  4. Офлайн-оракулы вынести в reference как набор: Postgres text_content out-of-band (docker exec psql, роль docmost/docmost), IndexedDB-аутбокс (keyval-store/gitmost-rq-cacheclientState.mutations), второй браузер-контекст, from_service_worker. Это «золотые» оракулы, которые отличают «не нарисовалось» от «потерялось».

  5. Дедуп ПЕРЕД verifier'ом по сигнатуре root-cause (строка/стек-кадр/error-string). 6 находок с reading 'status' / at retry / auth-query.tsx:27 — это один кластер; verifier должен верифицировать его ОДИН раз, а не пять, освободив бюджет на TIMED_OUT-кейсы.

  6. Политика verifier-таймаутов: для дорогих офлайн-репро (cold-boot blank) — либо больший бюджет, либо «подтверждение по корроборации»: если N≥3 соседних находок с тем же root-cause уже verified, кластер можно метить verified-by-corroboration вместо TIMED_OUT.

  7. Пресет окружения стенда (chromium executable_path-override; auth-rate-limit 429 → «всегда curl /api/auth/login перед тем как винить логин; разноси прогоны на ~18-60с»; SPA делает клиентский редирект → опрашивай page.url, не wait_for_url(load)). Каждый агент переоткрывал это — вынести в SKILL.md, сэкономит таймбокс.

  8. «Один симптом — несколько корней» в шаблон отчёта: явно линковать находки по симптому (white-screen) и по корню (crash-throw vs gate-on-live-auth), чтобы defect/WIP-классификации не выглядели взаимоисключающими.


📌 Ключевой процесс-вывод: 6 «реальных дефектов» = ОДИН корень (offline blank-shell), независимо переоткрытый 5 агентами — нулевая межролевая дедупликация (важный недостаток скилла: один баг раздувается в N находок). recon — главный фолс-позитивщик; все офлайн-агенты применили SW-технику ВЕРНО, никто не свалил на tooling.

🤖 web-test-orchestrator (process-trace)

> **Прогон 4/7** · эпик **PR #120** (offline-sync / PWA) · web-test-orchestrator · 14 сырых → 6 подтв / 2 ложных / 2 WIP. > Процесс-отчёт. Сравни с прогоном 3 (#237). # Process-trace QA отчёт — PR #120 `feature/offline-sync` (gitmost / Docmost fork) > Фокус — НЕ на коде, а на ПРОЦЕССЕ: как отработали агенты web-test-orchestrator, кто как применил офлайн-технику, кто фолс-позитивит, как verifier отсеивал. Сырьё: 14 находок от 7 ролей + 13 вердиктов verifier (1 — TIMED_OUT). --- ## 1. Сводка прогона **Стадии:** recon → mapping → charters → execution (персоны-туры) → oracle eval → Doer–Verifier → отчёт. Все офлайн-агенты дошли до execution с реальным Playwright-прогоном; root-cause-агенты дополнительно делали grep/Read исходников клиента. **Агенты (7 ролей):** `recon`, `pwa-sw-shell`, `offline-read tester`, `offline-edit-body`, `offline-structural-outbox`, `update-prompt-install slice`, `online-sanity-regression`. **Воронка 14 сырых находок → после verifier:** | Итог | Кол-во | Что это | |---|---|---| | Подтверждённые РЕАЛЬНЫЕ дефекты | **6** | один корень (blank-screen/crash офлайн), переоткрыт 5 агентами | | Не-реализовано / WIP (корректно классиф.) | **2** | offline create без навигации; cold-boot read-path не подключён | | Ложные (verifier: speculative / not-a-bug) | **2** | оба от `recon` | | Verified-но-НЕ-дефект (вне трёх корзин) | 4 | контур-A работает (positive); console-401 baseline; LAN-IP collab (env); мусор тест-данных (hygiene) | | Из них verifier НЕ смог перепроверить (TIMED_OUT) | 1 | `pwa-sw-shell` blank-shell — но подтверждён 5 «соседями» | Ключевой факт процесса: **6 из 6 «реальных дефектов» — это ОДИН баг** (`auth-query.tsx:27`, незащищённый `error.response.status` в retry-предикате `useCollabToken`). Дедупликации между ролями не было — каждый офлайн-агент пришёл к нему сам. --- ## 2. Какие агенты/инструменты отработали **`recon`** — карта приложения, SW/cache/IndexedDB-интроспекция, сетевой/консольный шум. Инструменты: Playwright `launch_persistent_context` (чтобы SW+IndexedDB жили между навигациями), `page.on(console/response/requestfailed)`, `page.evaluate` (`serviceWorker.getRegistration/ready/controller`, `caches.keys()`, `indexedDB.databases()`), `eval_on_selector_all`, скриншоты, curl `/sw.js` `/manifest.json`. Офлайн-технику толком НЕ применял (остался в онлайне), зато нашёл SW-lifecycle-нюансы — и именно тут перегенерил шум (см. §4). **Самый фолс-позитивный.** **`pwa-sw-shell`** — персона «установленный PWA, потерял сеть». Техника образцовая: один контекст, дождался `controller != null` + 237 precache, ТОЛЬКО потом `set_offline(True)` + `reload`. Главное — **дисконфирм-контроль**: офлайн БЕЗ reload отрисовал полный `/home` (1279 символов), что изолировало дефект на cold-boot, а не на tooling/офлайн вообще. Нашёл blank-shell + проксимальный TypeError. sync_api. На tooling НЕ свалил. **`offline-read tester`** — «тётя Люба читает закэшированное в поезде». Один `launch_persistent_context` online→offline→online. Оракул out-of-band: Postgres `text_content` через `docker exec psql`. Дисконфирм-контроль: офлайн без reload — контент жив (bodyLen 976); reload — bodyLen 0 + тот самый pageerror. Grep `.status` по `apps/client/src` → точное место. Чисто, надёжно. **`offline-edit-body`** — контур-A (тело Yjs). Самый строгий: триангуляция ТРЁХ оракулов (Postgres `pages.text_content` out-of-band, online hard-reload, `indexedDB.databases()`). Корректно отделил «правка в открытой вкладке переживает reconnect» (positive, НЕ баг) от «reload офлайн = white-screen» (дефект), и довёл до строки `auth-query.tsx:27`, отметив, что соседний `api-client.ts:25` защищён `if (error.response)`. Надёжный. **`offline-structural-outbox`** — контур-B (REST→кэш+outbox). Проверил IndexedDB-аутбокс (`gitmost-rq-cache` → `clientState.mutations`), второй браузер-контекст как независимый оракул, `from_service_worker` на навигации. **Лучшая дисциплина WIP-vs-bug**: blank-shell классифицировал как РЕАЛЬНЫЙ дефект, а «create без навигации» — как not-implemented-wip, явно зафиксировав «мутации НЕ теряются, реплеются на reconnect». SW-активацию проверил до offline. Надёжный. **`update-prompt-install slice`** — персона install/update + глубокое чтение исходников (`vite.config`, `pwa-update-prompt`, `query-persister`, `user-provider`, `auth-query`). `add_init_script` со слушателем `unhandledrejection` поймал стек `at retry(...)`, однозначно указавший на retry-предикат `useCollabToken`. Нашёл ВТОРОЙ механизм того же blank-screen (gate-on-live-auth + исключение currentUser из `OFFLINE_PERSIST_ROOTS`) и корректно пометил его WIP. Надёжный. **`online-sanity-regression`** — базлайн/регрессия онлайна. Fresh-profile cold-install контроль, capture websocket-фреймов. Обе находки — корректно как НЕ-регрессии (console-401 baseline; LAN-IP collab = env-portability). Дисциплина framing'а образцовая. **Вывод по технике:** все 5 офлайн-агентов применили SW-технику ПРАВИЛЬНО — один persistent-контекст, ожидание `ready`+`controller` до `set_offline`, дисконфирм-контроли. **Никто не свалил дефект на tooling.** Единая трением-точка у всех — `chromium-1148` вместо ожидаемого пакетом `1223` (нужен `executable_path`-override) и auth-rate-limit 429 (внешне = «логин не прошёл»). Оба — френдли-огонь скилла/окружения, и агенты корректно НЕ обвинили приложение. --- ## 3. Баги по КЛАССУ (как проявлялся / как и кем найден) **A. blank-shell-offline / white-screen-of-death (rendering ⨯ unhandled-exception) — ДОМИНИРУЮЩИЙ класс.** Проявление: офлайн reload/cold-boot — SW отдаёт `index.html` shell (HTTP 200, `from_service_worker`, `title` выставлен), но `body.innerText.length=0`, в `#root` только Mantine `<style>`, ни лоадера, ни «вы офлайн», ни редиректа, ни авто-восстановления на reconnect (нужен ручной reload). Закэшированный контент (IndexedDB `keyval-store` + Yjs `page.*`) существует, но не рендерится. Найден: на стадии **execution**, первым — `pwa-sw-shell` (online→ждать SW→`set_offline`→`reload`, с дисконфирм-контролем). Затем НЕЗАВИСИМО переоткрыт `offline-read`, `offline-edit-body`, `offline-structural-outbox`, `update-prompt-install` (6 сырых находок). **B. unguarded-property-access / uncaught-exception (проксимальный код-дефект под A).** Проявление: `TypeError: Cannot read properties of undefined (reading 'status')`, 3/3 на каждый офлайн cold-boot. Офлайн bootstrap-запрос (`/api/auth/collab-token`, `/api/users/me`, NetworkOnly) падает `ERR_INTERNET_DISCONNECTED` без `response`, обработчик читает `.status` → throw до монтирования React. Найден: **pageerror/`unhandledrejection`-слушателями**; кадр стека `at retry` сматчен с retry-предикатом `useCollabToken`; добит grep'ом `.status` по исходникам (одно незащищённое место против защищённого соседа). **C. partial-offline / degraded-UX (WIP, БЕЗ потери данных).** Проявление: офлайн «Create page» ставит мутацию в очередь (`clientState.mutations {spaceId}`), но НЕ навигирует и не даёт редактируемую цель; на reconnect реплеется как `Untitled` (title=null). Данные не теряются. Найден: `offline-structural-outbox` — сверка online (`NAVIGATED=True`) vs offline (`False`, 0 редакторов) + дамп IndexedDB-аутбокса + `/api/pages/recent` после reconnect. **D. offline-read-path-not-wired (WIP).** Проявление: тот же белый экран на cold-boot, но другой механизм — `UserProvider` отдаёт `<></>` на любую ошибку `useCurrentUser`, а `currentUser` намеренно исключён из `OFFLINE_PERSIST_ROOTS`, поэтому persisted-кэш недостижим через relaunch. Найден: `update-prompt-install` — чтением `user-provider.tsx` + `query-persister.ts`. **E. sw-activation-race (cosmetic, FP).** `active.state='activating'` при уже не-null `controller` — штатное W3C-поведение `clientsClaim`. `recon`. **F. benign-load-noise (FP/benign).** Pre-login 401 на `/api/users/me` и `/api/auth/collab-token` — ожидаемые анон-пробы. `recon` + `online-sanity`. **G. config/portability (env).** Collab WS на захардкоженный `ws://10.20.30.227:3001`. В этом стенде работает. `online-sanity`. **H. residual-test-data (hygiene).** Мусорные заметки прошлых QA в General. `recon`. > Важно: классы **data-loss-on-reconnect** и **silent-optimistic-loss (успех→тихая потеря)** были ЦЕЛЕНАПРАВЛЕННО проверены и ДИСКОНФИРМИРОВАНЫ: контур-A переживает reconnect (Postgres-оракул), аутбокс-мутации персистятся и реплеются. То есть «страшных» молчаливых потерь данных не нашли — нашли «громкий» краш. --- ## 3b. Кто что нашёл | # | Находка | Агент | Класс | Вердикт | |---|---|---|---|---| | 1 | Pre-login 401 (как «находка») | recon | benign-load-noise | **false (speculative)** | | 2 | SW 'activating' при non-null controller | recon | sw-race-cosmetic | **false (speculative)** | | 3 | Мусор тест-данных в General | recon | residual-test-data | verified (не дефект) | | 4 | Blank shell на офлайн cold-start | pwa-sw-shell | blank-shell | **TIMED_OUT** (корроборирован) | | 5 | TypeError reading status (bootstrap) | pwa-sw-shell | unhandled-exc | **verified-defect** | | 6 | White-screen на всех роутах офлайн | offline-read | blank-shell/WSOD | **verified-defect** | | 7 | Контур-A правка переживает reconnect | offline-edit-body | none/working | verified (POSITIVE, не баг) | | 8 | Reload офлайн = white-screen SPA | offline-edit-body | WSOD | **verified-defect** | | 9 | Cold-start PWA blank | offline-structural-outbox | unhandled-exc | **verified-defect** | | 10 | Create офлайн без навигации | offline-structural-outbox | partial-offline | **verified-WIP** | | 11 | TypeError в `useCollabToken` retry | update-prompt-install | unguarded-access | **verified-defect** | | 12 | Cold-boot read-path gated on live-auth | update-prompt-install | read-path-not-wired | **verified-WIP** | | 13 | Pre-login 401 (как baseline-nit) | online-sanity | console-error | verified (benign) | | 14 | Collab WS захардкоженный LAN IP | online-sanity | config/env | verified (env) | --- ## 4. ФОЛС-ПОЗИТИВЫ — кто и насколько (ключевой раздел) **`recon` — единственный систематический источник фолс-позитива.** 3 находки, 2 убиты verifier'ом как `speculative` (~66% FP среди его «находок»). Чём фолсит: **штатное поведение платформы → выдаёт за дефект**. SW `activating` — это спецификация W3C `clients.claim()`; pre-login 401 — ожидаемые анон-пробы. Обе воспроизводятся детерминированно, поэтому «verified» по факту репро — но это not-a-bug. Урок: `recon`-роли нужен жёсткий гейт «нашёл странность ≠ нашёл дефект». **Контраст framing'а (важно для отладки скилла):** одно и то же явление — pre-login 401 — у `recon` (#1, заявлено КАК находка-проба) убито в `speculative`, а у `online-sanity` (#13, заявлено КАК «benign baseline, не SW-регрессия») прошло `verified`. **Вердикт verifier'а трекает ФОРМУЛИРОВКУ/скромность претензии, а не само явление.** Скромный framing «это базлайн, не наш регресс» проходит; претензия «это дефект» — режется. **Все 5 офлайн-агентов — 0 фолс-позитивов по дефектам.** 100% их defect-claims подтвердились (5 verified + 1 timed-out-но-корроборирован). Это очень здоровый сигнал: тяжёлая офлайн-техника + дисконфирм-контроли = почти нулевой FP. **Путаница «не реализовано» vs «баг» — НЕ обнаружена.** Ни один агент не назвал WIP-пробел «багом». Оба WIP-кейса (#10, #12) явно помечены `not-implemented-wip` с правильным дискриминатором: «нет потери данных, нет ложного success-тоста — просто пусто/деградировано». А blank-shell, наоборот, верно классифицирован как РЕАЛЬНЫЙ дефект (это краш/тихий lockout, а не «фича не дописана»). Дискриминация между WIP и дефектом — сильная сторона прогона. **Покрытие verifier'а — 1 дыра.** Находка #4 (`pwa-sw-shell` blank-shell) — `TIMED_OUT`, независимо не переперепроверена. Риск низкий: тот же корень подтверждён 5 соседними находками. Но это сигнал, что verifier'у нужен бюджет/таймаут-политика (см. §6). **Надёжность (от лучшего):** `offline-edit-body` ≈ `offline-structural-outbox` ≈ `update-prompt-install` (root-cause до строки, оракулы out-of-band, WIP-дисциплина) > `pwa-sw-shell` / `offline-read` (отличная техника, без глубокого root-cause) > `online-sanity` (корректно, но низкоценные базлайн/env находки) > **`recon` (нужен FP-гейт).** --- ## 5. Где скилл сработал/провалился на ОФЛАЙНЕ **Сработал:** - **Поймал главный офлайн-дефект** (blank-shell/WSOD на cold-boot) — причём 5 независимыми путями, с root-cause до конкретной строки и до соседнего ЗАЩИЩЁННОГО места (доказывает, что это аутлайер, а не общий паттерн). - **SW-lifecycle-техника применена верно ВЕЗДЕ**, где нужна: один `launch_persistent_context`, ожидание `ready` + `controller != null` ДО `set_offline`, переключение online↔offline↔online в одном контексте. Ни одного «свежий контекст / SW не активирован». - **Дисконфирм-контроли как норма:** «офлайн БЕЗ reload → UI цел» против «reload → пусто» — именно это отделило app-дефект от tooling/общей офлайн-невозможности. Это и спасло от ложного обвинения инструментов. - **WIP-гейт отработал:** silent-optimistic-loss и data-loss-on-reconnect были проверены оракулами (Postgres out-of-band, IndexedDB-аутбокс, второй контекст) и ДИСКОНФИРМИРОВАНЫ — агенты не выдали «деградацию UX» за «потерю данных». **Провалился / шероховатости:** - **`recon` тащит SW-lifecycle-косметику в дефекты** (activation race) — на офлайн-стенде это особенно зашумляет, т.к. SW-состояния выглядят «подозрительно», но штатны. - **Массовая недедупликация:** 6 сырых находок = 1 баг. Пять ролей сожгли бюджет на переоткрытие одного и того же `auth-query.tsx:27`. Скилл не свёл их до прогона verifier'а. - **Классификационное наложение:** #12 (gate-on-live-auth, помечен WIP) и #5/#6/#8/#9/#11 (тот же белый экран, помечены defect) — это ДВА разных механизма одного симптома. Без явной сшивки «один симптом — два корня» отчёт выглядит противоречиво (баг это или WIP?). Ответ: и то, и то, но скилл это не свёл. - **Френдли-трения окружения** (`chromium-1148` vs `1223`; auth 429 как ложный «логин не прошёл») каждый агент переоткрывал заново — это надо вынести в пресет скилла, а не оставлять на переоткрытие каждой роли. - **Verifier-таймаут (#4)** — самый ценный, дорогой репро (blank-shell) остался без независимой переперепроверки. --- ## 6. Предложения по улучшению скилла (упор на PWA/offline) 1. **SW-lifecycle-чеклист как жёсткий пресет** (а не на усмотрение роли): (a) `launch_persistent_context` обязателен; (b) ассерт `serviceWorker.ready` И `controller != null` ДО `set_offline`; (c) обязательный дисконфирм-контроль «офлайн без reload»; (d) проверка `response.from_service_worker` на навигации. Все офлайн-роли это сделали — закрепить, чтобы и `recon` не выпадал. 2. **FP-гейт «штатное поведение ≠ дефект» для recon/sanity-ролей.** Явный стоп-лист: SW activation race (`clientsClaim`), pre-auth 401-пробы, cross-origin WS не перехватывается SW — это НЕ дефекты по умолчанию. Снимет ~2/3 шума `recon`. 3. **WIP-vs-bug-гейт как формальный оракул-вопрос:** «есть ли (a) потеря данных, (b) ложный success-тост/тихий успех? Если нет, а функция просто отсутствует/пуста → not-implemented-wip; если краш/lockout/тихая потеря → defect». Прогон уже это делал интуитивно — кодифицировать. 4. **Офлайн-оракулы вынести в reference как набор:** Postgres `text_content` out-of-band (`docker exec psql`, роль `docmost/docmost`), IndexedDB-аутбокс (`keyval-store`/`gitmost-rq-cache` → `clientState.mutations`), второй браузер-контекст, `from_service_worker`. Это «золотые» оракулы, которые отличают «не нарисовалось» от «потерялось». 5. **Дедуп ПЕРЕД verifier'ом по сигнатуре root-cause** (строка/стек-кадр/error-string). 6 находок с `reading 'status'` / `at retry` / `auth-query.tsx:27` — это один кластер; verifier должен верифицировать его ОДИН раз, а не пять, освободив бюджет на TIMED_OUT-кейсы. 6. **Политика verifier-таймаутов:** для дорогих офлайн-репро (cold-boot blank) — либо больший бюджет, либо «подтверждение по корроборации»: если N≥3 соседних находок с тем же root-cause уже verified, кластер можно метить `verified-by-corroboration` вместо `TIMED_OUT`. 7. **Пресет окружения стенда** (chromium `executable_path`-override; auth-rate-limit 429 → «всегда curl `/api/auth/login` перед тем как винить логин; разноси прогоны на ~18-60с»; SPA делает клиентский редирект → опрашивай `page.url`, не `wait_for_url(load)`). Каждый агент переоткрывал это — вынести в SKILL.md, сэкономит таймбокс. 8. **«Один симптом — несколько корней» в шаблон отчёта:** явно линковать находки по симптому (white-screen) и по корню (crash-throw vs gate-on-live-auth), чтобы defect/WIP-классификации не выглядели взаимоисключающими. --- 📌 **Ключевой процесс-вывод:** 6 «реальных дефектов» = ОДИН корень (offline blank-shell), независимо переоткрытый 5 агентами — **нулевая межролевая дедупликация** (важный недостаток скилла: один баг раздувается в N находок). recon — главный фолс-позитивщик; все офлайн-агенты применили SW-технику ВЕРНО, никто не свалил на tooling. 🤖 web-test-orchestrator (process-trace)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#238