dr-fanout · diff

v1.0.0 to git:20261003.a2d662f

137 added, 510 removed. Audit B to B.

---
name: dr-fanout
- description: "Одна команда — разнести Deep Research промпт сразу по нескольким внешним LLM (Claude x3 бака / ChatGPT x2 / Gemini /… Триггеры: /dr-fanout, «разнеси ДР», «разошли дипресёрч», «запусти DR в трёх», «fan out the DR», «раздай промпт по LLM», а также САМ после шага 3 Альфа-протокола (мандат Антона 2026-07-14: любое количество DR без спроса — квоты не экономим, деградация ChatGPT мягкая"
- version: 1.0.0
+ description: >-
+ Fan one deep-research prompt out to several external LLMs at once through a logged-in browser,
+ then collect the reports, archive the originals and synthesize a consensus. Use at the final
+ stage of a research protocol, instead of hand-pasting one prompt into N sites. Triggers:
+ "/dr-fanout", "fan out the DR", "distribute the research prompt".
+ license: MIT
---
- # /dr-fanout — раздать Deep Research по 6 LLM и собрать консенсус
-
- > Финал Alpha Protocol на автомате. Каналы: **ChatGPT** (chatgpt.com) · **Gemini** (gemini.google.com) · **Grok** (grok.com) · **claude.ai** (claude.ai) · **GLM** (chat.z.ai) · **Mistral Le Chat** (chat.mistral.ai, с 05.08.2026 — дверь ещё не открыта, см. рецепт). ⭐ **МЕХАНИКА ЗАВИСИТ ОТ ТИПА СЕССИИ, и это не деталь, а корень класса** (`courier-сессия-dr_queue-без-chrome-mcp`, 5 дат: 08-11, 08-26, 09-04, 09-06, 09-07 — курьер пять раз объявил collect невыполнимым, стоя рядом с работающей дверью). **Сессия-приложение** (есть браузерные MCP-инструменты) — живой залогиненный Chrome Антона, Claude-in-Chrome MCP. **Безлюдная сессия** (`claude -p`, launchd, рутина — у неё браузерных MCP нет и не будет) — ТОЛЬКО headless: `dr_ff_rail.py` (Firefox AutoFF; claudeai/chatgpt/gemini/glm), `dr_ff_collect.py` (забор готового отчёта), `dr_headless_dispatch.py` (grok; ⛔ codex И claude CLI для ДР запрещены — anton голосом 22.09.2026: бак Codex кодит Антон, бак Claude — оркестратор; ноги ChatGPT/Claude = только веб. Headless ПОКА можно grok/mistral/glm/gemini — «пока там есть лимиты»). ⛔ Не проверяй наличие Chrome-MCP, чтобы решить, выполнима ли работа: **машинная истина о дверях = `python ~/.claude/scripts/dr_doors.py list`** (один источник; собирает карту ИМПОРТОМ у тех модулей, которые двери и открывают). ⚠️ Прежняя строка тут звала поле `doors` в `robot-work` и карту `RAIL_DOORS` — ни того, ни другого в коде НЕТ (проверено 14.09.2026 grep'ом по всему дереву): указатель на несуществующий прибор — тот же класс, что и рельса без двери. Нет двери — так и написано словами. Канон: [[alpha-protocol-recall-plus-dr]], decision-multi-llm-vendor-independence (гетеро-консенсус), [[chrome-autonomy-self-drive]], [[browser-work-on-peers-not-hub]] (строго локально).
- >
- > ⭐ **КВОРУМ 4 (из 5, с 05.08 — из 6)** (приказ Антона 04.08.2026: «я бы считал что ДР выполнен если сделано 4 из 5 ЛЛМ»). `dr_queue.derive_status` закрывает заказ, когда собраны ЛЮБЫЕ 4 рельсы (из 5, а с 05.08.2026 — из 6) — одна молчащая рельса больше не держит запись заложником (замер: gemini 32 заказа / 6 отчётов). ⛔ Кворум НЕ отменяет пятую рельсу: недобранное плечо продолжает светиться в `status` строкой «⚠️ кворум 4/5, не собрано: …» и в `robot-work` полем `missing_quorum_ok` — «сойдёт» должно быть ВИДНО. Узкий веер (3 цели) по-прежнему требует все 3: кворум = `min(4, сколько заказано)`. ⭐ Шестая рельса (Mistral) планку НЕ подняла — она добавлена, чтобы 4 набиралось легче. Гейт: `python ~/.claude/scripts/_test_dr_quorum.py`.
- >
- > ⭐ **ВЕЕР 04.08.2026 = ПЯТЬ РЕЛЬС** (два прямых распоряжения Антона в один день): «теперь ВСЕГДА добавляй КЛОД.аи в ДРы» + «glm ТОЖЕ ИСПОЛЬЗУЕМ ДЛЯ ДР… ВХОД ЧЕРЕЗ ббПЛАТИНУМ». Машинная истина дефолта — реестр `~/.claude/dr_rails.json` (с 14.09.2026 `dr_start.py` берёт дефолт ОТТУДА, а не из литерала в коде: копии списка рельс по файлам и были источником целей без дверей); ⛔ сокращать веер молча нельзя, снятие рельсы = `dr_queue.py retarget --drop` с доказанными дверями (обе новые рельсы уже в `BROWSER_RAILS`).
-
- ## ⭐⭐ ПРИКАЗ 14.09.2026 (голосом): МАКСИМУМ ПОПЫТОК · МАКСИМУМ ДУМАНИЯ · ПОСТ СРАЗУ
-
- > «Всегда нужно делать максимальное количество попыток: отправлять запросы в как можно
- > большее количество мест для deep research… Всегда включаем максимальное думание,
- > максимально качественный ответ, максимально долгие и подробные размышления.»
-
- **Машинная истина о рельсах, аккаунтах и режимах думания = `~/.claude/dr_rails.json`.**
- Один файл, три ответа: какие рельсы существуют (7), какие у них аккаунты (12), и КАК на
- каждой включить самый сильный режим. ⛔ Не пересказывать список здесь и не держать вторую
- копию — расхождение прозы с JSON = баг прозы.
-
- **① МАКСИМУМ ПОПЫТОК.** Дефолт веера — 6 рельс. Perplexity объявлена седьмой 14.09, её дверь
- ещё не построена: dispatch честно печатает «нет двери», а не молчит. **Пол = 3 разные LLM**
- (`min_rails`): ДР в две LLM не бывает, это не ДР. Кворум не набрался основным веером →
- **широкий добор вторыми аккаунтами** того же вендора (chatgpt a2@, claudeai a2@/bb@,
- gemini a2@) — это ещё 5 попыток, и они дешевле, чем ждать молчащую рельсу.
-
- **② МАКСИМУМ ДУМАНИЯ — ЧАСТЬ КОНТРАКТА, А НЕ НАСТРОЙКА.** Каждая рельса запускается в самом
- сильном режиме, какой даёт подписка: у Gemini это `More tools → Deep Research`, у ChatGPT
- `Deep research`, у Grok `DeeperSearch + Think`, у claude.ai `Extended thinking + Research`,
- у Perplexity режим `Research`. ⛔ **Быстрый режим не считается попыткой**: обычный чат-ответ,
- записанный в `results/`, — это подделка рельсы, тот же класс, что `0 searches / 0 citations
- = dead`. Не смог включить сильный режим → рельса `missing`, а не «собрана».
-
- **③ КВОРУМ 4/6 ЗАКРЫВАЕТ СЕССИЮ, НО НЕ ЗАКАЗ.** Пришли 4 — синтез идёт сразу, оставшиеся
- две не ждём. Они не теряются: `dr_ff_collect.py` забирает готовый отчёт из последнего чата
- вендора, `dr_debt_watch.py` осушает долг реестра суточным обходом. Именно поэтому закрытие
- по кворуму законно — недобранное доедет само.
-
- **④ ЗАКРЫЛИ ДР → В ТОМ ЖЕ ЗАХОДЕ ЧЕРНОВИК ПОСТА.** Не «потом», не в ежедневной полосе:
-
- ```bash
- python ~/.claude/scripts/dr_post_draft.py --id <DR-номер> --topic "<вопрос одной строкой>" --audience "<кому это полезно>" --verdict "<главный вывод>" --collected <сколько рельс> --why "<что искали>" --link <ссылка на корпус/синтез>
- ```
-
- Печатает две части. **Тело** — тизер 240–300 знаков HARD: польза («кому интересен X»),
- тема, строка «глубокое исследование в N/6 LLM», короткий вердикт, и путь вниз «Сами
- исследования и синтез — в комментариях». Ссылок в теле нет — геймплей лаборатории.
- **Первый комментарий** — ссылки на отчёты и синтез плюс обязательная атрибуция: заказали
- Tony Dzi (Anton Dziatkovskii) и Майкрофт, Palo Alto AI Research Lab, что искали,
- available for hire, Calendly, Linktree. Тексты атрибуции берутся из `_STYLE-footer.md`,
- ⛔ не сочиняются ([[post-mandatory-elements]]).
-
- Инструмент **не надувает текст водой**: короткий вердикт → отказ с требованием конкретики
- (цифра, ограничение, что удивило), а не разжатие мысли. Черновик, наружу не уходит —
- публикация остаётся под §3.2 и матрицей площадок. Та же атрибуция обязана стоять **внутри
- синтеза**, а не только под постом. Гейт: `python ~/.claude/scripts/_test_dr_post_draft.py`. Канон: [[dr-max-thinking-and-wide-fanout]].
-
- ## ⭐ ЗАЧЕМ ЭТО ВООБЩЕ: замкнутая петля САМООБУЧЕНИЯ (anton 04.08.2026)
-
- > «Это очень удобная штука для самообучения ИИ — когда ИИ сама заказывает ДР.»
-
- Скилл выглядит как «разослать промпт по сайтам», но это только транспорт. Настоящая ценность — **петля,
- в которой ИИ сама чинит свои пробелы**, и человек в ней не курьер, а владелец решений:
-
- ```
- ① пробел RECALL по волту+памяти не отвечает на вопрос → GAP назван вслух (Alpha Protocol)
- ② заказ ИИ САМА нумерует DR и разносит промпт по 5 рельсам (мандат 14.07: без «+», квоты не экономим)
- ③ сбор доказательство работы, не красивый текст: 0 searches / 0 citations = `dead`, не `collected`
- ④ синтез гетеро-кворум (разные вендоры = разные обучающие базы) → insight-DR + Decision Memo
- ⑤ ЗАПИСЬ вывод уходит в ДОМА правил (CLAUDE.md · Библия · память · скилл) — §8.4/§8.6
- ⑥ следующая сессия стартует уже умнее. Петля замкнулась.
- ```
-
- **Шаг ⑤ — единственное, что отличает самообучение от «почитал и забыл».** DR без записи в дом = потраченная
- квота: замер 29.07 — 184 из 246 отчётов висели в статусе `synthesized` и никуда не легли. Отсюда жёсткая
- клауза §9.1: у каждого DR есть КОНЕЦ (`applied` с «что поменяли» либо `parked` с «почему не берём»).
-
- **Три опоры, без которых петля врёт сама себе:**
- 1. **Гетерогенность.** Пять рельс = пять разных моделей. Один вендор, спрошенный пять раз, — это не пять мнений.
- 2. **Доказательство работы.** У отчёта должны быть источники/поиски/время думанья. Красивый текст из
- параметрической памяти неотличим от исследования на вид — и отравляет синтез молча.
- 3. **Обратная сторона той же монеты — рельсы РЕВЬЮ** (`secondop.py`, CLAUDE.md §4.3): DR-веер учит,
- ломатель проверяет. Локальные headless: `grok` · `gemini` (04.08; ⛔ `codex` и `claude` CLI выведены из ДР 22.09 — их баки заняты кодингом Антона и оркестрацией; ПОКА-разрешение grok/mistral/glm/gemini живо, пока у них есть лимиты); веб-дверь: `glm` и остальные.
- Тот же принцип «дверь закрыта ≠ вендор мёртв» и тот же запрет тихой подмены вендора.
+ # /dr-fanout — fan a Deep Research prompt out to 3+ LLMs and collect a consensus
- **Безлюдный режим:** `dr_headless_dispatch.py` (04.08) гоняет grok без человека (⛔ codex и claude CLI запрещены 22.09, скрипт отбивает fail-closed, клапан DR_RAIL_BAN_OK=1 только по слову Антона). ⚠️ Провал там судится
- по РАЗМЕРУ выхода, а не по exit-коду: ведущий `---` YAML-фронтматтера убивал обе рельсы при честном exit 0 и
- файле в 0 байт.
+ > The final stage of the Alpha Protocol, automated. Channels: **ChatGPT** (chatgpt.com) · **Gemini** (gemini.google.com) · **Grok** (grok.com). The mechanism = the Claude-in-Chrome MCP (the operator's live logged-in Chrome). Canon: [[alpha-protocol-recall-plus-dr]], decision-multi-llm-vendor-independence (heterogeneous consensus), [[chrome-autonomy-self-drive]], [[browser-work-on-peers-not-hub]] (strictly local).
- ## ⭐ Что уже решено (фундамент, не переисследовать) — обновлено 2026-07-16
- 1. **Браузерный слой = Firefox-first** (Decision Memo `02-Decisions/decision-2026-07-16-browser-automation-layer.md`, DR26-07-16-HUB-01, уверенность high). Chrome 127+ шифрует куки (ABE) и с апреля 2026 привязывает сессии к железу (DBSC) → внешнее извлечение куки невозможно без malware-техник. **Firefox куки открыты** (plaintext SQLite, DBSC не реализует) → выделенный per-service Firefox-профиль + Playwright `launch_persistent_context`; Chrome CDP-attach только как fallback для строго-Chromium сайтов. Хаб-стек уже поднят: `firefox_cookies.py` (`~/.claude/scripts/_shared/`), профили `[путь владельца]`.
- 2. **Живой Chrome-MCP (Claude-in-Chrome) остаётся осознанным anti-ban путём** для действий «как человек в реальном сеансе» (fb-post/x-post едут так). Для dr-fanout выбор пути исполнения (живой Chrome-MCP vs headless Firefox-Playwright) уточняется идущим DR (см. п.4).
- 3. **CLI-обход НЕ даёт Deep Research по подписке** (проверено 15.07): Codex CLI / Gemini CLI = только web search; настоящий Deep Research потребительской подписки программно не дёргается (Google DR-агент = платный API отдельно). ⇒ браузерная веб-морда — единственная дорога к DR по подпискам, значит делаем её анти-хрупкой, а не бежим от неё.
- 4. **ToS-риск, острее всего у Grok:** xAI AUP прямо запрещает автоматический/не-человеческий доступ (риск suspension/termination). Задокументированных банов за автоматизацию СВОЕГО аккаунта нет, но текст явный → Grok-канал гнать в человеческом темпе; решение «оставить/притормозить/заменить на Claude.ai» — за Антоном.
- 5. **Grok — просто продолжаем использовать** (решение Антона 2026-07-16). xAI AUP формально запрещает автоматизацию, но охота идёт за масс-скрейпингом (штраф $15k/1M запросов), а наш темп естественно крошечный (несколько DR в день максимум) → мы не мишень. Ценность третьего независимого голоса > управляемого риска. НЕ городить лимиты/троттлинг ([[ak47-simplicity]]) — Grok в обычной ротации; если сам вендор упрётся (капча/challenge) — доложить и пропустить этот канал, без драмы.
- 6. **Путь исполнения — ГИБРИДНЫЙ, под каждого вендора свой** (решение Антона 2026-07-16, «и так и так»). Не один способ на всех:
- | Вендор | Путь | Почему |
+ ## ⭐ What is already decided (the foundation, don't re-research) — updated 2026-07-16
+ 1. **The browser layer = Firefox-first** (Decision Memo `02-Decisions/decision-2026-07-16-browser-automation-layer.md`, DR26-07-16-HUB-01, confidence high). Chrome 127+ encrypts cookies (ABE) and since April 2026 binds sessions to the hardware (DBSC) → external cookie extraction is impossible without malware techniques. **Firefox cookies are open** (plaintext SQLite, DBSC not implemented) → a dedicated per-service Firefox profile + Playwright `launch_persistent_context`; a Chrome CDP attach is only a fallback for strictly-Chromium sites. The hub stack is already up: `firefox_cookies.py` (`~/.claude/scripts/_shared/`), profiles in `<AUTOMATION_BROWSERS_ROOT>\Firefox\`.
+ 2. **The live Chrome MCP (Claude-in-Chrome) remains the deliberate anti-ban path** for actions that must look like "a human in a real session" (fb-post/x-post go that way). For dr-fanout the choice of execution path (live Chrome MCP vs headless Firefox+Playwright) is being clarified by an ongoing DR (see item 4).
+ 3. **A CLI workaround does NOT give you subscription Deep Research** (verified 07-15): the Codex CLI / Gemini CLI only do web search; real consumer-subscription Deep Research cannot be triggered programmatically (Google's DR agent = a separate paid API). ⇒ the browser front end is the only road to subscription DR, so we make it anti-fragile instead of running away from it.
+ 4. **ToS risk, sharpest at Grok:** the xAI AUP explicitly forbids automated/non-human access (risk of suspension/termination). There are no documented bans for automating YOUR OWN account, but the text is explicit → run the Grok channel at human pace; the decision to "keep / slow down / replace with claude.ai" belongs to the owner.
+ 5. **Grok — we simply keep using it** (the owner's decision, 2026-07-16). The xAI AUP formally forbids automation, but enforcement hunts mass scraping (a $15k/1M-requests penalty), and our pace is naturally tiny (a few DRs per day at most) → we are not the target. The value of a third independent voice > the managed risk. Do NOT build limiters/throttling ([[ak47-simplicity]]) — Grok stays in the normal rotation; if the vendor itself pushes back (a captcha/challenge) — report it and skip that channel, no drama.
+ 6. **The execution path is HYBRID, per vendor** (the owner's decision, 2026-07-16, "both ways"). Not one method for everyone:
+ | Vendor | Path | Why |
|---|---|---|
- | **Grok** | живой Chrome-MCP, человеческий темп | ToS-чувствителен → действуем как человек в реальном сеансе (макс anti-ban, как fb-post [[chrome-autonomy-self-drive]]); headless-бот тут = максимум риска |
- | **ChatGPT** | выделенный Firefox-профиль headless (безлюдно) ИЛИ живой Chrome-MCP | ToS мягче; извлечение отчёта = backend JSON (работает в обоих); для расписания без человека → Firefox |
- | **Gemini** | выделенный Firefox-профиль headless (безлюдно) | двухфазный (план→Start research), терпим к автоматизации; кандидат №1 на полностью безлюдный прогон |
- Принцип: чем жёстче ToS/бан-чувствительность вендора → тем ближе к «живой человек в сеансе» (Chrome-MCP); чем терпимее + важнее безлюдность → тем ближе к выделенному Firefox-профилю (Playwright persistent, фундамент HUB-01).
- 7. **✅ Оркестрация — ПОДТВЕРЖДЕНА внешним DR** (`DR26-07-14-FLEE-01`, синтез ChatGPT+Grok 2026-07-16, выжимка `03-Insights/insight-DR-DR26-07-14-FLEE-01-*`). Оба вендора независимо: ядро = **durable state-machine + job-ledger, НЕ «долгоживущий автономный браузер-агент»**; локальный ledger-FSM достаточен для одно-хозяйного хаба. Оба независимо советуют **НЕ строить безлюдную Grok-автоматизацию** (xAI AUP + enforcement реален: >52k банов в 2026, Reuters 15.07) → наша матрица п.6 уже это соблюдает (Grok только живой Chrome-MCP, никогда в демоне). **Безлюдное расписание стартуем с 2 вендоров: ChatGPT + Gemini.**
- 8. **Вендор-логику держать ТОНКОЙ, оркестрацию — общей.** UI-специфичные репо мрут быстро (`chatgpt-automation-mcp` архив 27.04.2026, `browserbase/gemini-browser` архив 20.05.2026). Всё вендор-специфичное = сменные «адаптеры» внизу; автомат/ledger сверху не меняется.
- 9. **⚠️ ОТКРЫТО — официальный путь для Gemini:** Deep Research Agent / **Interactions API** (`background=True` + polling, collaborative_planning) — production-ready, снимает самый хрупкий и медленный браузерный канал. НО ⚠️ УСЛОЖНЕНИЕ + неясен биллинг: входит ли в подписку Ultra или это отдельные деньги (ChatGPT-отчёт: «НЕ то же free-with-subscription»). **Проверить биллинг ДО стройки** ([[prefer-included-limits-before-paid-api]]) — если платный, не заводить без «+» Антона.
-
- ## ✅ GEMINI-ДР НА [машина флота] — РАБОЧИЙ РЕЦЕПТ, пройден вживую 01.08.2026 (DR26-08-01-MACANTON-02-659)
-
- Приказ Антона голосом 01.08: «делать чтобы через ГЕМИНИ!!!» ⇒ `gemini` вернулся в `DEFAULT_TARGETS` (`dr_queue.py`).
- Дверь ровно одна и она **НЕ API**: живой Chrome под `you@example.com` («Punk», платный AI Pro). Шаги, каждый проверен:
-
- 1. `list_connected_browsers` → набор МЕНЯЕТСЯ между заходами (в этом прогоне за 10 минут стало 2 Chrome вместо 1). Взял свой сам, `select_browser`, у Антона НЕ спрашивал ([[browser-and-account-pick-yourself]]).
- 2. `navigate` на `https://gemini.google.com/app?authuser=you@example.com` → **скриншот** (innerText врёт). Признак живой сессии: «What's the vibe, Punk?» + селектор `Pro Extended`. Аккаунт подтверждать `aria-label` кнопки профиля: `Google Account: Punk Crypto (you@example.com)`.
- 3. Транспорт промпта — `window.name`, направление **localhost → gemini** (обратное COOP рвёт): `python3 -m http.server` в скретчпаде → `navigate` на файл → `window.name = await fetch(location.href).then(r=>r.text())` → `navigate` на gemini. Замер: 5656 симв. и 100 кириллических доехали 1-в-1.
- 4. Чип Deep research ставить в ПУСТОМ композере: «+» (`Upload & tools`) → `More tools` → `Deep research`. ⚠️ Кликать по **ref** из `find`, не по координатам: клик по координатам подменю промахнулся молча, меню закрылось без чипа, и это видно только скриншотом. Признак успеха: плейсхолдер меняется на `What do you want to research?` и рядом появляется пилюля `Deep research`.
- 5. Вставка — только JS: фокус в `.ql-editor` → каретка в конец → `document.execCommand('insertText', false, txt)` (сел с первого раза; синтетический paste держим фолбэком). Сверять ДВУМЯ мерками: длина (`innerText` даёт +60 симв. на блочных переносах — это норма) и счётчик кириллицы (обязан совпасть точно).
- 6. Send → **двухфазность**: `Generating research plan` (~1 мин) → `find` кнопку `Start research` → клик по ref. Доказательство старта: «I'm on it… you can leave this chat» + карточка `Creating your report…` с чипами реальных источников внизу.
-
- ⛔ API-ключ ДР-рельсой НЕ является и не станет без денег. Замер 01.08, 3 чередования подряд в одной минуте (`probe2.py`): `gemini-flash-lite-latest` без `google_search` → 200 все три раза, с `google_search` → 429 все три раза, БЕЗ имени метрики и без `violations` — подпись «квота грунтинга 0 на free tier». Первый прогон, где 429 приходил и на plain-запросы, был собственным RPM (быстрый цикл по 6 моделям) — отделяется паузой 65 с, иначе ловишь ложный диагноз. Побочно: `gemini-2.5-flash` → 404 «no longer available to new users», `gemini-2.5-pro` на free-tier → `limit: 0`.
-
- 🔒 Дверь против рецидива: `dr_queue.py retarget --drop <браузерная рельса>` теперь ТРЕБУЕТ `--doors` с ≥2 проверенными дверями отдельными аргументами (гейт судит действие, не подстроку в reason). Ложный drop снимается `dr_queue.py restore <ID> --restore gemini --why "<чем доказано>"`.
-
- ## 🔴 GEMINI НА [машина флота] — читать ПЕРВЫМ, если Gemini «просит залогиниться» (разбор 31.07.2026, два ложных диагноза подряд)
-
- **Симптом-обманка:** `gemini.google.com` показывает «Sign in» + Flash-Lite, куки `.google.com` в профиле есть все (`SID`, `LSID`, `__Secure-1PSID`) — выглядит как протухшая сессия. Я выдал ДВА неверных диагноза («сессия протухла» → ask Антону, отозван; «гео-блок на [машина флота]» → заказ хабу, отозван), прежде чем нашёл настоящие причины. Обе ошибки ловились скриншотом и вопросом «а ЧЕЙ это браузер?».
-
- **Настоящих причин две, обе проверены:**
- 1. **⚠️ Chrome-MCP ≠ эта машина.** «Gemini isn't currently supported in your country» я увидел в Chrome через MCP — а из трёх подключённых Chrome тот оказался на ноуте [коллега] (IP в России, там Gemini закрыт). Свой IP я мерил curl-ом с [машина флота] (Вена, AT) и склеил факты с двух разных машин. **Правило: IP меряется ИЗНУТРИ того браузера, где виден симптом** (`fetch('https://ipinfo.io/json')` в той же вкладке). На [машина флота] гео-блока НЕТ — проверено изнутри Firefox: country-block False.
- 2. **Стена Google-consent («Before you continue to Google»)** перехватывает страницу, и ПОД ней рендерится разлогиненная оболочка — по DOM неотличимо от «разлогинен». Снимается трастед-кликом Selenium; кнопка ищется ТОЛЬКО по вложенному span: `//button[.//span[normalize-space(text())='Reject all']]` — поиск по `b.text` её НЕ находит (текст в потомке). После клика стена не возвращается.
-
- **Остаток после снятия стены:** куки Google в AutoFF реально не аутентифицируют → нужен ОДИН живой вход Антона: `firefox -no-remote -profile ~/.claude/browser-profiles/autoff https://gemini.google.com/app` окном, дальше рельса безлюдная. Свежий логин отличается по `creationTime` кук (не `lastAccessed` — его обновляет любой пинг).
-
- ⚡ **Порядок диагностики (30 секунд, а не два часа):** (1) скриншот — видимый текст первичен, `document.body.innerText` в фоновой вкладке отдаёт 0–324 симв. и врёт; (2) IP изнутри ТОГО ЖЕ браузера; (3) только потом гипотезы про сессию.
-
- **⛔ Прежде чем снять gemini через `retarget --drop` с формулировкой «на этом узле рельсы нет» (рецидив 01.08: раннер снял рельсу с 6 заказов, а рельса была жива в другом Chrome под Punk/`a@`):**
- 1. `list_connected_browsers` и обойти **КАЖДЫЙ** подключённый Chrome, не первый попавшийся; набор браузеров меняется между заходами — «в 06:00 был корп» ≠ «в 14:00 нет личного».
- 2. В каждом браузере пробовать вход **`https://gemini.google.com/app?authuser=you@example.com`** — даже если по умолчанию профиль открывает корп-аккаунт, authuser-редирект достаёт личный, если он залогинен в том же Chrome.
- 3. Причина drop обязана ПОИМЁННО перечислить проверенные двери (сколько Chrome обошёл, что показал каждый, пробовал ли authuser). «Chrome — корп-аккаунт» без счёта браузеров = недоказанный claim ([[prichina-kak-claim]]).
- 4. Drop = «leg не собран в этом заходе», а НЕ «узел мёртв» — вечные выводы про узел в reason не писать.
-
- Гипотезы, уже проверенные и **опровергнутые** — не тратить на них время заново:
- 1. «клон профиля теряет `storage/`/localStorage» — полная `rsync`-копия профиля ведёт себя так же;
- 2. «виноват headless» — headed идентичен;
- 3. «куки не долиты из WAL» — `cookies.sqlite-wal` 0 байт, снимки полные;
- 4. «живой Firefox держит сессию в памяти» — штатный SIGTERM, `cookies.sqlite` не изменился ни на байт;
- 5. «гео-блок на австрийском IP» — НЕТ: изнутри Firefox на [машина флота] блока нет; блок был на ЧУЖОМ Chrome (RU IP).
- 10. **⭐ ChatGPT-канал по умолчанию = Pro + инструмент «Web search», а НЕ чип Deep research** (замер 2026-08-04, разбор инцидента 26.07). Чип DR на этом аккаунте резолвится в `deep-research-mini`: ран обрывается посреди плана (`status: completed`, шаги 3–5 `pending`, 5–7 мин вместо 20–40) и открывает мало источников (12 уникальных URL при запрошенных 15–25). Тот же вопрос через **Pro + Web search** дал 73 поисковых запроса и 31 прочитанную страницу (`DR26-07-26-ZB-02-harari-alpha-chatgpt.md`, там же вендорский журнал поиска). ⇒ ChatGPT в веере = Web search-рельса; DR-чип — только когда явно нужен длинный автономный ран. ✅ **Тест проведён 04.08** (один ран, чип DR, пикер Pro, чат `6a71e627`): `resolved_model_slug = gpt-5-thinking` — ни полного DR, ни mini; 3m44s, обрыв на шаге 2, отчёт 13.4 КБ и **citations = 0** (URL набраны текстом, маркеров 【…】 нет) ⇒ сегодня чип DR отвечает из памяти по-настоящему. Лестница деградации канала: `deep-research` → `deep-research-mini` (21–26.07, поиск был) → `gpt-5-thinking` (04.08, поиска нет). Заодно закрыто: модель в пикере ни при чём — outer turn у DR всегда `gpt-5-5-instant`. 🤔 Причина (квота vs политика вендора) не доказана: эндпоинта с лимитами в вебе нет (`/backend-api/*limits*` = 404). ⇒ Практический вывод не меняется: **ChatGPT-канал = Web search**, DR-чип на `a2@` не тратить.
-
- ## ⛔⛔ КОРЕНЬ 22.09.2026 вечером: «ОТПРАВИЛОСЬ» ДОКАЗЫВАЕТСЯ ТОЛЬКО API ВЕНДОРА
-
- Замер, стоивший четырёх ложных ног и одного неверного доклада Антону: пять заказов ушли в GLM через живой Chrome, и по ВСЕМ признакам раны стартовали: URL сменился на `/c/<uuid>`, композер опустел, в сайдбаре появились заголовки чатов на русском по нашим темам. Через три часа `GET /api/v1/chats/` показал правду: на сервере существуют ТОЛЬКО ДВА чата из пяти, и у обоих `assistant: 0 байт` при целом `user: 3208`. То есть промпты доехали, а ответов не было НИ ОДНОГО.
-
- **Правило:** у браузерной рельсы состояние `started` ставится ТОЛЬКО после ответа API вендора, где есть assistant-сообщение длиной > 0. Для z.ai это:
- ```js
- const t=localStorage.getItem('token');
- const r=await fetch('/api/v1/chats/'+id,{headers:{Authorization:'Bearer '+t}}).then(x=>x.json());
- Object.values(r?.chat?.history?.messages||{}).map(m=>m.role+':'+String(m.content||'').length)
- ```
- ⇒ `["user:3208","assistant:0"]` = рельса НЕ работает, как бы убедительно ни выглядела страница.
-
- ⛔ Список признаков, которые СЕГОДНЯ ДОКАЗАНО лгут и больше не считаются стартом: смена URL на `/c/<id>` · опустевший композер · заголовок чата в сайдбаре · наличие нашего промпта в теле страницы. Первые два я сам записал в этот файл утром того же дня как доказательство — это было неверно ([[instrument-is-a-claim-too]]).
-
- ⚠️ Соседний замер того же вечера: три разные веб-рельсы (GLM, Mistral/Vibe, claude.ai) в живом Chrome вели себя одинаково: промпт садится 1-в-1 (длина и кириллица сверены), Send не доводит до чата, вкладка ловит CDP-таймаут 45 с. ⇒ Chrome-MCP для веера из нескольких заказов — хрупкая дверь; штатная — `dr_ff_rail` на ЗАЛОГИНЕННОМ робот-профиле.
-
- ✅ **Запрет протух: Mistral (теперь «Vibe») ЗАЛОГИНЕН в Chrome под «PaloAlto Ai Research Lab»**, стены ToS нет (блок 01.09 «требует принять новые Terms» больше не действует). Композер = `contenteditable`, режимы `Fast` / `Think` (брать **Think**), вставка только `execCommand('insertText')` — синтетический paste доносит ТОЛЬКО первую строку (102 из 2570 знаков).
-
- ## ⭐⭐ ПРИКАЗ 24.09.2026 (голосом, mid-run): БРАУЗЕР ПЕРВЫМ ВСЕГДА, CLI — ТОЛЬКО КОГДА БРАУЗЕР НЕДОСТУПЕН
-
- > «CLI двери мы используем только если браузеры недоступны. То есть мы всегда идём в браузер —
- > Chrome, Firefox — и только после этого мы идём в CLI.»
-
- Порядок дверей на КАЖДУЮ рельсу: **(1) живой Chrome-MCP → (2) Firefox-профиль (`dr_ff_rail`) →
- (3) CLI (`dr_headless_dispatch`) — только когда обе браузерные двери проверены и закрыты**, и в
- леджере названо, ЧЕМ закрыты (нет Chrome-MCP у сессии · капча · разлогин без права логина).
- Причина: браузерная дверь идёт по подписке в САМОМ СИЛЬНОМ режиме (Deep Research / Heavy /
- Advanced Search), а CLI отдаёт web-search-огрызок или вовсе хвост агента (замер 10.09: `claude -p`
- = 4302 б «Addendum», grok CLI = обрывок 696 б). Замер-родитель правила 24.09: сессия сожгла
- grok CLI и объявила gemini «мёртвым» по CLI-ошибке лицензии Code Assist, не сходив в веб —
- Антон отбил: «Gemini у нас работает прекрасно. Ты пробовал через Firefox и через Chrome?»
- ⛔ «CLI отработал» не закрывает рельсу, у которой браузерная дверь не проверялась.
- Безлюдные рутины без браузерных MCP по-прежнему едут headless — у них браузерной двери нет,
- это и есть законное «недоступен».
-
- ## ⛔ ШАГ 0 ОБЯЗАТЕЛЬНЫЙ (с 14.09.2026): СНАЧАЛА ПРИБОР, ПОТОМ БРАУЗЕР
-
- ```bash
- python ~/.claude/scripts/_shared/ff_session_probe.py # таблица профиль × вендор, 0 сети, ~0.1с
- python ~/.claude/scripts/_shared/ff_session_probe.py --rail claudeai # адресно
- ```
-
- **Читать вывод асимметрично.** «кук НЕТ» = сессии точно нет. «куки есть» = может быть жива, доказывает только заход (замер 02.09: у Google счётчик кук не менялся, а сессия была мертва).
-
- **Почему шаг появился (замер 14.09.2026, заказ DR26-09-14-ZB-09-2008, этот узел).** Четыре ноги умерли за шесть минут, и сессия объявила, что «профиль AutoFF протух», а фактически написала это про браузеры вообще. Антон отбил: «у меня куча браузеров, везде всё работает» — и был прав. Прибор показал: **в робот-профиле `ff-autoff-profile` claude.ai = 0 кук и chatgpt = 0 кук, туда не логинились НИКОГДА**, а Chrome `Profile 3` в это время работал и держал свои куки под замком. Ложный диагноз собрался из склейки двух разных болезней: три ноги шли на КОПИИ профиля (копия ломает ротацию — известно с 04.09), а четвёртая упала на пункте меню Deep Research, то есть на ВЁРСТКЕ.
-
- **Что изменилось в `dr_ff_rail.py` (дефолты, а не проза):**
-
- - работа **В самом профиле — теперь ДЕФОЛТ**; копия только по явному `--copy`. Знание «копия = разлогин у любого вендора с ротацией» две недели лежало строкой в журнале, пока дефолт кода копировал. Правило, не въехавшее в дефолт, не работает;
- - параллельность больше не покупается копией: `profile_lock()` ставит второй прогон **в очередь** (`BUSY`), а не плодит копию;
- - четыре болезни — четыре кода и четыре разных слова: **`NO_SESSION`** сюда не логинились (отказ за 0.75с, БЕЗ поднятия браузера, с именем живого профиля) · **`LOGGED_OUT`** выкинуло (ловится `/auth`, `logout`, `challenge_redirect` — раньше `/auth` не ловился, и разлогин GLM уезжал под видом «нет композера») · **`LAYOUT`** залогинены, но сменилась разметка · **`BUSY`** профиль занят соседним прогоном;
- - **автоподбор профиля**: если в заданном профиле логина вендора НЕ БЫЛО, рельса сама уходит в профиль, где сессия есть, и говорит об этом вслух (`--no-auto-profile` выключает). Знание «живые сессии лежат в системном профиле» лежало в этом файле с 10.09, но код упрямо шёл в свой пустой AUTOFF: знание в скилле не работает, пока код идёт мимо него;
- - ⚠️ автоподбор — костыль, а не лечение: человеческий профиль гвард уводит на КОПИЮ, а копия со временем ломает ротацию. Замер 14.09: gemini через «Ct3iOc7B.Profile 1» зашёл и ответил — то есть вчерашнее «gemini не нашёл Deep Research» было про ПУСТОЙ робот-профиль, а не про вендора;
- - тест: `python ~/.claude/scripts/_test_dr_ff_rail_logout_and_copy.py` (5/5, красный прогон воспроизводит старую логику); проба узла: `python ~/.claude/scripts/_probe_ffrail_root.py`.
-
- **Тупик, который надо знать до того, как начнёшь его обходить.** Человеческий профиль (`Ct3iOc7B.Profile 1`) in-place запрещён гвардом — geckodriver травит его `user.js`; а копия человеческого профиля убивает ротацию сессии. Обе двери закрыты, и это не лечится флагом. **Здоровый выход ровно один: один раз залогинить РОБОТ-профиль** и дальше не копировать его никогда:
-
- ```bash
- "[путь владельца] Files\Mozilla Firefox irefox.exe" -no-remote -profile "%LOCALAPPDATA% f-autoff-profile" https://claude.ai https://chatgpt.com https://chat.z.ai
- ```
-
- Пароли вводит человек (Tier-2). После этого рельса безлюдная, и сессия живёт, потому что профиль больше не копируется.
-
- ## ⭐ ЗАМЕР 10.09.2026 ([машина флота], DR26-09-10-ZB-01-1030) — профиль решает больше, чем вендор
-
- 1. **AutoFF на этом узле разлогинен молча, и это видно только по симптому вендора.** claudeai → involuntary logout; mistral → страница `Sign in` + эхо промпта; gemini → тело с «Upgrade», то есть БЕСПЛАТНЫЙ аккаунт. Живые сессии ВСЕХ шести вендоров лежат в СИСТЕМНОМ профиле Firefox **`Ct3iOc7B.Profile 1`** (claude.ai 7 кук, chatgpt 8, google 36, z.ai 18, mistral.ai 5) — берётся через `--profile-dir "Ct3iOc7B.Profile 1"`. ⛔ Вывод «у вендора двери нет» законен только после обхода профилей: имена per-node, хардкодить нельзя, перечисляются по `%APPDATA%\Mozilla\Firefox\Profiles`.
- 2. **⛔ `--no-copy` на человеческом профиле рельса запрещает сама** («травит user.js через geckodriver») и молча уходит на копию — значит для Google по-прежнему действует грабля 02.09: копия крутит куки. Отсюда gemini на этом узле не даёт DR ни с `--deep` (кнопка «Start research» не поднялась за 7.5 мин), ни без него (эхо промпта + free-аккаунт).
- 3. **GLM: третья эпоха UI — голая кнопка формы с `data-active`, без ARIA и без текста.** Судья `glm_search_is_on` знал только органы с `role=switch`/`aria-pressed` и печатал «орган управления не найден» на ЖИВОМ включаемом органе — рельса выпадала из кворума на исправном аккаунте. Починено 10.09: судья понимает `data-active` (fail-closed при двух таких кнопках), добавлен `glm_enable_search()` — жмёт глобус НАТИВНЫМ кликом, затем ПЕРЕЧИТЫВАЕТ и дожимает тумблер `Advanced Search`, если клик открыл меню (эпохи чередуются в одной сессии). Сетка `_test_dr_ff_rail_glm_gate.py` 12/12, красный прогон показан. Итог живьём: `Advanced Search ON` + `Deep Think Max`, промпт ушёл.
- 4. **⛔ Но z.ai поставил КАПЧУ** («Please drag the slider to complete the [человек]», CertifyId в хвосте страницы). Капчу не обходим — рельса идёт в `missing` как требующая рук, а не как «сломанная».
- 5. **`grok -p` на этом узле отдаёт огрызок 696 б / 0 URL.** Проверено: многострочный argv и кавычки доезжают целиком (тесты-эхо), то есть прежний диагноз «обрезка ввода» НЕВЕРЕН — обрывается ВЫХОД: в stdout приезжает только первая строка ответа («I'll count the received prompt exactly…»). Два прогона подряд — третий тем же способом не гнать.
- 6. **Рельса `claude` (CLI) отдаёт ХВОСТ, а не отчёт.** `exit=0 bytes=4302 urls=3 -> OK`, а в файле — «Addendum к Q3 и Q4»: агент писал многими ходами, `-p` вернул последнее сообщение. `dr_leg_gate` честно покраснел (558 симв. тела). Плюс лега унаследовала НАШУ персону — первой строкой метка времени из CLAUDE.md. В кворум сбора входит, в кворум подтверждения — нет.
- 7. **`dr_queue.py robot-work` на этом узле НЕ отдаёт поле `doors`** — машинной карты дверей тут нет, двери проверяются фактом.
-
- ## Жёсткие рамки (читать первыми)
- 1. **⭐ Мандат Антона (2026-07-14, supersedes квота-гейт 05.07): любое количество DR, БЕЗ спроса.** «Делай любое количество депрезёрчей, не спрашивай меня, не беспокойся по поводу лимитов» — ChatGPT при выжатой квоте деградирует мягко (лайтовее отчёт, не отказ), гетеро-веер на 3 вендора компенсирует. Запускаю сам, докладываю постфактум. Единственное «но»: не жечь квоту на ДУБЛИ — дедуп-проверка Шага 0 обязательна.
- 2. **Браузер строго локально** на машине, где идёт сессия. Ничего не просить у других машин.
- 3. **Аккаунты Антона:** если сайт разлогинен → логин по [[social-auth-autonomous]] (креды в store); CAPTCHA/2FA-стена → позвать Антона одной фразой + скриншот.
- 4. **Ничего не отправляем КРОМЕ промпта** в композер DR. Не трогать другие чаты/настройки.
- 5а. ⛔ **`get_page_text` ВРЁТ НА СПИСКАХ (замер 2026-07-29/31).** Границу знать точно:
- для СТАТЬИ/сплошного текста он годится (на нём и держится вынос отчётов ниже), но для
- **динамического списка** — recents, сайдбар чатов, лента, инбокс — он отдаёт заглушку
- («Choose from your existing conversations…»), тогда как `read_page (filter: all)` на той же
- странице показывает все элементы. Замер: X-инбокс — `get_page_text` «пусто», `read_page`
- 15 тредов; форма Anthropic — «пусто», а там кнопка Apply. ⇒ **вывод «список пуст» имеет
- право на жизнь ТОЛЬКО из `read_page`**. Пустота из одного метода — не пустота
- ([[check-all-places-not-one]]); это ложная тишина, а она дороже громкой ошибки.
- 5. **ANTI-RECENTS при забО́ре отчёта:** ища готовый DR-чат/отчёт в веб-UI (ChatGPT/Gemini/Grok), НЕ заключай «отчёта нет» из беглого списка recents — используй встроенный ПОИСК по ключам/ID + Projects/архив + подтверди активный аккаунт по email. Сперва реестр (`_DR-Registry.md`, Шаг 0), потом UI-поиск, и только потом вывод «нет». Канон: память [[web-ui-search-not-recents]] (инцидент Woom 2026-07-23).
- 6. **⭐ МОДЕЛИ ПО РОЛЯМ КОНВЕЙЕРА (anton 14.08.2026, «всё правильно — обнови скилл»).** Три роли, три планки:
- - **Курьер-сессия fanout (этот скилл: вставить промпт в композеры, забрать ссылки, леджер) = Sonnet, эффорт low.** Работа механическая; Fable/Opus на разносе = жжение бака без прироста качества. Поднимая ДР-сессию слотом — модель на задаче через MCP не задаётся и в карточке не видна: проверь фактическую модель ПЕРВОЙ строкой транскрипта прогона (`"model":` в jsonl); поехал Fable → один прогон дотерпеть (выхода у курьера мало), на повторе перевесить на Sonnet-слот.
- - **Чужие вендоры внутри их DR = всегда их САМАЯ умная модель + максимальное рассуждение** (§6.3, список сверять у вендора, не по памяти) — это уже зашито в рецептах ниже.
- - **Синтез-консенсус (Шаг 4) = Fable (fallback Opus), эффорт высокий** — это мышление и Decision Memo, курьеру его не отдавать: курьер довозит отчёты до `_originals` и реестра, синтез — отдельный заход умной моделью.
-
- ## Шаг 0 — вход
- ⭐ **ДЕДУП ПЕРЕД КВОТОЙ (anton 2026-07-14):** прежде чем жечь DR-квоты — проверь, не готов ли отчёт уже. (1) Есть ID в промпте → его строка в реестре: `grep "<DR-ID>" "$OBSIDIAN_VAULT/_DR-Registry.md"` — статус `collected`/`synthesized` = СТОП, fan-out не нужен: доложи «уже собран», покажи файлы (`_originals\deep-research\*<DR-ID>*`, `03-Insights\insight-DR-<id>*`), иди в Шаг 4 (синтез). (2) ID нет → grep реестра по ключевым словам темы: та же тема в `issued` → переиспользуй ТОТ ID; в `collected+` → покажи готовое, спроси, нужен ли вообще новый прогон. Ночной `dr_collect.py` (хаб 05:05) флипает статусы по экспортам сам — реестр свежее памяти сессии.
- ⭐ Номер DR обязателен (anton 2026-07-03): если у промпта ещё нет ID `DRYY-MM-DD-МАШИНА-NN` — выделить: `python $IMPORTS_ROOT/dr_registry.py new "<тема>" --tool chatgpt,gemini,grok` и поставить ID первой строкой промпта (`# DR26-07-03-ZB-01 — <тема>`). Код машины скрипт определяет сам (своя очередь у каждого компа — дублей при синке нет). Канон: `reglament-numeratsiya-dr-i-reestr`.
- Промпт берём: из текущего чата (только что сэмитили по Альфе) / из файла, что укажет Антон. «+» НЕ спрашиваем (мандат 14.07) — объявляю строкой `🚀 DR-fanout: разношу <ID> в ChatGPT+Gemini+Grok` и еду.
-
- ## Шаг 0.5 — тюнинг промпта под вендоров (обязательно)
- Перед раздачей приклеить к телу промпта: `§1 УНИВЕРСАЛЬНЫЙ ADD-ON` из [[dr-platform-playbook]] (`08-Templates\dr-platform-playbook.md`) — всегда, всем; **плюс платформенный блок §2 (Grok) / §3 (Gemini) / §4 (ChatGPT)** под каждого конкретного вендора. Тело (из `deep-research-prompt-template.md`) + §1 одинаковы у всех; платформенный блок различается НАМЕРЕННО (играет на сильную сторону: Grok=реалтайм/X+жёсткие цитаты, Gemini=правка плана/официоз/глубина). ID `DRYY-MM-DD-МАШИНА-NN` первой строкой у всех.
-
- ## Шаги 1-3 — АВТОМАТ submit → probe → collect (per vendor)
- > Ядро надёжности v2, ✅ подтверждено внешним DR (см. п.7). Каждый вендор проходит автомат независимо; сломался на шаге — падает В ФОЛБЭК того шага, не роняя остальных. Золотое правило: **probe перед burn** — ни одна DR-квота не тратится, пока не доказано: (а) режим включён, (б) промпт целиком, (в) ран стартовал.
- >
- ⭐ **ВОРОТА ПЕРЕД `collected` (правило 04.08, дверь построена 14.08).** Прежде чем назвать легу собранной,
- записать её в `_originals` и флипнуть реестр — прогнать пороги:
- ```
- python3 ~/.claude/scripts/dr_leg_gate.py --prompt <файл-заказа> <файл-леги>
- ```
- ⭐ **`--prompt` ОБЯЗАТЕЛЕН** (15.09.2026). Без него спит порог № 0 «ЭХО», и снимок
- НЕЗАЛОГИНЕННОЙ страницы уезжает как готовое исследование: объём закрывает эхо нашего же
- заказа, а источники — ссылки и годы ИЗ НЕГО ЖЕ. Живые случаи в этом же файле:
- mistral 14.09 («5872 б, Sign in + эхо» → заказ закрыт ФАЛЬШИВОЙ 4-й рельсой) и glm («сайдбар +
- эхо промпта», строка «гейт пропускает такое exit 0» ниже по тексту). Гейт без заказа
- предупреждает об этом вслух первой строкой — увидел предупреждение, значит судишь вслепую.
- ```
- ```
- exit 0 = годна · exit 1 = `collected-EMPTY`, в синтез НЕ идёт. Три порога: объём ≥5000 · источники (ссылки/годы) ·
- движок не сказал сам, что поиск не работал. **`exit 0` вендора ничего не доказывает:** `grok --tools ""` отключает
- поиск и отдаёт 243 байта преамбулы нулевым кодом — так лега DR26-07-26 пролежала «собранной» 5 дней.
- Не прошло → гнать по ДРУГОЙ оси (авторизация · движок · аккаунт · браузер), а не тем же параметром;
- рельса выглядит мёртвой → сперва `deploy_check.py` (см. `/secondop`). Легу без источников НЕ сохраняем даже
- «чтобы было»: по ней примут решение. Канон: `reglament-vneshnyaya-lega-schitaetsya-sobrannoy-tolko-posle-porogov`.
-
- > **Состояния** (ledger = `_drafts/DR-FANOUT-<DR-ID>-*.md`, ключ = DR-ID → resume идемпотентен): `staged → mode_verified → submitted → started → waiting → ready → collected → delivered`. Аварийные: `needs_reauth` · `drift_suspected` · `probe_failed` · `aborted`. ⭐ **Человеко-гейта ровно два — `needs_reauth` и `drift_suspected`; всё остальное безлюдно** (консенсус DR).
- > **Локаторы:** ARIA/role первыми → CSS → и только затем LLM/vision. ⛔ Семантический/LLM-поиск элемента — ТОЛЬКО в dry-run/repair-режиме, НИКОГДА на квота-сабмите (консенсус DR).
-
- Инструменты одним ToolSearch: `tabs_context, navigate, computer, read_page, tabs_create, form_input, get_page_text, read_console_messages`.
-
- ### СОСТОЯНИЕ 1 — SUBMIT (включить DR-режим + вставить промпт)
- Новая вкладка → дождаться загрузки → залогинен? (нет → [[social-auth-autonomous]]; стена 2FA/CAPTCHA → скриншот + пропустить вендора). Затем **найти DR-режим ГЛЯДЯ на страницу** (не по памяти — UI плывёт у всех троих):
- - **ChatGPT** (аккаунт youraccount.**a2**@gmail.com): сперва селектор модели → **Pro, максимальная** (сейчас GPT-5.6) + максимальный уровень думания; затем композер → меню инструментов («+»/«Tools») → «Deep research». ⭐ anton 21.07: всегда самая умная модель, имя меняется — принцип нет.
- - **Gemini** (аккаунт youraccount.**a**@gmail.com, личный): ⚠️ 31.07 в Chrome этот аккаунт (индекс u/2) отдал МАРКЕТИНГОВЫЙ ЛЕНДИНГ, а не приложение; рабочее приложение было под `[рабочий аккаунт]@` — перед прогоном проверять глазами, какой аккаунт реально открывает app. Прежняя пометка: **платный Google AI Pro, 5 ТБ, с 06.01.2026** (проверено 28.07) — DR ≈20/день, лимиты ~4×, контекст 1M → тяжёлые ДР сюда гоним УВЕРЕННО, это НЕ урезанный бесплатный тир (память [[gemini-two-rails-free-api-vs-paid-ai-pro]]; «free» = только API-ключ ломателя /tt, другая рельса). Модель = **Pro** (сейчас 3.1), ⛔ НЕ Flash (тихо откатывается — проверять!); включить **Extended thinking** (галочка справа возле микрофона); «+» → «Deep Research» → промпт → Enter → план → **дожать OK/Start**.
- - **Grok** (аккаунт **avvalon**@icloud.com — с двумя «v», проверено 31.07 — там же Twitter Антона): ⭐ anton 21.07 — режим **Heavy** ДЕФОЛТ (куплена максимальная подписка; supersedes прежнее «Expert, Heavy не трогать»). Отдельной DR-кнопки нет → в тело промпта добавить строку «Search the web extensively and cite sources»; следить, чтобы селектор не свалился в Expert/Fast (тихий деграде ZB-03 20.07). Методика «DR-grade в Grok Heavy» (собрано 21.07, DR26-07-21-HUB-02): **Heavy сам и есть Deep Research** — рой 8–16 суб-агентов, ищут параллельно и спорят; Expert теперь одноагентный и для citation-heavy слабее; DeepSearch/DeeperSearch убраны и растворены в Heavy. Без принуждения Heavy отвечает из памяти → в промпт обязательно: «search the web and X extensively» + 15–25 первичных источников + короткая цитата и точный URL на каждое утверждение + «cite ONLY URLs you actually opened» + финальный проход верификации. Доказательство настоящего прогона: «Thought for» в минутах + счётчик «N sources»; мгновенный ответ без источников = деграде, перезапуск. Квоты = недельный общий пул (Settings → Usage, в процентах), контекст 256k–500k, прогон 5–20+ мин. Экспорта одной кнопкой нет (выделить-скопировать); Share = ПУБЛИЧНАЯ ссылка ⛔. Полный шаблон промпта — в `_originals\deep-research\DR26-07-21-HUB-02-grok-heavy-playbook-grok.md`, раздел «(b) Reusable Prompt TEMPLATE»; синтез — `insight-DR-DR26-07-21-HUB-02-grok-heavy-as-a-deep-research-engine`.
- - **claude.ai** (аккаунт youraccount.**a2**@gmail.com, Claude Max, org `a673590f`) — в дефолте с 04.08.2026 («теперь ВСЕГДА добавляй КЛОД.аи в ДРы»). ⚠️ ПЕРВЫМ ДЕЛОМ проверить, ПОД КЕМ открыт claude.ai: `GET /api/organizations` → должен быть `a673590f`; под `[рабочий аккаунт]` это ДРУГОЙ аккаунт (та же ловушка, что топит ночной `claudeai-sync`, [[claudeai-sync-needs-a2-account]]). ⛔⛔ **Вход НЕ через logout в живом Chrome Антона** (приказ Антона 30.08, свип #595c4751, канон `reglament-hab-brauzernye-lichnosti-bb-i-roboty`): его Chrome = `[рабочий аккаунт]` ВСЕГДА, робот там не выходит из аккаунта и не переключает его — это и был корень «Chrome постоянно вылогинивает». a2 живёт ТОЛЬКО в выделенном профиле `_chrome_profile_a2`; сессия мертва → перелогин ТОЛЬКО его: `python $IMPORTS_ROOT/claude-ai/railc_login_a2.py` ([человек]-link просится сам, ссылку несёт Gmail-коннектор a2; ⛔ «Continue with Google» = попап, расширению НЕ виден — не тратить на него заход). Пулл оттуда же: `pull_rail_c.py --run --profile=a2`. DR-режим = **Research** в меню инструментов композера (рядом со скрепкой); модель — самая умная из доступных. Приватный URL чата = `claude.ai/chat/…`.
- - ⛔ **МОДАЛКА «Suggested connectors» ТИХО ДЕРЖИТ РАН (замер 05.08.2026, HUB).** После Send чат создаётся, URL меняется на `/chat/…`, снаружи выглядит как стартовавший Research — **а поиск не начинается вообще**, пока в диалоге «Suggested connectors … Skip / Confirm» не нажат **Skip**. Простояло ~10 минут; сразу после клика пошло «Searching for sources…». ⇒ У claude.ai probe-after-start обязан включать проверку модалки, иначе получишь `not-collected` при полностью живой сессии. Skip выбираем осознанно: сторонние коннекторы внешнему ДР не нужны и тянут приватность.
- - ⏱ **Research тут ДОЛГИЙ:** в этом же прогоне рельса шла 1 час и не завершилась, пока остальные четыре уже сдали отчёты. Не бракуй по времени — кворум закрывается без неё, а отчёт подберёт ночной `dr_collect.py`.
- - **GLM** (chat.z.ai, Z.ai/Zhipu) — в дефолте с 04.08.2026 («glm ТОЖЕ ИСПОЛЬЗУЕМ ДЛЯ ДР»). 🔑 **ВХОД = Google SSO под `[рабочий аккаунт]@gmail.com` («ббПлатинум») — прямое указание Антона**, пароль в [[credential-store]] (`secrets\google_bb.env`), подаёт его САМ Chrome. ⛔ API-ключ z.ai не подставлять: рельса ПОДПИСОЧНАЯ, ключ = поштучная оплата мимо правила «выгребай лимиты» (CLAUDE.md §6.3). Приватный URL чата = `chat.z.ai/c/…` (образец от Антона: `chat.z.ai/c/41c2bab7-533e-4557-9631-ef404fbe7d2c`).
- - ✅ **ЗАМЕР ДВЕРИ 04.08.2026, HP17** (не claim — читано со страницы): сессия ЖИВА в **Chrome «Browser 2»**, а в «Browser 1» стоит `Sign in` ⇒ проверять ОБА подключённых Chrome, один профиль ничего не доказывает ([[check-all-places-not-one]]). Аккаунт подтверждён запросом `/api/v1/auths/` → `[рабочий аккаунт]@gmail.com`, имя «PaloAlto Ai Research Lab» — этим и проверять, а не глазами по аватарке.
- - ✅ **ЛОКАТОРЫ КОМПОЗЕРА (замерены там же):** редактор = обычный **`<textarea>`** внутри `form` (⛔ НЕ ProseMirror, `isPM:false`) ⇒ в каскаде `paste_verify.js` садится нативный React-сеттер, синтетический paste не нужен. Три кнопки в композере: `+` (файлы) · 🌐 **глобус = веб-поиск** · «атом» с `aria-label="Deep think enabled"` (по умолчанию ВКЛЮЧЁН, синий) — **рядом с надписью `Deep Think` стоит выпадающий селектор УРОВНЯ (`Max` и более слабые), и «включён» ≠ «Max»** · `aria-label="Send Message"`. Селектор модели — слева сверху; список 04.08: **GLM-5.2 (NEW, флагман)** · GLM-5.1 · GLM-5-Turbo · GLM-5V-Turbo · GLM-4.7. По правилу «всегда самая умная» **переключено на GLM-5.2** (было 5.1).
- - ⭐ **ДР-РЕЖИМ ЕСТЬ, ОН СПРЯТАН ПОД ГЛОБУСОМ** (найдено в первом живом прогоне 04.08, DR26-08-04-ZB-11-2142 — утренняя запись «отдельной кнопки Deep Research нет» была верна про видимую панель и неверна про рельсу). Клик по 🌐 открывает меню с двумя режимами: `Search` («Single-round search, quickly get information») и **`Advanced Search`** («Multi-round search, in-depth research and analysis») — тумблер, **по умолчанию ВЫКЛЮЧЕН**. ⛔ Без него рельса отдаёт однораундовый ответ: файл в `results/` появится, а разведки в нём не будет — тот же класс тихого брака, что Grok в Expert вместо Heavy. Порядок сабмита: селектор модели → **GLM-5.2** (дефолт 5.1, переключать руками) → 🌐 → `Advanced Search` ON → **Deep Think = `Max`** (см. пункт ниже — отдельный обязательный шаг) → JS-вставка в `<textarea>` → Send.
- - 🔧 **ПРИБОР:** `~/.claude/skills/dr-fanout/glm_probe.js` (read-only чтение композера, ничего не кликает) + судья `~/.claude/scripts/glm_probe.py` (0 LLM, exit-код, счётчик `_glm_probe_usage.jsonl`). Тесты: `_test_glm_probe.py` (14 проверок) · `_test_glm_probe.js` (node, DOM-заглушка со скриншотов + 5 мутантов). ⚠️ Заглушка ≠ живой chat.z.ai: селекторы списаны с замера 04.08 и скриншотов 31.08 — первый живой прогон обязан сверить `evidence`-строки; не совпало = UI поплыл, чинить ассет, а не обходить гейт.
- - ⭐⭐ **DEEP THINK = ВСЕГДА `Max` (приказ Антона 31.08.2026, со скриншотом композера; память `glm-deep-think-must-be-max`).** Отдельный шаг, а не деталь модели: у «Deep Think» есть выпадашка уровня, и заказ уходит на том уровне, что стоит в поле — тихий брак того же класса, что `Advanced Search` OFF и Grok в Expert вместо Heavy. Порядок: **сначала выставить `Max`, потом вставлять промпт и жать Send** (после вставки композер растёт и элементы уезжают). ✅ Проверка перед Send = ПРОЧИТАТЬ со страницы, что в композере написано `Deep Think Max`; не прочитал — считай, что не выставил ([[prichina-kak-claim]]). Не читается / выпадашка не поддалась → рельса идёт в `missing`, а не «сойдёт и так».
- - ⭐ **ЗАМЕР 08.09.2026, [машина флота] (AUTO-[машина флота]-dr-quorum-topup) — что изменилось у вендора:**
- - **Модель теперь `GLM-5.3`**, не 5.2. Правило читать как «бери ВЕРХНЮЮ в списке», а не «выставь константу»: `glm_probe.py` до 08.09 требовал ровно `glm-5.2` и печатал ворчание на более новой 5.3 — прибор ругался на ПРАВИЛЬНОЕ состояние. Починено: `MIN_MODEL` + сравнение версий, ниже минимума = заметка, выше = молчит (посылка `glm-probe-min-model-[id]`).
- - **Глобус живёт в ДВУХ эпохах UI, и они чередуются в пределах одной сессии.** На `/` после навигации клик по глобусу открыл МЕНЮ с тумблером `Advanced Search` (старая эпоха), а до навигации тот же клик прямо переключил `data-active` (новая). Не помни, какая эпоха — ЧИТАЙ `form button[data-active]` после каждого клика и жми тумблер в меню, если появилось меню.
- - ⏱ **Рельса МЕДЛЕННАЯ, а не мёртвая:** ~9–10 мин от Send до конца ответа, из них первые ~6 — фаза `Thinking...` с ПУСТЫМ `.chat-assistant`. Приговор «застряла» до 12-й минуты не выносить (тот же вывод был 11.08).
- - 📥 **ЗАБОР ОТЧЁТА С z.ai — работает Blob-download, остальное закрыто.** Проверено в этом прогоне: `navigator.clipboard.writeText` → **CDP-таймаут 45 с**; `document.execCommand('copy')` → **`false`** (нужен жест); `fetch` на `127.0.0.1` → **`Failed to fetch`** (CSP `connect-src`). А `Blob` + `a.download` + `a.click()` **долетел** (33 457 б в `~/Downloads/`) — то есть общее правило «Blob может тихо не долететь» на z.ai в эту сторону не сработало. Порядок: Blob → **обязательный `ls ~/Downloads`** → не долетело, тогда `get_page_text`. Селектор тела ответа = `.chat-assistant.markdown-prose` (второй по величине — `.markdown-prose` пользователя, не спутать).
- - ⛔ **«ОТВЕТ ПУСТ» ПО СЕЛЕКТОРУ — НЕ ДОКАЗАТЕЛЬСТВО, ЧТО РЕЛЬСА ВСТАЛА.** В том же прогоне на ВТОРОМ сообщении чата `.chat-assistant.markdown-prose` отдавал 11 симв. (`Thinking...`) на 22-й минуте, когда на ЭКРАНЕ ответ был уже расписан до раздела 3 с таблицами; на первом сообщении того же чата селектор давал верные 20 078 б. Перед приговором «застряла» — **скриншот**, а не только DOM ([[instrument-is-a-claim-too]]).
- - ✅ **ПРОГОН ПОДТВЕРЖДЁН 04.08 21:47** (HP17, Chrome «Browser 1» — утром живой была «Browser 2», ⇒ проверять ОБЕ, а не помнить): промпт 3400 симв. сел нативным React-сеттером, чат `chat.z.ai/c/86f270ee-…`, доказательство старта = текст в потоке «Начинаю многошаговое исследование… серию параллельных поисков». Кнопка Send уезжает вниз вместе с растущим композером — брать её координату ПОСЛЕ вставки, иначе клик попадёт в пустоту (первый клик так и пропал).
- - **Mistral Le Chat** (chat.mistral.ai) — шестая рельса с 05.08.2026 («добавь мистраль шестой рельсой»). Взят вместо третьей китайской осознанно: GLM/Qwen/DeepSeek делят корпус и источники, Le Chat тянет европейские — веер растёт независимостью мнений, а не количеством. ДР-режим в Le Chat = **Deep Research** в панели инструментов композера (рядом с веб-поиском); модель — самая умная из доступных.
- - ✅ **ДВЕРЬ ОТКРЫТА С 26.08.2026** (замер, не claim): первый боевой прогон 6-й рельсы — `DR26-08-25-HUB-03-2301/results/mistral.md`, **40 168 б, 26.08 07:11**, хаб. Аккаунт Антон завёл, вход дальше ведётся самостоятельно.
- - ⚠️ **НО КАЧЕСТВО ЛЕГИ НЕ ДОКАЗАНО**: в том же заказе mistral вернул **0 проверяемых ссылок** — тело есть, разведки в нём нет. Перед синтезом гонять `dr_leg_gate.py --strict`: такая лега в кворум СБОРА входит, в кворум ПОДТВЕРЖДЕНИЯ — нет ([[quorum-is-a-counter-not-proof]]).
- - 🔑 Вход = Google SSO под `you.assistants@example.com` (та же почта, что у ChatGPT и claude.ai), пароль подаёт САМ Chrome. Локаторы Deep Research в композере до сих пор **по документации, не по замеру** — дописать с первого живого прогона с этого узла.
- - 📜 ИСТОРИЯ (не стирать): с 05.08 по 26.08 здесь стояло «аккаунта нет» — верный на день замера и протухший через 3 недели; 21 день строка врала всем узлам. Запрет тоже claim и протухает ([[ban-is-a-claim-recheck-before-workaround]]).
- - Вставка промпта — ТОЛЬКО через JS, НИКОГДА `computer type` (каждый Enter = отправка, улетит обрезок, квота сгорит). ⭐ **Каскад `paste_verify.js`** (рядом со скиллом, от [машина флота] 07-16, лечит брак 07-10 «execCommand не сел»; форевер-фикс Grok-ProseMirror 07-17 FLEE-03): прочитать файл `~/.claude/skills/dr-fanout/paste_verify.js`, выполнить его тело через `javascript_tool`, затем `window.__drPasteVerify(PROMPT, "chatgpt"|"gemini"|"grok")`. Он сам перебирает методы (⭐ **синтетический paste-event для ProseMirror/TipTap** → execCommand → нативный React-сеттер textarea → node-параграфы Quill/CE → directSet), сверяет length+head+tail после КАЖДОГО (для ProseMirror читает `el.innerText`, а НЕ textarea-зеркало) и возвращает `{ok, method, gotLen, wantLen, isPM, ...}`.
- - ⚠️ **Grok 4.5 = TipTap/ProseMirror contenteditable** (`div.tiptap.ProseMirror`), а видимый `<textarea>` — это СКРЫТОЕ ЗЕРКАЛО: заполнение textarea (nativeSetter) даёт `ok:true`, но форма/React из зеркала НЕ обновляются → Submit-кнопка не рендерится, Enter=no-op, ран не стартует. **Настоящий редактор надо заполнять синтетическим paste-event** (`ClipboardEvent('paste',{clipboardData:DataTransfer})`) → ProseMirror штатно адоптит текст → `button[type="submit"]` появляется enabled → клик. Каскад теперь целит ProseMirror ПЕРВЫМ и делает это сам; textarea оставлен последним фолбэком.
- - Ручной фолбэк (если ассет недоступен): для Grok/ChatGPT — `const ed=document.querySelector('.tiptap.ProseMirror')||document.querySelector('.ProseMirror'); ed.focus(); window.getSelection().selectAllChildren(ed); const dt=new DataTransfer(); dt.setData('text/plain',PROMPT); ed.dispatchEvent(new ClipboardEvent('paste',{clipboardData:dt,bubbles:true,cancelable:true}))`; Gemini (Quill+TrustedHTML CSP) — `<p>`-параграфы через `createElement`/`textContent` + `dispatchEvent(new InputEvent('input'))`.
- - Путь исполнения по вендору — гибрид (см. п.6 «что решено»): **Grok = живой Chrome-MCP**; **Gemini/ChatGPT = живой Chrome-MCP сейчас, выделенный Firefox-профиль для безлюдного расписания** (фундамент HUB-01).
- - ⭐ **GLM ТЕПЕРЬ ЕЗДИТ И БЕЗЛЮДНО — `python3 ~/.claude/scripts/dr_ff_rail.py --rail glm` (профиль autoff, замер и починка 08.09.2026, [машина флота]).** До этого дверь была только через живой Chrome-MCP, то есть ночная рутина glm собрать НЕ МОГЛА: гейт отбивал каждый прогон словами «орган управления Advanced Search не найден». Причина оказалась НЕ в логине и НЕ в headless — обе версии были догадкой, обе опровергнуты замером:
- - логин в Firefox ЖИВ (autoff держит 17 кук z.ai; `Sign in`/`Log in`/`Войти` = False; имя `PaloAlto` на странице; сайдбар с историей наших DR-чатов) — прежняя строка «z.ai залогинен только в Chrome» неверна;
- - headless и headed ведут себя ОДИНАКОВО (2615 симв. страницы, 4 кнопки, поповеров 0) — значит режим ни при чём.
- - **В этой поверхности старой эпохи (меню под глобусом) НЕТ ВООБЩЕ**: ни одного `role=switch`/`checkbox`/`aria-pressed`, и клик по кнопкам меню не открывает. Веб-поиск = **единственная кнопка ФОРМЫ с `data-active`** (соседки различимы по id: `upload-file-button`, `send-message-button`), переключается **нативным** кликом Selenium `false → true`; синтетические pointer/mouse-события через `dispatchEvent` состояние НЕ меняют.
- - Починено в `dr_ff_rail.py`: новая `glm_enable_search()` жмёт глобус ДО суда и **перечитывает состояние со страницы** («нажал» ≠ «включилось»), а судья `glm_search_is_on` понимает собственный `data-active` кнопки. Гейт остался fail-closed, у предков состояние по-прежнему не берём. Глобусов стало два → снова fail-closed (значит вёрстка поплыла, и это честнее угадывания). Сетка `_test_dr_ff_rail_glm_gate.py` 13/13, красный прогон показан.
- - ⏱ Рельса всё равно МЕДЛЕННАЯ (~9–10 мин): судить только по содержимому чата после перезагрузки, не по спиннеру.
-
- ### СОСТОЯНИЕ 2 — PROBE (доказать до траты квоты) ⭐ сердце v2
- НЕ жать Send, пока три проверки не зелёные:
- 1. **Режим включён:** на странице видна активная плашка Deep research / Expert (read_page/screenshot подтверждает, а не память). ⭐ **GLM = ДВА факта разом: `Advanced Search` ON И в композере читается `Deep Think Max`** (anton 31.08 — «не забывай включать Deep Think на Max» + «это тоже должно быть ВКЛЮЧЕНО ADVANCED SEARCH», оба со скриншотами). Глазами не судим — есть ПРИБОР:
- ```bash
- python3 ~/.claude/scripts/glm_probe.py js # → инъекция в javascript_tool, вернёт JSON-вердикт
- python3 ~/.claude/scripts/glm_probe.py verdict '<этот JSON>' # exit 0 = Send можно, 3 = нельзя
- ```
- Судья пересчитывает всё сам и поле `ok` из браузера игнорирует; fail-closed — «не прочитал» = запрет (меню глобуса закрыто → открыть и прогнать probe снова). exit 3 и не чинится → рельса `glm` в `missing`.
- 2. **Промпт целиком:** вердикт = `ok` от `__drPasteVerify` (length + head + tail сверены каскадом). `ok:false` → каскад сам перебирает методы; 2 неудачи подряд → пропустить вендора, квота цела, пинг в леджер. (Ручная проверка без ассета: `editor.innerText.length` ≈ длине И совпали первые/последние ~60 символов.)
- 3. Только теперь Send/Run.
- Затем **доказать старт** (иначе «отправил» ≠ «пошёл»):
- - ChatGPT: план/«starting research»/счётчик источников растёт.
- - **Gemini ДВУХФАЗНЫЙ:** сперва генерит план и ЖДЁТ кнопку «Start research» — ОБЯЗАТЕЛЬНО дожать, иначе ресёрч не начнётся. Подтверждение: «Great, I'm on it… Researching N websites».
- - Grok: «Researching…»/searched web N results.
- - Старт не подтвердился за 2 попытки-с-переосмотром → НЕ перезапускать вслепую (жжёт) → пометить в леджере `probe-failed`, пропустить вендора, доложить.
-
- ### СОСТОЯНИЕ 3 — LEDGER (сразу после старта каждого вендора)
- Записать/дополнить `$OBSIDIAN_ROOT/_drafts/DR-FANOUT-<DR-ID>-<slug>.md`: тема · промпт целиком · время старта · по вендору {started|skipped+причина|probe-failed} · URL вкладки. Это единственная страховка от «забыли забрать» при безлюдном прогоне — коллектор (см. ниже) работает по этому файлу.
+ | **Grok** | live Chrome MCP, human pace | ToS-sensitive → act like a human in a real session (maximum anti-ban, same as fb-post [[chrome-autonomy-self-drive]]); a headless bot here = maximum risk |
+ | **ChatGPT** | a dedicated headless Firefox profile (unattended) OR the live Chrome MCP | milder ToS; report extraction = backend JSON (works in both); for an unattended schedule → Firefox |
+ | **Gemini** | a dedicated headless Firefox profile (unattended) | two-phase (plan → Start research), tolerant of automation; candidate #1 for a fully unattended run |
+ The principle: the harsher a vendor's ToS / ban sensitivity → the closer to "a live human in a session" (Chrome MCP); the more tolerant it is + the more unattended operation matters → the closer to a dedicated Firefox profile (Playwright persistent, the HUB-01 foundation).
+ 7. **✅ The orchestration is CONFIRMED by an external DR** (`DR26-07-14-FLEE-01`, a ChatGPT+Grok synthesis 2026-07-16, digest in `03-Insights/insight-DR-DR26-07-14-FLEE-01-*`). Both vendors independently: the core = a **durable state machine + a job ledger, NOT "a long-lived autonomous browser agent"**; a local ledger FSM is sufficient for a single-owner hub. Both independently advise **NOT to build unattended Grok automation** (the xAI AUP + enforcement is real: >52k bans in 2026, Reuters 07-15) → our matrix in item 6 already honours that (Grok only via live Chrome MCP, never in a daemon). **Start the unattended schedule with 2 vendors: ChatGPT + Gemini.**
+ 8. **Keep the vendor logic THIN and the orchestration SHARED.** UI-specific repos die fast (`chatgpt-automation-mcp` archived 2026-04-27, `browserbase/gemini-browser` archived 2026-05-20). Everything vendor-specific = swappable "adapters" at the bottom; the state machine/ledger above them does not change.
+ 9. **⚠️ OPEN — the official path for Gemini:** the Deep Research Agent / **Interactions API** (`background=True` + polling, collaborative_planning) — production-ready, and it removes the most fragile and slowest browser channel. BUT ⚠️ ADDED COMPLEXITY + unclear billing: is it included in the Ultra subscription or is it separate money (the ChatGPT report says "NOT the same free-with-subscription")? **Check the billing BEFORE building** ([[prefer-included-limits-before-paid-api]]) — if it is paid, don't set it up without the owner's "+".
- ### СОСТОЯНИЕ 3.5 — ДОЛОЖИТЬ АНТОНУ: промпт + ССЫЛКИ (обязательно, anton 17.07)
- Как только вендор перешёл в `started` — **сразу в диалог Антону, не дожидаясь отчёта**: полный текст промпта блоком ```text``` (paste-ready) + строка `🔗 <vendor>: <url>` на КАЖДЫЙ стартовавший чат. Живая сессия → в ответ; безлюдный прогон → в TG-03 через `bus_send.py`.
- - URL брать из того же снимка вкладки, что и probe (`tabs_context_mcp` / `page.url`) — он уже содержит id чата.
- - **Ссылка = приватный URL чата** (`chatgpt.com/c/…` · `gemini.google.com/app/…` · `grok.com/chat/…` · `claude.ai/chat/…` · `chat.z.ai/c/…`). ⛔ Публичный share-линк (`/share/…`, `g.co/gemini/share/…`) — это ПУБЛИКАЦИЯ наружу (индексировалось Google), только по явной просьбе Антона.
- - Не снял URL → сказать честно, с причиной; молча пропустить нельзя.
- - Зачем: Антон смотрит с телефона и забирает результат сам по этой ссылке — она его точка входа. Канон: `reglament-vneshniy-resech-vsegda-[человек]-i-ssylka-v-chat`, память [[dr-prompt-paste-in-chat]].
+ ## Hard boundaries (read these first)
+ 1. **⭐ The owner's mandate (2026-07-14, supersedes the quota gate of 07-05): any number of DRs, WITHOUT asking.** "Run as many deep researches as you like, don't ask me, don't worry about limits" — with an exhausted quota ChatGPT degrades gracefully (a lighter report, not a refusal), and a heterogeneous fan-out across 3 vendors compensates. I launch them myself and report after the fact. The only caveat: don't burn quota on DUPLICATES — the dedup check in Step 0 is mandatory.
+ 2. **The browser stays strictly local** on the machine running the session. Ask nothing of the other machines.
+ 3. **The owner's accounts:** if a site is logged out → log in per [[social-auth-autonomous]] (credentials in the store); a CAPTCHA/2FA wall → call him with one sentence + a screenshot.
+ 4. **We send NOTHING but the prompt** into the DR composer. Don't touch other chats/settings.
+ 5. **ANTI-RECENTS when collecting a report:** while looking for a finished DR chat/report in a web UI (ChatGPT/Gemini/Grok), do NOT conclude "there is no report" from a quick glance at recents — use the built-in SEARCH by keywords/ID + Projects/archive + confirm the active account by email. Registry first (`_DR-Registry.md`, Step 0), then the UI search, and only then the conclusion "not there". Canon: memory [[web-ui-search-not-recents]] (an incident on 2026-07-23).
- ### СОСТОЯНИЕ 4 — COLLECT (через ~20-40 мин, по леджеру)
+ ## Step 0 — the entrance
+ ⭐ **DEDUP BEFORE QUOTA (the owner, 2026-07-14):** before burning DR quota — check whether the report already exists. (1) There is an ID in the prompt → find its line in the registry: `grep "<DR-ID>" "$OBSIDIAN_VAULT/_DR-Registry.md"` — status `collected`/`synthesized` = STOP, no fan-out needed: report "already collected", show the files (`_originals\deep-research\*<DR-ID>*`, `03-Insights\insight-DR-<id>*`), go to Step 4 (synthesis). (2) No ID → grep the registry by the topic's keywords: the same topic sitting in `issued` → reuse THAT ID; in `collected+` → show what exists and ask whether a new run is needed at all. The nightly `dr_collect.py` (hub, 05:05) flips statuses from the exports by itself — the registry is fresher than the session's memory.
+ ⭐ A DR number is mandatory (the owner, 2026-07-03): if the prompt has no `DRYY-MM-DD-MACHINE-NN` ID yet — allocate one: `python $IMPORTS_ROOT/dr_registry.py new "<topic>" --tool chatgpt,gemini,grok` and put the ID as the first line of the prompt (`# DR26-07-03-ZB-01 — <topic>`). The script derives the machine code itself (each computer has its own sequence — no collisions when syncing). Canon: the rulebook entry on DR numbering and the registry.
+ Where the prompt comes from: the current chat (just emitted by the Alpha Protocol) / a file the owner points to. We do NOT ask for a "+" (the 07-14 mandate) — I announce it with one line, `🚀 DR-fanout: distributing <ID> to ChatGPT+Gemini+Grok`, and go.
- > ⭐ **ПЕРЕД ЛЮБЫМ «Chrome-MCP недоступен» — ОДНА КОМАНДА (замер 06.08.2026, хаб, DR26-08-06-HUB-01-1055).**
- > `Claude in Chrome is not connected` и пустой `list_connected_browsers` в 1 случае из 1 означали,
- > что **Chrome просто не запущен**: `Get-Process chrome` → 0. Лечение: `Start-Process
- > "[путь владельца] Files\Google\Chrome\Application\chrome.exe"` → подождать ~12 с → `tabs_context_mcp`.
- > Расширение подключилось, все 4 тела веера снялись подряд за ~5 минут.
- > **Цена не проверки:** параллельная сессия записала в реестр «chatgpt: тело не снято, Chrome-MCP
- > не подключён», подняла лишнее замещающее плечо через Codex CLI и оставила в реестре строку
- > «рельса недоступна», которая переживёт сессию. Ноль процессов ≠ мёртвая рельса
- > ([[dead-verdict-expires]], память `chrome-mcp-dead-check-process-first`).
- > Chrome ЖИВ, а расширение молчит → вот это настоящая поломка, тогда Firefox/эскалация.
+ ## Step 0.5 — tuning the prompt per vendor (mandatory)
+ Before distributing, append to the prompt body: `§1 THE UNIVERSAL ADD-ON` from [[dr-platform-playbook]] (`08-Templates\dr-platform-playbook.md`) — always, for everyone; **plus the platform block §2 (Grok) / §3 (Gemini) / §4 (ChatGPT)** for each specific vendor. The body (from `deep-research-prompt-template.md`) and §1 are identical for all; the platform block differs DELIBERATELY (it plays to each one's strength: Grok = realtime/X + hard citations, Gemini = plan editing/formality/depth). The `DRYY-MM-DD-MACHINE-NN` ID is the first line for all of them.
- > ⛔⛔ **ПЕРВОЕ, ЧТО ЧИТАЕШЬ ПЕРЕД БРАКОВКОЙ (замер 04.08, ZB-04 — я сам на этом попался).**
- > **Строка `Research completed in Nm · 0 citations` НЕ ЯВЛЯЕТСЯ ДОКАЗАТЕЛЬСТВОМ ПУСТОГО РАНА.**
- > 04.08 я забраковал ChatGPT-ран по этой строке, написал файл-вердикт `dead` — а потом
- > достал backend и получил **35 citations · 34 рабочих URL · тело 17 622 симв.** Отчёт был
- > живой и полный. Файл-вердикт пришлось удалять, заметку синтеза — переписывать дважды.
- > **Ни один вендор не бракуется, пока не прочитан МАШИННЫЙ признак** (ChatGPT — `citations`
- > из `widget_state`; Grok — «N sources»; Gemini — список источников). Нет доступа к признаку =
- > статус `not-collected` («не смог прочитать»), **а НЕ `dead`** («вендор не работал»).
- > Это два разных факта, и путать их — врать в данных.
- >
- > ✅ **ДОЛГ ЗАКРЫТ ЗАМЕРОМ 04.08 — и он оказался хуже, чем я предполагал.**
- > Перепроверены ВСЕ забракованные по счётчику прогоны волны ZB, у которых в леджерах остался
- > chat-URL. **4 из 4 — живые отчёты с источниками, выброшенные не глядя:**
- >
- > | DR | прежний вердикт | по backend | тело |
- > |---|---|---|---|
- > | ZB-01 sci-fi (26.07) | `dead` ×2, «таблица целиком ИЗ ПАМЯТИ» | **57 citations** | 15 162 |
- > | ZB-02 Харари (26.07) | `dead` ×2, «отчёт из памяти» | **106 citations** | 25 423 |
- > | ZB-03 пантеон (26.07) | канал `dead`, ушли в обход через Web search | **52 citations** | 22 828 |
- > | ZB-04 HackerNoon (28.07) | `dead`, «в синтез НЕ берём» | **108 citations** | 18 185 |
+ ## Steps 1-3 — the SUBMIT → PROBE → COLLECT state machine (per vendor)
+ > The reliability core, v2, ✅ confirmed by an external DR (see item 7). Each vendor runs the machine independently; a break at one step falls into THAT step's fallback without taking the others down. The golden rule: **probe before burn** — no DR quota is spent until it is proven that (a) the mode is on, (b) the prompt is complete, (c) the run actually started.
>
- > У ZB-01 ChatGPT-вендора в волте не было ВООБЩЕ — веер шёл двумя вендорами вместо трёх.
- > Все четыре подняты и лежат в `_originals` с пометкой `recovered_from`.
- > **Вывод жёстче прежнего:** ноль в счётчике не значил ничего ни разу. Единственный признак —
- > `citations` из backend. Формулировку «рельса ChatGPT DR сломана системно» из старых леджеров
- > не цитировать: она построена на приборе, который сам не проверяли.
- > ⛔ **«НЕ СОБРАН» — ЭТО ТОЖЕ CLAIM, И ЕГО ИСТОЧНИК ЛОКАЛЬНЫЙ (замер 05.09, ZB-14).**
- > Статус в реестре читается из ШАРДА ЭТОГО узла, а `03-Insights` доезжает синком с задержкой.
- > 05.09 я объявил `DR26-08-04-ZB-14-2214` несобранным и отправил задачу хабу — отчёт был собран
- > и синтезирован СУТКАМИ РАНЬШЕ рутиной `AUTO-[машина флота]-dr-runner` на [машина флота] (4 рельсы, вердикт готов).
- > Локальный `running` + пустой grep = «мой узел этого не видит», а НЕ «работа не сделана».
- > **Перед выводом «не собран» и перед отправкой заказа другому узлу — две дешёвые проверки:**
- > (1) `ls $OBSIDIAN_VAULT/03-Insights | grep <DR-ID>` И `grep -rl <DR-ID> 03-Insights` (заметка синтеза может уже лежать);
- > (2) возраст своего шарда — `ls -la $OBSIDIAN_VAULT/[шина]/_dr/DR-registry__from-*.md` (чужие шарды старше суток = вид отстал).
- > Пусто в обеих → вывод правомерен. Иначе это лишняя работа чужому узлу.
-
- DR думает 10-40 мин. По каждой started-вкладке: готов → извлечь (лестница ниже) → сохранить **verbatim** в `$OBSIDIAN_ROOT/_originals/deep-research/<DR-ID>-<slug>-<vendor>.md` (провенанс сверху: source/topic/date/origin) → `dr_registry.py update <DR-ID> --status collected --file "<путь>"`. ⭐ **ГЕЙТ ДОКАЗАТЕЛЬСТВА РАБОТЫ (21.07, DR26-07-21-HUB-02; ⚠️ ПЕРЕСМОТРЕН 04.08 — см. ниже):** перед сохранением прочитать доказательство прогона — Grok: «N sources» + «Thought for…»; Gemini: список источников; **ChatGPT: НЕ строку над виджетом.** Она у DR-виджета врёт: «0 citations · 0 searches» стоит у ВСЕХ connector-прогонов этого аккаунта, в том числе у тех, чьи отчёты мы приняли и использовали (21.07 HUB-02) — в backend'е у них 40–106 живых цитат. Настоящее доказательство ChatGPT-DR = `mapping[*].message.metadata.chatgpt_sdk.widget_state` → `JSON.parse` → `report_message.metadata.citations.length` (и `resolved_model_slug` там же). Пусто/0 цитат в citations → `dead`; ненулевой массив → искал, каким бы ни был счётчик. Для Grok/Gemini прежний порядок в силе: нет источников → `dead`, не `collected`. Не готов → отметить, вернуться позже. Безлюдный режим: ночной `dr_collect.py` (хаб) сам подхватит DR-ID из истории/Downloads и флипнет статус — ручной сбор нужен, только если отчёт нужен СЕЙЧАС.
-
- **Фолбэк-лестница извлечения** — общий порядок (консенсус DR): **официальный export/share → backend JSON → DOM-scrape → эскалация человеку**. DOM — низший приоритет, не первый. Далее по вендорам:
- - **ChatGPT** (отчёт в КРОСС-ДОМЕННОМ sandbox-iframe `connector_openai_deep_research` — JS туда не лезет, синтет-клики игнорит):
- 1. **Backend JSON (основной, без кликов, ✅ 2026-07-14):** page-JS `s=await fetch('/api/auth/session').then(r=>r.json()); conv=await fetch('/backend-api/conversation/<id>',{headers:{Authorization:'Bearer '+s.accessToken}}).then(r=>r.json())` → Blob-download JSON → на диске Python: `mapping[<node>].message.metadata.chatgpt_sdk.widget_state` (JSON-строка → `json.loads`) → `report_message.content.parts[0]`. Узел = walk по «Executive Summary».
- 2. **Без widget_state** (часть DR, ✅ DR26-07-11-HUB-02): отчёт прямо в `mapping[*].message.content.parts[0]` — walk по mapping, самая длинная строка >3000 симв.
- 3. ⚠️ **РЕГРЕССИЯ 04.08: «Export to Markdown» синтет-кликом БОЛЬШЕ НЕ РАБОТАЕТ (ZB-04).** Меню по координатному клику открывается, но клики по ПУНКТАМ меню не доходят: меню остаётся открытым, Escape его не закрывает, `Copy contents` не меняет буфер (проверено сентинелом), `Export to Markdown` не создаёт файл (проверено `ls Downloads` ×3). Меню живёт в кросс-доменном iframe, куда синтет-клики не проходят. **Не тратить на этот путь больше одной попытки — путь 1 (backend JSON) 04.08 отработал с первого раза на том же самом чате.** Ниже — прежнее описание пути на случай, если UI откатят:
- 3-бис. ⭐ **Меню виджета «Export to Markdown» — работало синтет-кликом, безлюдно (✅ 2026-07-17, HUB-06; ❌ 04.08 — см. выше):** новый connector-формат DR не отдаёт widget_state ВООБЩЕ (пути 1-2 мертвы) и невидим для find/accessibility-tree → только КООРДИНАТНЫЙ клик: иконка download в шапке виджета (правый верх, рядом с expand) → меню `Copy contents / Export to Markdown / Export to Word / Export to PDF` → **Export to Markdown** → `deep-research-report.md` в Downloads (проверить `ls`!) → переложить в `_originals` с провенансом. Человека звать НЕ нужно.
- 4. ⚠️ **Rate-limit врёт молча:** при «Too many requests» backend отдаёт mapping БЕЗ widget_state → выглядит как «отчёта нет», хотя отчёт готов и виден на экране. «Пусто из API» ≠ «нет отчёта» → сверься со СКРИНШОТОМ до вывода, подожди пару минут.
- 5. ⚠️ Открывать `iframe.src` отдельной вкладкой БЕСПОЛЕЗНО — песочница пустая, контент прилетает через postMessage.
- - **Gemini:** отчёт в `STRUCTURED-CONTENT-CONTAINER` (канвас, same-origin) → `innerText` узла с заголовком → Blob-download → фолбэк: рендер в `<pre>` + get_page_text.
- - **Grok:** отчёт в основном потоке → `document.querySelector('main').innerText`, отрезать эхо-промпт и хвост-подсказки → Blob-download. ⭐ Якорь обрезки: **«Thought for…» надёжнее первого «Executive Summary»** (проверено на прогоне FLEE-01 — экстракт зацепил эхо промпта).
- - **Общий на всех:** большой текст мимо обрезки дисплея (JS-тул режет ~1500, get_page_text ~50k/проход) → Blob-download → Read из Downloads. ⚠️ **Blob-download может ТИХО не долететь** (2026-07-14: grok — да, chatgpt/gemini — нет; `a.click()` без ошибки, блок невидим) → ВСЕГДА `ls Downloads` после; не долетело → фолбэк `pre.textContent=txt; document.body.replaceChildren(pre)` (TrustedHTML-safe) → get_page_text кусками. Клипборд-пути (navigator.clipboard виснет; execCommand/Ctrl+C нужен жест) — НЕ тратить попытки.
- - ⭐ **Полевое подтверждение 2026-07-21 (добор веера 14.07, 5 отчётов 16–85 KB — Blob НЕ долетел ни разу, Chrome multiple-downloads):** дефолтом сразу бери `get_page_text`, Blob не пробуй. Что нового узнали: (а) вывод >50 KB харнес САМ персистит в `tool-results/toolu_*.json` на диск → читаешь Read'ом, контекст не жжёшь; <50 KB приходит in-band; (б) жёсткий кап 50000 симв/проход обходится сдвигом окна видимого текста (паддинг/подмена узлов) + склейкой двух срезов по overlap последних ~300 симв — так собран отчёт 77k; (в) клипборд не просто «виснет», он отдаёт СТАРОЕ содержимое буфера Антона = ложный успех, всегда сверяй длину и первые слова; (г) **поиск чата в Grok по названию** — не UI (Ctrl+K мёртв, OneTrust-баннер ест клики), а same-origin `fetch('/rest/app-chat/conversations?pageSize=50',{credentials:'include'})` → `{conversations:[{conversationId,title}]}`; (д) **Gemini = SPA**: свежий `navigate` на URL чата грузит отчёт надёжнее синтетического клика по сайдбару (сайдбар лениво рендерит пустой текст); (е) возврат сырых заголовков чатов из JS ловит контент-фильтр (`BLOCKED: Cookie/query string`) → возвращай короткий статус-токен, не данные.
- - ⭐ **Полевое подтверждение 2026-07-21 ВЕЧЕР (сбор HUB-02):** (а) **вброшенная на страницу СВОЯ кнопка не обходит запрет жестов** — синтетический/координатный клик по ней не считается user gesture, blob так и не качается (onclick-счётчик = 0; не изобретать заново); (б) **клики и клавиши расширения могут вообще не доходить до страницы** (окно без фокуса): симптом — Send нажат, а поле ввода не пустеет; лечение — программный `document.querySelector('button[data-testid="send-button"]').click()` из JS, React принимает его как настоящий (проверено: сабмит ушёл, композер опустел); (в) большой текст из DOM — сперва в копилку `window.__x`, offsets искать вторым вызовом, резать уже в Python из персиста `tool-results\`; (г) выделение узла Range+addRange и Ctrl+C поверх — буфер остаётся ПУСТ (не путать со «старым содержимым»: и такое, и такое бывает — потому `Get-Clipboard` сверять всегда).
- - ⭐⭐ **Blob-download у ChatGPT: ОДНА ЗАГРУЗКА = ОДНА СВЕЖАЯ ВКЛАДКА (замер 04.08, аудит 4 отчётов).** Первый `a.click()` в новой вкладке скачивается всегда; **второй и последующие в ТОЙ ЖЕ вкладке молча не долетают** — это Chrome «multiple automatic downloads», блок тихий, ошибки в JS нет, `ls Downloads` пуст. Лечение дешёвое и надёжное: `tabs_create_mcp` → `navigate` на chatgpt.com → одна загрузка → следующая вкладка. Проверено: 4 отчёта, 4 вкладки, 4 файла. ⛔ Не лечить это перезагрузкой той же вкладки (пробовал — блок держится) и не пытаться отдать текст на локальный приёмник (`fetch` на `http://127.0.0.1` с chatgpt.com **режет CSP**, `Failed to fetch` — путь закрыт, не тратить попытки). ⚠️ На тяжёлых чатах сборка строки и Blob в одном вызове упирается в **CDP-таймаут 45 с** → разбить на два вызова: первый кладёт текст в `window.__H`, второй только качает.
- - ⭐ **Полевой замер 04.08 (ZB-04, сбор трёх вендоров с ноута) — рельсы по вендорам разошлись, запомнить раскладку:**
- - **ChatGPT → ТОЛЬКО backend JSON (путь 1).** Отработал с первого раза; всё остальное мертво (см. регрессию выше). ⚠️ Мой промах, чтобы не повторяли: я дёрнул `/backend-api/conversation/<id>` **без заголовка Authorization** → **404**, и прочитал это как «пути нет». 404 тут = «нет токена», а не «нет отчёта». Bearer обязателен: `s=await fetch('/api/auth/session').then(r=>r.json())` → `Authorization:'Bearer '+s.accessToken`.
- - **Gemini → Blob-download РАБОТАЕТ** (`new Blob([document.body.innerText])` + `a.click()`, файл лёг в Downloads с первой попытки, 99 KB). Отменяет прежний совет «Blob не пробуй, сразу get_page_text» — для Gemini он неверен. Тело отчёта попадает в `body.innerText` целиком вместе с хвостом «Sources read but not used» (это ценно — сохранять весь снимок).
- - **Grok → Blob и data-URI НЕ работают** (CSP режет, `a.click()` молча без файла), `navigator.clipboard.writeText` → **CDP-таймаут 45 с**. Работает `get_page_text` — забрал весь отчёт одним проходом.
- - **Чтение больших срезов через JS ловит контент-фильтр:** `body.innerText.slice(a,b)` на странице с URL-ами вернул `[BLOCKED: Cookie/query string data]`. Короткие статус-выражения (`.length`, `.indexOf`) проходят. ⇒ **данные тащить файлом/`get_page_text`, а не возвратом из JS.**
- - **Буфер обмена — общий на машину и врёт (§3.6):** после «копирования» в нём лежал чужой текст из параллельной сессии. Лечение, которое сработало: **писать сентинел ДО** (`SENTINEL-...`) и сверять после — иначе «успешная» копия неотличима от невыполненной.
- - ⚠️ **Вендор может ОТКАЗАТЬСЯ отвечать** (Gemini, тема анти-бан аутрича — счёл обходом защит). Отказ = валидный результат: сохранить verbatim в `_originals` как обычный файл, статус `collected`, а в Decision Memo явно пометить «консенсуса нет, база = N вендоров» и не выдавать single-vendor за веер.
+ > **States** (the ledger = `_drafts/DR-FANOUT-<DR-ID>-*.md`, key = the DR-ID → resume is idempotent): `staged → mode_verified → submitted → started → waiting → ready → collected → delivered`. Emergency states: `needs_reauth` · `drift_suspected` · `probe_failed` · `aborted`. ⭐ **There are exactly two human gates — `needs_reauth` and `drift_suspected`; everything else is unattended** (the DR consensus).
+ > **Locators:** ARIA/role first → CSS → and only then LLM/vision. ⛔ A semantic/LLM element search is for dry-run/repair mode ONLY, NEVER on a quota-spending submit (the DR consensus).
- ## Шаг 4 — синтез-консенсус (Alpha Protocol step 4)
+ Tools in one ToolSearch: `tabs_context, navigate, computer, read_page, tabs_create, form_input, get_page_text, read_console_messages`.
- > ⛔ **ГЕЙТ ПЕРЕД ПЕРВОЙ БУКВОЙ СИНТЕЗА (04.08, ZB-04): «а его уже не синтезировали?»**
- > Порядок: `dr_registry.py list | grep <DR-ID>` **+** `ls 03-Insights | grep <DR-ID>`.
- > - статус `synthesized`/`applied` **или** уже есть `insight-DR-<DR-ID>-*` → **НОВУЮ заметку НЕ создавать.**
- > Дописать в существующую датированный раздел «ПОПРАВКА <дата>: что нового и что это меняет».
- > - **⛔ Статус в реестре не понижать.** 04.08 я сбил `applied` → `collected` командой сбора и стёр
- > факт, что DR давно закрыт. Перед `update --status` посмотреть текущий статус: назад по
- > лестнице (`applied` → `collected`) двигаться только осознанно, с `--note` о причине.
- >
- > Замер цены: у ZB-04 **две** insight-заметки за один час 28.07 от двух сессий, плюс 04.08
- > третий веер по уже закрытому DR. Прямое следствие §8.4 (одобрение старше суток исполняется
- > только после RECALL «не сделано ли уже») и §7.7 (табличка ON AIR не выставлялась ни разу).
+ ### STATE 1 — SUBMIT (turn the DR mode on + paste the prompt)
+ A new tab → wait for the load → logged in? (no → [[social-auth-autonomous]]; a 2FA/CAPTCHA wall → screenshot + skip the vendor). Then **find the DR mode BY LOOKING at the page** (not from memory — the UI drifts on all three):
+ - **ChatGPT** (the work Google account): the model selector first → **Pro, the maximum** (currently GPT-5.6) + the maximum thinking level; then the composer → the tools menu ("+"/"Tools") → "Deep research". ⭐ The owner, 07-21: always the smartest model; the name changes, the principle does not.
+ - **Gemini** (the personal Google account): the model = **Pro** (currently 3.1), ⛔ NOT Flash (it silently rolls back — check!); enable **Extended thinking** (the checkbox on the right, near the microphone); "+" → "Deep Research" → the prompt → Enter → the plan → **press OK/Start**.
+ - **Grok** (the vendor account that also holds the owner's Twitter): ⭐ the owner, 07-21 — **Heavy** mode is the DEFAULT (the top subscription was bought; supersedes the earlier "Expert, don't touch Heavy"). There is no separate DR button → add a line to the prompt body, "Search the web extensively and cite sources"; watch that the selector does not fall back to Expert/Fast (a silent downgrade, 07-20). The "DR-grade in Grok Heavy" method (assembled 07-21, DR26-07-21-HUB-02): **Heavy IS Deep Research** — a swarm of 8–16 sub-agents searching in parallel and arguing; Expert is now single-agent and weaker for citation-heavy work; DeepSearch/DeeperSearch were removed and dissolved into Heavy. Without being forced, Heavy answers from memory → the prompt must include: "search the web and X extensively" + 15–25 primary sources + a short quote and an exact URL per claim + "cite ONLY URLs you actually opened" + a final verification pass. Proof of a real run: "Thought for" measured in minutes + an "N sources" counter; an instant answer with no sources = a downgrade, restart. Quotas = a weekly shared pool (Settings → Usage, as a percentage), context 256k–500k, a run takes 5–20+ min. There is no one-click export (select and copy); Share = a PUBLIC link ⛔. The full prompt template is in `_originals\deep-research\DR26-07-21-HUB-02-grok-heavy-playbook-grok.md`, section "(b) Reusable Prompt TEMPLATE"; the synthesis is `insight-DR-DR26-07-21-HUB-02-grok-heavy-as-a-deep-research-engine`.
+ - Pasting the prompt — ONLY through JS, NEVER `computer type` (every Enter = a send, a truncated fragment flies off and the quota burns). ⭐ **The `paste_verify.js` cascade** (next to the skill, from 07-16, it cures the 07-10 defect "execCommand did not take"; the forever-fix for Grok/ProseMirror is 07-17 FLEE-03): read the file `~/.claude/skills/dr-fanout/paste_verify.js`, execute its body through `javascript_tool`, then call `window.__drPasteVerify(PROMPT, "chatgpt"|"gemini"|"grok")`. It walks the methods itself (⭐ **a synthetic paste event for ProseMirror/TipTap** → execCommand → the native React textarea setter → Quill/CE paragraph nodes → directSet), checks length+head+tail after EACH one (for ProseMirror it reads `el.innerText`, NOT the textarea mirror) and returns `{ok, method, gotLen, wantLen, isPM, ...}`.
+ - ⚠️ **Grok 4.5 = a TipTap/ProseMirror contenteditable** (`div.tiptap.ProseMirror`), and the visible `<textarea>` is a HIDDEN MIRROR: filling the textarea (nativeSetter) returns `ok:true`, but the form/React do NOT update from the mirror → the Submit button never renders, Enter is a no-op, the run does not start. **The real editor must be filled with a synthetic paste event** (`ClipboardEvent('paste',{clipboardData:DataTransfer})`) → ProseMirror adopts the text normally → `button[type="submit"]` appears enabled → click it. The cascade now targets ProseMirror FIRST and does this by itself; the textarea is left as the last fallback.
+ - The manual fallback (if the asset is unavailable): for Grok/ChatGPT — `const ed=document.querySelector('.tiptap.ProseMirror')||document.querySelector('.ProseMirror'); ed.focus(); window.getSelection().selectAllChildren(ed); const dt=new DataTransfer(); dt.setData('text/plain',PROMPT); ed.dispatchEvent(new ClipboardEvent('paste',{clipboardData:dt,bubbles:true,cancelable:true}))`; for Gemini (Quill + TrustedHTML CSP) — `<p>` paragraphs via `createElement`/`textContent` + `dispatchEvent(new InputEvent('input'))`.
+ - The execution path per vendor is hybrid (see item 6 of "what is decided"): **Grok = the live Chrome MCP**; **Gemini/ChatGPT = the live Chrome MCP for now, a dedicated Firefox profile for the unattended schedule** (the HUB-01 foundation).
- Прочитать все собранные отчёты → таблица «сошлись / разошлись / уникальное у каждого» → Decision Memo (проблема · знания · DR · варианты · риски · рекомендация). Гетеро-принцип: расхождения НЕ сглаживать — показать Антону как развилки. Memo → `02-Decisions/` (если решение) или отчёт в чат. Леджер закрыть (`status: collected`).
+ ### STATE 2 — PROBE (prove it before spending quota) ⭐ the heart of v2
+ Do NOT press Send until three checks are green:
+ 1. **The mode is on:** an active Deep research / Expert chip is visible on the page (confirmed by read_page/screenshot, not by memory).
+ 2. **The prompt is complete:** the verdict is `ok` from `__drPasteVerify` (length + head + tail checked by the cascade). `ok:false` → the cascade walks the methods itself; 2 failures in a row → skip the vendor, the quota is intact, note it in the ledger. (A manual check without the asset: `editor.innerText.length` ≈ the expected length AND the first/last ~60 characters match.)
+ 3. Only now Send/Run.
+ Then **prove the start** (otherwise "sent" ≠ "running"):
+ - ChatGPT: a plan / "starting research" / a growing source counter.
+ - **Gemini is TWO-PHASE:** first it generates a plan and WAITS for the "Start research" button — you MUST press it, or the research never begins. Confirmation: "Great, I'm on it… Researching N websites".
+ - Grok: "Researching…" / searched web N results.
+ - The start was not confirmed after 2 attempts with a fresh look → do NOT blindly restart (that burns quota) → mark `probe-failed` in the ledger, skip the vendor, report it.
- ⭐ **ВЕНДОРОВ НЕ УСРЕДНЯЕМ — ценность веера в СТОЛКНОВЕНИИ, а не в кворуме (замер волны DR26-07-26).** Три вендора дали трёх РАЗНЫХ победителей, потому что судили по трём разным критериям (замысел · недостающие механизмы · доказанный выход) — и это честнее любого единого рейтинга. Одинаковый ответ трёх вендоров — сигнал СЛАБЫЙ; поймать ОДНОГО вендора на подлоге — сильный.
+ ### STATE 3 — LEDGER (immediately after each vendor starts)
+ Write/extend `$OBSIDIAN_ROOT/_drafts/DR-FANOUT-<DR-ID>-<slug>.md`: the topic · the full prompt · the start time · per vendor {started|skipped+reason|probe-failed} · the tab URL. This is the only insurance against "we forgot to collect it" on an unattended run — the collector (below) works off this file.
- В синтезе ОБЯЗАТЕЛЬНЫ две секции: **(а) расхождения с указанием КРИТЕРИЯ каждого вендора**; **(б) «прямое опровержение внутри веера»**, если оно было. Усреднить = потерять главное.
+ ### STATE 3.5 — REPORT TO THE OWNER: the prompt + the LINKS (mandatory, the owner 07-17)
+ As soon as a vendor reaches `started` — **straight into the chat with him, without waiting for the report**: the full prompt text as a ```text``` block (paste-ready) + a `🔗 <vendor>: <url>` line for EVERY started chat. A live session → in the reply; an unattended run → into the fleet log chat via `bus_send.py`.
+ - Take the URL from the same tab snapshot as the probe (`tabs_context_mcp` / `page.url`) — it already contains the chat id.
+ - **The link = the PRIVATE chat URL** (`chatgpt.com/c/…` · `gemini.google.com/app/…` · `grok.com/chat/…`). ⛔ A public share link (`/share/…`, `g.co/gemini/share/…`) is PUBLICATION to the outside world (it has been indexed by Google) — only on his explicit request.
+ - Failed to capture the URL → say so honestly, with the reason; silently skipping it is not allowed.
+ - Why: he reads from his phone and collects the result himself through that link — it is his entry point. Canon: the rulebook entry on always putting the prompt and the link in the chat, memory [[dr-prompt-paste-in-chat]].
- Пример 26.07: ChatGPT опроверг цифру Gemini (21x LLM-Wiki против RAG) по первоисточнику — цифра оказалась честной, но приклеенной к чужому объекту.
+ ### STATE 4 — COLLECT (after ~20-40 min, driven by the ledger)
+ A DR thinks for 10-40 minutes. For each started tab: ready → extract (the ladder below) → save it **verbatim** into `$OBSIDIAN_ROOT/_originals/deep-research/<DR-ID>-<slug>-<vendor>.md` (provenance at the top: source/topic/date/origin) → `dr_registry.py update <DR-ID> --status collected --file "<path>"`. ⭐ **THE PROOF-OF-WORK GATE (07-21, DR26-07-21-HUB-02):** before saving, read the run counter — ChatGPT: the line "Research completed in Xm · N citations · M searches" above the widget; Grok: "N sources" + "Thought for…"; Gemini: the source list. **`0 searches` / `0 citations` / no sources → the status is `dead`, NOT `collected`**, restart with an explicit demand to search, and it does not go into the synthesis. This really happened: ChatGPT Pro "researched" for 9 minutes and produced a beautiful report with tables entirely from memory — outwardly indistinguishable from a real one. Not ready → note it and come back later. Unattended mode: the nightly `dr_collect.py` (hub) picks the DR-ID up from history/Downloads and flips the status itself — manual collection is only needed if the report is wanted NOW.
- ⭐ **Шаг 5 — ЗАКРЫТЬ РАЗВЕДКУ (anton 27.07, обязателен).** `synthesized` — не финиш: отчёт написан, а система не изменилась. Каждый ДР доводится до одного из двух терминальных статусов, оба требуют `--note`:
- - `dr_registry.py update <ID> --status applied --note "<что реально поменяли: Decision Memo / правка в проде / новая рутина>"`
- - `dr_registry.py update <ID> --status parked --note "<почему не берём и что изменит решение>"`
+ **The extraction fallback ladder** — the general order (the DR consensus): **the official export/share → backend JSON → DOM scraping → escalate to a human**. The DOM is the lowest priority, not the first. Then per vendor:
+ - **ChatGPT** (the report lives in a CROSS-DOMAIN sandbox iframe `connector_openai_deep_research` — JS cannot reach in, and synthetic clicks are ignored):
+ 1. **Backend JSON (the main path, no clicks, ✅ 2026-07-14):** page JS `s=await fetch('/api/auth/session').then(r=>r.json()); conv=await fetch('/backend-api/conversation/<id>',{headers:{Authorization:'Bearer '+s.accessToken}}).then(r=>r.json())` → a Blob download of the JSON → then in Python on disk: `mapping[<node>].message.metadata.chatgpt_sdk.widget_state` (a JSON string → `json.loads`) → `report_message.content.parts[0]`. Find the node by walking for "Executive Summary".
+ 2. **No widget_state** (some DRs, ✅ DR26-07-11-HUB-02): the report sits directly in `mapping[*].message.content.parts[0]` — walk the mapping and take the longest string over 3000 characters.
+ 3. ⭐ **The widget's "Export to Markdown" menu — WORKS with a synthetic click, unattended (✅ 2026-07-17, HUB-06):** the new connector DR format does not expose widget_state AT ALL (paths 1-2 are dead) and is invisible to find/the accessibility tree → only a COORDINATE click works: the download icon in the widget header (top right, next to expand) → the menu `Copy contents / Export to Markdown / Export to Word / Export to PDF` → **Export to Markdown** → `deep-research-report.md` lands in Downloads (check with `ls`!) → move it into `_originals` with provenance. No human needed.
+ 4. ⚠️ **The rate limit lies silently:** on "Too many requests" the backend returns the mapping WITHOUT widget_state → it looks like "there is no report", while the report is finished and visible on screen. "Empty from the API" ≠ "no report" → check against the SCREENSHOT before concluding, and wait a couple of minutes.
+ 5. ⚠️ Opening `iframe.src` in a separate tab is POINTLESS — the sandbox is empty, the content arrives over postMessage.
+ - **Gemini:** the report lives in a `STRUCTURED-CONTENT-CONTAINER` (a canvas, same-origin) → `innerText` of the node with the heading → a Blob download → fallback: render into a `<pre>` + get_page_text.
+ - **Grok:** the report is in the main stream → `document.querySelector('main').innerText`, then cut off the echoed prompt and the trailing suggestions → a Blob download. ⭐ The trimming anchor: **"Thought for…" is more reliable than the first "Executive Summary"** (verified on the FLEE-01 run — the extract had caught the prompt echo).
+ - **Common to all:** a large text beyond the display truncation (the JS tool cuts at ~1500, get_page_text at ~50k per pass) → a Blob download → Read it from Downloads. ⚠️ **A Blob download can SILENTLY fail to land** (2026-07-14: grok yes, chatgpt/gemini no; `a.click()` throws nothing, the block is invisible) → ALWAYS `ls Downloads` afterwards; it did not land → fall back to `pre.textContent=txt; document.body.replaceChildren(pre)` (TrustedHTML-safe) → get_page_text in chunks. Clipboard paths (navigator.clipboard hangs; execCommand/Ctrl+C needs a gesture) — do not waste attempts on them.
+ - ⭐ **Field confirmation 2026-07-21 (finishing the 07-14 fan-out, 5 reports of 16–85 KB — the Blob NEVER landed once, Chrome multiple-downloads):** default straight to `get_page_text`, don't try the Blob. What we learned: (a) output over 50 KB is persisted BY THE HARNESS itself into `tool-results/toolu_*.json` on disk → you read it with Read and burn no context; under 50 KB arrives in-band; (b) the hard 50000-character-per-pass cap is worked around by shifting the window of visible text (padding / swapping nodes) + stitching two slices on an overlap of the last ~300 characters — that is how a 77k report was assembled; (c) the clipboard does not merely "hang", it returns the OLD contents of the operator's buffer = a false success, so always check the length and the first words; (d) **searching for a chat in Grok by title** is not a UI job (Ctrl+K is dead, the consent banner eats clicks) but a same-origin `fetch('/rest/app-chat/conversations?pageSize=50',{credentials:'include'})` → `{conversations:[{conversationId,title}]}`; (e) **Gemini is an SPA**: a fresh `navigate` to the chat URL loads the report more reliably than a synthetic click in the sidebar (the sidebar lazily renders empty text); (f) returning raw chat titles out of JS trips the content filter (`BLOCKED: Cookie/query string`) → return a short status token, not the data.
+ - ⭐ **Field confirmation, the EVENING of 2026-07-21 (collecting HUB-02):** (a) **your OWN button injected into the page does not bypass the gesture requirement** — a synthetic/coordinate click on it does not count as a user gesture and the blob still never downloads (the onclick counter = 0; don't reinvent this); (b) **extension clicks and keystrokes may not reach the page at all** (an unfocused window): the symptom is Send being pressed while the input field does not clear; the cure is a programmatic `document.querySelector('button[data-testid="send-button"]').click()` from JS, which React accepts as genuine (verified: the submit went through, the composer emptied); (c) a large text out of the DOM — first into a stash `window.__x`, look for the offsets in a second call, and slice it in Python from the persisted `tool-results\`; (d) selecting a node with Range+addRange and pressing Ctrl+C on top leaves the clipboard EMPTY (not to be confused with "the old contents": both happen — which is why you always verify with `Get-Clipboard`).
+ - ⚠️ **A vendor may REFUSE to answer** (Gemini, on an anti-ban outreach topic — it judged that to be circumventing protections). A refusal is a valid result: save it verbatim into `_originals` as a normal file, status `collected`, and in the Decision Memo state explicitly "no consensus, the base is N vendors" instead of passing a single vendor off as a fan-out.
- `parked` — легальный и честный финал, не поражение ([[gate-implement-critical-only]]: не всё исследованное обязано быть внедрено). Гейт в `dr_registry.py` v3.3 роняет попытку без причины (exit 1). Повод правила: 27.07 в реестре 184 из 246 разведок висели `synthesized`, до `02-Decisions` дошло ~20 — отличить «кормит систему» от «просто лежит» было нельзя. Канон: память [[dr-finish-applied-or-parked]], CLAUDE.md §9.1.
+ ## Step 4 — the synthesis consensus (Alpha Protocol step 4)
+ Read all the collected reports → a table of "agreed / disagreed / unique to each" → a Decision Memo (problem · what we know · the DR · options · risks · recommendation). The heterogeneous principle: do NOT smooth over the disagreements — show them to the owner as forks. The memo goes to `02-Decisions/` (if it is a decision) or into the chat as a report. Close the ledger (`status: collected`).
- ## ⛔ ПОЛЕВЫЕ ДАННЫЕ НОЧИ 26.07.2026 (партия ZB-01…ZB-05, ноут HP17) — читать перед запуском
- 1. ~~**🔴 ChatGPT Deep Research = `dead` на 26.07, «он просто НЕ ИСКАЛ, отдав таблицу из памяти».**~~ ⛔ **ВЫВОД ОПРОВЕРГНУТ 04.08 разбором backend'а — симптом был реален, причина названа неверно.** Что оказалось на самом деле: (а) счётчик «0 citations · 0 searches» стоит у ВСЕХ 10 DR-прогонов 21–26.07, включая принятые и использованные — он не про поиск, `story_events` у connector-DR всегда пуст; (б) те же «мёртвые» прогоны несут 40–106 цитат с живыми URL в `widget_state.report_message.metadata.citations` (одна проверена вживую на странице-источнике); (в) настоящая деградация другая — `resolved_model_slug: deep-research-mini` у всех прогонов и обрыв посреди плана (шаги 3–5 `pending` при `status: completed`, 5–7 мин вместо 20–40), отсюда мало источников и «красиво, но пусто» на глаз; (г) веб-поиск на аккаунте НЕ выключен (`beta_settings.browsing: true`, `disable_web_search: false`) — усиление промпта не помогало не потому, что вендор не искал. **Правило теперь:** ChatGPT-канал гнать через Pro + Web search (п.10 «что решено»), а если запущен DR-чип — судить по `citations`, а не по счётчику. Retry больше двух раз по-прежнему не жечь.
- 2. **🔑 Gemini: заходить ТОЛЬКО по имени аккаунта, индекс `u/N` НЕ СТАБИЛЕН.** ⛔ Правка 27.07 (supersedes «всегда `u/7`»): `https://gemini.google.com/u/7/app` открылся под `au[id]@gmail.com` — free-тариф, модель Flash, кнопка Upgrade. Индексы переезжают между сессиями, «мой номер» запоминать нельзя. **Рабочий вход:** `https://gemini.google.com/app?authuser=you@example.com` (редиректит на нужный `u/N` сам). Детект аккаунта без кликов, ОБЯЗАТЕЛЬНО до вставки промпта: `document.querySelector('a[aria-label*="Google Account"]').getAttribute('aria-label')` + проверка `document.body.innerText.includes('Upgrade')` (true = free-аккаунт). Без этой сверки отчёт молча уедет на Flash и будет выглядеть просто «слабоватым». Переключатель аккаунтов живёт в кросс-доменном iframe — `find`/скролл его не берут.
- 3. **Gemini молча откатывает модель на Flash-Lite** в каждой новой вкладке. Смотреть селектор ГЛАЗАМИ перед каждым запуском; Deep research переехал в «+» → **More tools** → «Deep research» (в первом уровне меню его больше нет).
- 4. **ChatGPT: порядок «чип → промпт», а НЕ наоборот** (supersedes прежняя заметка ZB-02 20.07). Чип «Deep research» — это инлайн-нода ВНУТРИ ProseMirror, встающая по позиции каретки: кликнешь в середину текста — расщепит предложение (ловилось как `chipIdx:470` посреди фразы). Рабочий порядок: (а) включить Deep research в ПУСТОМ композере — чип встаёт первым узлом; (б) поставить каретку в КОНЕЦ (`range.selectNodeContents(ed); range.collapse(false)`); (в) синтетический paste-event — вставка в коллапсированную каретку ничего не заменяет, чип выживает. ⚠️ Повторный paste при `selectNodeContents` НЕ заменяет текст, а ДОПИСЫВАЕТ (получишь удвоение) → чистить только живыми клавишами `ctrl+a` + `Delete`.
- 5. **Gemini-забор: `querySelector('.markdown-main-panel')` берёт ПЕРВУЮ панель = research-план, а не отчёт.** Сохранишь 1.7 KB плана вместо 33.8 KB отчёта и не заметишь. Правильно: якорь на заголовок отчёта → `h2('ПЛАН ИССЛЕДОВАНИЯ').closest('.markdown-main-panel').innerText`.
- 6. **Вынос большого текста:** `javascript_tool` режет вывод на ~1000-1500 симв. Единственный рабочий путь — сложить в `window.__R`, СРАЗУ подменить body на `<pre>` и СРАЗУ `get_page_text` (кап ~50k, отчёт 33.8k прошёл одним проходом). Подмена body ломает страницу → `window.__R` теряется при перезагрузке, порядок нарушать нельзя. Blob-download не пробовать (полевые заметки 21.07: не долетает).
- 7. **«Начать исследование» жать ДВАЖДЫ-с-переосмотром:** первый `find` находит кнопку, но клик приходит раньше, чем она смонтирована. Повторный `find` даёт новый ref — второй клик срабатывает. Доказательство старта = канвас «Starting research…» / «Прекрасно. Вы можете закрыть этот чат», а не факт клика.
- 8. **🔁 ДЕДУП — на КАЖДОМ вендоре, а не только в реестре.** Инцидент 03:0x: реестр показал ZB-03 = `issued`, дедуп по истории Grok дал «чисто» (похожий чат оказался от 22:49 UTC = ДО создания промптов партии) → запустил. А в Gemini Recents уже висел свой `DR26-07-26-ZB-03` от параллельной сессии → лишний прогон Gemini DR. Реестр = первый фильтр, история КАЖДОГО вендора, куда шлёшь = второй, обязательный. Это [[check-all-places-not-one]], применённое к вендорам вместо дисков.
+ ⭐ **Step 5 — CLOSE THE RECONNAISSANCE (the owner, 07-27, mandatory).** `synthesized` is not the finish: a report was written, but the system did not change. Every DR is driven to one of two terminal statuses, and both require a `--note`:
+ - `dr_registry.py update <ID> --status applied --note "<what actually changed: a Decision Memo / a production edit / a new routine>"`
+ - `dr_registry.py update <ID> --status parked --note "<why we're not taking it and what would change the decision>"`
- 9. **Корневой композер ChatGPT ОБЩИЙ на все вкладки — свой же черновик поедет за тобой.** 27.07: открыл вторую вкладку под ZB-04 — там лежал ZB-03 из первой; paste-event ДОПИСАЛ (8303 симв. вместо 4175), а `execCommand selectAll+delete` визуально очистил, но ProseMirror восстановил состояние и дописал снова (12450). Лечится только живой клавиатурой: клик в композер → `ctrl+a` → `Delete` → сверить `innerText.length===0` → и лишь потом paste.
- 10. **`ctrl+a`+`Delete` сносит и ЧИП режима** (Web search / Deep research) — прогон уйдёт без поиска, и это не видно в тексте промпта. Порядок для ChatGPT: очистить → вставить промпт → **включить чип заново** → сверить → Send. И ещё: текст чипа попадает в `innerText` композера то префиксом `Web search\n`, то суффиксом `\nWeb search` → при сверке длины срезать его с ОБОИХ концов, иначе ловишь ложный mismatch и начинаешь «чинить» целый промпт.
+ `parked` is a legal and honest ending, not a defeat ([[gate-implement-critical-only]]: not everything researched must be implemented). The gate in `dr_registry.py` v3.3 rejects an attempt with no reason (exit 1). Why the rule exists: on 07-27 the registry had 184 of 246 researches hanging at `synthesized`, while only ~20 reached `02-Decisions` — there was no way to tell "this feeds the system" from "this just lies there". Canon: memory [[dr-finish-applied-or-parked]], CLAUDE.md §9.1.
- ## ⭐ ПОЛЕ 31.07.2026 ([машина флота], DR26-07-29-MACANTON-01-1302) — рельсы вендоров и три молчаливые грабли
- 0. **ВЫБОР БРАУЗЕРА И АККАУНТА — МОЙ, ВСЕГДА** (anton 31.07, канон `reglament-brauzer-i-akkaunt-vybiray-sam-nikogda-ne-sprashivay`). Три подключённых Chrome → беру сам, не пошёл → следующий, потом Firefox. ⛔ Вопрос «какой браузер/аккаунт взять?» Антону запрещён. Цена нарушения замерена в этот же день: вендор выпал из веера при живом пути.
- 1. **Рельса Gemini на 31.07 = ТОЛЬКО живой Chrome.** Оба CLI-пути мертвы: бесплатный ключ AI Studio отдаёт 429 (один на весь флот), OAuth — `IneligibleTierError` (Code Assist for individuals закрыт, миграция в Antigravity). Аккаунт Gemini = `youraccount.a`, НЕ `a2`. Путь в UI: «+» → **More tools** → **Deep research** (в меню первого уровня его НЕТ), затем двухфазность — план → кнопка **«Начать исследование»**, доказательство старта = «Researching N websites…».
- 2. **⛔ Не клонировать профиль Firefox, который держит живой GUI-браузер.** На диск попадает вчерашний слепок (свежие куки живут в памяти процесса) → селениум видит «Sign in» на сайте, где сессия на самом деле жива. Я сделал из этого вывод «сессия мертва на стороне Google» и он был неверным.
- 3. **`pbcopy` без UTF-8 локали убивает кириллицу.** Вставка «проходит успешно», в композере мойибаке, длина расходится в 1,5 раза. Всегда `export LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8` перед `pbcopy`, и сверять поле не только длиной, но счётчиком кириллицы: `(t.match(/[а-яА-Я]/g)||[]).length`.
- 4. **Забор ChatGPT DR:** `widget_state` может быть ПУСТ — отчёт лежит в `mapping[*].message.content.parts[0]` (взять самую длинную строку по ВСЕМУ mapping, а не по цепочке от `current_node`). `body.innerText` про готовность ВРЁТ — держится на ~12 КБ сайдбара, даже когда библиография из 69 источников уже отрисована; готовность проверять СКРИНШОТОМ. И читать первую строку отчёта: «## Продолжение отчёта — с §N» = половина не доехала.
- 5. **Забор Gemini DR:** отчёт в `structured-content-container` (их несколько — брать самый длинный), надёжнее всего `get_page_text`, харнес сам персистит >50 КБ в `tool-results/*.json`, оттуда режем питоном.
- 6. **Проверка цитат в ДВА шага, не в один.** (а) все ссылки на код ответа — детерминированно, 0 токенов; (б) **прочитать содержание у 3–5 утверждений, на которых стоит решение**. Замер 31.07: 30/30 ссылок Grok живые, но ссылка ChatGPT на JCR вела на статью про делимость цен, а Grok выдал настройку Zapier за поведение продукта. Писать «цитаты проверены» после одного шага (а) — ложь. [[live-url-is-not-a-verified-citation]]
+ ## ⛔ FIELD DATA FROM THE NIGHT OF 2026-07-26 (batch ZB-01…ZB-05, laptop) — read before launching
+ 1. **🔴 ChatGPT Deep Research = `dead` as of 07-26, the channel is excluded from the fan-out.** Three independent confirmations in one night: ZB-01 had two consecutive runs of "Research completed in 6m · **0 citations · 0 searches**" (the second one already AFTER an explicit follow-up "at least 20 searches / 20 sources" in the body), plus the same symptom on ZB-05 in a parallel session. The prompt arrived in full, the Deep research chip was on, the run started and "thought" for 6 minutes — it simply DID NOT SEARCH, handing back a pretty table from the model's memory. **Not a paste defect on our side.** Before putting ChatGPT back into the fan-out — do one probe run and read the counter; `0 searches` → `dead`, we go with 2 vendors and write that explicitly in the synthesis. Don't burn more than two Retries (a third Retry only cures `Error in message stream`, not an empty search).
+ 2. **🔑 Gemini: enter ONLY by account name, the `u/N` index is NOT STABLE.** ⛔ Correction 07-27 (supersedes "always `u/7`"): `https://gemini.google.com/u/7/app` opened under a different account — free tier, the Flash model, an Upgrade button. Indices move between sessions; you cannot memorise "my number". **The working entrance:** `https://gemini.google.com/app?authuser=<the personal account>` (it redirects to the right `u/N` by itself). Detect the account without clicks, MANDATORY before pasting the prompt: `document.querySelector('a[aria-label*="Google Account"]').getAttribute('aria-label')` + a check of `document.body.innerText.includes('Upgrade')` (true = a free account). Without that check the report silently goes out on Flash and just looks "a bit weak". The account switcher lives in a cross-domain iframe — `find`/scrolling cannot reach it.
+ 3. **Gemini silently rolls the model back to Flash-Lite** in every new tab. Look at the selector WITH YOUR EYES before every launch; Deep research moved into "+" → **More tools** → "Deep research" (it is no longer on the first level of the menu).
+ 4. **ChatGPT: the order is "chip → prompt", NOT the other way round** (supersedes the earlier 07-20 note). The "Deep research" chip is an inline node INSIDE ProseMirror that lands at the caret position: click in the middle of the text and it splits the sentence (caught as `chipIdx:470` in the middle of a phrase). The working order: (a) enable Deep research in an EMPTY composer — the chip becomes the first node; (b) put the caret at the END (`range.selectNodeContents(ed); range.collapse(false)`); (c) the synthetic paste event — pasting into a collapsed caret replaces nothing and the chip survives. ⚠️ A repeat paste with `selectNodeContents` does NOT replace the text, it APPENDS (you get a duplicate) → clean it only with real keystrokes `ctrl+a` + `Delete`.
+ 5. **Gemini collection: `querySelector('.markdown-main-panel')` takes the FIRST panel = the research plan, not the report.** You will save 1.7 KB of plan instead of 33.8 KB of report and never notice. The right way: anchor on the report's heading → `h2('<the plan heading>').closest('.markdown-main-panel').innerText`.
+ 6. **Getting a large text out:** `javascript_tool` truncates output at ~1000-1500 characters. The only working path is to stash it in `window.__R`, IMMEDIATELY replace the body with a `<pre>` and IMMEDIATELY call `get_page_text` (cap ~50k; a 33.8k report went through in one pass). Replacing the body breaks the page → `window.__R` is lost on a reload, so the order cannot be changed. Don't try the Blob download (per the 07-21 field notes: it does not land).
+ 7. **Press "Start research" TWICE, with a fresh look between:** the first `find` locates the button, but the click arrives before it is mounted. A second `find` gives a new ref and the second click works. Proof of the start is the canvas "Starting research…" / "Great, you can close this chat", not the fact that you clicked.
+ 8. **🔁 DEDUP — at EVERY vendor, not only in the registry.** The 03:0x incident: the registry showed ZB-03 = `issued`, the dedup over Grok's history came back "clean" (a similar chat turned out to be from 22:49 UTC = BEFORE the batch's prompts were created) → I launched it. But Gemini's Recents already had its own `DR26-07-26-ZB-03` from a parallel session → one wasted Gemini DR run. The registry = the first filter, the history of EVERY vendor you send to = the second, mandatory one. This is [[check-all-places-not-one]] applied to vendors instead of disks.
- ## ⭐ ПОЛЕ 28.07.2026 (ZB-04-2349, ноут HP17) — транспорт промпта и забор отчёта решены
- 1. **🔑 ТРАНСПОРТ ПРОМПТА = `window.name`, а не инлайн в javascript_tool.** Промпт 12 КБ инлайном на трёх вендоров = ~37 КБ контекста плюс риск экранирования. Рабочий путь, 0 токенов: `navigate` вкладку на локальный файл промпта → `window.name = await fetch(location.href).then(r=>r.text())` → `navigate` ТУ ЖЕ вкладку на сайт вендора → `window.name` доезжает целиком (проверено 12 224 / 12 279 / 12 467 знаков). Раздача: крошечный HTTP-сервер из скретчпада.
- ⚠️ **Исключение — Gemini:** COOP на `google.com` рвёт browsing context, и при уходе С gemini на localhost `window.name` обнуляется. Обратное направление (localhost → gemini) работает.
- 2. **🔑 ЗАБОР ОТЧЁТА = POST на локальный сервер, текст в мой контекст не попадает.** Тот же приём наоборот: в чате вендора сложить текст в `window.name` → `navigate` на `http://127.0.0.1:<порт>/sink` → оттуда `fetch('/save?name=raw-<vendor>.txt',{method:'POST',body:window.name})`. Сервер пишет файл, дальше проверяю полноту Python-ом (разделы, число URL) за копейки. Так забраны отчёты 16 КБ / 34 КБ / 83 КБ.
- ⚠️ **Для Gemini** (COOP убивает window.name) работает **фрагмент URL**: `location.href='http://127.0.0.1:<порт>/sink#'+encodeURIComponent(txt)` → на sink-странице `decodeURIComponent(location.hash.slice(1))` → POST. Фрагмент на сервер не уходит, приватность цела.
- 3. **Что НЕ работает, не тратить попытки:** `fetch` с страницы вендора на 127.0.0.1 (CSP `connect-src` — режут и chatgpt.com, и gemini.google.com) · отправка формой на localhost (CSP `form-action`) · CDP `ctrl+v` (клавиша доходит, вставки нет) · кнопка «Copy contents» в UI (нужен фокус окна, а окно фоновое — буфер молча не меняется; всегда сверять `Get-Clipboard` с сентинелом).
- 4. **🔴 ChatGPT Deep Research — ПЯТЫЙ подряд `0 citations · 0 searches`** (4 раза 26.07 + 1 раз 28.07, аккаунт `youraccount.a2@`, 15 минут «думал» и выдал внешне красивый, но пустоватый отчёт — ⚠️ 04.08: «из памяти» неверно, он искал, но урезанно; счётчик врёт, см. п.1 полевых данных). Web search на том же аккаунте и той же модели ищет нормально (90+ запросов, 80+ страниц, 168 URL в отчёте). ⇒ **Не тратить DR-чип на этом аккаунте: ChatGPT-канал вести сразу через Web search** + в тело промпта строку «перечисли выполненные запросы и реально открытые URL перед финальным отчётом». Экономит 15 минут и один прогон.
- 5. **ChatGPT DR стал ДВУХФАЗНЫМ, как Gemini:** после Send показывает карточку плана с `Edit / Cancel / Start` и автостартом по таймеру ~30 с. Кнопку дожимать.
- 6. **ChatGPT: `execCommand insertText` сел, синтетический paste-event НЕ сел** — ровно наоборот, чем у Grok (там paste-event с первого раза). Каскад нужен обоим, порядок методов по вендору разный. Чип режима ставить в ПУСТОМ композере, потом каретка в конец, потом вставка — чип выживает.
- 7. **Gemini: кнопка «Начать исследование» остаётся видимой и enabled после успешного клика.** Доказательство старта — не исчезновение кнопки, а канвас `Прекрасно. Вы можете закрыть этот чат` + `Researching N websites`. И `bodyLen` у Gemini скачет на порядок (327 887 → 14 403 за ре-рендер), как признак старта не годится.
- 8. **Gemini-забор: брать панель по МАКСИМАЛЬНОЙ длине**, а не первую. На готовом отчёте `.markdown-main-panel` было три штуки: 1861 (план), 144, 34 444 (отчёт). Панель отчёта рендерится лениво — если её нет, кликнуть карточку отчёта в ленте.
- 9. **Grok Heavy: 485 sources и НОЛЬ инлайн-ссылок.** Источники отданы абзацем с перечнем доменов, анкоров на странице 2. `innerText` ничего не теряет, но проверяемость Grok-фактов низкая — спорные цифры сверять руками (в этом прогоне Grok ошибся: заявил, что платных ускорителей нет, а Story Boost за $159,99 существует).
- 10. **Два подключённых Chrome в MCP.** Один может быть чистым профилем, разлогиненным везде. Проверять аккаунт (`/api/auth/session` у ChatGPT, `aria-label` у Gemini, `Sign in` в тексте у Grok) ДО вывода «разлогинен, зовите Антона».
+ 9. **The root ChatGPT composer is SHARED across all tabs — your own draft follows you around.** 07-27: I opened a second tab for ZB-04 — ZB-03 from the first tab was sitting there; the paste event APPENDED (8303 characters instead of 4175), and `execCommand selectAll+delete` cleared it visually, but ProseMirror restored the state and appended again (12450). The only cure is a real keyboard: click into the composer → `ctrl+a` → `Delete` → verify `innerText.length===0` → and only then paste.
+ 10. **`ctrl+a`+`Delete` also removes the MODE CHIP** (Web search / Deep research) — the run goes out with no search, and that is invisible in the prompt text. The order for ChatGPT: clear → paste the prompt → **turn the chip back on** → verify → Send. Also: the chip's text lands in the composer's `innerText` sometimes as the prefix `Web search\n` and sometimes as the suffix `\nWeb search` → when checking the length, strip it from BOTH ends, otherwise you get a false mismatch and start "fixing" a perfectly good prompt.
- 11. **⭐ Blob-download на chatgpt.com РАБОТАЕТ — и это единственный способ забрать отчёт целиком (27.07, supersedes полевую заметку 21.07 «Blob не долетает»).** Замер: отчёт 73 144 симв. приехал файлом 97 992 байта, второй — 60 623 симв., оба с первого раза. `get_page_text` для таких объёмов НЕПРИГОДЕН: режет на 50 000 симв. **и отрезает ровно хвост — раздел Proof of work**, то есть само доказательство, что вендор искал. Порядок: собрать текст последнего `[data-message-author-role="assistant"]` в `window.__R` → Blob + `a.click()` → **обязательно `ls Downloads`** → перенести скриптом с провенансом. Контекст сессии при этом не тратится вообще — текст идёт диск-в-диск. ⚠️ Трюк «добить пэддингом до >50 КБ, чтобы get_page_text persist-нул на диск» НЕ работает: тул иногда персистит, а иногда режет инлайном — поведение непредсказуемо, не закладываться.
- 12. **`exit 0` от `brain_embed_update.py` при занятом локе — НЕ баг и не враньё.** В коде осознанно: `busy_code = 3 if index_age_hours() > STALE_HOURS else 0` (порог 26 ч). Код отвечает на вопрос «индекс протух по часам?», а НЕ «мой запрос выполнился?». После записи новых заметок это разные вопросы: свежий по часам индекс их всё равно не содержит. ⇒ После реиндекса проверять ФУНКЦИОНАЛЬНО — запросом к `brain_ask.py` на фразу, которой нет нигде, кроме новых файлов. Счётчик `harari ×N` в `_brain_e5_meta.pkl` не доказательство: там пути файлов, не текст чанков.
+ ## ⭐ FIELD NOTES 2026-07-28 (ZB-04-2349, laptop) — prompt transport and report collection solved
+ 1. **🔑 PROMPT TRANSPORT = `window.name`, not inline in javascript_tool.** A 12 KB prompt inlined for three vendors = ~37 KB of context plus an escaping risk. The working path, 0 tokens: `navigate` the tab to a local file holding the prompt → `window.name = await fetch(location.href).then(r=>r.text())` → `navigate` THE SAME tab to the vendor's site → `window.name` arrives intact (verified at 12,224 / 12,279 / 12,467 characters). Serving: a tiny HTTP server from the scratchpad.
+ ⚠️ **The exception is Gemini:** COOP on `google.com` breaks the browsing context, and navigating AWAY from gemini to localhost zeroes `window.name`. The reverse direction (localhost → gemini) works.
+ 2. **🔑 REPORT COLLECTION = a POST to the local server, so the text never enters my context.** The same trick in reverse: inside the vendor's chat stash the text in `window.name` → `navigate` to `http://127.0.0.1:<port>/sink` → from there `fetch('/save?name=raw-<vendor>.txt',{method:'POST',body:window.name})`. The server writes the file, and then I check completeness with Python (sections, URL count) for pennies. Reports of 16 KB / 34 KB / 83 KB were collected that way.
+ ⚠️ **For Gemini** (COOP kills window.name) the **URL fragment** works: `location.href='http://127.0.0.1:<port>/sink#'+encodeURIComponent(txt)` → on the sink page `decodeURIComponent(location.hash.slice(1))` → POST. The fragment is never sent to the server, so privacy is intact.
+ 3. **What does NOT work, don't waste attempts:** a `fetch` from the vendor's page to 127.0.0.1 (CSP `connect-src` — both chatgpt.com and gemini.google.com block it) · submitting a form to localhost (CSP `form-action`) · a CDP `ctrl+v` (the key arrives, the paste does not) · the "Copy contents" button in the UI (it needs window focus, and the window is in the background — the clipboard silently does not change; always compare `Get-Clipboard` against a sentinel).
+ 4. **🔴 ChatGPT Deep Research — a FIFTH consecutive `0 citations · 0 searches`** (4 times on 07-26 + once on 07-28, on the work account; it "thought" for 15 minutes and produced a beautiful report from memory). Web search on the same account and the same model searches fine (90+ queries, 80+ pages, 168 URLs in the report). ⇒ **Don't spend the DR chip on this account: run the ChatGPT channel through Web search directly** + add a line to the prompt body, "list the queries you ran and the URLs you actually opened before the final report". That saves 15 minutes and one run.
+ 5. **ChatGPT DR became TWO-PHASE, like Gemini:** after Send it shows a plan card with `Edit / Cancel / Start` and an auto-start on a ~30s timer. Press the button anyway.
+ 6. **ChatGPT: `execCommand insertText` took, the synthetic paste event did NOT** — exactly the opposite of Grok (where the paste event works first time). Both need the cascade, and the method order differs per vendor. Set the mode chip in an EMPTY composer, then put the caret at the end, then paste — the chip survives.
+ 7. **Gemini: the "Start research" button stays visible and enabled after a successful click.** Proof of the start is not the button disappearing but the canvas "Great, you can close this chat" + "Researching N websites". And Gemini's `bodyLen` jumps by an order of magnitude (327,887 → 14,403 on a re-render), so it is useless as a start signal.
+ 8. **Gemini collection: take the panel with the MAXIMUM length**, not the first one. On a finished report there were three `.markdown-main-panel` elements: 1861 (the plan), 144, and 34,444 (the report). The report panel renders lazily — if it is absent, click the report card in the feed.
+ 9. **Grok Heavy: 485 sources and ZERO inline links.** The sources are handed back as a paragraph listing domains, with 2 anchors on the page. `innerText` loses nothing, but the verifiability of Grok's facts is low — check contested figures by hand (in this run Grok was wrong: it claimed there are no paid boosts, while a $159.99 Story Boost exists).
+ 10. **Two Chromes connected to the MCP.** One of them can be a clean profile, logged out everywhere. Check the account (`/api/auth/session` on ChatGPT, the `aria-label` on Gemini, the word `Sign in` in the text on Grok) BEFORE concluding "logged out, call the owner".
- ## ⭐ ПОЛЕ 16.09.2026 ([машина флота], DR26-09-16-MACANTON-01-0446, безлюдная рутина С Chrome-MCP) — шесть строк, каждая замерена
- 1. **ChatGPT веб (a2 Pro) в живом Chrome: план DR стартует САМ, кнопки Start нет.** Порядок сработал с первого раза: «+» → `Deep research` (ref из `find`) в ПУСТОМ композере → `execCommand insertText` в конец (кириллица 84=84) → `button[data-testid="send-button"].click()`. Статус — `widget_state.status` (`researching` → `completed`, ~9 мин). Отчёт в `report_message.content.parts[0]` (58 КБ). ⚠️ `citations` в metadata = 0, но в тексте 22 URL, и гейт засчитал; `resolved_model_slug` = `gpt-5-thinking`. Blob из той же вкладки долетел.
- 2. **Gemini веб (a@ Punk, Pro Extended, Deep research) — провал без текста.** «Создание плана» с активной кнопкой Stop держалось >10 мин. Кнопка `Start research` так и не появилась ни в фоновой, ни в свежей вкладке. Потом заголовок чата сменился на «…Request Failed», а `get_page_text` — пусто. Признак провала = **заголовок вкладки**, а не DOM. Gemini CLI в тот же час: exit=1 за 6 с.
- 3. **claude.ai: Cloudflare «Performing security verification» висит и в ЖИВОМ Chrome**, не только в headless FF. Капчу не трогаем, рельса = `missing`. Перед этим выводом хук `dead_claim_guard` требует `rail_sweep.py <вендор>` — прогоняй его ДО фразы «недоступен».
- 4. **GLM с `Advanced Search ON` + `Deep Think Max` сам пишет «I can't browse the live web»** и отдаёт 0 URL. `dr_ff_rail` при этом печатает OK за 1 мин на эхо (гейт: collected-EMPTY); настоящий ответ забрал `dr_ff_collect --title "Bay Area"` через ~15 мин (`--title "Конферен"` не нашёл — заголовок GLM английский). ⛔ Такая нога **выдумала выгодный факт о заказчике** («PRs merged into Claude Code») — `gh search prs --merged` показал 0. **Несущие факты ноги без ссылок сверять до синтеза.**
- 5. **Вторая нога того же вендора** (веб-DR, когда `chatgpt` уже занят codex CLI) подшивается дописыванием `chatgpt-a2` в `targets:` манифеста — `attach` иначе отбивает (так уже сделаны `claudeai-a2/bb`). Независимых вендоров при этом НЕ прибавилось, и в синтезе так и пишем.
- 6. **На macOS нет `timeout`** — цикл с `timeout 600 python3 …` молча прогнал 0 раз (`command not found`, exit 0 цикла). У `dr_ff_collect` есть свой `--timeout`.
+ 11. **⭐ The Blob download on chatgpt.com DOES WORK — and it is the only way to take the whole report (07-27, supersedes the 07-21 field note "the Blob does not land").** Measured: a 73,144-character report arrived as a 97,992-byte file, a second one at 60,623 characters, both on the first attempt. `get_page_text` is UNUSABLE at that size: it cuts at 50,000 characters **and cuts off exactly the tail — the Proof of work section**, i.e. the very evidence that the vendor searched. The order: collect the text of the last `[data-message-author-role="assistant"]` into `window.__R` → Blob + `a.click()` → **mandatory `ls Downloads`** → move it with a script, with provenance. The session's context is not spent at all — the text goes disk to disk. ⚠️ The trick of "padding it past 50 KB so that get_page_text persists it to disk" does NOT work: the tool sometimes persists and sometimes truncates inline — the behaviour is unpredictable, don't rely on it.
+ 12. **`exit 0` from `brain_embed_update.py` while the lock is held is NOT a bug and NOT a lie.** It is deliberate in the code: `busy_code = 3 if index_age_hours() > STALE_HOURS else 0` (a 26h threshold). The exit code answers "is the index stale by the clock?", NOT "did my request run?". After writing new notes those are different questions: an index that is fresh by the clock still does not contain them. ⇒ After a reindex, verify FUNCTIONALLY — query `brain_ask.py` with a phrase that exists nowhere but in the new files. The `harari ×N` counter in `_brain_e5_meta.pkl` is not proof: it holds file paths, not chunk text.
- ## ⭐ ПОЛЕ 14.09.2026 ([машина флота], DR26-09-14-MACANTON-01-1204) — пять строк, каждая замерена
- 1. **⛔ `dr_ff_rail.py --rail glm` (autoff) печатает `OK … 9563 символов` и exit 0 за 2 мин, а Send НЕ ушёл**: файл = сайдбар z.ai + эхо промпта с YAML-фронтматтером, `/api/v1/chats/<id>` → 0 сообщений. `dr_leg_gate.py` пропускает такое exit 0 с пометкой «0 URL». ⇒ после этой рельсы проверять чат через API (`localStorage.token` → `/api/v1/chats/?page=1`), а не верить OK. Рабочая дверь в этот день — живой Chrome-MCP: меню глобуса (старая эпоха) → тумблер `Advanced Search` → `glm_probe.py` (JS грузится через `window.name`, `(0,eval)` проходит) → `#send-message-button.click()`; 50 КБ / 35 URL за ~14 мин.
- 2. **Gemini: клик `Send message` по ref из `find` НЕ отправил** (текст остался в композере, скриншот). Отправил координатный клик по стрелке. Кнопка `Start research` рендерится ниже видимой области — `find` её не видит до `scroll` вниз по плану.
- 3. **Gemini в фоновой вкладке показывает скелетон «исследую» даже после конца.** Готовность судить свежим `navigate` + `innerText` на «I've completed your research». Blob `body.innerText` долетел (118 КБ), 23 URL.
- 4. **`claude -p` рельса отдала 34 КБ за 1366 с с 0 источников** — диспетчер честно отбил в `results-failed/`. Не засчитывать.
- 5. **`dr_post_draft.py` на [машина флота] лежит в транзите** `[шина]/_transit/scripts-from-[машина флота]/` (там же `dr_rails_registry.py` и тесты), в `~/.claude/scripts` не установлен — запускать оттуда. Я сначала написал «нет», проверив одно место, и хук `false_no_guard` поймал: перед «нет X» — `python3 ~/.claude/scripts/have.py <имя>`. `dr_rails.json` на 14.09 `have.py` не нашёл ни в одном из 9 корней. Длинный `--verdict` инструмент режет многоточием — давать ≤80 знаков.
+ ## Errors/pitfalls (things that did not make it into the state machine)
+ - ⚠️ **A background/minimized Chrome tab (verified 2026-07-17):** viewport 0×0, the layout is frozen → synthetic JS clicks and Radix/Angular buttons (Gemini's "Start research", ChatGPT's "+" menu) do NOT fire, and `computer` clicks land in the wrong place. The cure: `tabs_create_mcp` → a new tab (it gets a layout even in a background window) → open the same conversation URL → `find` → `computer left_click ref` (CDP-trusted). The prompt is already sent by then — you only lose "press the button", not the quota.
+ - ⭐ **"started" in the ledger ≠ actually running (incident HUB-06, 07-16→17):** three vendors were marked started while in fact ONE was working. Gemini was stuck on an unpressed "Start research" button (the page held only the prompt, panel=0), and Grok was never submitted at all (the path stayed `/`, the prompt sat in the composer). A night was lost. → **the probe-after-start is mandatory and must be evidential:** the path changed to /chat/ · a progress indicator is visible · the page's volume grew. Pasting ≠ sending; sending ≠ starting. A `submitted` state without a confirmed `started` is not started.
+ - ⭐ **ChatGPT DR stops at the research plan (verified 2026-07-20, ZB-02):** the first run (~12 min, "0 citations · 0 searches") can return ONLY a research plan + an output structure, WITHOUT any real research, and finish (`finished_successfully`, end_turn). This is NOT a paste/start bug — the run really happened, it just degenerated into a plan. The cure: a follow-up in the same chat, "Proceed now: execute this plan and write the FULL final report… Do not stop at the plan" → the second run (65 min in our case) produces a full report with live URLs. When collecting: if the backend JSON's longest part starts with "Research Plan:" and the mapping holds only one widget with the plan — that is the plan, not the report; nudge it, don't save it as collected. (Gemini/Grok don't suffer from this — in Gemini the plan is a separate phase with a button.)
+ - ⚠️ **ChatGPT's DR mode chip lives INSIDE the editor (ZB-02, 07-20):** the `paste_verify` cascade (directSet/execCommand) clears the editor and ERASES the "Deep research" chip → the probe will show `chip:false`. The order: paste the prompt first, THEN turn Deep research on over it (the "+" menu → Deep research), then check the chip and Send. Otherwise an ordinary chat message flies off — the DR quota is intact but the answer is the wrong kind.
+ - ✅ **Grok, the textarea/contenteditable mirror — the ROOT CAUSE was found and cured (FLEE-03, 07-17):** Grok 4.5 = a TipTap/ProseMirror contenteditable (`div.tiptap.ProseMirror`); the visible `<textarea>` is a HIDDEN mirror. Filling the textarea (nativeSetter / value + InputEvent) returns `ok:true`, but the React/PM state does not update from the mirror → Submit never renders, Enter is a no-op (exactly what burned time on 07-10 and 07-17). **The fix in the cascade:** target `.tiptap.ProseMirror` FIRST + a synthetic paste event (`ClipboardEvent('paste',{clipboardData:DataTransfer})`) → PM adopts the text → `button[type="submit"]` appears enabled → click. Verified live on 07-17 (FLEE-03 Grok `/c/e621f761`). If the UI drifts again and the paste event stops working → a new chat + a probe, don't burn time.
+ - ⭐ **ChatGPT DR silently does not search — and a prompt does NOT cure it (2026-07-26, ZB-02 + ZB-05 independently).** The symptom: "Research completed in Xm · **0 citations · 0 searches**", a beautiful report entirely from memory. Measured: 4 runs, 2 different chats, 2 independent sessions, one Pro account; the second run of each pair went out WITH an explicit demand to search — it did not help. ⛔ The rule: **two `dead` results in a row = do not try a third time the same way**, close the channel, build the synthesis on the remaining vendors and state explicitly "the base is N vendors". The discriminating test (cheap, run it BEFORE drawing conclusions about the cause): the same question in an ordinary chat with the **Web search** tool — that goes down a different code path. If Web search works fine (in our case: 24+ queries, "Searched N websites" blocks) → it is the DR path that is broken, and 🤔 most likely the DR quota is exhausted and the vendor degrades silently instead of erroring honestly. A side benefit: Web search + a hard prompt ("list the queries and the URLs you opened before answering") produces a usable, citable report — a working workaround while DR is down.
+ - ⭐ **The root composer at `chatgpt.com/` is shared per account and parallel sessions tear it apart (2026-07-26).** The draft syncs between sessions: in one run someone else's `ZB-05` and `ZB-06` passed through it, a neighbouring session rolled my pastes back with its own React state, and once my line stuck to the tail of SOMEONE ELSE'S prompt (it could not be cleaned — the edits would not hold). ⛔ The rule: when working in parallel, **do not touch the root composer**; run inside YOUR OWN `/c/<id>` (the composer is per-chat and uncontested), and create a new chat only when the root one is empty. Always read the composer before pasting: non-empty + someone else's ID = stop, not "I'll overwrite it".
+ - A logout in the middle of the research → the report may be lost: after logging back in, check the vendor's chat history, a DR is usually saved there.
+ - A long report gets truncated in get_page_text → scroll/expand ("Show more") before reading; compare the end of the text with the end of the report.
+ - ⛔ Never set up a PAID API path as a "fallback" without approval ([[prefer-included-limits-before-paid-api]]).
+ - The same prompt goes to every vendor VERBATIM, except the deliberate platform block §2/§3/§4 (otherwise the consensus is dirty).
+ - ⚠️ **An account can flag automation:** on the FLEE-01 run ChatGPT showed a "Suspicious activity detected" banner when a DR was started from automation (it did NOT block it, the research ran). That is exactly the failure mode both DR vendors predicted. Saw the banner → don't panic and don't hammer retries; note it in the ledger and continue. If it repeats systematically → `drift_suspected`, report to the owner.
+ - ⚠️ **Nobody publishes session longevity** (the DR consensus) → treat a forced re-auth as INEVITABLE, don't build on a timer. `needs_reauth` = a first-class state + an out-of-band ping to the human (the approval channel).
+ - ⏳ **A fully unattended LAUNCH** is the next build step (the architecture is known from the DR: a ledger FSM + a dedicated Firefox profile + cron/systemd; start with ChatGPT+Gemini). For now only COLLECTION is unattended (the nightly `dr_collect.py`); launching requires a live session with a browser. The hole is acknowledged and closes after the owner decides on a "standby browser session on the hub".
- ## ⭐ ПОЛЕ 10.09.2026 (ZBOOKG8, добор кворума DR26-08-28-MACRUS-01-1218) — четыре строки, каждая замерена
+ ## /tt — how to test v2 (after FLEE-01 lands, or when editing)
+ Don't run a live DR just to test (it burns quota). Test in parts: (1) the probe logic — on an already-open tab, verify that mode + length detection works WITHOUT pressing Send; (2) extraction — run the parser over an ALREADY collected past DR (backend JSON / innerText) and compare against the saved `_originals`; (3) the ledger + dr_collect — run them against an existing DR-ID. A live end-to-end run only when the research is genuinely needed.
- 1. **⛔ AutoFF НЕ ЕДИНСТВЕННАЯ ПОВЕРХНОСТЬ, И НА ЭТОМ УЗЛЕ ОН ПУСТ.** Замер кук в `~/AppData/Local/ff-autoff-profile`: claude.ai **0**, z.ai **0**, mistral.ai **0**, chatgpt.com **0**, google.com 1. Три рельсы подряд упали «разлогинен» — и это читалось как «вендор закрыт». Живые сессии лежали в СИСТЕМНОМ профиле `Ct3iOc7B.Profile 1` (bb-platinum, дефолт установки): claude.ai 7, google 37, **z.ai 18**, mistral 5, chatgpt 8, grok 8. ⇒ **Перед приговором рельсе — обойти ВСЕ профили одним скриптом** (`moz_cookies` по хостам, 0 токенов, ~2 сек), затем `--profile-dir "<имя папки>"`. ⚠️ Профиль bb держит ЖИВОЙ Firefox Антона → `--no-copy` там запрещён, а для google даже копия ломает его сессию ротацией (грабля 02.09) — google из bb НЕ трогать.
- 2. **🔴 GEMINI МЁРТВ ПО ПОДПИСКЕ, А НЕ ПО ТЕХНИКЕ (улика со страницы).** `banner: "Your Google AI Pro subscription ended"`, `model: Gemini 3.6 Flash`, меню инструментов = Files/Drive/Google Photos/Notebooks, **`deepResearch: false`, `moreTools: false`**. Аккаунт при этом залогинен и верный (`Google Account: Punk Crypto (you@example.com)`). ⇒ Строка «платный Google AI Pro, DR ≈20/день» ПРОТУХЛА; `dr_ff_rail --deep` честно печатает «не нашёл пункт Deep Research» — это не поломка рельсы. Продление = деньги = **Tier-2**, решает Антон, сами не чиним.
- 3. **📥 GLM: СБОРЩИК БЕЗ `--title` САДИТСЯ НА ЛЕНДИНГ.** `dr_ff_collect --rail glm` без заголовка отдал 3134 симв. рекламы GLM-5.3-Flash и сайдбара — гейт справедливо отбил. С `--title "<кусок заголовка чата>"` тот же чат отдал **19 376 симв., 42 источника, `dr_leg_gate` PASS**. Заголовок берётся из сайдбара, который виден в самом «пустом» снимке. ⇒ **Для glm всегда `--title`.** Отправляющая рельса при этом вышла по тишине на фазе `Thinking...` (в хвосте её снимка читаются `Deep Think / Max` и `Advanced Search` — режимы встали верно): «отправить» и «забрать» — две разные операции по времени, это не брак.
- 4. **⛔ claude.ai ЧЕРЕЗ Chrome-MCP: ПРОМПТ САДИТСЯ, SEND НЕ ПРОХОДИТ.** Залогинен верно (`/api/organizations` → `a673590f…you.assistants@example.com's Organization`), `Research mode` доказан прибором (`aria-pressed:"true"`), модель Fable 5 High, промпт сел `execCommand insertText` 1-в-1 (кириллица 2562 = 2562). Дальше — стена: `button[aria-label="Send message"]` не disabled, но **не отправляет ни программным `.click()`, ни CDP-кликом по ref, ни живым Enter** (3 способа), URL остаётся `/new`, композер не пустеет. На странице висит `Use caution before running this prompt. Malicious conversation content could trick Claude…` — вендорская защита от вставленного извне текста. ⇒ Считать рельсу требующей человека; больше двух попыток Send не жечь. Побочно: **длинная вставка в claude.ai превращается в вложение `PASTED`**, и каждая попытка каскада плодит ЕЩЁ ОДНО (получил 4 дубля); чистятся программным кликом по `button[aria-label^="Remove Pasted text"]`, текст в композере при этом целый — `ctrl+a`+`Delete` карточки НЕ убирает.
- 5. **🔧 ПОЧИНЕН КОРЕНЬ `dr_ff_collect.py`:** жёсткий потолок стоял на `signal.SIGALRM`, которого **на Windows нет** → `exit 4` на первой секунде, то есть половина конвейера «забрать готовый отчёт» не работала НИ НА ОДНОМ Windows-узле с 03.09, а выглядело как «вендор не отдал отчёт». Теперь единый вход `_alarm()` (POSIX → `signal.alarm`, Windows → `threading.Timer` + `_thread.interrupt_main`); тест `_test_dr_ff_collect_alarm.py`, красный на старой версии показан. Посылка `dr-ff-collect-win-alarm-[id]` подписана и разослана на 6 узлов.
- ## ⭐ ПОЛЕ 22.09.2026 ([машина флота], веер из 5 заказов по найму) — две грабли на вызове рельс
+ <!--kit-footer-->
- 1. **`dr_ff_rail.py` НЕ ПРИНИМАЕТ DR-ID позиционно** — только `--prompt-file` и `--out`. Заход сгорел на `dr_ff_rail.py --rail glm <ID>` → `error: unrecognized arguments`. Рабочая форма:
- `python dr_ff_rail.py --rail glm --profile-dir "<профиль>" --deep --prompt-file "<очередь>\<ID>.md" --out "<очередь>\<ID>\results\glm.md"`
- (файл заказа лежит в `<волт>\[шина]\_dr\queue\<ID>.md`, рядом одноимённая папка под результаты).
- 2. **На этом узле обе двери Firefox закрыты одновременно, и это не лечится флагом.** `ff_session_probe` показал: живые сессии только в ЧЕЛОВЕЧЕСКОМ профиле `m26xxxkf.anton-clean`, а робот-профиль `ff-autoff-profile` пуст у всех вендоров (mistral вообще «НЕТ»). Рельса честно отбивает: «человеческий профиль с живой сессией: копия разлогинит Антона, in-place отравит user.js». ⇒ Пока робот-профиль не залогинен руками Антона (Tier-2, пароли вводит человек), **GLM и Mistral с этого узла безлюдно не едут** — это «требует рук», а не «вендор мёртв» ([[dead-verdict-expires]]).
- 3. ⚠️ Рабочий обход на 22.09 = **headless CLI grok+gemini** через `dr_headless_dispatch.py <ID...> --rails grok,gemini`; ноги ChatGPT и Claude по приказу 22.09 идут только вебом.
+ ---
- 4. **⛔ GLM В CHROME: РАБОТАЕТ ТОЛЬКО АКТИВНАЯ ВКЛАДКА.** В фоновой вкладке (созданной через tabs_create) клики по глобусу НЕ доходят вообще: `data-active` остаётся `false`, меню не открывается, а скриншот показывает нормальный layout — выглядит как «сломанная вёрстка», а на деле заморожен layout фоновой вкладки. В АКТИВНОЙ вкладке тот же клик срабатывает с первого раза. ⇒ много заказов гоним ПОСЛЕДОВАТЕЛЬНО в одной вкладке через «New Chat», а не веером по вкладкам.
- Две эпохи UI чередуются в одной сессии (подтверждён замер 08.09): иногда клик по глобусу сразу даёт `true`, иногда открывает меню с тумблером (координата ~(700,345) при viewport 1568x670). Суди ТОЛЬКО по `data-active` после каждого клика.
- ⚠️ Клик по `ref` из read_page по тумблеру `[role=switch]` НЕ переключает его — работает только координатный клик.
- ⚠️ Программный `#send-message-button.click()` срабатывает не всегда; надёжнее координатный клик по стрелке (~(1284,530)). После отправки текст может ОСТАТЬСЯ в textarea как черновик — это НЕ признак неотправки: суди по смене URL на `/c/<id>` и по наличию промпта в теле страницы; черновик после этого чистить, иначе улетит дублем.
- 5. **⛔ GLM ОТКАЗЫВАЕТ ПО ПЕРЕГРУЗКЕ И ПРЕДЛАГАЕТ FLASH — НЕ СОГЛАШАТЬСЯ.** Замер 22.09: на четвёртом заказе подряд вместо ответа пришло «GLM-5.3 is intensifying the coordination of resources, please switch to GLM-5.3-Flash for experience or try again later» с кнопками Cancel / Switch. Согласиться = тихий брак (Flash вместо флагмана, тот же класс, что Grok в Expert). Рельса идёт в `missing` с причиной «перегрузка вендора». ⇒ Потолок GLM на один заход — примерно ТРИ тяжёлых заказа подряд.
- ## Ошибки/грабли (не вошедшее в автомат)
- - ⚠️ **Фоновая/свёрнутая вкладка Chrome (проверено 2026-07-17):** viewport 0×0, layout заморожен → синтетические JS-клики и Radix/Angular-кнопки (Gemini «Start research», ChatGPT «+»-меню) НЕ срабатывают, а `computer` кликает мимо. Лечение: `tabs_create_mcp` → новая вкладка (получает layout даже в фоновом окне) → открыть тот же URL разговора → `find` → `computer left_click ref` (CDP-trusted). Промпт при этом уже отправлен — теряется только «дожать кнопку», не квота.
- - ⭐ **«started» в леджере ≠ реально запущено (инцидент HUB-06, 16→17.07):** три вендора помечены started, по факту работал ОДИН. Gemini висел на непрожатой кнопке «Start research» (страница = только промпт, panel=0), Grok вообще не отправлен (path остался `/`, промпт в композере). Потеряна ночь. → **probe-after-start обязателен и доказателен:** path сменился на /chat/ · виден индикатор прогресса · объём страницы вырос. Вставка ≠ отправка; отправка ≠ старт. Состояние `submitted` без подтверждённого `started` = не started.
- - ⭐ **ChatGPT DR останавливается на research-плане (проверено 2026-07-20, ZB-02):** первый ран (~12 мин, «0 citations · 0 searches») может выдать ТОЛЬКО research-план + output-structure, БЕЗ настоящего ресёрча, и завершиться (`finished_successfully`, end_turn). Это НЕ баг вставки/старта — ран реально шёл, но выродился в план. Лечение: follow-up в тот же чат «Proceed now: execute this plan and write the FULL final report… Do not stop at the plan» → второй ран (у нас 65 мин) даёт полный отчёт с живыми URL. При сборе: если backend-JSON longest-part начинается с «Research Plan:» и в mapping только один widget с планом — это план, не отчёт; пнуть, не сохранять как collected. (Gemini/Grok этим не страдают — план у Gemini отдельная фаза с кнопкой.)
- - ⚠️ **Плашка DR-режима ChatGPT живёт ВНУТРИ редактора (ZB-02, 20.07):** каскад `paste_verify` (directSet/execCommand) чистит редактор и СТИРАЕТ чип «Deep research» → probe покажет `chip:false`. Порядок: сначала вставить промпт, ПОТОМ включить Deep research поверх (меню «+» → Deep research), затем сверить чип и Send. Иначе улетит обычный чат, квота DR цела но ответ не тот.
- - ✅ **Grok, зеркало textarea/contenteditable — КОРЕНЬ найден и вылечен (FLEE-03, 17.07):** Grok 4.5 = TipTap/ProseMirror contenteditable (`div.tiptap.ProseMirror`); видимый `<textarea>` — СКРЫТОЕ зеркало. Заполнение textarea (nativeSetter/value+InputEvent) даёт `ok:true`, но React/PM-состояние из зеркала не обновляется → Submit не рендерится, Enter=no-op (ровно это жгло время 07-10 и 07-17). **Фикс в каскаде:** целить `.tiptap.ProseMirror` ПЕРВЫМ + синтетический paste-event (`ClipboardEvent('paste',{clipboardData:DataTransfer})`) → PM адоптит текст → `button[type="submit"]` появляется enabled → клик. Проверено вживую 17.07 (FLEE-03 Grok `/c/e621f761`). Если UI снова уплывёт и paste-event не сработает → новый чат + probe, не жечь время.
- - ⭐ **«ChatGPT DR молча не ищет» — симптом реален, диагноз был ложный (заведено 26.07, вскрыто 04.08).** Счётчик «Research completed in Xm · 0 citations · 0 searches» — сломанная телеметрия connector-DR, а не отчёт о поиске: он одинаково нулевой у прогонов с 40–106 цитатами. Что делать при виде нуля: (1) НЕ объявлять канал `dead` по счётчику — открыть backend `widget_state.report_message.metadata.citations` (`resolved_model_slug` рядом); (2) не гнать «усиленный» повтор — усиливать нечего, вендор искал; (3) реальная слабость канала = `deep-research-mini` + обрыв посреди плана → ChatGPT ведём через Pro + Web search (замер: 73 запроса / 31 страница против 12 URL у mini). Правило «два `dead` подряд = не гнать третий раз тем же способом» остаётся, но `dead` теперь ставится по цитатам, не по счётчику. Урок шире DR: индикатор, по которому мы объявляем что-то мёртвым, сам обязан быть проверен — [[prichina-kak-claim]].
- - ⭐ **Корневой композер `chatgpt.com/` — общий на аккаунт и его рвут параллельные сессии (26.07.2026).** Черновик синкается между сессиями: за один прогон там побывали чужие `ZB-05` и `ZB-06`, мои вставки соседняя сессия откатывала своим React-состоянием, а один раз моя строка успела прилипнуть в хвост ЧУЖОГО промпта (вычистить не удалось — правки не держались). ⛔ Правило: при работе в параллель **не трогать корневой композер**; вести прогон внутри СВОЕГО `/c/<id>` (композер пер-чатовый, не оспаривается), новый чат создавать только когда корневой пуст. Перед вставкой всегда читать композер: непустой + чужой ID = стоп, а не «перезапишу».
- - Разлогин посреди ресёрча → отчёт может потеряться: после логина проверить историю чатов вендора, DR обычно сохраняется в истории.
- - Длинный отчёт обрезается в get_page_text → прокрутить/раскрыть («Show more») перед чтением; сверить конец текста с концом отчёта.
- - ⛔ Никогда не заводить ПЛАТНЫЙ API-путь как «фолбэк» без согласования ([[prefer-included-limits-before-paid-api]]).
- - Один и тот же промпт всем вендорам ДОСЛОВНО, кроме намеренного платформенного блока §2/§3/§4 (иначе консенсус грязный).
- - ⚠️ **Аккаунт может флагнуть автоматизацию:** на прогоне FLEE-01 ChatGPT показал баннер «Suspicious activity detected» при старте DR из автоматизации (НЕ заблокировал, ресёрч пошёл). Это ровно тот failure-mode, что предсказали оба DR-вендора. Увидел баннер → не паниковать и не долбить ретраями; отметить в леджере, продолжать. Повторяется системно → `drift_suspected`, доложить Антону.
- - ⚠️ **Session longevity никто не публикует** (консенсус DR) → forced re-auth считать НЕИЗБЕЖНЫМ, не строить на таймере. `needs_reauth` = первоклассное состояние + пинг человеку out-of-band (02/QQQ).
- - ⏳ **Полностью безлюдный ЗАПУСК** — следующий шаг стройки (архитектура известна из DR: ledger-FSM + выделенный Firefox-профиль + cron/systemd; старт с ChatGPT+Gemini). Пока безлюден только СБОР (ночной `dr_collect.py`); запуск требует живой сессии с браузером. Дыра осознана, закрывается после решения Антона по «дежурной браузер-сессии на хабе».
+ **Like this skill?** It is one of 100 in [second-brain-starter-kit](https://github.com/tonydzi/second-brain-starter-kit): the second brain we built for ourselves and run every day at Palo Alto AI Research Lab. Install the whole set with `npx skills add tonydzi/second-brain-starter-kit`. Everything is open source and free, so take what you need.
- ## /tt — как проверить v2 (после прихода FLEE-01 или при правке)
- Не гонять живой DR ради теста (жжёт квоту). Проверять по частям: (1) probe-логика — на уже открытой вкладке проверить, что детект режима+длины работает БЕЗ Send; (2) извлечение — на УЖЕ собранном прошлом DR (backend JSON / innerText) прогнать парсер, сверить с сохранённым `_originals`; (3) леджер+dr_collect — прогнать на существующем DR-ID. Живой end-to-end — только когда реально нужен ресёрч.
+ Flagships worth a look on their own: [secondop-panel](https://github.com/tonydzi/secondop-panel) (a second opinion from a panel of external models), [claude-memory-tidy](https://github.com/tonydzi/claude-memory-tidy) (stop your agent's memory from rotting), [telegram-mcp-kit](https://github.com/tonydzi/telegram-mcp-kit) (your own Telegram over MCP in about 15 minutes).
+ Author: **Anton Dziatkovskii**, Palo Alto AI Research Lab. Telegram [@tonydzi](https://t.me/tonydzi) - WhatsApp [+1 341 222 9178](https://wa.me/13412229178) - X [@Tony_Stef_](https://x.com/Tony_Stef_)
- ## ⭐ Поправка 23.09.2026 — забор отчётов из живого Chrome-MCP (замер DR26-09-23-ZB-02-1231, ZBOOKG8, 4/6 собрано)
- 1. **ChatGPT Deep Research (Pro, High) теперь отдаёт отчёт в «Deep Research App»**, а не в чат: чат показывает только «Deep Research has started working…», карточка живёт на `chatgpt.com/deep-research`, `my/recent/deep_research_reports` даёт `backing_conversation_id`, но `/backend-api/conversation/<backing>` = 404 `conversation_deleted`, виджет = cross-origin iframe (`web-sandbox.oaiusercontent.com`), текст из него не читается. **Дверь**: в ТОМ ЖЕ чате попросить «Please paste the complete final Deep Research report verbatim» → модель печатает отчёт целиком в чат (18 мин ран, 53 цитаты → 67 КБ текста), забирать `get_page_text`. `get_page_text` режет на 50 000 знаков: срезать уже прочитанные узлы (`[data-message-author-role]`, дети `.markdown`) через JS и читать хвост вторым вызовом. Ссылки-цитаты в теле теряются, список источников в конце остаётся.
- 2. **Скрытая вкладка Chrome-MCP (viewport 0×0 / `visibilityState=hidden`)**: `computer.type`/`Return` теряются, screenshot падает по CDP-таймауту, DOM не обновляется при стриме. Вставка = `execCommand('insertText')` в ProseMirror + клик `button[aria-label="Send prompt"]` через JS; прогресс читать через `/backend-api/conversation/<id>` с bearer из `/api/auth/session` (в JS страницы, токен наружу не выносить). `javascript_tool` режет вывод ~1 000 знаков и блокирует текст с query-string — большие тексты только через `get_page_text`.
- 3. **Mistral Vibe deep-research** (`chat.mistral.ai/work?skill=deep-research`, режим Work): ответ приходит канвасом «Edited a canvas», весь текст виден в `get_page_text` (~49 КБ), ~40 компаний/47 источников за ~10 мин — полноценная нога.
- 4. **GLM в скрытой вкладке**: ответ может сорваться молча (`/api/v1/chats/<id>`: assistant content len 0, Stop-кнопки нет); переотправка через `textarea#chat-input` + `form.requestSubmit()` из скрытой вкладки НЕ уходит — нужна живая вкладка или `dr_ff_rail`. **Gemini Deep Research** второй раз за день не вышел из «Starting research…» (>2 ч) — ногой не считать до появления текста, добирает `dr_latecomer_sweep`.
+ **Engineers: want to test-drive this setup?** Message me. I hand out free starter seeds to engineers who test and report back, and custom skill requests are welcome.