Commit Graph

856 Commits

Author SHA1 Message Date
Дмитрий 3197e24bbb docs(прогрев): план реализации — 4 страницы, ниша/менеджер/пагинация/дата/карточки
10 задач по TDD: бэкенд (firmRow +ниша/дата/менеджер/состояние/каналы, маршрут
назначения для СМС, sms-канал, блок warming в проспектах), фронт (composable
useWarmingFirms + 4 ячейки, v-data-table на 4 экранах, фильтры, select-all,
карточки воронки), полный регресс.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 15:41:49 +03:00
Дмитрий d11778a32b docs(прогрев): спека — 4 страницы, ниша, менеджер, постраничность, дата запуска, пометки на карточках
Портальная часть (пункты 1,2,3,5,6,7): общий движок таблицы на v-data-table,
ниша+дата колонки и фильтры, Отметить все+счётчик, показ менеджера +
назначение на СМС, пагинация 10/25/50/100, пометки греётся/прогрет + значки
каналов на карточках. Пункт 4 (поиск клиентов) — следующим заходом.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 15:34:55 +03:00
Дмитрий 14a6b801d7 docs(deploy): runbook выката «три площадки прогрева» (кусок A)
Предполёт GO, пошаговый план: миграция+бэкенд (redeploy.sh) → фронт
(deploy-build.sh, маркер обновлён), smoke-проверки, откат. Ждёт «эскейп».

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 12:22:50 +03:00
Дмитрий 1078566795 docs(прогрев): план куска A — фундамент площадок + три страницы
9 задач через TDD: миграция таблицы настроек площадок + бэкфилл из state,
модель SalesAdAudiencePlatform, джоб Яндекса на строку площадки,
контроллер по {platform}, маршруты /warming/{platform}, фронт (API +
общая обёртка трёх страниц + меню), уборка старого экрана + схема v8.81,
регресс «поведение не изменилось» + предполёт.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 10:15:19 +03:00
Дмитрий ecbcea8eed docs(прогрев): дизайн — три площадки прогрева + витрина по порталу
Кусок A (к реализации): фундамент «фирма на площадке», таблица настроек
по площадкам (свой рубильник/пороги/синхронизация), три пункта меню
Яндекс/ВК/Телеграм; поведение прогрева не меняется, 177 номеров → «Яндекс».
Куски B (витрина: значки на карточках, колонки «Греются/Прогреты», история
эпизодов, СМС) и C (раздельные сроки) — дорожная карта. Плюс справочник 11 сроков.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 10:01:46 +03:00
Дмитрий 6e771636ef feat(смс): модуль «Прогрев СМС» с заделом под мультиклиентность
Начальник отдела продаж отмечает фирмы прогрева галочками, пишет текст,
видит цену ДО отправки и журнал после. Отправки СМС в проекте не было
вообще — ни у СМС-центра (только баланс и HLR), ни у МТС (только файл).

Что сделано:
- разъём провайдера SmsProvider: новый оператор подключается одним файлом
- заглушка FakeSmsProvider — модуль работает и проверяется ДО согласования
  имени отправителя у операторов (это недели), иначе разработку не закончить
- маршрутизация по оператору: билайновский номер уходит через Билайн за
  4,75 ₽, прочие через МТС — без ручного выбора канала
- стоп-лист: кто отписался, тому не шлём никогда, проверка перед списанием
- отбор получателей с шестью причинами пропуска, все ДО траты денег
- списание скопировано с AutopodborChargeService; пока клиента нет
  (tenant_id пуст) с баланса не берём — платим оператору напрямую
- оператор номера доезжает из «Поиска клиентов» в прогрев (был известен
  и оплачен ДаДате, но терялся при передаче)

Мультиклиентность в костях: колонка tenant_id во всех четырёх таблицах
СМС с первого дня, NULL = «Лидерра сама». Клиент добавляется строкой,
а не переделкой модуля.

Найдено и закрыто при исполнении:
- замок от двойного списания стоял не на том соединении: кампания на
  pgsql_supplier, деньги на pgsql, lockForUpdate по кампании отпускался
  сразу. На бою два запуска списали бы дважды, обрыв — оставил бы пометку
  «оплачено» при неушедших деньгах. Источник правды перенесён в
  balance_transactions под замок по тенанту. Доказано тестом: старый код
  списывал 700 вместо 850
- приём в портал требовал phones строкой по regex — словарь с оператором
  получал 422, в базу не доезжало ничего. Тесты были зелёные, потому что
  звали сервис МИМО контроллера. Проверка теперь принимает оба формата,
  тест идёт через HTTP
- телефоны директоров в contacts остаются строками (договор
  SalesProspectController), словари — только в верхнем phones

Заодно вылечена мигающая поломка 48 тестов доставки лидов: помощник
createRoutingSnapshotFromProject клал снимок на сегодня, а LeadRouter
после 21:00 МСК ищет завтрашний (вечерний переворот заливки) — вечерние
прогоны падали, дневные проходили. Помощник теперь зеркалит активную дату
роутера в любой час. Регрессия SnapshotHelperTimeOfDayTest замораживает
22:00 МСК и пинит инвариант. Боевой LeadRouter не тронут.

Тесты: 84 бэкенд + фронт по экрану + 397 поисковика, весь набор 3226
зелёный, статанализ чист. Все защиты проверены вырезанием.

План: docs/superpowers/plans/2026-07-20-sms-progrev-modul.md
Спека: docs/superpowers/specs/2026-07-20-sms-progrev-modul-design.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 06:35:43 +03:00
Дмитрий 3fd0d81e09 @
docs(александра): передача по стройке — лёгкий оператор и точило

Приняли архитектуру по замыслу владельца: наставник не даёт подсказку
на каждый ход, а точит промпт оператора в фоне. Замер: лёгкий промпт
2.60с против 3.14с, наставник успевает лишь в 35% ходов — итого 0.77с.

Точило ВЫБИРАЕТ блоки из 13, а не пишет текст: промпт собирается кодом,
поэтому дрейфа нет. Опасные темы выбираются кодом мгновенно, оттенки —
моделью в фоне, её не ждём никогда.

В файле: где что лежит, замки лаборатории, эталон боевого с возвратом,
состав 13 блоков и утверждённый ответ про источник заявок, пять
провалившихся попыток ускорения с числами, карта задержек, ловушки
и открытые вопросы за владельцем.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-20 19:17:01 +03:00
Дмитрий 8e687f99c1 feat: сквозной путь клиента от рекламного клика до Вебвизора
Путь человека рвался пополам: лендинг и кабинет считали разные счётчики,
а вход и регистрация не писались вообще. Почему люди бросают регистрацию,
узнать было нельзя.

Счётчик лендинга 110476275 становится счётчиком полного пути и грузится
на всех страницах кабинета. Прежний счётчик кабинета 110494416 не тронут,
его история цела, на страницах кабинета работают оба.

Что сделано:
- загрузчик Метрики поднимает счётчики по области: public или app
- белый список раскладок: новая раскладка Метрику НЕ получает по умолчанию
- формы входа и регистрации закрыты от записи классом ym-hide-content
- метка utm не теряется при заходе сразу в кабинет минуя лендинг

Найдено при исполнении и закрыто:
- почта выводится в заголовке ДВУХ экранов, то есть вне формы: класс на форме
  её не накрывал, утекла бы в записи открытым текстом. Замаскирована точечно
- Метрика, единожды запустившись, пишет дальше сама и роутером не выключается.
  Админ входит через общий /login и идёт в админку к чужим телефонам.
  Корни админки и портала продаж закрыты ym-hide-content
- ключ metrika в config/services.php был объявлен ДВАЖДЫ: раздвоил его мой
  же merge 42e907c8 от 14.07. PHP молча берёт последний, правка первого блока
  не дала бы ничего и не выругалась. Дубль вычищен, прочие конфиги проверены

В кабинете Метрики включена галочка «включая поддомены»: счётчик принимал
данные только с liderra.ru и молча выбрасывал бы всё из кабинета.

Заодно погашен долг по статанализу: 63 ошибки держали коммит. Все до одной
в тестах, в боевом коде ноль. Природа ложная — анализатор не понимает
устройство Pest и ругается на обычный вызов внутри теста. Их гасят списком
игнора, а список пересобирали 18.07, тогда как тесты добавлялись 19-20.07,
в том числе мои по рекламной аудитории. Список пересобран, стало 0 ошибок.
Долг накопился в том числе потому, что вчера я обошёл эту проверку.

Тесты: 27 новых, все проверены вырезанием защиты. Полный набор 202 файла зелёный.

План: docs/superpowers/plans/2026-07-20-skvoznoy-put-do-vebvizora.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 16:47:19 +03:00
Дмитрий c503e93c8a docs(александра): передача сессии — ритм разговора и задержки 20.07
Два дня работы: звук (хрип от несовпадения A-law/µ-law, заворот высоких,
канал proxy.market) и механика разговора (сторож эха ел вопросы клиента,
глухота между её же предложениями, поток мозга по предложениям).

Ответ по существу 6.05с → 3.64с, пауз внутри реплики 2 → 0.

В файле: что читать следующей сессии, чем мерить, 8 ловушек
и незакрытый слой, который за владельцем.

Номер боевой линии не пишем — сторож ПДн прав, правило одно для всех
телефонов; номер берётся из журнала моста.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 10:09:38 +03:00
Дмитрий 8697f8b0a2 docs(finder): спецификация и план — фильтр по нише и групповые действия над списками
Постановка владельца 19.07.2026: на экране «Последние списки» нужен фильтр под
выбранную нишу, галочки на списках и групповые действия (удалить / собрать телефоны /
прогреть / отдать менеджеру) — все только по горячим фирмам.

Решения владельца зафиксированы: горячие = 70+, уже собранных и отданных пропускаем
и сообщаем сколько, перед платным действием и удалением спрашиваем с числом,
Телеграм и СМС — заглушки до готовности модулей.

Найдено при проектировании: прогрев берёт только фирмы с собранным мобильным, значит
порядок работы — телефоны → прогрев → менеджер; после прогрева на нашей стороне не
оставалось следа (добавляем пометку площадки); показ 1000 списков требует переноса
счётчиков в колонки, иначе главная разбирает всю базу на каждое открытие.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 08:00:27 +03:00
Дмитрий bd23c20504 docs(sales): план трёх площадок прогрева и модуля МТС
Одно поле channels не растягивается на третью площадку — сочетаний восемь.
Заменяем тремя галочками ch_yandex/ch_vk/ch_mts с переносом значений:
на бою 99 фирм со значением yandex, они получают ch_yandex.

Для МТС — выгрузка файлом: программного доступа к рекламе в Telegram у них
нет, их REST API умеет только SMS (проверено по документации 20.07).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 07:47:37 +03:00
Дмитрий 0f2b8bd51f fix(реклама): про свечение в промпте надо говорить прямо
Владелец сравнил новые картинки с прежними и сразу увидел: «со слитками
поярче было». Так и есть — на первых двух горячее светящееся ядро вышло
САМО СОБОЙ, и выбрал он их именно за это, а в промпте про свет не было
ни слова. Следующая пара без указания получилась матовой и тусклой.

Дописал в общую часть промпта: ценная сторона обязана быть источником
света, а не просто тёплым цветом — горячее ядро, слитки ловят свет и
сияют, контраст яркости выжимать до предела.

Замер для сверки (средняя яркость / самые яркие точки):
  было матово: 33.5/166 и 43.1/192 при промахе мимо стиля
  прежние одобренные: 26.7/102 и 32.4/137
Числа тут вторичны — решает глаз владельца, но замер помогает поймать
явный провал до показа.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 05:56:43 +03:00
Дмитрий 5b7f1660c1 feat(реклама): формы картинок под ВК — лента 4:5 и Истории 9:16
🪤 С первой попытки модель отдала для 9:16 ШИРОКУЮ картинку, дорисовав
чёрные полосы сверху и снизу до вертикали. В Историях это читается как
брак. Лечится прямым запретом на полосы плюс требованием перестроить
сюжет по вертикали: клики сыплются сверху, золото собирается снизу.

Проверять полосы дёшево: средняя яркость верхней и нижней десятой части
кадра против центра. У letterbox верх ~0, у настоящей композиции все три
близки.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 05:50:19 +03:00
Дмитрий 133f3e529d docs(sales): подобраны хвосты по рекламе — ВК в передаче, план отмечен
В плане исправлена последняя проверка: она была написана так, будто
миграция уже на боевом. До выката она обязана падать «column channels
does not exist» — это правильный результат, а не поломка. Отмечены
выполненными 65 шагов.

В передачу дописано состояние ВК (кабинет, охват меньше сотни, открытый
вопрос по API) и три грабли вечера: вырезанная субагентом защита,
негодный тест на защиту, и git commit без явных путей.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 20:38:21 +03:00
Дмитрий ddfb50cd44 docs(sales): план выбора площадки прогрева (10 задач)
Поле channels у фирмы с бэкфиллом «яндекс» существующим 64, фильтр состава
в яндексовой заливке, приём площадки от «Поиска клиентов», массовая смена
кнопками, колонка «Где греем», джоб заливки в ВК с тремя состояниями.

Тело обращения к API ВК вынесено за рамки плана намеренно: документация
закрыта до получения доступа, гадать нельзя. Джоб, порог 2000 и тесты
пишутся сейчас, меняться будет только тело одного метода.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 19:18:13 +03:00
Дмитрий d3ccf2db63 docs(sales): описание выбора площадки прогрева (Яндекс/ВК/оба)
Признак channels у фирмы, три кнопки и колонка «Где греем» на экране
начальника, заливка в ВК с тремя статусами (нет доступа / ждёт объёма /
работает). Порог автомата у ВК — 2000 номеров, это его же документация.

Зафиксированы находки 19.07: охват списка в ВК меньше сотни при 111
загруженных номерах, и что «111 из 111» у Яндекса — проверка формата,
а не совпадений. Открытый вопрос про перезапись списка в API ВК помечен
явно — уточняется при получении доступа.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 19:11:17 +03:00
Дмитрий 61f7da3eeb docs(sales): передача по рекламе на кандидатов — состояние на вечер 19.07
Модуль на бою, две боевые поломки найдены и исправлены (права у ночного
пересчёта, отсутствующий confirm сегмента). Сегмент 58034825 создан порталом,
111 из 111 номеров приняты. Пошаговый план на утро + риск порога в 100 номеров.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 17:55:33 +03:00
Дмитрий 31d6df0fcc feat(реклама): промпт и скрипт генерации картинок под Яндекс.Директ
Буклет 2:3 Директ не принимает. Два формата под требования Яндекса
(квадрат 1:1 и широкий 16:9), текста на картинке нет кроме логотипа,
макет телефона и карточка с номером убраны — риск модерации по 152-ФЗ.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 12:10:57 +03:00
Дмитрий 9a410a3358 docs(sales): поправки плана рекламы по ходу выполнения (stage_changed_at, оба трейта в тестах)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 11:53:54 +03:00
Дмитрий 9bc587c2de fix(sales): реальный телефон директора убран из тестов и планов; клиент Яндекс.Аудиторий возвращён в main
Коммит d2c2ec43 от 19.07 оторвался от main (dangling, ни в одной ветке):
чистка ПДн и YandexAudienceClient в основную ветку так и не попали.
Номера заменены на фиктивные 7999000000X, клиент и его тесты внесены заново.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 10:24:21 +03:00
Дмитрий ba98334e8c docs(sales): план рекламы на кандидатов v2 — прогрев до менеджера, сроки по стадиям
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 09:53:57 +03:00
Дмитрий e09657bbb9 docs(sales): HANDOFF рекламной аудитории + спека v2 (порядок перевёрнут)
Владелец переформулировал: сначала ГРЕЕМ рекламой, потом отдаём менеджеру.
Прогрев — отдельный этап ДО воронки, карточка рождается при назначении менеджера.

Правила рекламы теперь следуют за стадией карточки, все сроки настраиваются:
прогрев 3 дня, новые 3, взят в работу 14, переговоры до даты созвона
(просрочена → +3 → стоп), недозвон 7, отказ 3, регистрация/тестирование 30,
пополнил баланс и пользователь — стоп.

Проверено на боевых данных: у «Взят в работу» и «Регистрация/Тестирование»
даты созвона нет и не будет — им обязателен свой срок, иначе реклама вечная.
У «Переговоров» дата обязательна в коде, логика владельца закрывает полностью.

HANDOFF содержит промпт для следующей сессии, все технические грабли,
состояние Яндекса (сегмент 58029600, письмо в поддержку отправлено)
и запись об инциденте с ПДн в истории коммитов.

Все телефоны в документах замаскированы.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-19 09:34:59 +03:00
Дмитрий 4f172ad88b @
docs(golos): HANDOFF — судья и четыре дефекта Александры

Передача следующей сессии: где что лежит, что сделано, четыре дефекта найденных
ГЛАЗОМ (судья их пока не видит) и порядок работы — сперва научить судью их ловить,
показать владельцу, и только потом чинить.

🔴 Главное правило вынесено в шапку: ни судью, ни Александру нельзя точить под
конкретный случай. Никаких регулярок под «база перепуталась», списков с «натяжными
потолками» и синонимов «гарантии» в маршрут. Для каждого дефекта указан КЛАСС
проблемы: смысловая связность, сила свидетельства о нише, доверие к компании,
независимость маршрута от точного слова.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-19 07:27:22 +03:00
Дмитрий dc4a17cb43 docs(finder): правка владельца — живость менеджеру не показываем, зачёркиваем только «не существует»
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:05:11 +03:00
Дмитрий 37809697b6 @
docs(golos): мини-прогон трёх сценариев на сервере + первый суд

Карта судьи по 3 разговорам: доля речи 75-82% при норме 35-45, за 4 реплики один
довод из 13, выдумки ушей в каждом разговоре.

🔴 Записаны слепые пятна судьи — то, что глаз увидел, а он нет: самопротиворечие
внутри реплики, разворот ниши не сработал (замок «подтвердить дважды» слишком строг —
клиент называет сферу ОДИН раз), признание клиенту «база у нас перепуталась».

🔴 Механическая находка: клиент спросил про гарантии, уши съели слово «гарантии» —
маршрут по словам не сработал, и дешёвая модель полезла рассуждать о законе
(«отвечать будете вы», «согласие на обработку данных»). Съеденное ухом ключевое
слово ломает маршрутизацию — это дефект схемы, а не промпта.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-19 06:02:51 +03:00
Дмитрий 28db52fb6e docs(разведка): проверка первоисточниками — 4 факта Perplexity оказались неверны + письмо в поддержку Яндекса
Три агента перечитали официальную документацию Яндекса, ВК и МТС.
Итог: 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>
2026-07-18 19:33:37 +03:00
Дмитрий 7ee40fcde5 docs(разведка): реклама по своим номерам (4 площадки) + аналоги поставщика в СНГ и мире
Две находки одной сессии.

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>
2026-07-18 18:45:16 +03:00
Дмитрий 17cf679652 @
feat(sudya): план судьи + рубрика на 36 признаков

Рубрика — единственный источник правды по критериям: спектры I звук, II техника
разговора, III правда и обязательства, IV характер, V продажа (новое — этого не
судил ни один прежний судья), VI проверка самого судьи.

Каждый признак несёт тяжесть: СТОП двигает вердикт в брак, ТРЕВОГА зовёт смотреть
глазами, СИГНАЛ идёт только в статистику. Из 36 признаков 16 — СТОП.

Тесты закрепляют целостность: ровно 36, номера без дыр, поля из допустимых множеств,
спектр V судит только продавец.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 18:39:18 +03:00
Дмитрий d2b74c8b04 docs(finder): спека и план проверки телефонов (ДаДата + HLR)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 18:22:40 +03:00
Дмитрий d9e82f6e3c @
docs(sudya): проект сводного судьи диалогов Александры

Собран из трёх существующих семейств судей: голосовые (NISQA/дуэли/glitch),
чатовые (AnswerGuard + слепые судьи-агенты), нормативные (llm-judge/reviewer-agent/
judge-evaluator). Ни одно из них не судило ГЛАВНОЕ — продала ли она; для номера
менеджера по продажам на лендинге это ключевой спектр.

Устройство: приборы (приговор) → коллегия узких судей-ролей (находки) →
судья над судьями (доля промахов). 36 признаков в шести спектрах.

Протокол честности, каждое правило оплачено ошибкой: слепота, нейтральный вопрос,
живой якорь в партии (забраковал якорь → партия недействительна), роли вместо
одной большой рубрики, находка без цитаты источника не считается.

Границы названы явно: звук живых клиентов не пишем (ПДн — отдельная работа),
судья не правит Александру сам, владелец остаётся высшей инстанцией.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 18:09:39 +03:00
Дмитрий 277800149f @
fix(sales): строгое разделение двух ролей начальника — экраны «мои» больше не показывают отдел

Начальник продаёт сам и руководит отделом. Правило «начальник видит всё»
применялось к ЧЕЛОВЕКУ, а не к экрану, поэтому разделы меню врали:

- «Потенциальные клиенты» показывали все карточки отдела — точную копию
  «Воронки отдела» (это владелец и заметил);
- «Мои клиенты» и «Сводка» — всех клиентов отдела;
- «Привязать клиента» — очередь заявок отдела, причём в ЧУЖОМ формате
  ({pending, history} вместо {data}), форма получала не те данные.

Новое правило: роли разделяются по ЭКРАНУ. Любой запрос по умолчанию отдаёт
только личное — включая начальника. Весь отдел выдаётся только по явному
?scope=department, и просят его только экраны раздела НАЧАЛЬНИК. Менеджеру
параметр ничего не даёт: проверка по роли, не по параметру.

ownedTenantIds теперь ВСЕГДА личные привязки (тип сузился с ?array до array),
добавлен visibleTenantIds для области видимости запроса.

Правом начальника осталось открыть ЛЮБУЮ карточку — кандидата и клиента:
иначе из «Воронки отдела» не открылась бы карточка чужого менеджера.
Ограничены только списки, не доступ к записи.

Следствие: у начальника сейчас 0 своих кандидатов и клиентов, поэтому его
личные экраны станут пустыми — это правильно, а не поломка.

Pest 272/272, Vitest зелёный, vue-tsc чист, Larastan без своих ошибок.
Спека — §23.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 15:59:56 +03:00
Дмитрий e9edb206c8 @
feat(sales): кабинет начальника — единый период (без 500) + пополнения баланса

Экраны начальника отстали от вчерашних правок кабинета менеджера (§16–§21).

1. Живой баг: «Произвольный» период до выбора дат ронял запрос в 500 на пяти
   точках из шести (сводка отдела, доход, результативность, выплаты, тарифы).
   Разбор периода вынесен в трейт ResolvesSalesPeriod: 422 вместо падения,
   период по умолчанию d30 вместо this — как показывает сам PeriodPicker.

2. Пополнения баланса (topup_rub) добавлены в dashboard/overview (kpi +
   строки менеджеров) и managers/performance. На экранах: плашка «Пополнили
   баланс» в сводке отдела и колонка «Пополнили ₽» в обеих таблицах
   результативности. Из подписей убрано «(мес)» — период больше не месяц.

3. «Воронка отдела» правок не потребовала: она рендерит те же доску и карточку,
   что экран менеджера, а карточка сама грузит журнал и сохраняет контакты.

Тесты: SalesPeriodRequestTest проходит по всем шести точкам сразу.
Pest 263/263, Vitest 1420/1420, vue-tsc чист.
Спека — §22.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 15:20:44 +03:00
Дмитрий 6416ec3789 @
feat(sales): периоды сегодня/вчера/7/30 дней календарём, пополнения за период, скролл доски наверх

Замечания владельца по сводке и доске.

ПЕРИОДЫ:
- Резолвер понимает today/yesterday/d7/d30; «7 дней» = сегодня и 6 предыдущих.
  Месячные this/prev/prev2 сервер принимает по-прежнему.
- По умолчанию 30 дней.
- ПОЧИНЕНО: выбор «Произвольный» без дат ронял запрос (500). Теперь понятный 422,
  а на фронте период применяется только когда отмечены ОБЕ даты.
- Произвольный выбирается календарём-диапазоном, не руками; порядок дат неважен.

ПОПОЛНЕНИЯ ЗА ПЕРИОД (переиспользован готовый topupsRub):
- Сводка: плашка «Пополнили баланс» рядом с «Σ баланс».
- Мои клиенты: колонка «Пополнил».
  Заодно даёт число, которое видимо меняется при смене периода.

ДОСКА: горизонтальная полоса прокрутки поднята НАД колонками (колонки высокие,
системная полоса уезжала за экран); синхронизация в обе стороны, ResizeObserver
на приезжающие карточки.

Спека §21 (включая §21.4 — как по коду заполняется «Требуют внимания»).
Гейты: Pest 257/257 sales+unit, Vitest 1417, vue-tsc чисто, Larastan 0 в своих. TDD.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 14:29:18 +03:00
Дмитрий 1e0442facf @
feat(sales): результат разговора и его содержание — одной записью в журнале

Владелец: «объедини в одну запись: договорились… сверху, внизу текст».
Было две записи подряд — в ленте читалось как два события, хотя разговор один.

- БД v8.75: sales_prospect_notes.title VARCHAR(500) NULL — что решили.
- Одна запись kind=note: title = «Договорились на созвон 20.07.2026 17:35»,
  body = краткое содержание. Есть результат без содержания — как раньше,
  одна запись kind=stage без заголовка. Ручная заметка — без заголовка.
- В ленте заголовок строкой сверху, под ним текст.
- Старые парные записи задним числом не сливаем — историю не переписываем.

Спека §20.2. Гейты: Pest 240/240 sales, Vitest 64/64 воронка, vue-tsc чисто,
Larastan 0 в своих файлах. TDD RED→GREEN.
🪤 Тесты DOM для v-dialog: контент уезжает телепортом в body — искать через
document.body.querySelector, а не wrapper.find.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 14:00:55 +03:00
Дмитрий 2cd99d6ddc @
fix(sales): одна кнопка «Сохранить» в карточке — контакты больше не отдельно

Владелец: «исправь сохранения контакта убери, все на кнопку Сохранить заведи».
Две кнопки в одном окне путали: можно было записать результат и уйти, потеряв
только что набранные телефоны.

- Кнопка «Сохранить контакты» и подпись «сохранено» убраны.
- «Сохранить» теперь: сохраняет контакты → если выбран результат, проверяет
  и отправляет его → если результат не выбран, просто закрывает окно.
- Контакты не сохранились (нет сети) — результат НЕ отправляем и показываем
  ошибку, иначе стадия уехала бы, а телефоны потерялись.
- submit() стал асинхронным, кнопка показывает загрузку.

Спека §20.1. Гейты: Vitest 62/62 воронка (4 новых теста), vue-tsc чисто. TDD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 13:49:14 +03:00
Дмитрий 09f67a92a9 docs(golos): стенд-двойник боевого звонка + первый честный замер задержек
Прочитан боевой /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>
2026-07-18 13:37:21 +03:00
Дмитрий 138550207a @
feat(sales): содержание разговора — вместе с результатом; недозвону дата перезвона

Владелец после первого показа карточки: «куда звонить убери; договорились на
созвон — ниже краткое содержание, и оно копится в Историю разговоров, свежие
в начало; недозвон — поставь дату следующего перезвона».

- Блок «Куда звонить» убран: дублировал строку «Телефон общий» из данных фирмы.
- «Краткое содержание разговора» переехало последним полем в блок «Результат
  разговора» (было отдельное поле с кнопкой слева — два места для одного
  действия). Уходит параметром summary вместе с результатом, ложится в журнал
  отдельной записью kind=note. Пустое — не пишем.
- Порядок внутри одного сохранения: сначала автозапись про этап, затем
  содержание → у него больший id и в ленте оно оказывается НАД этапом.
- Недозвон получил необязательное поле «Когда перезвонить»: пишется в
  next_call_at (видно на плитке) и дописывается в автозапись журнала.

Спека §20. Гейты: Pest 236/236 sales, Vitest 59/59 воронка, vue-tsc чисто,
Larastan 0 в своих файлах. TDD RED→GREEN.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии
tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 13:20:27 +03:00
Дмитрий 41fbc4491d @
feat(sales): журнал разговоров по кандидату + переделка обоих окон воронки

Владелец: «краткое содержание разговора писать, чтобы не потерять историю»
и «переделай обоих дизайн, очень не практично, спроси у перплексити».

ЖУРНАЛ (БД v8.74, таблица sales_prospect_notes, append-only):
- kind=note — менеджер написал руками; kind=stage — автозапись о переезде
  по стадии (взял в работу, созвон, недозвон, отказ, регистрация).
  Повторное открытие карточки журнал не засоряет.
- GET/POST /api/sales/prospects/{id}/notes; лента свежими сверху, грузится
  при открытии карточки, а не вместе с доской.
- PATCH /prospects/{id} БОЛЬШЕ НЕ принимает notes: он молча затирал прошлую
  запись — ровно та потеря истории, ради которой журнал и появился.
  Нашёл rls-reviewer, закрыто тестом. Старые notes перенесены в журнал.

ДИЗАЙН (по разбору Pipedrive/HubSpot/Salesforce через Perplexity):
- Карточка 1100px, две колонки. Слева «что за фирма» + история разговоров
  с полем «о чём поговорили». Справа зона действия: «Куда звонить» (номер
  крупно, ссылкой tel:), «Результат разговора» своим фоном, контактные лица.
  Кнопки внизу окна. Пустая история объясняет, что делать.
- Форма создания разбита на разделы: Компания / Контактные лица / Заметка;
  Юрлицо и Город в одну строку; обязательных полей по-прежнему два.

Спека §19. Гейты: Pest 231/231 sales, Vitest 60/60 воронка, vue-tsc чисто,
Larastan 0 в своих файлах, rls-reviewer PASS. TDD RED→GREEN.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии
tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 13:04:02 +03:00
Дмитрий 68428f16c6 @
feat(sales): карточка кандидата — девять полей владельца + правка контактных лиц

Владелец задал список полей карточки и попросил дать менеджеру записывать
контактных лиц прямо в карточке: поиск отдаёт 5-7 ПРЕДПОЛАГАЕМЫХ номеров
директора, живой из них выясняется обзвоном; а если директор перенаправил
к маркетологу — менеджер фиксирует и его, людей может быть 2-3.

- Карточка показывает РОВНО девять полей в его порядке: Юрлицо, Сайт, ИНН фирмы,
  Адрес, Телефон общий, Каналы, Бюджет, Директор, Тел. директора (предполагаемый).
  Убраны Оценка, Достоверность, Реклама, Запросы в Директе, ОГРН, Статус юрлица,
  Личный ИНН директора, Почта директора — данные остаются в payload.
- PATCH /api/sales/prospects/{id}/contacts — список заменяется целиком, пустой
  стирает всех; права как у update() (менеджер свои, начальник любые); главный
  телефон карточки из поиска не трогается.
- ProspectContactsEditor.vue + utils/prospectContacts.ts — один редактор контактов
  на диалог создания и карточку; диалог создания переведён на него.
- Закрывает хвост §16: у 24 живых карточек из поиска контактных лиц не было,
  теперь дозаполняются руками.

Спека §18. Гейты: Pest 223/223 sales, Vitest 196 файлов / 1397 тестов,
vue-tsc чисто, Larastan 0 в своих файлах. TDD RED→GREEN на каждом шаге.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии
tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 12:29:04 +03:00
Дмитрий 48dd6c44af @
fix(sales): «Зарегистрировался» подаёт ЗАЯВКУ начальнику, а не привязывает клиента сразу

Владелец заметил: в отделе есть штатный порядок «через начальника» (экран «Заявки
на привязку»), а кнопка в карточке кандидата создавала SalesClientAssignment напрямую
и в истории заявок ничего не появлялось.

- registerProspect() теперь зовёт SalesAttachmentService::submit() от имени ВЛАДЕЛЬЦА
  карточки. Свободен → заявка pending + письма менеджеру и начальникам; занят другим →
  заявка с пометкой конфликта, чужая привязка не трогается; уже свой → заявки нет.
  Привязка со снимком тарифа создаётся только при одобрении (handleApprove).
- Стадия карточки едет в «Зарегистрировался» СРАЗУ (решение владельца): регистрация —
  факт, воронка показывает правду; «чей клиент и кому деньги» решает начальник.
  Автожизнь не зависит от одобрения — джоб смотрит linked_tenant_id.
- Отменён прежний 422 «клиент уже закреплён за другим менеджером» — теперь это заявка.
- Подсказка под полем e-mail говорит про одобрение начальником.

Спека §17 (отменяет правило §6 «привязываем сразу»). Гейты: Pest 218/218 sales,
Vitest 38/38, Larastan 0 в своих файлах. TDD RED→GREEN.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии
tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 12:09:24 +03:00
Дмитрий 1011a37e77 @
feat(sales): кандидат — ИНН обязателен, юрлицо отдельно от бренда, контактные лица

Замечание владельца по форме «Добавить кандидата»: телефонов бывает много, нужны
ФИО и должность человека, ИНН обязателен, бренд и юрлицо — разные вещи, юрлицо
подтягивать по ИНН через ДаData.

- БД v8.73: sales_prospects.legal_name VARCHAR(500) + contacts JSONB DEFAULT [].
  phone остаётся «главным телефоном»; inn в БД по-прежнему nullable — карточки
  из поиска и 24 живые строки могут быть без него.
- store(): ИНН обязателен + контрольная сумма ФНС; повтор ИНН у того же
  менеджера — понятный 422 вместо 500 от уникального индекса; пустые контакты
  и телефоны отсекаются; phone = первый телефон первого контакта.
- POST /api/sales/prospects/lookup-inn — юрлицо/город по ИНН через готовый шов
  PartyLookup (тот же, что в «Реквизитах»). Ничего не сохраняет; ДаData молчит
  или упала — заводим руками.
- Диалог создания: ИНН* с кнопкой «Найти», бренд*, юрлицо, блок контактных лиц
  (+человек / +телефон). Карточка показывает юрлицо и контакты со ссылками tel:.

Спека §16, CHANGELOG_schema v8.73. Гейты: Pest 28/28, Vitest 38/38,
Larastan 0 в своих файлах, rls-reviewer PASS 4/4.

LEFTHOOK_EXCLUDE: larastan/cspell падают на файлах параллельной сессии
tests/Feature/Admin/*Balances*, свои файлы проверены отдельно и чисты.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@
2026-07-18 11:39:48 +03:00
Дмитрий 5b51c738b0 feat(sales): миграция — стадия «Взят в работу» + источник карточки (search|manager)
stage CHECK += in_work (между new и negotiation); новая колонка source
VARCHAR(16) NOT NULL DEFAULT 'search' CHECK (search|manager) + индекс.
CHANGELOG_schema v8.72. RLS-review PASS 7/7 (GRANT наследуется колонкой,
идемпотентность и down() прогнаны, squawk 0).

NB: LEFTHOOK_EXCLUDE=larastan,cspell — гейты падали на ЧУЖИХ файлах параллельной
сессии (Admin/Billing тесты балансов), мои файлы их проходят.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 10:43:18 +03:00
Дмитрий 793f8d3d4e docs(golos): главный открытый хвост Александры — ПЕРЕБИВАНИЕ друг друга (barge-in)
Владелец после приёмки 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>
2026-07-18 10:22:53 +03:00
Дмитрий 34bc92ca73 Merge feat/aleksandra-knowledge-base → main: мозг знаний + Александра v9 «друг-профи»
Приносит в 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>
2026-07-17 21:14:52 +03:00
Дмитрий 7d0c06ca51 docs(golos): v9 «друг-профи» + голосовой движок engine_v9 — идеал по слуху владельца
Системный разворот характера (по разбору владельца, что 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>
2026-07-17 20:56:42 +03:00
Дмитрий 0bcfb8c09c docs(golos): эксперимент оператор+наставник v6/v7/v8 — закрыт баг «наставник пишет реплику» (разбор Перплексити)
- v6 (stand6.py): строгая 4-строчная шпаргалка МОТИВ/ХОД/ФАКТ/ФЛАЖОК — помогло частично (утечка реплики 5/8).
- Перплексити разобрала промты, дала 4 приёма (JSON, инфинитивы, few-shot, наставник-классификатор).
- v7 (stand7.py): наставник→JSON {motiv,hod,fakt,flazhok} + оператор-антипаррот + защита в коде (при срыве JSON текст наставника выбрасывается) → паррот 0/8, баг закрыт на уровне системы.
- v8 (stand8.py): наставник-КЛАССИФИКАТОР (ход = код из enum) → валидный ход 8/8, ретраи 0, паррот 0. Пойман мой баг: chat резал подчёркивания и портил коды/JSON-ключи. Зазубрина хода 7 (флэш представлялся заново на закрытии) залечена: запрет пере-представления + эскалация закрывающих ходов на хайку.
- дописан раздел 4б + обновлены шапка/стартовый блок находок.

FLOOR-ESCAPE: владелец разрешил коммит.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 11:34:44 +03:00
Дмитрий 6ed30ff042 docs(golos): эксперимент оператор+наставник v4/v5 — гибрид-маршрут, замок фактов, фикс долг/долгий
- 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>
2026-07-17 10:54:01 +03:00
Дмитрий feecf22d1f docs(golos): эксперимент оператор+наставник — фиксация (3 прогона, баги, старт-промпт) + код стендов 2026-07-17 10:33:27 +03:00
Дмитрий 1393319d65 docs(golos): телефония Mango ПРОБИТА (бот отвечает через NAT) + звук + мозг знаний
- NAT-фикс: Contact=rport (порт-дырка) + keepalive → INVITE доходит, бот берёт трубку
- звук: реплика целиком (без underrun-хрипа) + нормализация громкости перед 8-бит
- канал Cartesia через EXA-тоннель (прямой поток РФ→США режется)
- мозг знаний подключён (заплата feat/aleksandra-knowledge-base), offline-смоук OK
- рестарт-промт под компакт обновлён; тест-номер замаскирован

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 09:51:58 +03:00
Дмитрий 2bc85f6979 docs(brain): turnkey-заплата подключения мозга к движку aleksandra_engine.py 2026-07-17 09:29:02 +03:00