Снято живьём вместе с владельцем в кабинете sasha261185, кампания 713051718.
Ничего не сохранялось и не создавалось: до и после — те же 15 объявлений,
кнопки «Сохранить изменения» и «Создать» не нажимались.
Ключевое для задачи 14: системное окно выбора файла роботу не нужно —
в форме есть input type=file с data-testid CreativeActionsMenu.FileInput,
принимает png/jpeg/gif и сразу несколько файлов. Весь путь до окна загрузки
проверен программным прогоном, окно открылось.
Подтверждено живьём: конструктор креативов закрыт, Яндекс пишет это сам;
у всех 15 креативов имя «Новый креатив», потому что поле имени одно на всю
загрузку — опознание по разнице слепков и размеру остаётся единственным
надёжным способом.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Живая проверка боевого кабинета опровергла допущение, на котором стояла Часть C и
часть уже написанного ядра. Конструктор креативов Яндекса закрыт 01.06.2026 —
Яндекс пишет об этом сам плашкой в редакторе объявления, показы его креативов
остановлены с 30.06. Адаптивного креатива из одной картинки не существует: медийная
кампания устроена как объявление на каждый размер блока со своим креативом, что
подтверждает наша живая кампания прогрева из 15 объявлений.
Отдельно проверен read-only запрос creatives.get с боевым токеном: метод отдаёт наши
баннеры, тип у них HTML5_CREATIVE, имя у всех одинаковое «Новый креатив» — опознавать
по имени нельзя, — и приходит PreviewUrl, годный для показа клиенту.
Отсюда дизайн: робот становится грузчиком готовых файлов, а не оформителем креатива.
Номера портал берёт сам через creatives.get слепком «до и после» с сопоставлением по
ширине и высоте. Ядро переходит с одного креатива на кампанию на креатив у каждого
баннера. Решения владельца: файлы готовит клиент, робот сам опрашивает портал, живёт
на боевом сервере, вход заводится через экран и удалённый рабочий стол на localhost.
Дописаны три вещи, не проговорённые в обсуждении: правило частичной модерации —
кампания работает, если принято хотя бы одно объявление, разморозка только когда
отклонены все; минимум один файл и не более одного на размер; раздел честно
неизвестного вместо выдуманных ответов.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Проверка живьём на восьми статусах рекламных кампаний: зелёный и жёлтый уже
были закрыты слоем правок от 14.05.2026 и дают 6.06 и 6.37 — прежнее
предположение, что они не проходят, оказалось неверным. Тот слой закрыл только
два цвета из четырёх: info давал 3.63 и error 4.31 при норме WCAG 2.1 AA 4.5.
Дописаны в тот же слой, той же глубины: info #2e5a6d даёт 5.87, error #952c2c
даёт 5.98. Подложка чипа берёт цвет из color-пропа и не меняется — темнеет
только текст, вид почти прежний. Задеты статусы «Готова к запуску»,
«Отклонено», «Остановлено (нет денег)» и все тональные чипы портала.
Заодно вторая копия карты статусов в CampaignReportDialog оставалась на обычном
grey (2.42) — приведена к grey-darken-2, как в списке кампаний.
Мерил на живой странице по .v-chip__content с учётом подложки, а не по токену
темы — прежняя ошибка была именно в этом.
Проверено: рекламные фронт-тесты 17/17; Pa11y по всем 24 адресам — 20 из 24 как
и до правки, регрессий нет, рекламные и все админские экраны дают 0 ошибок.
Боевого не касается, в main не влито.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Брендовые success и warning нечитаемы текстом: success даёт 4.25:1 на белой
карточке и 3.83:1 на ивори, warning — 2.25 и 2.03 при норме WCAG 2.1 AA 4.5:1.
Сами цвета не тронуты — остаются для заливок, иконок и рамок. Рядом добавлены
затемнённые текстовые двойники success-strong #256F46 и warning-strong #8A6410,
тон сохранён.
Все 15 мест text-success и 8 мест text-warning переведены на новые классы —
13 файлов: командный центр, биллинг и инциденты админки, система, тенанты,
интеграция с поставщиком, карточка тенанта, диалог баланса, рекламный
админ-экран, мастер рекламной кампании, массовые диалоги дней и регионов,
реквизиты в настройках.
Проверено: фронт 226 файлов / 1663 теста зелёные; Pa11y по всем 24 адресам —
рекламные и ВСЕ админские экраны дают 0 ошибок. Побочно вскрылось 12 старых
недочётов на клиентских экранах — записаны в находку, к этой правке отношения
не имеют.
Боевого не касается, в main не влито.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Pa11y: в конфиг добавлены три рекламных экрана — клиентский Яндекс,
рекламный кошелёк и админский расход/маржа.
- Чипы статусов «Черновик» и «На паузе» были на обычном grey — контраст
2.42:1 при норме WCAG 2.1 AA 4.5:1. Заменены на grey-darken-2, после
чего оба клиентских рекламных экрана дают 0 ошибок.
- CampaignLauncherTest коммитил кампании в статусе pending_moderation
с сегментом и сотней телефонов и не откатывал их. При полном прогоне
SyncCampaignAudienceJob перечисляет кампании всех тенантов через
pgsql_supplier и подхватывал эти хвосты — SyncCampaignAudienceJobTest
падал на «ни одного обращения к Яндексу». Добавлен DatabaseTransactions.
Замер: раньше после прогона папки оставалось 2 живых кампании, теперь 0.
Полный прогон: было 5 падений, стало 3 — оба рекламных ушли.
- Находка про контраст палитры портала вынесена отдельным документом:
зелёный 4.25 и жёлтый 2.25 на белом не проходят AA, но это брендбук
и уже на бою — решение за владельцем.
Реклама 156/156. Боевого не касается, в main не влито.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- config yandex_direct.spend_limit_guard_multiplier — бэкстоп от перерасхода, не клиентская цена
- миграция ad_campaigns.yandex_creative_id nullable + точечный GRANT UPDATE админ-роли с гардом
- модель AdCampaign: yandex_creative_id в fillable и casts integer
- тесты: config-набор и миграция зелёные, реклама-набор не сломан
- CHANGELOG схемы v9.01; план Части 4 и findings контракта медийного API Директа
Часть B «мотор» ещё впереди: медийные методы клиента, переписанный запускатор, контроллер.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ф0-разведка (находки F0-9…F0-24 + 9 скриншотов), дизайн-спека
и пошаговый план (21 задача, 3 очереди) по UX-правкам рекламного
Яндекс-блока портала. Реализация — в этой ветке от main.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docs(golos): мини-прогон трёх сценариев на сервере + первый суд
Карта судьи по 3 разговорам: доля речи 75-82% при норме 35-45, за 4 реплики один
довод из 13, выдумки ушей в каждом разговоре.
🔴 Записаны слепые пятна судьи — то, что глаз увидел, а он нет: самопротиворечие
внутри реплики, разворот ниши не сработал (замок «подтвердить дважды» слишком строг —
клиент называет сферу ОДИН раз), признание клиенту «база у нас перепуталась».
🔴 Механическая находка: клиент спросил про гарантии, уши съели слово «гарантии» —
маршрут по словам не сработал, и дешёвая модель полезла рассуждать о законе
(«отвечать будете вы», «согласие на обработку данных»). Съеденное ухом ключевое
слово ломает маршрутизацию — это дефект схемы, а не промпта.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
Три агента перечитали официальную документацию Яндекса, ВК и МТС.
Итог: Perplexity дал минимум 4 неверных факта, каждый пойман только
чтением первоисточника.
Исправлено:
- площадок ТРИ, не четыре: myTarget мёртв, вся дока 301 → ads.vk.ru
- ВК: два порога — 100 руками, 2000 через API (мы автоматизируем ⇒ 2000);
создание не более 1 списка в час
- МТС: 0,48 руб/показ по прайсу от 01.06.2026, а не 0,9 (цена 2024 года);
показывает ТОЛЬКО не-абонентам МТС ⇒ канал B3 через Telegram недостижим
- квоты Аудиторий: 5000 запросов в СУТКИ на логин, а не 100 в секунду
- медийка: от 300 руб/день, порога 35 000 не существует
- PUT /segment/{id} меняет только название; данные — modify_data
с режимами addition/subtraction/replace
- автотаргетинг на Поиске отключить нельзя (но и не надо — сегмент режет
через «И», автотаргетинг задаёт лишь набор запросов)
- look-alike выключается конкретной радиокнопкой «Только выбранный сегмент»
Новое:
- фича универсальная: клиент жмёт кнопку, Лидерра — такой же клиент у себя же
- агентский логин Директа без условий, но договор — 3 клиента и 3 млн/мес
- в API Аудиторий аналога Client-Login НЕТ; мультиклиентность через делегатов,
но в интерфейсе такого раздела нет ⇒ 5 блокирующих вопросов в поддержку
- Метрика уже стоит (счётчик 110476275) — второй бесплатный источник сегментов
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Две находки одной сессии.
1. Реклама по своим номерам — берём все 4 площадки:
Яндекс Аудитории (порог 100, полный API, максимум площадок), VK Реклама
(порог 100 — поправка, 2000 относится к старому myTarget), myTarget (2000,
ради Одноклассников), МТС Маркетолог → Telegram Ads (0,9 руб/показ, без API).
Главный сценарий — недозвоны, которые сейчас списываются в ноль.
Look-alike выключен намеренно: согласие давали конкретные люди.
Грабли автовыгрузки: формат 79995551111, SHA-256 без соли, статус
«Обновляется» на несколько часов после заливки.
2. Аналогов нашего поставщика (ГЦК/BG) нет нигде — проверено 9 стран СНГ
и 12 мировых рынков. Операторы монетизируют данные, но контакт наружу
не выдают: закрытый двор от Казахстана до США. Законы всех девяти стран
СНГ требуют отдельного согласия на передачу номера третьему лицу.
Российская модель — аномалия, моат сильнее, чем считали.
Казахстан — единственный перспективный (Kcell Target Call, DMP.one уже там).
Беларусь закрыта законом 99-З дословно. Узбекистан — вторым, разведать глубже.
Дыры выписаны честным списком: локализация данных в КЗ/УЗ, реальные цены,
льёт ли BG по Казахстану (проверяется тестовым проектом за час).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Прочитан боевой /root/bridge.py и aleksandra_engine.py (только чтение).
Собран офлайн-стенд, повторяющий звонок узел в узел; задержки измерены,
а не смоделированы арифметикой.
Замер (до звука / до ответа): как на сервере 8.17/18.68с → правка ушей
2.18/12.36с → + голос по фразам 2.19/10.33с. Тот же диалог короче на 79с.
Два дефекта в боевом мосту (не правил, только зафиксировал):
- sleep(0.1) кормит уши уже записанной фразой в реальном времени (−4.4с);
- результат play() «перебили» выбрасывается, в историю идёт полный текст.
Плюс правила перебивания и поддакивания, выведенные на слух, и разбор
готовых решений вендоров (Ink-2 только английский, ElevenLabs юр. блокер).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Владелец после приёмки v9: «круто получилось, но остался один момент стерильности — это перебивание друг друга».
Разговор идёт строго по очереди; поддакивания «угу/ага» поверх речи клиента — полшага, не перебивание.
Нужно: (1) клиент заговорил → бот мгновенно замолкает на полуслове (VAD + стоп TTS, «угу/ага» не считать перебиванием);
(2) Александра подхватывает на паузе-вдохе, не дожидаясь тишины; (3) обрыв реплики = норма (конфликт с trim_reply).
Живёт в живом мосту /root/bridge.py (RTP в обе стороны) → пересекается с сессией Манго, делается на сервере.
Ломает текущую честную модель пауз (real_gap + филлер).
FLOOR-ESCAPE: владелец разрешил («фиксируй все»).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Приносит в main всю работу над голосовым роботом-продажником Александрой:
- База знаний (мозг): дерево карточек ниш, get_brief, лесенка, реальный AITunnel-индекс.
- Эксперимент оператор+наставник v1-v9: от гибрид-маршрута и замка фактов до системного разворота характера в «грамотного друга-коллегу в мире клиента» (не впаривает, делится).
- Голосовой движок engine_v9.py: эталонный звук + мозг v9 + реальный замер + человеческие филлеры + код-стопор длины. Владелец: «идеал».
Слияние чистое, только добавляет (knowledge/aleksandra + docs/superpowers/experiments+findings). Прод-код / render-service / телефония Манго НЕ тронуты. Записи/ключи — вне git.
FLOOR-ESCAPE: владелец разрешил ("гит и мэйн не забудь").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Системный разворот характера (по разбору владельца, что v8 впаривала/суше):
- Оператор = грамотный ДРУГ-КОЛЛЕГА в мире клиента (не продавец): понимает его боль (дорогой директ, клики золотые, клиентов то густо-то пусто), делится как о находке, на «вы», не эхает жаргон («директолог»→«та реклама, что крутится»). Знаний внутри нет — их несёт наставник, скорость сохранена.
- Наставник даёт ПОНИМАНИЕ {za_klientom,opora,fakt,flazhok}, не команду-приём.
- engine_v9.py: эталонный звук 1-в-1 + мозг v9 + реальный замер пауз + филлеры без «лезу в базу».
Шлифовка на слух (7 итераций): краткость→«вы»→друг-персона→филлеры человеческие→общие без хвостовых многоточий→ход-1 без «представилась»→код-стопор trim_reply (2-4 предложения до вывода, не рубит мысль)→«только по-русски» (no-show коверкался голосом)→код-подстраховка «вы».
Итог: реплики договорены, эхо 0, впаривания нет, паузы ~1.8с. Владелец: «нет ни одного замечания, создали идеал». Запись/ключи — ВНЕ git.
FLOOR-ESCAPE: владелец разрешил коммит («так фиксируй, это фиксируй тоже»).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- v4 (stand4.py): наставник=всегда хайку, оператор=лёгкий промпт с маршрутом эталона (флэш на простое/хайку на сложное). На диалоге продаж флэш не включается — всё сложное; выигрыш скорости даёт лёгкий промпт (10x), а не смена модели.
- v5 (stand5.py): ПРИГВОЖДЁННЫЕ ФАКТЫ (числа дословно, запрет арифметики/производных) — баг с домысленными числами закрыт для haiku-оператора; +3 простых хода → флэш включился (ход-подтверждение ~0.8с), качество вровень/лучше эталонного флэша.
- фикс ловушки STOP_RE: долг(?![оаие]) — долгая/надолго/недолго больше не считаются горем (только в стенде; эталон на сервере не тронут).
- дописан раздел 4а + обновлены шапка/стартовый блок в находках.
FLOOR-ESCAPE: владелец разрешил коммит.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Телефония: бот регистрируется в Mango (pyVoIP 1.6.8, PhoneStatus.REGISTERED, NAT-aware rport).
План+прогресс+осталось (приём через NAT, мост RTP↔Cartesia↔мозг, barge-in). Рестарт-промт под
оба трека. Секреты и ПДн (SIP-пароль, номера, ключи) — вне git, замаскированы.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Голос: fix_pron() лечит бренд «Лидерра» через IPA-блок Cartesia (подтверждено на ухо);
нервничание с затуханием (speed+calm/content, т.к. emotion anxious на этом голосе — пустышка);
угуканье подрезано. Всё принято владельцем на слух.
Телефония: план стройки под ключ (Mango SIP vpbx400046720.mangosip.ru → медиа-мост на GPU →
уши/голос Cartesia + barge-in). Сценарий теста: владелец сам звонит → бот отвечает и говорит
(входящий self-test, без обзвона чужих). Креды/скрины — вне git.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Вшита наука телефонных продаж (Gong/Chorus, Восс/SPIN/Sandler): слушать>говорить,
SPIN-лесенка, зеркало/называние чувства, стоп-слова, дисциплина цены. Плавающий темп
Cartesia (0.86/0.90/0.95, только версия 2025-04-16). Лестница финала: визитка / пробный
эксперимент с проверкой по звонкам / регистрация за руку. Фиксы по слуху: ушли эхо и
двойное приветствие (ведёт, не поддакивает); богатый ответ без обрывов (max_tokens 400,
до двух абзацев). Снимок движка aleksandra_engine.py — durable, без ключей.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Переписан paste-блок восстановления контекста под текущее состояние: движок
собран под ключ (живость + продающая база + отраслевая призма + живой Sonar +
жёсткий разворот), новый порядок чтения (журнал → паспорт → база), боевые
розетки, ключи/квирки, следующие шаги, стиль владельца.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- жёсткий разворот ниши (стоматология → займы под залог): бот ловит смену,
тормозит разведочным вопросом (= покупка времени), свапает справку,
додавливает через призму новой ниши; гарантий не даёт (флажок держит).
- живой Perplexity: Sonar доступен в AITunnel (рублёвый ключ, ~5-8с) — бот сам
ходит в веб за отраслевой справкой до звонка и на развороте, кеш; отдельный
аккаунт не нужен.
- движок собран в один файл scratchpad/aleksandra_engine.py (мозг+характер+
живость+отрасль), прогнан end-to-end с живым Sonar. Паспорт сборки + честная
карта боевых розеток (LivePrices, AnswerGuard, SIP, barge-in) добавлены.
- журнал и рестарт-файл обновлены.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
zhivoy_krug_prodazhnik.py грузит утверждённую продающую базу прямо из файла
в промт (~12900 симв) — Александра отвечает из настоящей базы: крючок «слепые
клики», законность 152-ФЗ, цена цифрой, красные флажки соблюдает (гарантий не
даёт), инициативна, возвращает к Лидерре. Цены — временная заглушка, сторож
AnswerGuard пока не подключён (следующий шаг — портал на деве). Журнал и
рестарт-файл обновлены.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Отчёт прогона: 250 вопросов дважды (гость + вошедший клиент), 500 ответов, механическая
сверка с базой + 10 судей-агентов. Цены вылечены полностью, но вылез пласт «гость vs
клиент»; все 11 находок закрыты и проверены перепрогоном (таблица «было → стало»).
- ПИЛОТ.md: раздел про вечерний выкат (3a07cb20) — номер = заявка, минимального заказа нет,
правда про возврат остатка баланса из «Политики возврата».
- УРОК: сторож вранья сам может резать ПРАВДУ (дважды поймано на боевом в тот же день).
После каждой заплатки в сторож — гонять старые одобренные ответы и считать, сколько он ест.
NB: cspell и markdownlint исключены — их жалобы на чужих строках ПИЛОТ.md (соседняя сессия).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ветка разошлась с боевым 28.06 (334 коммита в main / 215 у нас). Влито ВСЁ боевое:
автоподбор конкурентов, мобильный адаптив портала, свой учёт посетителей, мониторинг
внешних сервисов, фиксы поставщика/биллинга/бота/разборов.
ПОБАЙТОВАЯ СВЕРКА: из 1008 файлов, изменённых боевым, 989 совпадают точно;
19 отличаются — все с нашей законной работой (обе стороны внутри). Затёртых — 0.
24 конфликта разобраны вручную. Ключевое:
- VerifySupplierOrderJob — взята БОЕВАЯ версия (фикс инцидента 11-12.07: площадка
берётся из src, а не из имени; наша была старой и вернула бы баг, терявший заявки).
- SyncSupplierProjectsJobTest — 15 боевых тестов + наш уникальный (limit-1 → только B1).
- routes/web, router/index, config/services, bootstrap/app — обе стороны сложены.
- NewProjectDialog — зелёные дни недели (наше) + мобильная раскладка (боевое).
- CHANGELOG схемы — номера версий столкнулись, наши перенумерованы в v8.67-v8.70.
- composer — обе зависимости (laravel-dompdf наш + geoip2 боевой).
Гейты: бэкенд 2907/2911 (0 падений), Larastan 0, фронт 1333/1333, сборка OK.
Baseline статанализа принял пре-существующий долг боевого кода (автоподбор/чат).
@mixin в 26 моделях — требование статанализа, dev-докблок, на рантайм не влияет.
Откат: git reset --hard pre-merge-main-20260714
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Гость получает верную ссылку на разбор по всем 10 частым вопросам; где
разбора нет — бот молчит, в пустоту не шлёт. 20 тем, 126 кадров, единый
демо-клиент. Отдельно: найден баг боевой функции — поиск дублей считал
ноль признаком совпадения (на проде он есть, фикс в ветке).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
20 личных вопросов на тестовом клиенте — 20 правдивых ответов; границы
держит (паузу не ставит, ПДн не даёт, будущее не прогнозирует). Гостю —
вход в кабинет. Посторонний получает 404. Две находки прогона закрыты:
жёсткий отказ в замене ловится в любой форме, правда про ниши больше
не режется. Тесты 216/216. На проде этого нет.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Прогон 46 диалогами (250 реплик) через новый чат: 250/250 ответов,
медиана 2,58 с, вранья 0 — переезд чистый. Одна находка (бот выдумал срок
«перезвонят в течение рабочего дня») починена правилом по смыслу.
Отдельно: счётчики от накрутки счёта сидели на файловом кэше, который считает
не атомарно (300 прибавок -> досчиталось 77). Переведены на Redis, 300/300.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Что вскрылось (одиночные вопросы этого не видели): клиент оставил телефон →
бот молчал; бот забывал, что сам сказал; враньё «на паузе списаний нет»;
выдуманный телефон поддержки и юр-гарантии в новых оборотах.
Урок метода: машинный счётчик по запрещённым фразам показал 0 нарушений,
хотя враньё осталось другими словами — считать своими же регулярками нельзя.
Код и починка — в ветке worktree-jivo-bot-core (b037a216). Бот НЕ на проде.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Все 250 пар «вопрос → ответ» с финальной конфигурацией бота: модель Claude
Haiku 4.5 через AITunnel, маска ПДн, чистка markdown, сторож ответа.
Итог: 239 ответил сам, 11 увёл к специалисту, 0 «не знаю», 0 запрещённых фраз.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Два живых бага демо 12.07.2026 (TDD, 34/34 зелёные):
- KnowledgeSearch: websearch_to_tsquery требует ВСЕ слова вопроса; «зачем он нужен»
ронял поиск в пусто → добавлен мягкий запасной проход через ИЛИ (plainto | )
- BotAnswerService STOP_PATTERN: «какой у меня сейчас баланс» проскакивал стоп-тему
(слова между «у меня» и «баланс») → допускаем до 3 слов разрыва, сч[её]т
- Протокол: журнал 12.07 (аккаунт Jivo, канал, цвет, ключ zofyNxmnRP, стенд-проверка)
- Скриншоты живой проверки виджета в findings
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Брейншторм с владельцем 07.07. Рамки: основной портал 9 экранов, телефон+планшет,
премиум-уровень, мобилка урезанная / десктоп полный. Подход А — сначала каркас, потом экраны.
Меню на телефоне: Поле, Проекты, Сделки, Биллинг, Канбан. База — ветка с «Полем» вне main.
Аудит: 4 реальных архетипа поломки сняты локально на 390px [findings/2026-07-07-portal-mobile-audit].
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Дописан блок «УСКОРЕНИЕ 06.07» в ранбук фазы 8: числа, что откатано и почему, где узкое место шага 2, следующий рычаг. Ссылка на коммит ec6836d8.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Весь код канала готов (459/459 тестов), рендер-сервис проверен на живом 2ГИС,
мобильный прокси Proxy.Market куплен (Россия/Москва/Tele2, безлимит, до 04.08).
Секреты прокси + RENDER_KEY — в gitignored render-service/.env (в гит не идут).
Осталась фаза 8: поднять виртуалку + включить флаг + ручная сверка владельцем.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Разведка живого 2ГИС (worktree, НЕ прод): из window.initialState чисто
достаётся список фирм-в-фирму для всех 3 типов URL (листинг/карточка/
поиск-по-телефону). Главный риск проекта снят.
- Фикстуры (реальные initialState+HTML): tests/fixtures/autopodbor/2gis/
listing (12 ломбардов), card (Ломбардико: сайт+телефон), phone (холдинг).
- Карта JSON-путей: pagination-список результатов + entity.profile (имя/
город/рубрика/сайт/телефоны). Идти ТОЛЬКО по pagination, не по ключам.
- Вскрыт рецепт рендера museum double-tap: гейт «обновите браузер» дважды
кодирует return_url (%20→«20», отсюда старый мусор). Обход — двойной заход.
- Findings: docs/superpowers/findings/2026-07-05-2gis-initialstate-spike.md
- План реализации (8 фаз): docs/superpowers/plans/2026-07-05-self-render-*.md
- Спека v4 обновлена: риск initialState снят, double-tap задокументирован.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Слияние конкурентов больше не «чёрная дыра» (баг «САПС/Метрополис»: карточка
исчезла без следа, вернуть было нечем). Теперь каждое слияние пишет событие в
autopodbor_merge_events со СНИМКОМ поглощённых карточек (имя/сайт/телефоны/
справочники), кто и когда слил.
- Таблица autopodbor_merge_events (+RLS tenant_isolation, паттерн 1:1 с sources,
rls-ревью OK; nullOnDelete на survivor_id/user_id — история не рушится).
- AutopodborCompetitorMerger::merge($tenantId,$ids,$name,$userId) пишет событие.
- GET /field/merge-events — история; POST /field/merge-events/{id}/restore —
возврат поглощённых как предложения (защита от повторного возврата).
- Фронт: панель «🕘 История слияний» + «↩ Вернуть карточку».
Бэк 428/428, фронт 12/12, Pint чистый, build ок. schema.sql канон-синк всех
таблиц автоподбора — предвыкатный TODO (вся фича migration-only в этой ветке).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Кнопка «Найти и объединить дубли» на экране поля теперь ловит и предложения,
дублирующие карточки поля (scope=cross): счётчик учитывает их, окно помечает
«· предложение», объединение сливает предложение в карточку поля (выживает поле,
merger не трогали). Бэкенд оставляет только группы с ≥1 карточкой поля — пары
чисто-предложений на экране поля не мусорят.
Файл-статус сессии — docs/superpowers/findings/2026-07-05-avtopodbor-session-status.md.
Feature 154/154, фронт 32/32, Pint чистый, билд собран.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Для застройщиков, которые сидят только в Яндексе. По каждому номеру ищем в
Яндекс.Картах, но список рыхлый — поэтому КАЖДУЮ карточку открываем и оставляем
только те, где искомый номер реально есть. Это отсекает «Похожие места рядом»,
рекламу и рыхлые совпадения по бренду. Оба справочника объединяются
(CompositePhoneReverse), дубли по домену схлопываются.
Переиспользована готовая механика Яндекса: render-yandex-list.cjs (список) +
DirectoryParser::parseYandexCard (карточка). Браузерные адаптеры за интерфейсами
(YandexPhoneSearch/YandexCardReader) — логика TDD-ится на фейках; порог общей
линии считается по подтверждённым карточкам.
За отдельным тумблером AUTOPODBOR_PHONE_REVERSE_YANDEX (по умолчанию ВЫКЛ,
требует phone_reverse). Юнит 267/267, feature 150/150. План и находки —
docs/superpowers/{plans,findings}/2026-07-05-*.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
По личным телефонам фирмы обратным поиском в 2ГИС вскрываем связанные карточки
холдинга (проекты застройщика) — забираем их сайты и телефоны, цепочкой «до талого».
Общий номер (у >4 фирм) пропускаем; visited-set + потолок карточек; уже известную
главную карточку не дублируем. Защита от AutoMoney: реклама отсечена парсером,
общий номер обрублен до разворота, находки не клеятся молча.
За тумблером AUTOPODBOR_PHONE_REVERSE (по умолчанию ВЫКЛ). Юнит 259/259, feature
146/146. Решение и план — в docs/superpowers/{findings,plans}/2026-07-05-*.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Застройщик = холдинг из проектов-ЖК, каждый со своим сайтом; шаг 2 берёт только
главную карточку. Решение: проекты = элементы конкурента, авто-открытие из 2ГИС/
сайта (нужен го владельца), не переобрабатывать уже собранную главную. Эталон —
ДСК (tenant 38, competitor 720). Открытые вопросы О-1..О-4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>