decision-2026-07-16-browser-automation-layer.md (DR26-07-16-HUB-01)navigator.webdriver=true, то есть мы выглядим роботом сильнее, чем сейчас, когда я работаю в твоей живой вкладке Chrome. Для бан-чувствительных площадок (Grok, FB, X) Firefox-автоматизация — шаг назад по риску, а не вперёд. Мы это уже решали 16.07 и решили верно: гибрид, а не «всё на Firefox».
proposed. Прошло 13 дней. На трёх проверенных узлах работающего Firefox-пути нет ни одного: профили пустые, selenium не стоит, на Маяке нет самого браузера. То есть мы 13 дней живём на Chrome и думаем, что переехали. Это ровно класс vault-note-is-selfreport-not-evidence.
SMOKE=PASS на хабе, Mac16 и Маяке| Что сделал | Узел | Доказательство |
|---|---|---|
| Поставил Firefox (tarball Mozilla в хоум, не snap — snap-confinement ломает headless-профили) | Маяк | 153.0.1 + headless-скриншот 19 872 б |
Поставил geckodriver + закрепил firefox/geckodriver в /usr/local/bin, чтобы рутины не помнили про PATH | Маяк | 0.37.1, which отвечает |
venv ~/.venv-browser + selenium (обошёл PEP 668, системный pip запрещён) | Маяк | selenium 4.46.0 |
| Поставил selenium | Mac16 | 4.46.0 — версия сошлась с хабом |
Научил хелпер искать Firefox в ~/opt/firefox и /opt/firefox (без этого Linux-узел не находил браузер) | все | md5 d43995e6 совпал на 3 узлах |
Прогнал --smoke | хаб · Mac16 · Маяк | PASS ×3 FF 152.0.6 / 152.0.6 / 153.0.1 |
| Боевая проверка на реальной JS-странице (не data:-URL) | Маяк | 3 186 символов, JS-виджеты отрендерились, сессия анонимна |
Попробовал разблокировать хаб без рук Антона — клонировал его системный FF-профиль в google-main | хаб | ПРОВАЛ, честно — см. ниже |
| /tt со сторонними глазами: Codex сломал мою правку по трём пунктам — все три оказались реальны, все три починены | — | VERIFY + регресс _test_firefox_selenium.py, 7 проверок, PASS ×3 узла |
Поймал и починил чужую мину: Firefox 153 запретил data:-URL через WebDriver — на этом стоял наш smoke-тест | Маяк | forever-fix — тест переведён на локальный file://, PASS ×3, md5 bf33bfd1 |
1. Codex (внешний ломатель) нашёл три дыры в локаторе браузера: проверка была на exists(), поэтому директория с именем firefox и файл без бита +x проходили как годные — выигрывали выбор и роняли запуск вместо перехода к следующему кандидату. Хуже: writable-хоум ~/opt/firefox стоял перед root-owned путями, то есть любой файл, положенный туда, молча перехватывал бы запуск браузера. Починено: is_file() + os.access(X_OK), порядок «системные → /opt → хоум → snap последним», кривой STOCK_FIREFOX теперь кричит, а не уходит в тихий автопоиск.
2. Firefox 153 убил наш smoke-тест — и это была не моя правка. Тест проверял управление через data:text/html,...; в 153 Marionette запретил такую навигацию («not allowed in this context»). На хабе и Mac16 (FF 152) тест проходил, на Маяке (FF 153) упал. Соблазн был откатить хорошую правку — вместо этого проверил, какой бинарь резолвится до и после: один и тот же, значит правка ни при чём. Forever-fix: тест больше не стоит на том, что вендор вправе закрутить, а пишет временный file://-документ.
Побочная польза: разные версии Firefox на узлах (152 vs 153) работают как бесплатная канарейка — то, что упало на одном, придёт на остальные с ближайшим апдейтом.
646yqiss.default-release → D:\AutomationBrowsers\Firefox\google-main. Формально всё выглядело отлично: 63 куки, из них 46 Google, включая все критичные сессионные (SID, LSID, __Secure-1PSIDTS, __Secure-3PSID, __Host-GAPS, OSID, HSID, SSID), плюс 7 ChatGPT и 8 Facebook.
Но проверка делом, а не наличием файла, дала:
Google → redirect на accounts.google.com/signin/accountchooser ⇒ ANONYMOUS ChatGPT → /api/auth/session вернул пустой объект (email: None) ⇒ ANONYMOUS
Почему: Антон Firefox-ом на хабе не пользуется — последняя запись в его профиле 20.07, живые сессии лежат в Chrome. Мы скопировали не сессию, а её труп.
Что это значит: «профиль с 46 Google-куками» и «рабочая сессия» — разные вещи. Обхода нет. Ручной логин в Firefox — неустранимый блокер, и именно он, а не забывчивость, держит Firefox-first на месте 13 дней.
proposed, потому что упиралось в руки человека| Узел | Firefox | Headless | selenium / gecko | Профили автоматизации | Живые куки |
|---|---|---|---|---|---|
| Хаб A-2022BAYAREA Win11, резидентный IP, always-on |
152.0.6 | не гонял | selenium 4.46.0 | D:\AutomationBrowsers\Firefox\ → google-main, meta-main, telegram-main, x-mainвсе 4 ПУСТЫЕ cookies.sqlite отсутствует в каждом |
только системный профиль Антона 646yqiss.default-release — 524 KB, последняя запись 20.07 |
| Mac16 MacBook-Anton macOS, эта машина |
152.0.6 | ДОКАЗАН скриншот example.com снят сегодня | selenium НЕТ geckodriver НЕТ playwright есть |
нет ни одного выделенного | 0 кук профиль default-release, mtime 16.07 |
| Маяк FLEET-ANCHOR Ubuntu VPS, дата-центр IP |
НЕ УСТАНОВЛЕН | — | нет ни того, ни другого playwright тоже нет | нет ~/.mozilla вообще |
— есть /usr/bin/google-chrome |
| HP17-ZBook · Mac Русланы · машина Наташи | НЕ ПРОВЕРЕНО — по ssh отсюда недостижимы (в конфиге только hub и mayak). Заказ замера идёт по шине. |
||||
| # | Причина | Механика | Уверенность |
|---|---|---|---|
| 1 | Куки лежат открыто | cookies.sqlite, таблица moz_cookies — обычный SQLite. Извлечение = один SELECT. У Chrome 127+ база под App-Bound Encryption: ключ привязан к процессу браузера через привилегированный COM-сервис, внешний Python получает «Could not decrypt». | established 3/3 DR + наша ручная проверка |
| 2 | Firefox не реализует DBSC | Device-Bound Session Credentials: GA в Chrome 146 (10.04.2026), по умолчанию для всех Google-аккаунтов, выключателя в админке нет. Сессия привязана к TPM машины — даже вытащенная кука мертва без железной подписи. Сессия, залогиненная в Firefox, device-bound не становится. | established проверено живьём: 44 валидные Google-куки из FF-профиля |
| 3 | Выделенные профили — штатный, документированный путь | geckodriver официально поддерживает подготовленные профили (-profile). Chrome 136+ наоборот перестал слушать --remote-debugging-port для дефолтного профиля — автоматизация профиля владельца запрещена самим вендором. | established |
| 4 | Обход ABE есть, но это малварь | Process hollowing / COM-инъекция (xaitax и подобные). Ловит EDR/Defender, ломается с каждым апдейтом Chrome, неремонтопригодно нетехническим владельцем. Как стандарт — не рассматриваем даже теоретически. | established по риску |
| 5 | Один профиль на сервис вместо мега-профиля | Папка на диске = один логин-контекст (google-main / meta-main / x-main / telegram-main). Разводит разом: конфликт profile-lock (GUI и скрипт не делят профиль), изоляцию личного от автоматизации, и «сдохла одна сессия — не упало всё». | established |
Headless-режим у Firefox нативный, флаг --headless, отдельного «Firefox Headless» ставить не надо. Прогнал на Mac16 прямо сейчас:
/Applications/Firefox.app/Contents/MacOS/firefox --headless \
--screenshot ff_test.png https://example.com
→ ff_test.png, 18 803 байта ✅ HEADLESS_FIREFOX_OK
Два способа им управлять, и разница между ними важна:
Наш выбранный путь. ~/.claude/scripts/_shared/firefox_selenium.py уже написан и /tt-протестирован: --setup (один раз залогиниться руками) → --autoff (дальше headless без человека) → --smoke.
Внутри уже прошиты грабли, которые стоили крови: -no-remote (иначе запуск «украдут» уже открытые окна Антона), DoH-off, системный прокси, отдельный профиль.
Ставится одной командой: pip install selenium — geckodriver Selenium Manager качает сам.
На хабе физически не запускается: spawn UNKNOWN / SxS «mozglue v1.0.0.0 not found». Полная перекачка не помогла → уровень ОС, не битый файл. Проверено детерминированно, три гипотезы (AppLocker, битый манифест, EDR) отметены поимённо.
Причина не чинится из user-space. Именно поэтому основной путь — стоковый Firefox через geckodriver, а не бандл Playwright.
| Узел | Браузер | Что на нём делаем | Почему |
|---|---|---|---|
| Хаб Win11, always-on |
Firefox headless — основной дом | Безлюдные прогоны с нашими залогиненными аккаунтами: забор отчётов Gemini, экспорт кук для API-клиентов (notebooklm), keepalive сессий, всё ночное по расписанию. | Резидентный IP — главный аргумент, сильнее любого железа. Резкая смена IP/ASN мгновенно рвёт сессии Meta/X. Плюс always-on и уже стоящий selenium 4.46. |
| Маяк Ubuntu VPS |
Firefox headless — только анонимный | Публичный веб без логина: рендер JS-страниц для радаров, проверка живости наших публичных страниц, скриншоты, HTML→текст там, где curl не хватает. |
⛔ Наши залогиненные аккаунты сюда не носим. IP дата-центра — красная тряпка для anti-bot, а прилетит по нашим премиум-подпискам. Ставить FF на Маяк стоит, но под другую работу. |
| Mac16 / ноут живой интерактив |
Живой Chrome-MCP + Firefox ситуативно | Всё, где я работаю «как человек в реальном сеансе»: fb-post, x-post, Grok, логины. | Это осознанный anti-ban выбор, а не наследие. Здесь Firefox-автоматизация дала бы больше риска бана, не меньше. |
| Грабля | Firefox? | Разбор |
|---|---|---|
| Chrome ABE — куки не расшифровать снаружи rookiepy / browser_cookie3 → «Could not decrypt» |
ЛЕЧИТ | Родная зона Firefox. Открытый SQLite → один SELECT. Ровно так спасли notebooklm-py 16.07. |
| DBSC — сессия привязана к TPM | ЛЕЧИТ | Firefox DBSC не реализует → сессии, созданные в нём, остаются переносимыми. |
| Bearer ChatGPT дохнет каждые 5–9 дней L2-эскалация: «зайди Chrome-ом в /api/auth/session и достань токен» |
ЛЕЧИТ | Самый недооценённый выигрыш. Сегодня, когда session cookie умирает, token_heal.py зовёт живого человека или сессию с Chrome. С залогиненным Firefox-профилем эту петлю можно замкнуть насухо: сессия читается с диска, bearer перевыпускается сам. Ночной синк ChatGPT перестаёт зависеть от рук. |
| Забор отчётов Gemini / Grok DR26-07-14 висит несобранным с 21.07 |
ЛЕЧИТ частично | Забор = чтение, самый низкий ToS-риск и самая частая потеря. Кандидат №1 на безлюдный Firefox по расписанию. У ChatGPT забор уже безбраузерный (bearer-рельса) — там Firefox не нужен. |
| Буфер обмена — общий на машину 28.07: параллельная сессия трижды подменила текст в композере |
ЛЕЧИТ | Selenium/Playwright подают текст в поле своим кодом, минуя системный буфер. Класс ошибки исчезает по построению, а не по бдительности. |
| Chrome 136+ запретил автоматизацию дефолтного профиля | ЛЕЧИТ | У Firefox выделенный профиль — штатный документированный путь, а не обход. |
| Профиль занят: GUI и скрипт дерутся 14 живых окон Антона «крадут» запуск |
ЛЕЧИТ ценой дисциплины | Решается -no-remote + отдельный профиль (уже прошито в хелпере). Но правило «один профиль = одно использование» придётся соблюдать всегда. |
| Composer не принимает текст ProseMirror/TipTap: textarea — скрытое зеркало, даёт ложный успех |
НЕ ЛЕЧИТ | Это про фронтенд вендора, а не про браузер. Наш каскад paste_verify.js нужен одинаково в любом движке. |
| Composer FB заблокирован харнесом ФА не уходит в Messenger, текст отдаём Антону в руки |
ОБХОДИТ, но ценой | Selenium к харнесу не привязан — блок физически исчезает. НО: FB бан-чувствителен + IP-sensitive, а navigator.webdriver=true нас палит. Обмен «удобство сейчас ↔ риск аккаунта» — твоё решение, не моё. |
| computer-use: браузеры в read-tier клики и ввод заблокированы |
НЕ ЛЕЧИТ | Тир назначается по категории приложения. Firefox — такой же браузер, получит тот же read-tier. |
| Пароль символами не набрать (запрет харнеса) | НЕ ЛЕЧИТ | Ограничение моё, не браузерное. Сегодня спасает автозаполнение Chrome. У выделенного Firefox-профиля своё хранилище паролей — при переезде туда логины придётся заводить заново, руками, один раз на профиль. Это цена, а не бонус. |
| Anti-bot / риск бана | ДЕЛАЕТ ХУЖЕ | navigator.webdriver=true в Marionette. Живая вкладка Chrome с расширением такого флага не поднимает. Для Grok (AUP xAI прямо запрещает автоматизацию, 52k банов в 2026) — Firefox-робот строго противопоказан. |
| Сессии Google протухают раз в 1–4 недели | НЕ ЛЕЧИТ | Так у всех браузеров. Лечится не таймером, а детектом auth-ошибки и просьбой к человеку. |
Тихо не доехавшая загрузкаa.click() вернулся успехом, файла нет — 5 из 5 |
НЕ ЛЕЧИТ | Лечится проверкой факта на диске после каждой загрузки, в любом браузере. |
SMOKE=PASS.SMOKE=PASS, профиль google-main создан и ждёт ровно одного действия.Я не могу ввести пароль в поле — это жёсткий запрет, не каприз харнеса. А клон профиля, как выяснилось выше, не работает. Значит одноразовый ручной логин неизбежен. Две двери на выбор:
Дверь А — Mac16, ты прямо за этой машиной, 2 минуты:
/Users/anton/.brain-venv/bin/python \ ~/.claude/scripts/_shared/firefox_selenium.py --setup
Откроется Firefox с выделенным профилем AutoFF → залогинься в Google (dzyatkovskiy.a@) и ChatGPT (dzyatkovskiy.a2@) → закрой окно. Всё, узел рабочий.
Дверь Б — хаб, когда доберёшься до него (там резидентный IP, это главный дом):
python %USERPROFILE%\.claude\scripts\_shared\firefox_selenium.py ^ --setup --profile D:\AutomationBrowsers\Firefox\google-main
Куки Mac16 на хаб перенести нельзя — разные IP/ASN рвут сессии. Каждый узел логинится у себя.
proposed — за 13 дней не переведено в принятое.02-Decisions/decision-2026-07-16-browser-automation-layer.md (DR26-07-16-HUB-01, консенсус 3/3) · insight-DR-DR26-07-16-HUB-04 · insight-DR-DR26-07-17-HUB-03 · скилл /dr-fanout п.1–9 · _drafts/EPISODE-firefox-cookie-lockout-2026-07-16.md.