de0b09331cc1f6cdfbbcfccb7f2a423ece9e12e0
1224 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9bdced8173 |
docs: два промта следующим сменам — сведение ветки в главную и робот МТС
Accessibility (Pa11y live) / a11y (push) Has been cancelled
**Сведение ветки в главную** (`2026-08-10-PROMT-svedenie-vetki-smeny-v-glavnuyu.md`). Замерено: 262 коммита рабочей ветки против 14 коммитов главной, 735 файлов. Конфликтов всего три, и все решаются «берём версию ветки» — доказано замером: по обоим спорным файлам их версия оказалась строгой надстройкой (ноль удалённых строк). Главное предупреждение не про сведение, а про то, что после: боевой не равен ни одной ветке, а `routes/web.php` на бою существует в виде, какого нет нигде в git. Выкат целиком после сведения сотрёт работающее. **Робот МТС** (`2026-08-07-PROMT-mts-bot-kabinet-otbivaet-brauzer.md`). Совет из письма-тревоги («нужен другой адрес выхода») ошибочен — доказано тремя опытами: кабинет отдаёт 403 именно браузеру робота, а обычный запрос с той же машины, и напрямую, и через прокси, получает нормальный 401. Отдельно вынесен живой риск: оплаченная кампания идёт, а портал за ней не видит. Оба написаны по одному правилу: сначала то, что уводит не туда, потом замеры, потом отдельным разделом «что НЕ доказано» — чтобы догадки не выдавались за факты. В каждом — раздел граблей, на которые смена наступила сама. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1c08944bf1 |
docs: вернулись ещё два документа, поправлена ссылка на исчезнувшую рабочую папку — проверка ссылок стала зелёной
Продолжение предыдущего коммита. Возвращённые документы сами ссылались на два файла, которых в git тоже не было: HANDOFF по состоянию клиентской рассылки и её design-spec от 25.07. Оба лежали только на диске — вернул. Осталась одна ссылка, которую возвратом не починить: приёмка от 27.07 указывала на файл внутри временной рабочей папки `.claude/worktrees/client-sms`, а такой папки давно нет. Переписал на настоящий путь в репозитории — файл на месте, строка та же. Итог: `lychee` командой самого хука даёт 0 ошибок (было 20). Отправка на сервер снова открыта — она была закрыта для ВСЕХ смен, а не только для этой. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
930e28d2bf |
docs: возвращены в git 16 документов, на которые главная ссылалась, а их там не было
Найдено 07.08.2026 при попытке отправить починку сторожа пульса: проверка ссылок падала на 20 битых ссылках, и ни одна не была моей. Оказалось, что закоммиченные документы ссылаются на файлы, которые лежали только на диске рабочей машины и в git не попали ни разу. То есть главная не проходила проверку сама по себе — и отправка была закрыта ДЛЯ ВСЕХ смен, а не только для меня. У соседней смены на этот момент висело 5 неотправленных коммитов. Что вернулось: разборы и промты смен по клиентской СМС-рассылке (этапы 1-5, задачи 5-9, конец июля) и три промта смен 25-26 по кошельку и телеграму от 06.08. Все 16 — ровно те, на которые ссылались уже сохранённые документы, то есть их отсутствие было пропажей, а не задумкой. Отбор не на глаз: список получен из вывода lychee, каждый файл проверен на диске и на отсутствие в git. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
8d96cda70b |
docs: в отчёт смены вписаны номера обоих коммитов
Чтобы файл читался сам по себе, без обращения к истории. |
||
|
|
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> |
||
|
|
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> |
||
|
|
cc9a1a91a7 |
docs: заведён отчёт смены по запрету переадресации с тайным ключом
Скелет разделов. Пишется по ходу работы, чтобы не сгорело при обрыве. |
||
|
|
459947f76b |
Р126 третья дверь: работа оборванного круга сохранена и принята, дыра переадресации найдена
Круг смены 6 оборвали средой, работа помощника лежала в дереве несохранённой и её снёс бы первый же чужой откат. Замерил целостность, прочёл его отчёт, прогнал своей рукой, вынес приговор. Заново ничего не переделывал. ПРИНЯТО. Третья и последняя дверь с ключом рендера закрыта той же проверенной дверью. Список разрешённых машин общий с рендером и это доказано работой, а не доводом. Закрытая дверь красит СЕРЫМ, а не красным, и ключ при этом физически никуда не уходит, замерено мной двумя случаями по отдельному запуску на каждый. Помощник сверх задания нашёл и починил ложь, которой никто не искал: подпись плитки называла серый словами не отвечает, то есть гнала владельца продлевать исправные прокси. Мои ошибки называю первыми, их три. Пятьдесят девятая. Я назвал adminDashboardHelpers.ts чужим файлом соседней смены прямо в промте смене 7, в списке не трогать и в коммит не брать. Взял из головы, не замерив. Вся правка в этом файле - работа моего же помощника. Исполни следующая смена мой промт дословно, починка подписи плитки не попала бы в коммит и сгорела. Шестидесятая. Мой снимок оборванного круга был неполон: записал шесть файлов, их семь. Перечень собрал командой, но раньше, чем помощник закончил, и не перемерил перед тем, как назвать его окончательным. Шестьдесят первая. Мой датчик прогона искал не то слово и я чуть не объявил состоявшийся прогон несостоявшимся. Спас узкий прогон, которым я прибор перепроверил. Вырезание второго рода дало дыру. Допущение защиты: дверь проверяет адрес из настройки и считает, что запрос уйдёт именно туда. Случай мимо: разрешённая машина отвечает иди на другой адрес. Замерено на двух подставных машинах: тайный ключ уехал на машину, которой в списке разрешённых НЕТ, а плитка осталась ЗЕЛЁНОЙ и показала чужой адрес как свой. Перемерил на живой двери боевого Поиска клиентов тем же ножом, отдельным запуском - то же самое. Причина прочитана в исходнике библиотеки: при уходе на чужой адрес снимаются только два заголовка, и нашего среди них нет. Вторым прибором замерено, что отключения переадресации нет нигде во всём боевом коде. Это не отменяет Р126, дверь делает обещанное на своих случаях, но обещание шире дела и про это не сказано нигде. Отдельным кругом. Датчики: полный прогон моей рукой на своей базе 5344 проверки, 5340 зелёных, 4 пропущено, красных 0, арифметика сходится. Проверки интерфейса 3 из 3. Разметка 0 ошибок. |
||
|
|
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, шесть добыты этой сменой. |
||
|
|
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> |
||
|
|
d7b77d25f2 |
docs обзвон: приговор по восьмёрке в номере, цена решения названа честно
Решение владельца Р127 исполнено коммитом
|
||
|
|
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> |
||
|
|
09ed5e1b31 |
docs обзвон: приговор по двери боевого рендера, дверей оказалось три
Решение владельца Р126 исполнено коммитом
|
||
|
|
0181f2e3e7 |
docs: промт-передача следующей сессии по вкладке «Активность»
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
16d8191d08 |
docs: план переделки вкладки «Активность» под вопрос «жив ли клиент»
11 задач по TDD: два сервиса на бэкенде (вердикт с полоской и лента дел из пяти источников), ручка подгрузки, живая сортировка списка клиентов, типы и маппер, русские фразы, панель Vue, точка состояния в списке, полный прогон, приёмка глазами. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
475e2d6245 |
docs обзвон: знак и тело больше не расходятся, промт смене 7 написан
Портальная причина дыры закрыта коммитом
|
||
|
|
c9daf48bdc |
docs: спека переделки вкладки «Активность» под вопрос «жив ли клиент»
Замерено на боевом: вкладка читает журнал сделок, где 364 из 419 строк — системные «робот залил лид». Данные про входы и про дела клиента лежат в двух других журналах и на вкладку не попадают вовсе. Решения владельца: вердикт + полоска 90 дней + лента только дел, пороги 3 и 14 суток, входы только сверху, заодно чиним мёртвую сортировку списка клиентов по последней активности. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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 |
||
|
|
a0c660704c |
docs приёмка: дефект М-1 выкачен на боевой и доказан живыми данными
Задание 88 закончилось после выката и принесло ту же дату старта, а время изменения кампании №15 осталось от прошлого задания. Раньше совпадало с концом каждого задания до секунды — значит строку больше не трогают и счётчик 48 часов пошёл по-настоящему. Никого не стёрли: перепись боевого 1031 файл до и после, боевая копия файла до выката побайтово равна прежней версии, после — новой. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
575b6d6491 |
docs обзвон: приняты З-0.3, З-3.1 и половина З-0.6, в плане нашлась дыра
Три приговора вынесены своей рукой. Плюс в план заведена новая задача по решению владельца и записаны четыре его решения. З-0.3 принята, коммиты |
||
|
|
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> |
||
|
|
f671e21d01 |
fix обзвон: знак тот же, а тело задания другое — второму человеку не звонили молча
Замерено владельцем на приёмнике заданий: знак задания тот же, телефон в теле другой. Приёмник считал это повтором, второму человеку не звонил вовсе и отдавал порталу номер звонка ПЕРВОГО задания — портал привязал бы итог чужого разговора к другому человеку. Теперь вместе со знаком запоминается отпечаток тела задания. Тот же отпечаток — вправду повтор, ведём себя как прежде. Другой — не повтор, а ошибка портала: отвечаем 422, набора нет, чужой номер звонка не отдаём, память первого задания не трогаем. Почему 4xx, а не 5xx: по второму телу мы не набирали ничего, и это правда. 5xx сказало бы «звонок мог состояться», портал пометил бы человека как «может быть, звонили» и не позвонил бы ему никогда — та же беда, только навсегда. Отпечаток считается вычитанием, а не перечислением: вычтен один знак задания, всё остальное — включая поле, которое заведут завтра, — под защитой. Снят под тайным ключом, поэтому персональных данных в открытом виде в памяти нет. Проба приёмника: было 81 проверка, стало 108. До починки 7 красных, после 0. Починку ломал тремя разными ломами, все три покраснели; слепок приёмника после возврата совпал знак в знак. Портальная сторона не изменена ни строкой. Причина беды — там: портал даёт передавать знак и телефон врозь. Вынесено владельцу отдельным пунктом отчёта. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
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> |
||
|
|
b5ea25f2a1 |
docs обзвон: приговор по З-0.3 и лист З-3.1, заведённый до работы
Приговор по З-0.3 вынесен своей рукой. Портальная половина шва принята: клиент умеет позвать робота, спросить состояние и остановить. Резал своим ножом семь случаев, каждый отдельным запуском. Главное различение сделано правильно и проверено не текстом, а тем признаком, по которому будет решать будущий работник очереди: дверь закрыта и отказ означают, что звонка НЕ было и повторять можно, а не знаю означает, что звонок МОГ состояться и вслепую повторять нельзя. Мои ошибки называю первыми, их три. Пятидесятая. Я вложил в задание собственное противоречие: велел считать ответ двести и мусор отказом, и тем же заданием пунктом выше объяснял, что молчание ещё не значит отсутствие звонка. Буквальное исполнение моей строки вернуло бы ровно ту дыру, которую задание закрывало, и живому человеку позвонили бы дважды. Помощник поступил правильно, а не послушно. Пятьдесят первая. Мой собственный прибор соврал дважды за круг, обоими разами одинаково: мерил не то, о чём я его спрашивал. Подставной робот протёк из одного случая в следующие, и спрашивал я про заголовок по выдуманному имени. Перемерил каждый случай отдельным запуском, выводы поменялись. Пятьдесят вторая. Оставил в тексте плана посторонний иероглиф. Проверка образцом пометила весь файл подряд, то есть прибор снова был негодный; перемерил поиском по самому знаку. Вырезание второго рода дало три находки. Знак задания не различает перезапуск кампании: через месяц у тех же номеров он тот же, и робот может отказать законному звонку. Ключ уезжает открытым текстом, если адрес записан без шифрования. И предел одновременных считает обращения, а не разговоры, тогда как машину грузят именно разговоры, значит решение владельца Р84 этим пределом не закрыто и портал не может закрыть его в одиночку. Помощник возразил трижды и трижды был прав, а свою ошибку назвал первой: его прибор показывал ноль красных при красном стороже, потому что проверка журнала падает в поле ошибок, а не провалов. Поймала арифметика. Лист по З-3.1 заведён ДО работы, как требует метод. Разведка собрана командой: правило часов зовут двенадцать файлов живого модуля рассылки, час берётся одним смещением получателя, и в этом вся ловушка. Ловушка названа заранее вместе с пятью другими допущениями. Полный прогон своей рукой: 5207 проверок, 5203 зелёных, 4 пропущено, красных 0. Разметка 0 ошибок. |
||
|
|
c7ae012f48 |
docs обзвон: З-0.10 принята, дыра в двери закрыта, три решения владельца
Приговор по З-0.10 вынесен сменой 6 через сутки после работы — то есть отчёт помощника доказательством не служил вовсе, все десять замеров сделаны заново своей рукой. Шесть проверок плана закрыты, из них три главные живым действием: подставил итогу дату 78 часов назад и УВИДЕЛ письмо на ops@liderra.ru, хотя внутри итога всё зелено; подставил красного сторожа и увидел, что письмо назвало его поимённо; на здоровом итоге писем ноль. Вырезанием второго рода нашёл дыру: дверь принимала итог ЗЕЛЁНЫМ, когда тело само говорило "красных 2", а в списке лежал один зелёный. Длина списка нигде не сверялась с объявленным числом, а поле с числом красных не читалось вовсе. Замерено прибором вне хранилища на настоящей двери. Закрыто доделкой |
||
|
|
872cc4147b |
docs обзвон: в отчёт З-0.3 дописана проверка, что мои сторожа вправду в прогоне
Соседняя смена в своём отчёте назвала ровно те же числа полного прогона 5207 / 5203 / 0 / 0 / 4. Это выглядело так, будто мои 35 сторожей в прогон не попали, а число досталось мне от чужого замера. Проверено командой, а не на слово: сбор проверок даёт 5207, из них 35 моих. Мои внутри; у соседа своя основа была 5172, он гонял уже после того, как мой файл лёг в дерево. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
18f933550e |
feat обзвон: портал умеет позвать голосового робота — портальная половина шва З-0.3
Модуль «Обзвон» построен на 17 задач из 53 и при этом не мог позвонить ни разу: между порталом и роботом не было шва. Эта половина его закрывает — робот живёт на отдельной машине, портал теперь умеет сказать «позвони», спросить «что с разговором» и сказать «останови». Что сделано: - блок services.obzvon: адрес, тайный ключ, предел одновременных обращений, ожидание места, ДВА предела времени, список разрешённых хостов. Всё через env, ни одного секрета в коде; - ObzvonClient — три умения плюс опознавательный знак задания; - ObzvonOtvet и IskhodObrashcheniya — пять исходов вместо «вышло / не вышло»; - .env.example — семь настроек с пустыми значениями и пояснениями; - 35 сторожей. Главное решение. Ответ клиента НЕ булев. «Портал не получил ответа» — это не «звонка не было»: робот мог принять задание и уже звонить, пока ответ терялся по дороге. Слейся эти две правды — работник очереди повторил бы вслепую, и живому человеку позвонили бы дважды, а с кошелька клиента списали бы вторую трубку. Поэтому «не знаю» отделено от «точно не было», и у задания есть устойчивый опознавательный знак, одинаковый у всех повторов одной попытки. Решение владельца Р84: робот делит железо с боевым рендером «Поиска клиентов». Предел одновременных взят замками общего кэша, а не числом в памяти процесса — иначе два работника очереди дали бы двойную нагрузку. Что он ограничивает и чего НЕ ограничивает, сказано прямо в шапке клиента. Урок соседнего шва self_render взят дословно: успех — только по условленному слову робота. Ответ 200 с мусором успехом не считается. В отличие от задания, мусор записан не в «отказ», а в «не знаю» — иначе вернулась бы дыра с двойным звонком. Клиент, в отличие от SelfRenderClient, не повторяет запрос сам никогда. Журнал — только от «предупреждения» и выше: на бою LOG_LEVEL=warning. Незакрытое названо в отчёте: защита от двойного звонка ЗАЯВЛЕНА, но не замкнута, пока нет приёмника на машине робота З-0.6; настоящие пределы времени и предел одновременных на живой нагрузке не мерены; ключ едет открытым заголовком. Отчёт: docs/superpowers/priyomka/stroyka-6/otchyot-pomoshchnika-z-0-3-2026-08-06.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c351b0b6f5 |
fix обзвон: дверь итога сторожей проверяет связность того, что приняла
Дверь принимала итог, который сам себе противоречил, и записывала «всё хорошо». Годный по форме случай: тело говорит «сторожей 3, красных 2», а в списке лежит одна зелёная строка — двое сторожей исчезали молча. Дыры было две: - длина списка storozha ни с чем не сверялась; - поле storozhey_krasnyh не читалось вовсе — машина присылала своё показание, а дверь его выбрасывала. Теперь сверяются три показания о числе сторожей — настройка, объявленное число и длина списка — плюс объявленное число красных против нашего подсчёта по строкам. Красных считаем ровно по машинному правилу: код не ноль или провалов не ноль. Иначе зелёный сторож с нулём проверок давал бы ложную тревогу, потому что портал ругается на такого, а машина его красным не считает. Сверх заказанного закрыты два места того же рода. Поля, которых дверь не знает, ищутся вычитанием, а не перечислением — и в итоге, и в строке сторожа: тогда забытое поле оказывается под защитой, а не мимо неё. И ловится список нужной длины, набитый повторами одного имени: числа при этом сходятся все до одного, а гоняли одного сторожа трижды. Каждая новая проверка показана красной вырезанием своего куска по одному за раз. Без чтения storozhey_krasnyh случай с объявленной краснотой при трёх зелёных строках не ловит ничто — список бед выходит пустым. Машину не трогал, схему не трогал, остальную дверь не переписывал. Полный прогон: всего 5207, зелёных 5203, красных 0, ошибок 0, пропущено 4. |
||
|
|
9c0e0503d5 |
docs телеграм: снят неверный вывод о причине закрытия окна входа
Проверка на второй заход опровергла мой же разбор. На СТАРОМ коде служба отступала пять раз подряд, пока окно владельца было открыто, и вернулась к работе ровно в минуту закрытия — защита работала. Довод «в журнале нет ни одной строки ПРОПУСК» был замером через полминуты после открытия окна: пустой журнал доказывал лишь, что окно ещё не дожило до проверки. Причина закрытия окна НЕ установлена — записано открытым, с рабочим обходом. Починка сравнения путей остаётся как укрепление: старая проверка держалась на случайном вспомогательном процессе, слепом первые секунды. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0bbe4ce1c7 |
docs телеграм: вход в кабинет МТС восстановлен — служба лезла поверх окна владельца
Владелец не мог войти руками: окно закрывалось раньше, чем он успевал. Защита службы «профиль занят» сравнивала путь буква в букву и искала обратные косые черты, а браузер подписывается прямыми — совпадения не было никогда. Улика: за всю жизнь службы в журнале ноль строк «ПРОПУСК: профиль занят». Починка живёт вне git (C:\liderra\mts-telegram-robot): сравнение вынесено в etoNashProfil под 5 сторожей, тесты робота 197 -> 202. Проверено живьём: вход сохранён, сторож ALIVE, задание 52 ok=true, служба дважды отступила при занятом профиле. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
e377809205 |
docs обзвон: З-2.4 принята, волна 2 закрыта, промт смене 6 написан
Конец смены 5. Здесь приговор по последнему кругу, врезка в план и передача следующей смене. З-2.4 принята, коммиты |
||
|
|
67195f0bf8 |
feat обзвон: машина робота проверяет себя сама, портал следит за свежестью
Сторожа уборки записей телефонных разговоров запускал только человек, который про них помнил. Уборка могла умереть молча, и голоса чужих людей копились бы месяцами при обещанном сроке хранения. Теперь машина раз в сутки гоняет своих сторожей сама и стучится в портал с итогом. Портал хранит итог вместе с ЕГО СОБСТВЕННОЙ датой и шлёт письмо, когда итог красный ИЛИ протух. Зелёный итог недельной давности хуже красного сегодняшнего, поэтому возраст проверяется всегда. Решение владельца Р116: стучится машина, портал на машину не ходит — ключа от машины с голосами живых людей у боевого портала быть не должно. Решение владельца Р117: адрес письма из настройки MONITORING_ALERT_EMAIL, а не вписанный в код. На машине - суточный обход и его расписание, 05:20 МСК, под flock, от ubuntu - машинная копия 12 эталонов: своего ssh-ключа у машины нет и не будет - у сторожей появилась вторая створка двери LENA_MESTNAYA=1 — работа без ssh В портале - приём итога: подпись тела, без слова в адресе. Адреса текут в журналы nginx - ежедневная проверка свежести и красноты, письмо только когда плохо - итог лежит в scheduler_heartbeats, схема базы не тронута - сама проверка записана в EXPECTED_INTERVALS: присмотр без присмотра не жил бы Сторож нового обхода ходит с рабочего места по ssh и сверяет машинную копию с хранилищем побайтово — обход на машине сравнил бы копию сам с собой. Попутно закрыто: копия моста и журнал обхода стали новыми местами, где ложится похожее на речь. Разобраны поимённо, журнал обнуляется каждым прогоном. Замеры: сторожа 26/46/27 не изменились, обход 2,2 с под нагрузкой nice, проверок в портале 21 из 21, полный прогон 5161 при одной чужой красной. Три ножа показаны красными; один мой сторож при этом оказался ложно зелёным и переписан. Не выкачено: портальная половина не на бою, дорога с машины не настроена. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6e775055d9 |
feat обзвон: закрыта запись исхода через связь — третий пол и якорь по столбцу
Нож надзирателя пробил обе прежние половины. Случай: запись через связь, одной строкой, где нет ни имени класса, ни имени таблицы. Пол в модели молчал, потому что это построитель, а не объект; обход кода не начинался, потому что искал имена, которых в выражении нет. Проверил своим ножом: сторож дал восемь из восьми зелёных при живой дыре. Закрыто двумя вещами, и первая — не то, о чём просили. Свой построитель Eloquent, подставляемый моделью. Он ловит массовую правку на самой записи, разом все три формы: через модель, через связь и через новый запрос от строки. Имён переменных не читает вовсе. Проверяет по факту, а не по намерению: спрашивает базу, есть ли среди строк под правку хоть одна с состоявшимся разговором. Массовая правка тем и опасна, что пишущий не знает, что лежит в каждой строке, — значит знать обязан пол. Третий якорь в обходе кода — сам столбец. Замер надзирателя перемерил своей рукой и подтвердил: столбец ровно outcome есть во всём каноне схемы у одной таблицы, в миграциях его нет вовсе, у соседней таблицы он зовётся иначе. Но якорь в предложенном виде дал бы ложную красноту, и я его поправил дважды. Подстрока без кавычек совпала бы с именем столбца соседней таблицы — беру ключ в кавычках. И главное: ключ уникален в схеме, но НЕ уникален в коде — он есть ещё в пяти местах, и одно из них пояснение в шапке самой двери, где дословно написан образец запрещённого. Обход по тексту покраснел бы на самой двери. Поэтому комментарии убираются разбором PHP, а не вычёркиванием по образцу: разборщик отличает комментарий от такой же строки внутри кавычек. Ложная краснота хуже дыры: она приучает не смотреть. Список исходов про номер считается вычитанием из восьми, а не вторым списком: допишут девятый и забудут разложить — он окажется под защитой, а не мимо неё. Белого списка нет ни в одной из трёх половин. Исключений в обходе ровно два и оба по устройству: файлы, где полы и стоят. Чего не ловит и этот якорь, названо и в отчёте, и в подписи к сторожу: правку прямым SQL мимо портала, ключ и имя таблицы, собранные из кусков, столбец, переименованный в будущем, и код вне папки приложения. Полную защиту даст только замок в самой базе — это вопрос владельцу, схему не трогал. Новая половина показана красной ножом надзирателя: сторож назвал файл, строку и само выражение. Возврат доказан пустым состоянием дерева и слепками. Прогоны: полный 5166, зелёных 5162, красных ноль, ошибок ноль, арифметика сходится. Обзвон и сделки 447. Сторож мимо-двери 13 из 13. Статанализ ноль, deptrac ноль. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6d97a9691a |
docs обзвон: отчёт З-2.4 — восстановлен стёртый мной же раздел и числа чистого прогона
Три вещи в отчёт. Первое: раздел про голый шов я СТЁР сам, заменяя соседний кусок по границам «от заголовка до заголовка» — он лежал между ними и ушёл молча, вместе с коммитом. Восстановлен целиком. Поймал перечнем заголовков, а не памятью. Второе: моя ошибка в прогоне. Первый полный прогон круга 2 дал 44 ошибки «таблицы не существует». Причина не в коде и не в среде, а во мне: сборка тестовой базы идёт в начале КАЖДОГО прогона, поэтому второй прогон сносит таблицы под первым, а я запустил короткую проверку на своей же базе, пока на ней шёл мой полный прогон. Уронил сам себя ровно тем способом, от которого сам же предостерегал строкой выше в этом отчёте. Урок шире, чем «своя база на смену»: своя база на ПРОГОН. Третье: датчик снова врал. В сводке стояло «красных ноль», и по этому числу прогон читался зелёным, а настоящий счёт лежал в другом ключе и выход был два. Поймал сложением. Годная проверка прогона — не одно число и не код возврата, а сходится ли арифметика: всего равно зелёные плюс красные плюс ошибки плюс пропущенные. Чистый полный прогон: всего 5140, зелёных 5136, красных ноль, ошибок ноль, пропущено 4, утверждений 16188, выход ноль. Арифметика сходится. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
df8c4720cb |
feat обзвон: запись исхода мимо двери больше не проходит — пол в модели и обход кода
Голый шов. Правило Т84 «недозвон не затирает состоявшийся разговор» жило в двери ItogPoNomeru, и восемь сторожей доказывали, что дверь работает. Но все восемь ходили ЧЕРЕЗ дверь, а дверью можно не воспользоваться: запрета писать МИМО не было ни одного. Итог по номеру сегодня не пишет никто, значит первым пишущим будет следующая смена — она увидит у модели поле outcome раньше, чем найдёт дверь, напишет в него напрямую, и правило рухнет молча. Дверь осталась бы целой и никем не использованной. Защита разделена по УСТРОЙСТВУ, а не по тексту, и белого списка «кому можно» нет ни в одной половине — такой список сам стал бы дырой. Пол в самой модели ловит любую запись через объект: присваивание полю, fill, update у строки, save. Имя переменной он не читает вовсе — он стоит на самой записи, поэтому главная слабость текстового поиска закрыта не текстом, а местом. Проверяется смысл перехода, а не автор: дверь поблажек не имеет и проходит лишь потому, что запрещённого перехода не делает. Обход кода ловит то, чего пол не видит физически: массовую правку и запросы построителем — Eloquent на них событий не шлёт. Запрет действует на всех без исключений, включая саму дверь. Раскладка исходов НЕ задвоена: обе половины читают одну настройку. Повторено только применение правила — модели запрещено зависеть от служб, у слоя Model в настройке слоёв разрешённых зависимостей ноль. Два места связаны сторожем, который обходит все 64 пары исходов и требует одинакового ответа. Чего не ловит НИ ОДНА из половин, названо в бумагах: правку прямым SQL мимо портала, имя таблицы или столбца, собранное из кусков, и код вне app. Первое лечится только замком в самой базе — это правка канона схемы и вопрос владельцу, поэтому названо, а не сделано молча. Сторожа показаны красными. Настоящая запись мимо двери положена в САМ обходимый код, а не в песочницу: сторож назвал файл, строку 14 и само выражение. Снятие пола дало три красных, включая связку — пара transferred и no_answer. Возврат доказан слепком со снятием невидимых знаков конца строки. Заодно подписи двух значений в настройке: владелец закрыл обе развилки решениями Р120 и Р121 от 06.08.2026, оба совпали с поставленным. Значения не менялись, переписаны только пояснения, и рядом с каждым названо то, чего решение НЕ закрывает. Прогоны: обзвон и сделки 442, зелёных 441, красных ноль. Мои сторожа 32 из 32. Статанализ ноль, deptrac ноль нарушений. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d5216461bb |
docs лендинг: сборка с чистого листа для новой смены + картина ресурсов
Владелец остановил стройку и попросил собрать самодостаточную сборку, по которой новая смена начнёт с чистого листа и не привяжется к старому дизайну. Сборка docs/lending-sborka/ — восемь бумаг и восемь картинок: · 00 промт новой смене (роль дирижёра, порядок чтения и работы); · 01 продукт: содержание лендинга из портала и рекламной картинки владельца; · 02 разбор эталона по кадрам: четыре разных типа сцены, а не один; · 03 внешние генераторы: настоящие имена, поля и измеренные цены; · 04 скилы и вкус, кому что поручать; · 05 правила промтов субагентам с примерами хорошего и плохого; · 06 техническая база: что доказано работающим, с рецептами; · 07 изоляция: с чем не связываться и что отменено. Что снято практикой, а не рассуждением: · причина «белой ленты» — зеркальному металлу нечего было отражать; с картой окружения хром ожил, доказано снимком; · transmission на нашей связке не рисуется вовсе — второго прохода сцены нет; рабочий рецепт стекла найден перебором трёх вариантов рядом; · объёмные РУССКИЕ буквы работают; opentype рисует ось Y вниз, three.js вверх — без переворота буквы встают вверх ногами, и это не сразу заметно; · видео играет внутри стеклянной панели — то, чего не хватало четырём сборкам; · найдены два открытых адреса gen-api, по которым берутся настоящие имена моделей и списки их полей; угадывать больше не нужно; · измерены цены пяти моделей запуском, израсходовано 224 ₽ из 2000 ₽. Рабочая проверка landing-3d/ — все возможности на одном экране, снимальщик и переводчик шрифта. Решение владельца Р-К7 записано в протокол гриллинга. Попутно: сторож CSS был МЁРТВ — у семи пакетов внутри пустые папки, тот же класс поломки, что убивал сторожей текста 05.08. Цепочка stylelint починена добавлением недостающих файлов, ничего не удалялось. Всего в дереве найдено 67 пакетов без рабочих файлов — остальные не тронуты. Боевой liderra.ru не тронут. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
633cad6a04 |
docs передача: обе починки на бою, перепись доказала, что чужого не стёрли
Сторож очередей ожил и сразу завёл 2 инцидента, которых никто не видел с 05.08; расписание в 17:40 отработало без падения — до этого падало на каждом тике десять раз подряд. Записан датчик «никого не стёр»: посчитаны хеши всех 1030 файлов кода боевого до и после выката. Изменились ровно три файла, мои; не исчез ни один. И грабли: мало положить сборку — надо положить и исходник, иначе следующая пересборка из боевого кода молча вернёт дыру. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
07a17b2767 |
fix: пополнил кошелёк — реклама оживает; охрана очередей больше не слепнет от одной строки
Т-Б3 приёмки телеграма и падающая задача incidents:watch-failures. 1. Реклама, вставшая из-за нехватки денег, была в тупике: ручка возобновления принимала только `paused`, ручка запуска — только `draft`, а на экране у такой кампании не было ни одной кнопки. Клиент пополнял кошелёк и не мог вернуть рекламу ничем. Найдено чтением кода, БЕЗ траты живых денег и без остановки рекламы Яндекса — ровно то, ради чего карточка откладывалась. 2. incidents:watch-failures падал на бою каждые 10 минут с 05.08 09:30. Причина: не отправилось письмо тревоги, упавшее письмо легло в failed_jobs, а в его слепке — нулевой байт от закрытых полей объекта PHP. Postgres такую строку хранит, но текст из неё не достаёт и роняет весь запрос. Одна строка глушила всю охрану очередей и вебхуков поставщика, а в журнале был только «код 1». Сторожа обеих починок видены красными до правки. NB: настоящий нулевой байт из своих же комментариев убран — с ним git считал оба файла двоичными и переставал показывать различия. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
b0581e0bf8 |
docs обзвон: в отчёт по З-2.4 вписано второе затирание — коммит сняли с ветки
Работу З-2.4 за один круг снесли дважды разными способами. Первый раз откатили правки прямо в дереве, второй раз сняли с ветки уже записанный коммит: смена рекламы дважды подряд отступила на шаг назад, первым шагом убрав свою работу, вторым мою. Журнал переходов ветки показывает это по шагам. Оба раза восстановлено, содержимое сверено побайтно. Работа снова в ветке. Побочное и важное: тем же двойным отступлением с ветки ушла работа самой смены рекламы — девять файлов, среди них два новых сторожа. Чужое я не восстанавливаю, но об этом надо сказать им сегодня же, потому что они об этом, судя по всему, не знают. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
16fdbc9857 |
docs обзвон: отчёт по З-2.4 дополнен настоящими числами прогонов и происшествием
Соседняя смена по ходу круга снесла шесть моих правок в уже существующих файлах; уцелели только те файлы, которых git ещё не знал. Восстановить из заначки было нечем — заначки с моей работой не существовало. Правки нанесены заново, и это записано в отчёт как происшествие, а не замолчано. Полный прогон дважды НЕ состоялся: PHP валился по нехватке памяти, а моя обёртка при этом печатала «выход 0» — датчик врал зелёным, пока я не открыл сам файл вывода. Помог прямой вызов Pest с неограниченной памятью. Настоящие числа: полный прогон 5130 проверок, 5126 зелёных, 16099 утверждений, красных ноль. Обзвон 234 из 234. Пять красных в проверках интерфейса — все в одном чужом файле кошелька рекламы, и это доказано составом коммита, а не обещанием. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c84b8051b3 |
docs обзвон: хвосты З-0.11 приняты, и дорога владельцу была показана неполной
Добавка к кругу 3. Работу делал помощник, коммиты |
||
|
|
285b955f7c |
docs лендинг: база переделки — промт субагенту, приёмка, контракт с Fable
Видео-эталон разобрано целиком впервые: 32 кадра на все 19 секунд. Прежние разборы врали, потому что ролик снят в H.265 и его не читают ни Chrome на этой машине, ни ffmpeg из Playwright. Заголовок приходит на 3,3 секунде, а не на 6,5; полёт сквозь панели занимает 38% ролика; первым кадром вообще оказался чужой сайт с плашкой про убогий дизайн. Промт для субагента переписан трижды и дважды разнесён чужими моделями GPT-5.6 Sol и Perplexity, восемь заходов, 382 рубля. Обе независимо нашли одно и то же: приёмку можно было пройти невидимыми пустышками, промт требовал ждать владельца в автономном заходе, роль Fable не была назначена, а главная проверка «спрячь холст» пропускала обычный лендинг, нарисованный внутри WebGL. Разделено на три документа, потому что единый файл сам напоминал агенту про запрещённое устройство: рабочая инструкция, спецификация приёмки и контракт с Fable. Приёмочный скрипт пишет контроллер и держит вне рабочей папки, иначе агент перепишет его под себя. Решение владельца Р-К6: источников истины ровно три — видео-эталон даёт устройство, возможности портала суть, рекламная картинка содержание и зрительный язык. Снимков портала и любых картинок в сборке нет вообще. Следствие принято: без карты окружения хром и стекло мертвы, значит мир матовый и светящийся, как на рекламной картинке. Протокол гриллинга сохраняется в репозиторий впервые — до сих пор он жил только на диске и мог пропасть. В словарь добавлен 141 термин. Ещё 4 слова там — от соседней смены, её решение Р119 уже в главной, а слова оставались незакоммиченными. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fdbff6e2d4 |
docs: хвост Р118 — контрольный лист аудита 152-ФЗ помечен, приписка в отчёт о бое
Р118. Лист велел проверить защиту, которой нет. Мест там два пункта, а не один: кроме самого флага лжёт и пункт про индекс. Имён несуществующих охранников два — ProcessingRestrictedException и ProcessingRestrictionGuard, оба проверены и отсутствуют. Пометок три: одна отдельным пунктом ПЕРЕД лживыми, чтобы её не пропустил идущий по коробочкам сверху вниз, и две внутри самих пунктов. Три чужих давних слова в том же листе разрешены указанием для сторожа внутри самого файла, а не правкой общего словаря. Прибор проверен на подставной ошибке: разрешённые слова замолчали, бессмыслица поймана. Р119. Отчёт о готовности к бою получил приписку про тот же флаг. Слова в словарь дописаны прежним коммитом. В отчёт помощника записаны две мои беды круга: прошлый коммит унёс 152 чужие строки общего словаря, и правки в трёх файлах были стёрты чужой операцией в общем дереве между добавлением и коммитом. Ноль удалённых строк по каждому файлу. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
42043da777 |
docs телеграм: промт смене 4 переписан по факту выката
Промт писался до выката и утверждал «не выкачено» — теперь это неправда: коммит
|
||
|
|
f2f16a70a1 |
docs обзвон: З-0.11 принята, мест лжи оказалось 14 вместо четырёх
Круг 3 смены 5. Работу делал помощник, коммит
|
||
|
|
337f6b9897 |
feat телеграм: дата старта показов, признак живости системы и человеческий язык ошибок
Дата старта (решение владельца 06.08.2026). Портал не передаёт кабинету МТС ни одной даты — их ставит кабинет своими умолчаниями. Живой прогон показал: старт оказался ЗАВТРАШНИМ, тогда как экран обещал клиенту показы «7 дней», подразумевая сегодня. Робот читает день начала из ТОЙ ЖЕ строки списка, куда и так ходит за вердиктом — ни одного лишнего захода в кабинет; портал хранит его в client_tg_campaigns.starts_on и показывает клиенту «Показы начнутся 7 августа». Проверено на ЖИВОМ кабинете: три задания подряд вернули startDate 2026-08-07 по кампании МТС 2237821. Мастер перестал молчать о том, что день начала ставит кабинет, а не мы. Ф-2, карточка приёмки Т-Ф4. У кампаний в движении видно «Проверяли 5 минут назад». Считаются только ЗАКОНЧЕННЫЕ проверки, включая неудачные: задание в очереди работой не является, а неудачная проверка — всё равно признак жизни. Именно в такой тишине владелец 36 часов не знал, что робот вообще не может войти в кабинет. Ф-3. Имена полей в ошибках формы по-русски: «Лимит на объявление не может быть меньше 1 ₽» вместо «Поле budget cap rub должно быть не меньше 1». Серая кнопка «Запустить» называет причину и шаг, куда вернуться, а не гаснет молча. Карточки Т-Р3 и Т-Р4 закрыты тестами (живьём не воспроизвести). Попутно найдено: обе защиты, стерегущие ЕДИНСТВЕННОЕ место траты живых денег роботом, были без единого теста. Сторожа доказаны вырезанием. Тесты: ClientTg 378 зелёных, экраны 2158, робот 197. Статанализ 0, стиль 0, типы чисто. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
525af778be |
docs: правда про флаг прекращения обработки — 14 пометок в 5 бумагах, решение Р110
Бумаги проекта обещали, что флаг processing_restricted всё блокирует: особое исключение при попытке тронуть человека, охранник, не пускающий сотрудников в его карточку, «все операции обязаны проверять флаг и отказывать». Не построено ничего — флаг ставится и лежит. Рядом с каждым обещанием дописан замер «06.08.2026: не построено» с командой, которой это перемеряется. Прежний текст оставлен дословно, ноль удалённых строк. Галочка «закрыт» у Ю-9 на месте, версии в шапках не тронуты. План называл четыре места. Перечень собран заново прибором — их четырнадцать. Три самых опасных были вне списка: «реализовано через guard-исключение» в перечне сильных сторон, и два раздела ТЗ, написанных как описание готовой работы вплоть до текста заглушки и кода ответа 403. Два хвоста переданы владельцу. Первый: контрольный лист аудита 152-ФЗ в .claude/skills/pdn-152fz-audit несёт ту же ложь — путь запрещён к правке. Второй: отчёт по безопасности от 17.06.2026 остался непомеченным — сторож правописания краснеет там на пяти чужих словах, а поправить их значит удалить чужие строки. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |