Commit Graph

2003 Commits

Author SHA1 Message Date
Дмитрий 6897e2aa43 docs обзвон: отчёт смены — постройка, восемь порч, зовущие поимённо
Вписано: что построено файлами, чем ронял каждого сторожа и что он сказал,
слепки возврата, числа проб, соседи, свои ошибки первыми и что осталось
несделанным.

Числа полного прогона допишутся отдельно — он ещё идёт.
2026-08-07 17:39:07 +03:00
Дмитрий dc4d835b73 телеграм-реклама: клиент видит отчёт, управление и показы
Клиент после создания рекламы был слеп: ни отчёта, ни причины отказа проверки,
ни способа что-то изменить. Закрыто.

Что теперь видит клиент
- слова «МТС» на клиентских экранах больше нет — он покупает рекламу в Телеграме
- на карточке: увидят рекламу, зарезервировано, списано, показов, кликов, подписались
- кнопки «Отчёт», «Отменить», «Повторить эту рекламу»
- отчёт даёт ПОЛНЫЙ текст причин отказа проверки, дословно
- пересдача принимает новый заголовок и новую картинку
- вердикт проверки уходит клиенту письмом, а не только в колокольчик

Показы читает робот
- новый режим read-stats: список кабинета, срок «За всё время», строка кампании
- разбор строки С КОНЦА: начало ряда плавает, хвост из 12 колонок постоянен
- прочерк площадки значит «не знаем», а не ноль, и различие доезжает до экрана
- пять колонок stats_* в client_tg_campaigns, запись v9.73 в журнале схемы
- опросчик PollTelegramStatsJob раз в час

Закрыто по дороге, сверх заказа
- утечка: закупочная цена mts_cost_rub уезжала клиенту в браузер, из пары с
  actual_cost_rub наценка считалась вычитанием
- расход площадки stats_spend_rub скрыт по той же причине
- кабинет пишет «Запущена», робот такого слова не знал: кампания висела на
  проверке навсегда, хотя реклама уже шла и деньги площадки тратились
- в runner.js висел неразрешённый конфликт слияния — робот не запускался вовсе
- сторож сессии ходил БЕЗ окна, а работа робота ходит С окном: сторож ловил отказ
  там, где работа проходила, и слал письмо каждый час о беде, которой не было
- текст отказа больше не советует менять адрес выхода — совет был ошибочный и
  увёл целую смену на поиск блокировки, которой не существовало

Замеры
- Pest tests/Feature/ClientTg 396 зелёных, смежные области 97 зелёных
- тесты робота 182 зелёных, Larastan 0 ошибок
- Vitest tests/Frontend 2231 зелёный; 5 падений кошелька — чужие, были до этого
- сторожа проверены КРАСНЫМ: подсунутые ошибки красят их, возврат кода зеленит
- живая проверка чтения цифр на настоящей кампании кабинета

П-8 «Остановить» не входит: владелец запретил нажимать «Завершить» в кабинете,
а без этого неизвестно, что она делает с деньгами.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 17:24:58 +03:00
Дмитрий 2ecfc2a562 docs обзвон: разбор задания перед постройкой — чем называть ячейку
Замерено: мост берёт метку только каноническим UUID, а нынешний номер
звонка UUID не является. Значит ячейку называем каноническим видом того же
самого uuid, из которого сложен номер звонка, — одно рождение, два вида.

Записан отказ писать в общий запасной файл и цена отпечатка тела.
2026-08-07 16:46:23 +03:00
Дмитрий d2c5675cf7 docs обзвон: скелет отчёта помощника — кладущая половина имени
Заведён каркас отчёта смены 9. Пишется по ходу работы, чтобы
несохранённое не сгорело при обрыве.
2026-08-07 16:39:48 +03:00
Дмитрий 7b54146292 docs обзвон: конец смены 8, промт смене 9 с поправками к своему же прежнему промту
Смена 8 закрыта. Два круга: набор номера построен целиком, имя за звонок построено
наполовину. Задач стало 20 из 54.

В промте смене 9 поимённо названы ТРИ неверных места промта смены 8, и все три мои.

Первое и самое дорогое. Промт смены 8 говорил, что задачу про имя за звонок брать
нельзя, только пробы в отдельное окно. Прочитал решения владельца дословно: они отложили
ПРОБЫ, а не постройку. Из-за этой строки цепочка из трёх задач простояла запертой:
перевод на менеджера начинается только после этой задачи, а на переводе стоят предел
разговора, два плеча, тариф и половина исходов.

Второе. Порядок работ ставил вторым делом предел разговора. Брать его нельзя вовсе:
отсчёт идёт от соединения с менеджером, которого в роботе нет ни одним словом.

Третье. Число требований в промте не выходило ни из одной команды: живых 111, а не 112.

Заведены три правила сверх тридцати трёх. Отложенная проба не есть отложенная постройка,
и решение владельца читается дословно в протоколе, а не в пересказе промта. Замерил что
дорога есть - замерь, можно ли по ней проехать. Зелёная проба сама по себе не доказывает
ничего: одну и ту же поломку одна проба поймала шестью проверками, а вторая осталась
зелёной.

Прибавилось пять вопросов владельцу: короткие служебные номера проходят набор, имя
человека после оборванного звонка лежит на диске час, кто хозяин выбора номера при
стройке техники связи соседней сменой, открывать ли дорогу на машине, и задвоенные
номера решений Р116-Р127 между двумя протоколами.

Мест, ждущих выката, стало восемь.

Датчики: разметка обеих бумаг 0 ошибок, все ссылки промта проверены на существование,
команда чтения метода запускалась моей рукой в начале смены.
2026-08-07 15:50:48 +03:00
Дмитрий 093ae0e04f docs обзвон: приговор по имени за звонок, первая половина З-0.1
Круг 2 смены 8 принят. Имя того, кому звонят, больше не лежит одним файлом на всю
машину: у каждого звонка своё, взятие неделимое, метка проверяется на годность, есть
замок на число линий и уборщик просроченных имён. Беда, из-за которой живого человека
уже назвали чужим именем, закрыта в коде и показана красной на старом порядке.

Задача НЕ считается построенной целиком, и счётчик не растёт: остаётся 20 из 54.
Не хватает трёх вещей, все названы помощником самим. Кладущей половины нет - набор имя
никуда не кладёт. Настройка станции не поправлена, она отдаёт всем звонкам одну метку.
Замок остаётся на одной линии, значит требование о трёх линиях сегодня не в силе.

Мои ошибки называю первыми, их две.

Шестьдесят шестая, и она стоила стройке нескольких смен. В промте смены 8, который писал
я, сказано что З-0.1 брать нельзя, только пробы в отдельное окно. Прочитал решения
владельца дословно: Р96 отложил ПРОБЫ задачи, Р101 назвал условие для проб. Ни одно не
запрещает строить. Я прочитал отложены пробы как задачу не брать и записал это запретом.
Цена видна по цепочке: предел разговора стоит на переводе на менеджера, а тот начинается
только после З-0.1 и З-0.2, и З-0.2 построена ещё пятого августа. Вся цепочка упиралась в
одну задачу, которую я сам объявил незаходимой. И вторая половина той же ошибки: порядок
работ ставил вторым делом предел разговора, а его брать нельзя вовсе - отсчёт идёт от
соединения с менеджером, которого в роботе нет ни одним словом, замерено двумя приборами.

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

Помощник разобрал задание и поправил меня четырежды, все четыре по существу. Главное:
буквальное исполнение плана было бы ПЛАЦЕБО. Метка у станции константа, значит файл
названный по номеру звонка дал бы один файл на все звонки, и беда переехала бы в файл с
другим именем, выглядя вылеченной. Второе: метка приходила позже, чем нужна - мост брал
имя раньше, чем узнавал чей это звонок. Третье: замок на линии не заодно, он
единственное что защищает человека сегодня. Четвёртое: номер звонка из круга 1 по форме
меткой не годится, но нутро то же и превращение однозначно.

Мой нож. Сломал проверку годности метки - ту, без которой лечение плацебо. Его первая
проба покраснела шестью проверками, возврат доказан слепком со снятием невидимых знаков,
сошлось знак в знак. Побочно: вторая его проба на той же поломке осталась ЗЕЛЁНОЙ.
Записал, чтобы следующая смена не считала любую зелёную пробу доказательством.

Вырезание второго рода, случай объявленный мной ДО работы. После ОБОРВАННОГО звонка файл
с именем живого человека остаётся на диске, срок хранения час. Проверка два задачи
требует чтобы файл после конца звонка исчезал и имена людей не копились: для нормального
конца исчезает, для обрыва лежит до часа. Не дыра, а названная цена, но имена это
персональные данные и час их жизни должен быть решением владельца. Выношу, сам не
закрываю.

Датчики: полный прогон моей рукой 5361 проверка, 5357 зелёных, 4 пропущено, красных 0,
арифметика сходится. Девять проверок сверх точки отсчёта НЕ наши - замерил вторым
прибором, в дереве несохранёнными лежат семь изменённых и три новых проверочных файла
соседней смены телеграма. Пробы робота 43, 27 и 179, красных нигде. Сторожа машины 26,
27, 23 зелёные. Сторож текстового следа краснеет одной проверкой, и это правильно: мост в
хранилище починен, а на машине лежит старый, выката не было.
2026-08-07 15:46:54 +03:00
Дмитрий 21c59d6188 docs обзвон: числа полного прогона и проб робота в отчёт по имени за звонок
Портал 5361 проверка, 5357 зелёных, 4 пропущено, красных 0; девять лишних
против точки отсчёта — несведённая работа соседней смены, не моя. Пробы
робота: мои 43 и 27, прежние 23, 179, 26 и 27 — красных нигде нет.
2026-08-07 15:16:54 +03:00
Дмитрий 461d6fa84d docs обзвон: отчёт по имени за звонок — построенное, сторожа, вырезание
Десять вырезаний защит, девять покраснели сразу, десятое вскрыло дыру в охране
и потребовало дописать сторож. Старый порядок краснеет с первой же тройки:
11 чужих имён из 36 звонков. Названо вслух, чего круг не доказывает и что
осталось незакрытым, включая связку выката imya_zvonka.py вместе с most.py.
2026-08-07 15:02:19 +03:00
Дмитрий cc802fadbc docs обзвон: разбор задания и замеры до работы
Четыре возражения по существу: буквальное исполнение плана даёт плацебо,
метка приходит позже, чем нужна, запасной общий файл возвращает беду,
номер звонка по форме меткой не годится.
2026-08-07 14:16:35 +03:00
Дмитрий da9d977aa1 docs обзвон: заведён отчёт помощника по имени за звонок
Скелет разделов, дальше пишется по ходу работы.
2026-08-07 14:01:05 +03:00
Дмитрий aaf339b03c docs обзвон: приговор по набору номера, З-0.12 построена, стало 20 из 54
Круг 1 смены 8 принят. Робот вправду просит станцию набрать номер: приёмник открывает
короткое соединение к служебному входу, входит и просит начать исходящий звонок через
раздел набора, а снятую трубку станция отдаёт разговорному разделу. Диалплан не тронут -
оба раздела в нём уже были, проверено и в хранилище, и на живой станции.

Резал СВОИМ ножом, шесть случаев, каждый отдельным процессом: кривой знак задания,
ответ станции без метки, ответ с чужой меткой, знакомый отказ, обрыв связи посреди
просьбы, два задания на один номер. Все шесть отработали как должно. Вырезание первого
рода: сломал его лечение своей рукой - покраснели четверо его сторожей и мой нож на том
же месте. Возврат доказан слепком со снятием невидимых знаков, сошлось знак в знак.

Вырезание второго рода дало находку, которой не резал никто. Допущение объявлено мной
ДО работы: номер из цифр длиной от трёх до двадцати - годный телефон. Случай мимо:
короткий служебный номер. Замерено на настоящем коде - приёмник соглашается попросить
станцию набрать 112, 911 и 102. Чего НЕ замерял и замерять нельзя: дойдёт ли такой
звонок до настоящей экстренной службы. Выносится владельцу, сам не закрываю.

Мои ошибки называю первыми, их три.

Шестьдесят четвёртая. В промте смены 8, который писал я, стоит спека 112 требований, и
над таблицей написано что числа собраны командой. Это число не выходило ни из одной
команды: прибор из промта даёт 98, полный перечень меток 114, живых требований 111.

Шестьдесят пятая. В задании помощнику назвал служебный вход станции годной дорогой,
замерив только что он ЕСТЬ. Замерил после: учётных записей ноль, веб-вход выключен,
папка заданий закрыта правами. Все три дороги заперты, открытие любой - правка живой
машины и слово владельца. Поправка помощнику отправлена со своей ошибкой первой строкой.

Третья, помельче. Мой собственный нож соврал на первом запуске: подставная станция
принимала одно соединение, а набор открывает новое на каждый звонок. Второй звонок
получил станция промолчала, и это выглядело бедой проверяемого. Беда была моя.

Помощник разобрал задание и поправил меня трижды, все три раза по существу и все три
поменяли постройку. Главное: у станции два способа начать звонок и они значат
противоположное. При способе дождись конца ответ не принял значит человек не ответил, а
набор при этом БЫЛ - и портал позвонил бы человеку второй раз. Взят способ не жди.
Второе: всё что не принял считать отказом нельзя, список знакомых отказов белый. Третье:
я не назвал вход, через который течёт беда - перевод строки внутри номера превращает
одну просьбу станции в две, вторую на любой номер.

Приговор ПРИНЯТО с четырьмя оговорками, все названы мной, а не найдены потом. Живого
звонка не было и быть не могло. Дорога на машине заперта, это седьмое место ждущее
выката. Короткие служебные номера проходят. И номер, С КОТОРОГО звоним, набор не
выбирает и не сообщает - он зашит одной строкой в настройке станции.

Датчики: полный прогон моей рукой 5352 проверки, 5348 зелёных, 4 пропущено, красных 0,
арифметика сходится, ровно точка отсчёта. Проба робота 179 из 179, было 108. Разметка
обеих бумаг 0 ошибок. Построено стало 20 из 54.
2026-08-07 13:44:16 +03:00
Дмитрий ab59bd277c docs обзвон: числа полного прогона в отчёт помощника
Своя база, вывод в файл, датчик — числа, а не код возврата.
Зелёные 5348 + красные 0 + ошибки 0 + пропущенные 4 = всего 5352 —
ровно точка отсчёта. Проба робота 179 из 179, шестнадцать прогонов подряд.

Слепки обоих моих файлов кода после прогона совпадают с коммитом
со снятием невидимых знаков конца строки: во время прогона их никто
не переписывал.
2026-08-07 13:15:27 +03:00
Дмитрий 1855fe126e docs обзвон: отчёт помощника — постройка, сторожа красными, вырезание, ошибки
Записано по ходу, пока полный прогон идёт. Внутри: почему станцию просим не
ждать конца звонка, почему список знакомых отказов белый, шесть поломок с
дословными словами покрасневших сторожей и слепком возврата, перепись
зовущих глазами с четырьмя ловушками счётчика, и три моих ошибки первыми —
включая ту, где мой же сторож остался бы зелёным при живой дыре.

Раздел про полный прогон дописывается отдельно, когда прогон кончится.
2026-08-07 13:02:37 +03:00
Дмитрий e06606244f docs обзвон: разбор задания и замеры до работы по набору номера
Замерено своей рукой: проба приёмника даёт 108 проверок и ноль красных;
в диалплане уже есть оба нужных раздела, поэтому узкое горло трогать не
понадобится. Названы три места, где я с заданием не согласился, и почему
это меняет постройку.
2026-08-07 12:13:44 +03:00
Дмитрий 21ff2cd5db docs обзвон: заведён отчёт помощника смены 8 по набору номера
Скелет разделов заведён до всякой разведки, чтобы записи не сгорели вместе
с контекстом. Дальше файл наполняется по ходу работы, а не в конце.
2026-08-07 12:07:49 +03:00
Дмитрий 7f7c752c96 docs обзвон: приговор по запрету переадресации, конец смены 7, промт смене 8
Круг 2 принят. Дыра, которой никто не искал, закрыта во всех пяти построениях запроса
четырёх файлов. Замерено МОИМ ножом, тем же, каким находилась: на трёх плечах отдельным
запуском, включая пачечное плечо боевого Поиска клиентов, до неразрешённой машины не
доехало ничего.

Датчик проверен на БОЛЬНОМ случае, а не только на здоровом: снял запрет в одном месте,
утечка вернулась вместе с зелёной плиткой и чужим адресом на ней, двое его сторожей
покраснели на моём сломе. Возврат доказан слепком со снятием невидимых знаков.

Вырезание второго рода: допущение лечения - запрет стоит на КАЖДОЙ отправке. Собрал
отправки командой по всем четырём файлам: их пять, запрет на каждой, перечень полон.

Мои ошибки называю первыми, их две новых.

Шестьдесят вторая. Мой прибор копит улики в файл, а я перед замером проверял живость
подставной машины СВОИМ ЖЕ запросом - и он записался туда же. Первый замер после починки
показал утечка есть. Спасло только то, что я посмотрел, ЧТО ИМЕННО доехало: там стоял curl
и не было заголовка с ключом.

Шестьдесят третья. Числа полного прогона вписал в свою бумагу из отчёта помощника, пока
свой прогон ещё шёл. Сошлись знак в знак, но это удача, а не порядок: первое правило метода
гласит, что отчёт помощника не доказательство, и своей бумагой я его нарушил. Дождался
своего.

Помощник поправил меня по существу трижды и все три раза был прав: мест не четыре, а пять,
дверь голосового робота в бою не зовёт никто, и есть пятое место того же класса, у которого
двери нет вообще. Он же снял мою ложную тревогу: всё, что возит секрет через Authorization,
этой болезнью не больно, библиотека снимает такой заголовок сама.

Промт смене 8 написан. В нём поимённо названы ЧЕТЫРЕ неверных места промта смены 7, три из
них мои ошибки, и самое опасное: я назвал чужим файл, который был работой нашего же
помощника. Исполни следующая смена мой промт дословно, починка сгорела бы.

Датчики: полный прогон моей рукой 5352 проверки, 5348 зелёных, 4 пропущено, красных 0,
арифметика сходится. Разметка 0 ошибок. Задач 54, построено 19, требований 112, решений 127.
2026-08-07 11:13:01 +03:00
Дмитрий 8d96cda70b docs: в отчёт смены вписаны номера обоих коммитов
Чтобы файл читался сам по себе, без обращения к истории.
2026-08-07 10:39:39 +03:00
Дмитрий 171f531b61 docs приёмка: Т-М2 закрыта — живое одобрение МТС с движением денег
07.08 в 10:31 МТС одобрил кампанию №15. Числа сошлись с посчитанными ЗАРАНЕЕ
до копейки: кабинет взял 182.40, наценка 1.4 → списано 255.36, остаток 13.44
отпущен в ту же секунду, баланс 9869.50 → 9614.14, заморожено → 268.80.

Одобрение чуть не потерялось: кабинет написал седьмое слово «Запущена», словарь
робота знал шесть. Снаружи это неотличимо от «вердикта нет» — вскрыли, заглянув
в кабинет разовой пробой на чтение. Чинились ОБЕ половины (разбор и поиск ряда),
как предупреждает комментарий в коде; сторожа на обеих, тесты робота 202 → 206.

Непроверенной во всём блоке осталась одна вещь — живая половина пересдачи Т-М4:
для неё нужен свежий отказ МТС, а кампания одобрена.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 10:39:25 +03:00
Дмитрий 9ba2a6a49b fix(безопасность): за переадресацией не ходим — тайный ключ больше не уезжает чужому
Дверь проверяет адрес из настройки. Если разрешённая машина отвечает «иди на
другой адрес», перевозчик по умолчанию туда идёт и везёт наш заголовок дальше:
при уходе на чужой адрес Guzzle снимает только Authorization и Cookie, а
X-Render-Key и X-Obzvon-Key не из них.

Замерено до правки на подставных машинах: ключ рендера доехал до неразрешённой
машины из ленты Яндекса, из поиска клиентов одиночным запросом и пачкой, из
плитки прокси — и плитка при этом горела зелёным, показывая ЧУЖОЙ IP как свой.
Ключ голосового робота уезжал вместе с заданием.

Поставлен withoutRedirecting в пяти строениях запроса четырёх файлов. У
SelfRenderClient их два: пачка строит запрос сама, и запрет из одиночного пути
туда не доезжает — проверено вырезанием, снятие запрета только с пачки роняет
отдельного сторожа и даёт по утечке на каждый адрес порции.

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

Сторожа: app/tests/Feature/Security/KlyuchNeEdetPoPereadresaciiTest.php, 8
проверок, смотрят на запись переговоров, а не на текст исходника. Каждый показан
красным снятием своего запрета по одному. Отдельная проверка «датчик сам жив»
падает, если подставная сеть перестанет ходить за переадресацией, — иначе
остальные сторожа молча стали бы пустыми.

Отчёт смены: docs/superpowers/priyomka/stroyka-7/otchyot-pomoshchnika-zapret-pereadresacii-2026-08-07.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 10:37:22 +03:00
Дмитрий cc9a1a91a7 docs: заведён отчёт смены по запрету переадресации с тайным ключом
Скелет разделов. Пишется по ходу работы, чтобы не сгорело при обрыве.
2026-08-07 09:38:26 +03:00
Дмитрий 459947f76b Р126 третья дверь: работа оборванного круга сохранена и принята, дыра переадресации найдена
Круг смены 6 оборвали средой, работа помощника лежала в дереве несохранённой и её снёс бы
первый же чужой откат. Замерил целостность, прочёл его отчёт, прогнал своей рукой, вынес
приговор. Заново ничего не переделывал.

ПРИНЯТО. Третья и последняя дверь с ключом рендера закрыта той же проверенной дверью.
Список разрешённых машин общий с рендером и это доказано работой, а не доводом. Закрытая
дверь красит СЕРЫМ, а не красным, и ключ при этом физически никуда не уходит, замерено мной
двумя случаями по отдельному запуску на каждый.

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

Мои ошибки называю первыми, их три.

Пятьдесят девятая. Я назвал adminDashboardHelpers.ts чужим файлом соседней смены прямо в
промте смене 7, в списке не трогать и в коммит не брать. Взял из головы, не замерив. Вся
правка в этом файле - работа моего же помощника. Исполни следующая смена мой промт дословно,
починка подписи плитки не попала бы в коммит и сгорела.

Шестидесятая. Мой снимок оборванного круга был неполон: записал шесть файлов, их семь.
Перечень собрал командой, но раньше, чем помощник закончил, и не перемерил перед тем, как
назвать его окончательным.

Шестьдесят первая. Мой датчик прогона искал не то слово и я чуть не объявил состоявшийся
прогон несостоявшимся. Спас узкий прогон, которым я прибор перепроверил.

Вырезание второго рода дало дыру. Допущение защиты: дверь проверяет адрес из настройки и
считает, что запрос уйдёт именно туда. Случай мимо: разрешённая машина отвечает иди на другой
адрес. Замерено на двух подставных машинах: тайный ключ уехал на машину, которой в списке
разрешённых НЕТ, а плитка осталась ЗЕЛЁНОЙ и показала чужой адрес как свой. Перемерил на
живой двери боевого Поиска клиентов тем же ножом, отдельным запуском - то же самое. Причина
прочитана в исходнике библиотеки: при уходе на чужой адрес снимаются только два заголовка,
и нашего среди них нет. Вторым прибором замерено, что отключения переадресации нет нигде во
всём боевом коде. Это не отменяет Р126, дверь делает обещанное на своих случаях, но обещание
шире дела и про это не сказано нигде. Отдельным кругом.

Датчики: полный прогон моей рукой на своей базе 5344 проверки, 5340 зелёных, 4 пропущено,
красных 0, арифметика сходится. Проверки интерфейса 3 из 3. Разметка 0 ошибок.
2026-08-07 09:29:23 +03:00
Дмитрий 61182a1c55 docs обзвон: конец смены 6, проверка расписания закрыта живьём, круг 7 оборван
Смену остановил владелец. Довожу до логического конца.

Проверка 1 задачи З-0.10 закрыта ЖИВЬЁМ. Доказать её раньше 02:20 ночи было
нечем, я записал замену и назвал вслух, чего она не доказывает. Дождался и
замерил: 07.08.2026 в 02:20:01 машина робота обошла своих сторожей САМА, без
человека, за две секунды, все три зелёные, итог лёг со своей датой. Уборка
записей чужих голосов перестала зависеть от человеческой памяти, и это замерено,
а не обещано. Журнал того же обхода честно говорит отправка не настроена:
портальная половина не выкачена, и краснота одной проверки из 42 у сторожа обхода
и есть датчик завершённости выката.

Круг 7 оборван на середине. Помощник закрывал третью дверь с тем же тайным ключом
и не успел сохранить работу коммитом. Файлы перечислены поимённо в промте смене 7,
раздел 3.2, вместе с порядком: замерить целостность, прочесть его отчёт, прогнать
своей рукой, вынести приговор, НЕ переделывать заново. Приёмочный лист по этому
кругу не заведён, и это записано.

Итог смены. Задач 54, врезок ПОСТРОЕНО 19, требований 112, решений владельца 127.
Полный прогон 5301 проверка, 5297 зелёных, 4 пропущено, красных 0.

Мои ошибки: их одиннадцать, с 48 по 59, и все одного класса, прибор мерил не то,
о чём я спрашивал. Тяжелейшие три. Пятьдесят пятая: построил главный довод
задания на ложном замере, назвав упоминания зовущими. Пятьдесят восьмая: назвал в
задании одну дверь с тайным ключом, а их оказалось три. Пятьдесят девятая: вынес
владельцу цену решения, взятую из головы, а не из замера.

Правил стало 30, шесть добыты этой сменой.
2026-08-07 08:41:29 +03:00
Дмитрий 0bf43bfd1f docs приёмка: Я3 и Я4 закрыты по сроку — последние комбинации Яндекса 2026-08-07 08:38:44 +03:00
Дмитрий 8167dc7d79 docs приёмка: Я3 и Я4 закрыты по сроку — последние комбинации Яндекса
Срок обеих кампаний истёк 07.08 в 00:00 UTC, портал сам закрыл их и вернул
неоткрученное. Числа сняты с боевой базы, арифметика сходится до копейки:
833.50 - 9.00 = 824.50 и 833.50 - 40.50 = 793.00.

Я-Д5 воспроизвёлся трижды за четыре секунды на разных суммах — возврат по сроку
работает не по случайности.

Предсказание сбылось наполовину: Я4 обещали ~160 показов, вышел 81; Я3 обещали
ноль, вышло 18. Скорость по одному часу для суточного предсказания не годится.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 08:37:58 +03:00
Дмитрий d7b77d25f2 docs обзвон: приговор по восьмёрке в номере, цена решения названа честно
Решение владельца Р127 исполнено коммитом 56ddaa1e. Мой нож замерил: восьмёрка и
семёрка дают теперь ОДИН знак и ОДНО тело, границы держатся, семизначный и
тринадцатизначный номера не тронуты, казахстанский со своим знаком, и правило
устойчиво к повторному приведению.

Моя ошибка первой, пятьдесят девятая. Вынося развилку владельцу, я написал, что у
одиннадцати цифр с восьмёркой второго толкования нет. Я взял это из головы, НЕ
ЗАМЕРИВ. Второе толкование есть: иностранные номера длиной ровно одиннадцать
цифр с кодом на восьмёрку. Большинство дают несуществующий российский номер, но
вьетнамский превращается в живой подмосковный код, и род ошибки меняется с
звонок не состоится на звонок состоится, но не тому человеку.

Правило велит выносить развилку с полным набором дорог. Дороги я вынес полные, а
цену неполную, и владелец решал, не зная её.

Смягчает это одно, и не моя заслуга. Помощник докопал дальше и поправил САМ СЕБЯ:
общий нормализатор телефонов портала живёт в двадцати файлах, включая сам обзвон,
и делает ровно то же самое. Вьетнамский номер портится на входе везде уже
сегодня. Р127 опасности не добавляет, он прекращает расхождение обзвона с
остальным порталом.

Его находка, которую я перемерил своим прибором и подтверждаю: пара из десяти и
одиннадцати цифр даёт ДВА знака на одного человека, и ему позвонят дважды. При
этом общий нормализатор и проверка запрета звонить считают ту же пару ОДНИМ
человеком. То есть беда, ради которой принято Р127, на этой паре жива. Он не стал
чинить и правильно: лечение шире решения, надо сводить три разных канона
телефона, живущих в обзвоне, а один из них сторожит запрет звонить. Вынесено
открытым вопросом первым номером.

Ошибка помощника, названная им первой, редкого рода: он назвал цену нечестно и
едва не отдал её в таком виде, подав общую беду портала как новую опасность
решения. Проверил дальше и поправил себя прямым текстом. Это ровно то, чего метод
требует от надзирателя и чего надзиратель на этот раз не сделал: сперва замер,
потом слово.

Датчики: решений 127, разметка 0 ошибок, правописание протокола 0 жалоб.
Прогон 5301 проверка, 5297 зелёных, 4 пропущено, красных 0.
2026-08-07 08:36:21 +03:00
Дмитрий 56ddaa1ed4 fix обзвон: один человек, записанный через 8 и через +7, получал два звонка
Решение владельца Р127. В `odinVidNomera` восьмёрка приводится к семёрке
ТОЛЬКО когда цифр ровно одиннадцать. Короткие и длинные номера не трогаются
вовсе: слить двух разных людей в один знак — ошибка тише и хуже, второму не
позвонили бы никогда и молча.

Замерено до правки: `8 999 000-00-01` и `+7 999 000-00-01` давали два разных
знака и два разных тела. Сторожа смотрят на то, что вправду уехало роботу, и
сравнивают дословно — так же, как сравнивает приёмник.

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

Названная владельцу цена: иностранные одиннадцатизначные номера с кодом на
восьмёрку это правило портит. Вьетнамские `8496…`/`8497…`/`8498…` станут
похожи на живые коды Московской области — робот позвонит чужому человеку.
Лечится чисткой номеров на входе, это отдельная задача. Подробности и
незакрытые хвосты — в отчёте.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 08:25:28 +03:00
Дмитрий 09ed5e1b31 docs обзвон: приговор по двери боевого рендера, дверей оказалось три
Решение владельца Р126 исполнено коммитом 92472816, и исполнено ШИРЕ, чем я
заказал.

Моя ошибка первой, пятьдесят восьмая. Я назвал в задании ОДНУ дверь, через
которую уходит тайный ключ боевого Поиска клиентов. Помощник замерил: дверей
ДВЕ, и вторая шлёт тот же ключ по той же настройке. Перепроверил вторым прибором
на версии до его правки: у второй двери был ровно тот же вид проверки и тот же
заголовок с ключом. Почини он только названный мной файл, решение владельца
осталось бы невыполненным, а дыра открытой. Отсюда правило 29: одно найденное
место это находка, а не перечень.

И третья дверь нашлась потом: та же тайна уходит из плитки срока прокси по
другой настройке. Помощник назвал её и НЕ тронул, правильно. Перемерил сам,
вынес владельцу, закрыто отдельным заходом.

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

Помощник назвал свою ошибку первой, и она новая для этого проекта: он запустил
полный прогон раньше, чем закончил правку стиля, и через четыре минуты форматтер
переписал два его файла прямо во время прогона. Зелёный цвет такого прогона не
доказывает ничего. Отсюда правило 30.

Вторая его ошибка честнее первой: проверка покраснела на его же оплошности, и
первым побуждением было подогнать код под ошибку. Поправил проверку.

Оговорка, которую называю вслух. Боевое значение настройки адреса НЕ ЗАМЕРЕНО и
замерить его нельзя, это доступ к боевому. Перед выкатом нужна одна команда,
показывающая, начинается ли адрес с шифрованной схемы. Начинается с
нешифрованной, выкатывать нельзя: лечение не обход, а перевод на шифрование,
сертификат на виртуалке уже работает.

Датчики: разметка 0 ошибок, ссылки живые.
2026-08-07 08:14:19 +03:00
Дмитрий c2b3fe47fc docs: промт-передача следующей сессии по вкладке «Активность» 2026-08-07 08:12:50 +03:00
Дмитрий 0181f2e3e7 docs: промт-передача следующей сессии по вкладке «Активность»
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 08:12:36 +03:00
Дмитрий e4a4766c50 docs: план переделки вкладки «Активность» под вопрос «жив ли клиент» 2026-08-07 08:05:53 +03:00
Дмитрий 16d8191d08 docs: план переделки вкладки «Активность» под вопрос «жив ли клиент»
11 задач по TDD: два сервиса на бэкенде (вердикт с полоской и лента дел из
пяти источников), ручка подгрузки, живая сортировка списка клиентов, типы и
маппер, русские фразы, панель Vue, точка состояния в списке, полный прогон,
приёмка глазами.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 08:05:43 +03:00
Дмитрий 9247281688 fix поиск клиентов: дверь к рендер-виртуалке — разрешённые машины и обязательное шифрование, Р126
Тайный ключ SELF_RENDER_KEY уходил заголовком X-Render-Key на любой адрес, какой окажется
в настройке. Проверялось ровно одно: адрес не пуст и ключ не пуст. Отсюда две молчаливые беды:
опечатка в SELF_RENDER_ENDPOINT увела бы ключ чужому человеку навсегда и без признаков,
а http:// увёз бы его открытым текстом.

Дверь повторяет проверенное устройство Р123 от голосового робота: своя причина на пустой
адрес и на пустой ключ, список разрешённых машин с пустым списком как «закрыто всё»,
обязательное https кроме своей машины, а «своя машина» — два независимых ответа: окружение
из положительного списка И двоичная проверка петли 127.0.0.0/8, ::1, localhost по RFC 6761.
Закрытая дверь = мягкая деградация: наружу не ходим, отдаём пусто, причина в журнал уровнем
warning, потому что на боевом всё ниже не доезжает.

Тумблера «можно без шифра» нет намеренно: он и был бы той самой опечаткой.

Дыр было ДВЕ, а не одна. Тот же ключ и тот же SELF_RENDER_ENDPOINT уходят из
RenderServiceYandexListSource — лента Яндекс.Карт. Починка только названного файла оставила
бы дыру открытой, поэтому дверь общая на обе.

Боевой поиск не сломается: умолчание списка НЕ пустое и содержит замеренный боевой адрес
виртуалки 51-250-1-97.sslip.io — пустое умолчание остановило бы поиск в момент выката.
Набор тот же, что владелец уже принял для OBZVON_ALLOWED_HOSTS: это одна и та же машина.
Прогнаны все формы адреса, какие могут стоять в боевой настройке, в окружении production.

Проверок 37, сторожа показаны красными пятью отдельными сломами, возврат доказан слепками.
Larastan 0, Pint чисто.

Не закрыто и ждёт слова владельца: ProxyMarketProbe шлёт тот же ключ на другую настройку
без двери; боевое значение SELF_RENDER_ENDPOINT не замерено, на боевой не ходил.

Отчёт: docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-r126-dver-rendera-2026-08-07.md
2026-08-07 08:04:35 +03:00
Дмитрий 475e2d6245 docs обзвон: знак и тело больше не расходятся, промт смене 7 написан
Портальная причина дыры закрыта коммитом a4ff69aea. Помощник выбрал путь, где
портал считает опознавательный знак задания САМ внутри вызова, а наружу
принимает то, из чего знак складывается. Рассогласовать стало нечего.

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

Мой нож мерил не текст, а то, что вправду уезжает роботу. Один человек в двух
записях даёт один знак И одно тело. Строка без цифр закрывает дверь, наружу не
уходит ничего. Вторая попытка и другой клиент дают другой знак.

И мой нож замерил цену того, что помощник НЕ стал чинить осознанно: человек,
записанный восьмёркой и семёркой, считается двумя разными, и ему позвонят
дважды. Он нашёл это сам и вынес владельцу, потому что ошибка в обратную сторону
тише и хуже: слияние двух разных людей означало бы, что второму не позвонят
никогда и молча. Владелец закрыл это решением Р127: восьмёрку приводим к
семёрке только у одиннадцатизначных номеров.

Лучшая ошибка смены, названная помощником первой: его главный сторож был слеп
ровно к той половине беды, ради которой писался. Он сверял согласие с точностью
до приведения номера, а робот сравнивает тело дословно. Вернул беду в код,
сторож остался зелёным. Не сломай он свою починку руками, сдал бы работу с
дырявым главным сторожем.

Промт смене 7 написан: docs/superpowers/2026-08-10-PROMT-obzvon-stroyka-4.md.
В нём правила стройки вперёд всего, 57 ошибок надзирателя, 28 правил, числа
собраны командой, порядок работ и три ловушки, которые выглядят правильными.
В промте смены 6 поставлен указатель, что он отработан.

Датчики: задач 54, врезок ПОСТРОЕНО 19, требований 112, решений 127.
Разметка 0 ошибок, правописание протокола 0 жалоб, все ссылки промта ведут к
живым файлам.
2026-08-07 07:53:48 +03:00
Дмитрий c298789eef docs: спека переделки вкладки «Активность» под вопрос «жив ли клиент» 2026-08-07 07:49:07 +03:00
Дмитрий c9daf48bdc docs: спека переделки вкладки «Активность» под вопрос «жив ли клиент»
Замерено на боевом: вкладка читает журнал сделок, где 364 из 419 строк —
системные «робот залил лид». Данные про входы и про дела клиента лежат в
двух других журналах и на вкладку не попадают вовсе.

Решения владельца: вердикт + полоска 90 дней + лента только дел, пороги
3 и 14 суток, входы только сверху, заодно чиним мёртвую сортировку списка
клиентов по последней активности.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 07:48:57 +03:00
Дмитрий a4ff69aea3 fix обзвон: знак задания и номер в теле больше не могут разойтись
Портальный клиент голосового робота считал опознавательный знак задания от
ОДНИХ ЦИФР телефона, а в тело задания клал номер КАК ЕСТЬ. Один и тот же
человек, записанный `+7 999 000-00-01` и `79990000001`, давал ОДИН знак и
РАЗНЫЕ тела. Приёмник робота сравнивает тело дословно и на такую пару
отвечает отказом — то есть честный повтор получал отказ вместо звонка.

Вторая половина той же беды: знак и телефон приходили в `pozvonit` ДВУМЯ
независимыми доводами, и ничто не заставляло их сойтись. Работник очереди,
посчитавший знак один раз и перебирающий номера, отправил бы роботу
рассогласованную пару, и человеку не позвонили бы молча.

Что сделано:

- заведено ОДНО место приведения номера — `ObzvonClient::odinVidNomera`;
  оба потребителя берут номер оттуда: и знак, и тело задания;
- `pozvonit` больше НЕ принимает знак снаружи. Он принимает то, из чего знак
  складывается — арендатор, кампания, номер, попытка, — и складывает знак сам.
  Рассогласовать нечего: второго номера в клиенте не существует;
- отказ по номеру теперь считается по признаку "в номере ноль цифр", а не по
  `trim`. Раньше строка вроде "абв" проходила дальше и давала ОДИН И ТОТ ЖЕ
  знак на все такие задания — два разных задания столкнулись бы знаками у
  робота, и одному из людей не позвонили бы вовсе;
- в докблоке `pozvonit` вслух записано следствие решения владельца Р124:
  номер попытки нельзя прибавлять на исходе, где звонок МОГ состояться, —
  иначе знак станет другим и защита не сработает именно в том случае, ради
  которого заведена.

Разбор ответа робота, пределы времени, предел одновременных и проверка
шифрования Р123 не тронуты.

Мерки. Сторожа роняли работой, а не текстом: возвращали беду в код и
смотрели на то, что уходит подставному роботу.

- вернул в тело номер "как есть" — 4 красных из 55;
- вернул знак доводом снаружи — 1 красный из 55, сторож читает доводный ряд
  метода через `ReflectionMethod`, а не текст файла;
- возврат доказан слепком со снятием невидимых знаков конца строки,
  после возврата 55 из 55 зелёных;
- полный прогон на своей базе: 5293 проверки, 5289 зелёных, красных 0,
  ошибок 0, пропущено 4; арифметика сходится;
- `composer stan` — 0 ошибок, `pint --test` — passed.

Открытым оставлено и названо в отчёте: `8...` и `+7...` сегодня разные люди
для портала; `dopolnitelno` обязано быть одинаковым у повтора; правило счёта
попыток не назначено.

Отчёт: docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-znak-tela-2026-08-07.md
2026-08-07 07:43:34 +03:00
Дмитрий 4513fe1a58 docs приёмка: дефект М-1 выкачен на боевой и доказан живыми данными 2026-08-07 07:34:28 +03:00
Дмитрий a0c660704c docs приёмка: дефект М-1 выкачен на боевой и доказан живыми данными
Задание 88 закончилось после выката и принесло ту же дату старта, а время
изменения кампании №15 осталось от прошлого задания. Раньше совпадало с концом
каждого задания до секунды — значит строку больше не трогают и счётчик 48 часов
пошёл по-настоящему.

Никого не стёрли: перепись боевого 1031 файл до и после, боевая копия файла до
выката побайтово равна прежней версии, после — новой.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 07:33:36 +03:00
Дмитрий 9eba348ee8 fix телеграм: счётчик зависшей модерации сбрасывался каждой проверкой робота 2026-08-07 07:19:00 +03:00
Дмитрий 1464fd5c3f fix телеграм: счётчик зависшей модерации сбрасывался каждой проверкой робота
Кампания, застрявшая на модерации дольше 48 часов, обязана уйти в ручной
разбор — иначе висит вечно с замороженными деньгами клиента и молча.
Срок считается по времени изменения строки, а вчерашняя правка «день начала
показов» писала дату при КАЖДОЙ проверке робота массовым обновлением, которое
всегда двигает updated_at. Робот ходит раз в четверть часа — счётчик не
досчитал бы никогда. Защита была цела на вид и мертва на деле.

Улика с боевого: у кампании №15 время изменения строки совпадало с концом
последнего задания робота до секунды, при том что вердикта не было третьи сутки.

Пишем дату, только если она вправду изменилась. Сравнение сырых значений мимо
приведения типов: starts_on это date:Y-m-d, сравнение с Carbon разошлось бы молча.

Сторожа SchyotchikZavisshejModeraciiTest (3 шт) видены красными до правки.
Блок телеграма 381 зелёный на своей базе, статанализ 0, pint чисто.
На боевой НЕ выкачено.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 07:18:27 +03:00
Дмитрий 30424a4b52 fix телеграм: счётчик зависшей модерации сбрасывался каждой проверкой робота 2026-08-07 07:18:03 +03:00
Дмитрий d3f190806a @' 2026-08-07 07:04:13 +03:00
Дмитрий b522d98afe @
fix: письма о недоливе — одна сводка в сутки вместо потока на каждом прогоне

Сверка с поставщиком шла каждые 30 минут и на каждом прогоне слала письмо
на КАЖДУЮ пару (тенант, дата) с недоливом больше 20%. Вчерашняя дата остаётся
в окне сверки, поэтому поток рос день ото дня: 144 письма 27.07 → 510 за 06.08,
около 3000 за 12 дней на ops@liderra.ru.

Теперь пары собираются в один список и уходят одной сводкой раз в сутки
(отсечка по московской дате в redis; гонки нет — handle держит общий lock).
Частоту самой сверки не трогал.

Поштучный TenantBusinessDriftAlertMail с шаблоном удалён — стал мёртвым.

Тесты: сводка собирает все пары в одно письмо, второй прогон в те же сутки
молчит, в новые сутки письмо уходит снова. Красными их видел.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@
2026-08-07 07:02:45 +03:00
Дмитрий 575b6d6491 docs обзвон: приняты З-0.3, З-3.1 и половина З-0.6, в плане нашлась дыра
Три приговора вынесены своей рукой. Плюс в план заведена новая задача по
решению владельца и записаны четыре его решения.

З-0.3 принята, коммиты 18f933550 и dd3b6fb4b. Портальная половина шва: клиент
умеет позвать робота, спросить состояние, остановить, мягко деградировать и
требовать шифрования. Мой нож проверил восемь форм адреса на боевом окружении:
большие буквы, порт и пробелы проходят, четыре опасные формы закрыты, каждая со
своей причиной словами.

З-3.1 принята, коммит 5dfe32dc9. Ловушка решения Р115 закрыта и проверена моим
ножом на каждом часе суток: менеджер в Москве с 14 до 18 и получатель во
Владивостоке дают ноль общих часов, а менеджер с 10 до 18 даёт ровно три, и
арифметика сходится знак в знак. Что живая рассылка клиентов не изменилась,
помощник доказал не тестами, а вычитанием: 144 816 сверок, ноль расхождений,
прибор показан красным подложенной поломкой.

З-0.6 принята КАК ПОЛОВИНА и половина честная: из восьми проверок задачи закрыта
одна, две частично, пять не закрыты. Построен приёмник заданий с памятью знаков
на сутки по решению Р124. Мой нож нашёл дыру: тот же знак с другим телефоном
приёмник считал повтором, молча не звонил второму человеку и отдавал порталу
номер звонка первого. Закрыто доделкой, теперь громкий отказ.

Главная находка смены крупнее всех задач. Помощник разобрал моё задание и
сказал, что между принять задание и отчитаться лежит САМ НАБОР НОМЕРА, а его нет
нигде в плане. Проверил вторым прибором, перебрав все 53 задачи поимённо: он
прав. Диалплан набирать умеет, а начать звонок некому. Владелец решил завести
отдельную задачу, она заведена как З-0.12 и стоит сразу за швом.

Мои ошибки, их четыре за эти круги, и все одного класса.

Пятьдесят третья. Завёл приёмочный лист ПОСЛЕ отправки задания, а не до. Ровно
на этом месте метод и рассыпается: лист, написанный после, подгоняется под то,
что вышло.

Пятьдесят пятая, самая тяжёлая. Я построил главный довод задания на ложном
замере. Написал, что правило часов зовут двенадцать файлов живого модуля, что
обзвон уже читает его через тарификатор и что у проверки часа двенадцать мест
боевого кода. Все три неверны: зовущих пять, тарификатор правило не читает
вовсе, у проверки часа один боевой зовущий. Помощник разбил все три, я перемерил
и подтвердил. Перечень я собрал командой, как велит правило, но команда считала
УПОМИНАНИЯ, а я назвал их зовущими.

Пятьдесят седьмая. Моя подсказка к решению Р123 привела бы к негодной починке:
сторожа были бы зелёными при живой дыре. Помощник показал это замером.

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

Решения владельца, закрытые 07.08.2026: Р122 подпись письма вместо слова в
адресе, Р123 шифрование к роботу кроме своей машины, Р124 робот помнит знаки
сутки, Р125 номер без общего окна не набираем и говорим клиенту до запуска,
Р126 дверь боевого Поиска клиентов чинится отдельным заходом.

Датчики: задач 54, врезок ПОСТРОЕНО 19, требований 112, решений 126.
Разметка 0 ошибок, правописание протокола 0 жалоб.
2026-08-07 06:47:54 +03:00
Дмитрий dd3b6fb4b5 fix обзвон: к роботу только по шифрованной дороге, кроме своей машины — Р123
Дверь пускала http к разрешённому хосту, и тайный ключ уезжал заголовком
открытым текстом — молча, без единого признака. Одной опечатки в OBZVON_ENDPOINT
хватало. Теперь адрес без шифрования портал не принимает: дверь закрыта, звонка
нет, причина сказана словами и лежит в журнале уровнем предупреждения.

Исключение ровно одно — разработчик на своём компьютере — и устроено оно ДВУМЯ
независимыми ответами, чтобы одной перепутанной настройки на боевом для утечки
не хватило:

1. приложение само говорит, где живёт: спрашиваем Laravel, а не список слов.
   Список окружений положительный, а не «всё кроме боевого»: любое неназванное
   окружение обязано шифрование.
2. робот стоит на ЭТОЙ ЖЕ машине: адрес ведёт на петлю — вся сеть 127.0.0.0/8,
   ::1, ::ffff:127.x.x.x, имена localhost и *.localhost по RFC 6761. Определяется
   двоичным сравнением адреса, а не совпадением слов. Резолвер имён не зовём
   намеренно: он вносит в проверку безопасности неопределённость и щель между
   «проверили» и «пошли».

Именно второй ответ и закрывает то, что владелец назвал незакрытым: одной
ошибки в APP_ENV на боевом теперь мало — боевой робот петлёй не станет. На это
стоит именной сторож.

Тумблера «можно без шифра» нет намеренно: он и был бы той опечаткой, ради
которой Р123 принято.

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

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

Найдено и НЕ тронуто второе место того же класса: services.self_render шлёт
секрет заголовком, и его дверь не проверяет ни схему, ни хост вовсе. Путь живой,
боевой. Вынесено решением владельцу отдельно.

Отчёт: docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-r123-shifrovanie-2026-08-07.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:31:35 +03:00
Дмитрий f671e21d01 fix обзвон: знак тот же, а тело задания другое — второму человеку не звонили молча
Замерено владельцем на приёмнике заданий: знак задания тот же, телефон в теле
другой. Приёмник считал это повтором, второму человеку не звонил вовсе и отдавал
порталу номер звонка ПЕРВОГО задания — портал привязал бы итог чужого разговора
к другому человеку.

Теперь вместе со знаком запоминается отпечаток тела задания. Тот же отпечаток —
вправду повтор, ведём себя как прежде. Другой — не повтор, а ошибка портала:
отвечаем 422, набора нет, чужой номер звонка не отдаём, память первого задания
не трогаем.

Почему 4xx, а не 5xx: по второму телу мы не набирали ничего, и это правда. 5xx
сказало бы «звонок мог состояться», портал пометил бы человека как «может быть,
звонили» и не позвонил бы ему никогда — та же беда, только навсегда.

Отпечаток считается вычитанием, а не перечислением: вычтен один знак задания,
всё остальное — включая поле, которое заведут завтра, — под защитой. Снят под
тайным ключом, поэтому персональных данных в открытом виде в памяти нет.

Проба приёмника: было 81 проверка, стало 108. До починки 7 красных, после 0.
Починку ломал тремя разными ломами, все три покраснели; слепок приёмника после
возврата совпал знак в знак.

Портальная сторона не изменена ни строкой. Причина беды — там: портал даёт
передавать знак и телефон врозь. Вынесено владельцу отдельным пунктом отчёта.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 06:23:47 +03:00
Дмитрий 5dfe32dc91 feat: окно часов обзвона — общая рамка и своё окно клиента, З-3.1
Правило часов остаётся ОДНО и живёт в боевом SmsQuietHours — решение
владельца Р76. Обзвон получает не копию правила, а тонкую обёртку
ObzvonOknoChasov со своими числами: Р76 отдал в общее пользование
ПРАВИЛО, а не ГРАНИЦЫ. Админ, поправив окно рассылок, окно обзвона
не двигает.

Два окна живут в разных часах, и рамка — их пересечение, Р115. Часы
менеджера приходят вместе со СВОИМ смещением, LocalHoursWindow, и
меряются им, а не смещением получателя. Иначе московские 14:00-18:00
были бы прочитаны как владивостокские, робот перевёл бы звонок на
спящего менеджера, а на экране и в журнале всё бы сошлось.

Окно клиента только сужает рамку, Р64: 09:00-22:00 принимается как
10:00-20:00. Часы целиком вне рамки и непересекающиеся из-за поясов
окна дают пустой ответ «звонков не будет» — это ответ, а не молчание.

Входящие окном не ограничены, Р35: спросить обёртку про приём звонка
физически нечем, и на это стоит сторож.

Живая рассылка СМС не изменилась ни на один час — доказано вычитанием
против старого правила из git HEAD: 144 816 сверок на 13 поясах, всех
1440 минутах суток и 7 наборах границ, расхождений 0. Прибор показан
красным: подложенная поломка в один знак дала 6049 расхождений.

Подпись canSendNow не менялась — новое условие вошло третьим
необязательным доводом с умолчанием. nextWindowOpensAt, earliestOpening
и isValidWindow не тронуты вовсе. Границы читаются один раз на объект:
20 000 номеров — ровно один запрос к базе.

Сторожа показаны красными пятью врезами; дословные сообщения, разбор
задания и незакрытые хвосты — в отчёте
docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-z-3-1-okno-chasov-2026-08-07.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 05:58:59 +03:00
Дмитрий f409f8746b feat обзвон: робот принимает задание от портала — роботная половина шва З-0.6
Портальная половина шва построена 06.08.2026, а на роботной стороне не было
никого: приёмника заданий не существовало. Теперь есть.

Что построено

- bots/lena-golos/priyomnik.py — три ручки pozvonit, sostoyanie, ostanovit;
  память опознавательных знаков на сутки по решению владельца Р124; проверка
  тайного ключа; набор номера вынесен сменной деталью.
- bots/lena-golos/proba-priyomnika.py — проба без звонка, 81 проверка.
  Подставной набор номеров не набирает, а считает, сколько раз его позвали:
  "человеку позвонили дважды" выглядит здесь как "набор позвали два раза".
- bots/lena-golos/lena-priyomnik.service — эталон службы. На сервере его нет.
- bots/lena-golos/README.md — свой раздел: устройство, кто кого зовёт, цена по
  Р84, порядок выката, открытые хвосты.
- docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-z-0-6-priyomnik-2026-08-07.md

Главное, ради чего всё это

Портал читает 4xx как "звонка не было" и вправе повторить. Значит 4xx после
начала набора стоит второго звонка живому человеку. В приёмнике каждый 4xx на
ручке звонка стоит строго до обращения к набору; единственное исключение — когда
сам набор отдельным полем поклялся, что не начинался.

Память знаков лежит файлом на диске и переживает перезапуск робота, и не в /tmp:
эта папка вычищается целиком при каждой перезагрузке машины, и защита умирала бы
молча именно в день перезагрузки.

Два одинаковых знака почти одновременно: знак резервируется до набора одной
неделимой записью, проигравший не набирает и получает 5xx. Ни 4xx, ни выдуманный
номер звонка — оба были бы ложью.

Память знаков применяется только к ручке звонка. Портал шлёт Idempotency-Key на
всех трёх ручках, но на двух других кладёт туда номер звонка, а не знак задания.
Прими мы его за ключ памяти везде — второй вопрос о состоянии отдавал бы
запомненный ответ, и разговор вечно числился бы идущим.

Приёмник сегодня звонить не умеет и говорит об этом честно

Набора номера нет ни в первой половине З-0.6, ни во второй — это третий кусок,
и в плане он не назван. Пока его нет, на ручке звонка стоит NabornikNeNastroen,
и приёмник отвечает 4xx "набор не настроен", то есть говорит порталу правду:
звонка не было. Ответить "принял", не имея чем звонить, значило бы наполнить
отчёты звонками, которых нет.

Р84 замерено, а не оценено на глаз

Сторонних библиотек ноль — только http.server, sqlite3, hmac, json, threading из
самого Python. Пик памяти на 200 заданиях подряд 0,17 МБ, обращений к базе на
задание 7, один процесс, потолок 8 одновременных запросов, тело не длиннее
64 КБ. Служба понижена Nice=10 и IOSchedulingClass=idle.

Личные данные

В журнал не попадает ни телефон, ни имя, ни текст скрипта, ни тайный ключ —
тела запроса там нет вовсе. Журнал идёт в journald, а не в свой файл: свой файл
стал бы пятым местом текстового следа без срока и без уборки.

Сторож показан красным пять раз

Ронялки: приёмник забыл знак — 13 красных; 4xx при гонке вместо 5xx — 2 красных;
обычное равенство вместо hmac.compare_digest — 1 красный; телефон в журнал —
2 красных; память в /tmp — 1 красный. Две самые важные повторены на итоговом
слепке файла.

Моя ошибка, называю первой: первая редакция сторожа постоянного времени искала
слово compare_digest по ТЕКСТУ файла и нашла его в моём же комментарии — проба
осталась зелёной на сломанном коде. Починено: смотрю в co_names скомпилированной
функции.

На машину робота не ходил, ничего там не менял, в app/ не менял ничего.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 05:45:40 +03:00
Дмитрий b5ea25f2a1 docs обзвон: приговор по З-0.3 и лист З-3.1, заведённый до работы
Приговор по З-0.3 вынесен своей рукой. Портальная половина шва принята: клиент
умеет позвать робота, спросить состояние и остановить. Резал своим ножом семь
случаев, каждый отдельным запуском. Главное различение сделано правильно и
проверено не текстом, а тем признаком, по которому будет решать будущий работник
очереди: дверь закрыта и отказ означают, что звонка НЕ было и повторять можно,
а не знаю означает, что звонок МОГ состояться и вслепую повторять нельзя.

Мои ошибки называю первыми, их три.

Пятидесятая. Я вложил в задание собственное противоречие: велел считать ответ
двести и мусор отказом, и тем же заданием пунктом выше объяснял, что молчание
ещё не значит отсутствие звонка. Буквальное исполнение моей строки вернуло бы
ровно ту дыру, которую задание закрывало, и живому человеку позвонили бы дважды.
Помощник поступил правильно, а не послушно.

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

Пятьдесят вторая. Оставил в тексте плана посторонний иероглиф. Проверка образцом
пометила весь файл подряд, то есть прибор снова был негодный; перемерил поиском
по самому знаку.

Вырезание второго рода дало три находки. Знак задания не различает перезапуск
кампании: через месяц у тех же номеров он тот же, и робот может отказать
законному звонку. Ключ уезжает открытым текстом, если адрес записан без
шифрования. И предел одновременных считает обращения, а не разговоры, тогда как
машину грузят именно разговоры, значит решение владельца Р84 этим пределом не
закрыто и портал не может закрыть его в одиночку.

Помощник возразил трижды и трижды был прав, а свою ошибку назвал первой: его
прибор показывал ноль красных при красном стороже, потому что проверка журнала
падает в поле ошибок, а не провалов. Поймала арифметика.

Лист по З-3.1 заведён ДО работы, как требует метод. Разведка собрана командой:
правило часов зовут двенадцать файлов живого модуля рассылки, час берётся одним
смещением получателя, и в этом вся ловушка. Ловушка названа заранее вместе с
пятью другими допущениями.

Полный прогон своей рукой: 5207 проверок, 5203 зелёных, 4 пропущено, красных 0.
Разметка 0 ошибок.
2026-08-07 05:06:11 +03:00
Дмитрий c7ae012f48 docs обзвон: З-0.10 принята, дыра в двери закрыта, три решения владельца
Приговор по З-0.10 вынесен сменой 6 через сутки после работы — то есть отчёт
помощника доказательством не служил вовсе, все десять замеров сделаны заново
своей рукой. Шесть проверок плана закрыты, из них три главные живым действием:
подставил итогу дату 78 часов назад и УВИДЕЛ письмо на ops@liderra.ru, хотя
внутри итога всё зелено; подставил красного сторожа и увидел, что письмо
назвало его поимённо; на здоровом итоге писем ноль.

Вырезанием второго рода нашёл дыру: дверь принимала итог ЗЕЛЁНЫМ, когда тело
само говорило "красных 2", а в списке лежал один зелёный. Длина списка нигде не
сверялась с объявленным числом, а поле с числом красных не читалось вовсе.
Замерено прибором вне хранилища на настоящей двери. Закрыто доделкой c351b0b6,
и тот же мой нож теперь краснеет и называет обе беды раздельно.

Помощник доделки возразил мне по существу и был прав: мой довод про подделку
завышен. У того, кто владеет тайным словом, нет причины слать обрезанный список,
он пришлёт связный зелёный. Порог для подделки эта работа не подняла ни на
сколько, её честная цена другая — защита от случайной порчи и от будущих правок
обхода. Довод снят, это моя ошибка 49.

Своим ножом резал и саму доделку. Новая строгость к незнакомым полям имеет цену:
прибавят в итог безобидное поле — письмо пойдёт каждый день, а это воюет с
проверкой 5 той же задачи. Приговор: строгость оправдана, вред от мягкости
больше, и цена названа честно в описании машины там, где её увидят.

Проверка 1 задачи живьём НЕ доказана и раньше 07.08 доказана быть не может:
итог собран рукой, расписание сработает впервые ночью. Замерено вместо неё, что
файл расписания принят по всем формальным признакам. Датчик для следующей смены
записан.

Мои ошибки. Первой — 48: в сообщении собственного коммита e37780920 написал, что
файлы задачи лежат несохранёнными. Неправда, они были в коммите 67195f0b, я это
сам замерил и поправил промт, но сообщение коммита не перечитал. Отсюда правило
25: поправил бумагу — перечитай и то, что уже ушло в сообщение.

Владелец закрыл три развилки 07.08.2026, все с полным набором дорог:
Р122 машина стучится подписью письма, а не словом в адресе;
Р123 к роботу только по шифрованной дороге, кроме своей машины;
Р124 робот помнит опознавательные знаки заданий сутки.

Датчики: задач 53, врезок ПОСТРОЕНО 17, требований 112, решений 124.
Полный прогон своей рукой на своей базе: 5207 проверок, 5203 зелёных,
4 пропущено, красных 0. Арифметика сходится. Разметка 0 ошибок.
2026-08-07 04:59:37 +03:00