diff --git a/docs/superpowers/plans/2026-08-04-obzvon-pod-klienta.md b/docs/superpowers/plans/2026-08-04-obzvon-pod-klienta.md index 52d77f01..d14301ef 100644 --- a/docs/superpowers/plans/2026-08-04-obzvon-pod-klienta.md +++ b/docs/superpowers/plans/2026-08-04-obzvon-pod-klienta.md @@ -1477,6 +1477,40 @@ Asterisk и читает свой файл. Общий файл остаётся ### З-2.3. Материалы клиента на входе: приём, изоляция, срок, надпись +> ✅ **ПОСТРОЕНО 05.08.2026** — коммит `2b401298d`. Приговор: +> [priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md](../priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md). +> **Третий заход в узкое горло схемы**, счётчик таблиц канона 42→43. +> +> 🔴 **Разведка перед круго́м разошлась с текстом задачи ниже в пяти местах — +> верны замеры, а не текст:** +> +> 1. **«То же хранилище, что и звук обзвона» — такого хранилища не было.** Звук +> переезжает в портал задачей З-2.1, а она не построена. ⇒ хранилище завёл +> **этот** круг, узко, только под материалы клиента. +> 2. **Канон схемы разбит надвое с 02.08.** Таблица описана в +> `db/schema_modules.sql`, а не в `db/schema.sql`, — там таблиц обзвона нет ни +> одной. +> 3. **Проверка «убрать старый отказ „меньше пяти“» беспредметна:** такого отказа +> в коде нет вовсе, снимать было нечего. +> 4. **Журнал ПДн есть, зовётся иначе** — `pd_processing_log`, пишем готовым +> `PdAuditLogger`. Своего не заводили. +> 5. **Хозяин стирания — З-2.2, и она не построена.** ⇒ даты истечения +> проставляются, а стирать их пока **некому**. +> +> 🔴 **Шестое расхождение — моё собственное, не плана.** Я разрешил построить +> ручку приёма, а класть её некуда: файла маршрутов `app/routes/api.php` в +> проекте **не существует**. ⇒ **у построенного ноль зовущих в бою:** приём +> работает и проверен, но дороги к нему нет — её кладут задачи волны 4. +> +> 🔴 **Изоляция чужого голоса — ДВЕ половины замка, и обе нужны.** Защита по +> строкам стережёт **строку**, а путь к файлу — обычный текст, база про файлы не +> знает. Вторая половина — явная сверка клиента при открытии: на разработке +> портал ходит правами, которые защиту по строкам обходят. +> +> 🔴 **Найдено вырезанием второго рода — улов крупнее задачи:** стирание по +> требованию человека **уже работает** и уже ставит «выполнено», не тронув наш +> новый склад. **См. врезку в З-2.5** — её вес из-за этого меняется. + **Что делать.** Клиент отдаёт записи своих холодных разговоров. Их надо принять, положить в то же защищённое хранилище, что и звук обзвона, **изолировать между клиентами** и удалить через 30 дней. @@ -1624,6 +1658,31 @@ Asterisk и читает свой файл. Общий файл остаётся Это не мелочь и не «доделаем потом»: именно на этом строится претензия. +> 🔴🔴 **ЗАМЕР 05.08.2026 — беда ТЯЖЕЛЕЕ, чем описано выше.** Найдено вырезанием +> второго рода при приёмке круга З-2.3 +> ([приговор](../priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md), §6.5). +> +> Дело не только в том, что стирание «не знает» про звук. Замерено: служба +> `app/app/Services/Pd/PdErasureService.php` проходит `users`, `supplier_leads`, +> `deals` — и по окончании ставит обращению человека **`status = 'completed'`**. +> +> ⇒ Человек требует стереть его данные, портал отмечает **«выполнено»**, а голос +> этого человека остаётся лежать: звук месяц, расшифровка полгода. **Это не +> недоделка, а ложный отчёт** — и отчёт машинный, то есть он не забыт, а +> утверждает обратное. +> +> 🔑 **Бьёт по самым уязвимым:** в складе материалов клиента (З-2.3, построена +> 05.08) лежат голоса людей, которые согласия нам не давали вовсе — они +> собеседники клиента, не наши. Именно они и приходят с требованием «сотрите +> меня». +> +> ⚠️ **Честная граница: вред ЗАРЯЖЕН, но ещё НЕ СЛУЧИЛСЯ** — ничего не выкачено, +> склада на боевом нет. Тем этот случай отличается от записей разговоров Лены +> (З-0.2), где вред уже случился. +> +> ⇒ 🔴 **Эта задача обязана быть закрыта ДО первого живого обзвона**, а не «когда +> дойдёт очередь волны 2». + **И вторая половина той же беды:** звук живёт **месяц** (Т70), а обращение человека может прийти **через два**. К тому времени у нас не будет ни записи, ни доказательства, что она была и стёрта по сроку, — только пустое место, которое от diff --git a/docs/superpowers/priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md b/docs/superpowers/priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md index 2f17d864..a9e0d391 100644 --- a/docs/superpowers/priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md +++ b/docs/superpowers/priyomka/stroyka-1/z-2-3-materialy-klienta-2026-08-05.md @@ -18,7 +18,11 @@ | вершина на входе круга | `1fd0170de` | `git rev-parse --short HEAD` | | чужое несведённое в индексе | **0** | `git ls-files -u` | | сторожа текста живы | **да** — `markdownlint-cli2 v0.22.1`, `cspell 10.0.0` | запуск самих проверялок, не счёт папок | -| прогон сервера | запущен на входе круга, своя база `liderra_testing_obzvon` | `php artisan test`, без трубы | +| прогон сервера на входе круга | **4930 проверок, 4926 зелёных, 4 пропущено, 15 435 утверждений, красных 0**, код возврата 0, 19 мин 27 с | `php artisan test` из `app`, своя база `liderra_testing_obzvon`, **без трубы** | + +🔑 **Число совпало знак в знак с замером конца прошлого круга** — 4930/4926/4. Это +и есть доказательство, что за три чужих и три моих коммита в коде не изменилось +ничего: сверка чисел прогона надёжнее, чем чтение списка изменённых файлов. 🪤 **Вершина уехала под ногами ещё до начала круга:** после моего `2da472164` легла чужая смена `1fd0170de` — приёмка Яндекса. Замерено: **кода не касается**, @@ -128,3 +132,118 @@ вырезание второго рода, и только затем сам приговор. --- + +## 6. ПРИГОВОР + +### 6.1. 🔴🔴 СВОЯ ОШИБКА — ШЕСТАЯ ЗА СМЕНУ, И ОНА В САМОМ ЗАДАНИИ + +Я разрешил помощнику построить ручку приёма и назвал папку, куда её класть. +**Класть было некуда:** файла маршрутов `app/routes/api.php` в проекте +**не существует вовсе** — есть только `console.php` и `web.php`. Перемерил сам: +возражение помощника верно. + +Класс тот же, что и все предыдущие пять: **утверждение о коде без замера.** +Я перемерил пять утверждений плана и не перемерил **своё собственное**. + +🔑 **Правило из этого:** разведка перед заданием обязана покрывать не только то, +что утверждает план, но и то, что дописал от себя надзиратель. Своё утверждение +проверять труднее — оно не выглядит чужим и не вызывает подозрения. + +**Побочная цена, говорю сам:** из-за этого у построенного **ноль зовущих в бою**. +Приём материалов работает и проверен, но человек им пока воспользоваться +не может — дороги к нему нет. Это не поломка, а порядок стройки: дорогу кладут +задачи волны 4. Но назвать это вслух обязан я, а не владелец. + +### 6.2. Возражения помощника — пять, проверил каждое + +| # | возражение | мой замер | исход | +|---|---|---|---| +| 1 | ручку класть некуда: `app/routes/api.php` нет | `ls app/routes/` → только `console.php` и `web.php` | ✅ **верно**, см. 6.1 | +| 2 | защита по строкам стережёт **строку, а не голос**: путь к файлу — обычный текст, база про файлы не знает | верно по устройству | ✅ **верно**, и он достроил вторую половину замка сверх задания | +| 3 | моя мерка изоляции — половина мерки: запрос в базу доказывает «не видит», но не «не может открыть» | ✅ **верно** — и это моя же оплошность в приёмочном листе | принято | +| 4 | мой довод про сторожа служебной роли верен наполовину | согласен: «ноль до лечения» дыру доказывает, а запуск файла на боевом — нет | принято | +| 5 | проверка «удаляются на 31-й день» не проверяется ничем: стирает З-2.2 | так и есть | принято, изображать не даю | + +🔑 **Пять из пяти по существу, ложных ноль.** Но напоминаю себе прошлый круг: там +из пяти возражений **одно было ложным**, и отличить его удалось только замером. +Проверять надо каждое, а не доверять счёту. + +### 6.3. Свои находки — то, чего помощник не называл + +- **Мусор в дереве.** Помощник оставил три пустых файла-обломка от неудачных + команд оболочки. Снёс, снос проверил командой. Мелочь, но метод требует + убирать за собой; +- **Чужое в указателе не тронуто:** `docs/observer/STATUS.md` и чужой промт как + лежали застейдженными, так и лежат — поимённый коммит их не забрал ни разу; +- **Точка отсчёта сошлась знак в знак** с концом прошлого круга — 4930/4926/4. + Значит за шесть коммитов между кругами код не менялся. + +### 6.4. Четыре мерки — своей рукой + +**1. Сторож показан красным — ДВУМЯ СВОИМИ НОЖАМИ, не теми, какими резал +помощник.** + +| нож | что резал | что вышло | +|---|---|---| +| **1** | снял вторую половину замка изоляции — явную сверку клиента в `otkryt()` | 🔴 **1 из 24 красная**, код возврата 1. Покраснела ровно та: «клиент А не может **ОТКРЫТЬ** материал клиента Б, даже держа строку в руках» | +| **2** | сломал **умолчание** срока звука: 30 дней → 180 | 🔴 **2 из 24 красные**, код возврата 1. Покраснели «решение владельца: звук 30 дней, текст шесть месяцев» и «негодное значение настройки не принимается всерьёз». Дата уехала с 04.09.2026 на 01.02.2027 | + +🔑 **Второй нож был выбран нарочно:** ровно этим классом — «сторож всюду задаёт +значение явно и умолчание не проверяет вовсе» — нас укусило в прошлом кругу. +**Урок усвоен:** здесь умолчание под охраной. + +**Возврат доказан слепком, оба раза:** `git hash-object` до надрезов и после +возвратов — `cd70ab8b4efee4107be2327908c8b7423e7d1a10` знак в знак, дерево по +коду чисто. + +**2. Полный прогон своей рукой** — числа ниже, в 6.6. + +**3. Две строки про соседей:** + +- «моего имени нет ни в одном выводе ни одного сторожа»; +- «чужие файлы в дереве не тронуты» — с одной честной оговоркой: тронут общий + `SchemaDeltaTest`, счётчик таблиц канона 42→43. Это не самовольство: ровно так + же его трогали закрытые круги З-1.1 и З-1.3, у которых тоже была новая таблица. + +**4. Зовущие поимённо — глазами, не числом.** Замерил сам: у новой службы и +модели **ноль зовущих в бою**, только собственные сторожа. Единственные совпадения +вне их — служебный кэш анализатора, не код. Это следствие моей ошибки 6.1. + +### 6.5. 🔴🔴 ВЫРЕЗАНИЕ ВТОРОГО РОДА — УЛОВ КРУПНЕЕ ЗАДАЧИ, ТРЕТИЙ РАЗ ПОДРЯД + +**Допущение, на котором стоит защита:** «стирание записи по требованию человека — +дело будущей задачи З-2.5, сегодня его просто нет». + +**Годный по форме случай мимо этого допущения:** стирание по требованию +**уже существует и уже работает.** В портале живёт `PdErasureService`. Замерил, +до чего он дотягивается: `users`, `supplier_leads`, `deals` — и по окончании +ставит обращению человека **`status = 'completed'`**. + +🔴 **Нашего нового склада в этом списке нет.** Значит с той минуты, как модуль +поедет в бой, картина такая: + +> человек требует стереть его данные → портал честно проходит свои три таблицы → +> отмечает обращение **«выполнено»** → **а голос этого человека остаётся лежать у +> нас**: звук месяц, расшифровка полгода. + +**Это не недоделка будущей задачи. Это ложный отчёт человеку, реализующему своё +право** — и, что хуже, отчёт **машинный**: он не забыт, он утверждает обратное. + +🔑 **И бьёт он ровно по тем, кто уязвимее всех.** В этом складе лежат голоса +людей, которые нам согласия не давали вовсе — они собеседники клиента, не наши. +Именно они и приходят с требованием «сотрите меня». + +⚠️ **Честная граница находки: вред ЗАРЯЖЕН, но ещё НЕ СЛУЧИЛСЯ.** Ничего не +выкачено и не запушено, склада на боевом нет. Тем этот случай и отличается от +записей разговоров Лены в прошлом кругу, где вред **уже** случился. Порох сухой, +но выстрела не было. + +⇒ Задача **З-2.5 уже есть в плане**, новую заводить не надо. Но её вес меняется: +это не «дотянуть стирание до звука», а **закрыть ложный отчёт**. Вписываю это +в план прямо в задачу З-2.5. + +### 6.6. Полный прогон и приговор + +*(заполняется по окончании прогона)* + +---