# Платформенный пак: ЧЕЛОВЕКУ ПОКАЗЫВАЮТ ПУСТОЙ ЭКРАН, КОГДА ЕМУ ЕСТЬ ЧТО ПОДПИСАТЬ > ✅ **АРХИВ — ПАК ОТРАБОТАН И ПРИНЯТ 17.09: акт `D39.262`** (`ffd3751`, 21 путь зоны, контрактный минор **0.16.0**). > Платформенные половины рядов **224** и **253** ЗАКРЫТЫ: было 0, стало 69 и 66 на обоих купленных прогонах. > Мажор приёмки (`confidence` вне объявленного каноном диапазона) вылечен КЛАССОМ — число вне диапазона читается > как «не названо» у шва, гейт читает диапазоны ИЗ канона. **Инструкции отсюда НЕ ИСПОЛНЯТЬ** (правило архива): > живое из этого пака — в акте и в рядах **479** (части ярлыка `variants`, движковый долг) · **353** (свидетель > `SettledByBank`, движковая зона) · **484** и **486** (мутационный контур) · строки регистра `PD-467`/`PD-468`/`PD-469`. > ⚠ Состав полей, который этот промт называл в §4.1, был НЕВЕРЕН и исправлен зоной замером: обязательность > определяется `omitempty` у писателя движка — `conventions` обязательно, `variants` опционально. ## 1. Какая проблема и что решит твой результат Движок переводит книгу и один раз за прогон **останавливается**, чтобы человек подписал термины: как зовут героя, гору, секту. Это единственный момент во всём продукте, когда у человека спрашивают решение, и от него зависит связность всей книги — подписанный термин дальше едет законом. В этот момент движок кладёт рядом с базой книги файл-проекцию банка. Замерено на двух купленных боевых прогонах: | прогон | `terms` | `proposed` | `consolidation` | |---|---|---|---| | A (платная стоп-граница) | **0** | **69** | объект из 7 полей | | B (платная стоп-граница) | **0** | **66** | объект из 7 полей | Платформа читает из этого файла **только секцию `terms`** — и отдаёт человеку ноль. Десятки предложений лежат в том же файле непрочитанными, и первый слой ратифицированного `D39.256` («в продолжение едет подписанное») у любого пользователя пуст фактически: подписывать нечего, потому что предложения до него не доехали. **Ряды трекера, которые пак закрывает:** **224** (движковая половина закрыта 07.09, остаётся платформенная — у секции предложений ноль читателей) и **253** (поля на странице банка нет, у секции консолидации ноль читателей). Оба — заказ этого пака слово в слово. ## 2. Зона записи и git **Твоя зона — `platform/`** плюс зонный журнал `platform/docs/platform-PROGRESS.md` и, если понадобится, `platform/BACKLOG.md`. **Контракт `docs/architecture/14-api-contract/` — исключение: туда писать можно и нужно** (прецеденты: миноры 0.13.0, 0.14.0, 0.15.0 сданы платформенными паками), но только туда; остальной `docs/` не трогай. **Ты не коммитишь** — готовишь дерево и передаёшь оркестратору. Git-дисциплина целиком — `CLAUDE.md` §«Git-координация мультисессий». ⛔ **`frontend/docs/api-contract/` НЕ ТРОГАТЬ.** Зеркало фронта отстало на тринадцать миноров (`0.2.3` против `0.15.0`), и это **ратифицированное** отставание на время заморозки зоны (`D39.142` п.5). Типы фронта генерятся из зеркала — правка разбудит замороженную зону. ## 3. Карта чтения — ЗАКОН 1. `CLAUDE.md` в корне — канон проекта целиком. 2. **`platform/docs/ENGINEERING_STANDARDS.md`** — ратифицированный стандарт зоны; карта доков требует, чтобы каждый платформенный промт на него ссылался, отступление — пинг. Рядом `platform/docs/PLATFORM_DIRECTION.md` — ратифицированное направление зоны. 3. `platform/internal/ingest/bank.go` (153 строки) — существующий ридер проекции. **Читать целиком, включая комментарии: в них дисциплина, которую ты наследуешь** (§4.2). 4. **Путь артефакта целиком:** `platform/internal/runner/artifacts.go` → `platform/internal/pgstore/readmodel.go` (функция сохранения банка) → миграции `platform/internal/pgstore/migrations/`. Там решается, ломает ли новая секция дельта-чтение. 5. Контракт: `docs/architecture/14-api-contract/openapi.yaml` (адресно: страница банка, схемы термина и статуса) **и его компаньон `README.md` рядом** — компаньон ратифицирован и ведёт провенанс каждой строки; минор без него разойдётся с конструкцией. Код первичен: адреса — отправные точки. ⚠ **Числа этого промта сняты оркестратором; те, на которых строишь решение, пере-снимай сама.** ## 4. Что построить ### 4.1. Прочитать секции — поля снимаешь ЗАМЕРОМ, не по этому списку Научить ридер разбирать две секции, которые он сегодня игнорирует: **`proposed`** (предложения движка) и **`consolidation`** (итог прохода терминолога). ⛔ **Список полей НЕ переписывай из промта — сними сама, и НЕ с файлов, а С ПИСАТЕЛЯ.** ⚠ Первая редакция этого промта называла состав по двум снимкам сырья и ошиблась в членстве: обязательность определяется наличием `omitempty` у сериализуемой структуры движка, а не тем, что видно в файле. Верно (пере-снято зоной 17.09, доказательство построением): **обязательные** — `src`, `dst`, `kind`, `channel`, `freq`, `spread`, `conventions`, `conf`; **опциональные** — `invented`, `contradicts`, `bank_holds`, `variants`. ⚠ И отсутствие `conventions` в прогоне A — НЕ опциональность, а ДРУГАЯ СБОРКА движка: у поля нет `omitempty`, значит сериализатор опустить его не мог, ⇒ тот файл написан до коммита, добавившего поле. ⛔ **Несущее следствие: у обязательного ЧИСЛОВОГО поля «поля нет» ≠ «ноль».** `freq: 0` означает «поверхность видел только черновик», `conf: 0` — «роль сказала ноль процентов»; свернуть их в обычное число значит стереть смысл. ⚠ `contradicts` и `bank_holds` не встретились ни разу в 135 объектах — читатель их несёт, но исполнением они не проверены, и это идёт в «где прибор слеп». ⛔⛔ **`invented` — то самое поле, ради которого экран и существует:** движок объявляет его классом, который читают ПЕРВЫМ («консолидированная передача — НЕ та, что дали черновики»). Ридер без него покажет человеку список, в котором не видно, что движок выдумал имя. Не потеряй его так, как потерял первый черновик этого промта. ⛔ **САМОЕ ОПАСНОЕ МЕСТО ПАКА — слово `proposed` значит здесь ДВЕ разные вещи.** В контракте это значение статуса строки (движковый `auto` переводится в него); в проекции — имя секции с предложениями, и это другой объект с другими полями. Не заводи третий смысл и не переименовывай существующий. Как назвать новое во внешнем контракте — решай сама и аргументируй; мой приор, опровергаемый: во внешнем имени слова `proposed` избегать вовсе. ### 4.2. Взять у образца не форму, а ГАРАНТИЮ — ДЕЛАЙ РОВНО ТАК Существующий ридер несёт три решения, каждое с ценой ошибки в комментарии: документ **без версии банка отвергается** («пустой банк и документ, который эта сборка не умеет читать, декодируются одинаково, и один из них заменил бы весь банк книги ничем»); **неизвестный статус** читается как «просит решения»; **неизвестное происхождение** — как то, что заявляет о себе меньше всего. Твои секции наследуют **этот класс гарантий**. Конкретно спроси себя: - чем у тебя отличается «секции в файле нет» от «секция есть и пуста»? Если ничем — ты воспроизвёл ложный ноль, ради устранения которого пак заказан; - **то же про ПОЛЯ**: четыре из двенадцати опциональны, и «поля нет» не равно «значение ложно»; - **граница.** Проекция пишется на ПЯТИ границах прогона и сама это объявляет, несёт отметку границы и идентификатор прогона, а её экспорт трижды предупреждает, что файл может быть несвежим. Ридер сегодня эти поля не читает вовсе. ⇒ секция предложений читается только вместе с отметкой границы, и **«граница не та» обязано отличаться от «предложений нет»**. ### 4.3. Отдать наружу — контрактный минор, РЕШАЕШЬ САМА Канон `0.15.0`, полоса мажора `0`, добавление — минор. Форму решаешь ты: расширить ответ существующей ручки, добавить секцию рядом или отдельный ресурс. Аргумент обязан отвечать на вопрос «что увидит человек, которому надо подписать». ⚠ **Развилка, которую надо знать заранее: у предложения НЕТ идентичности.** У термина есть `id` и он несёт объяснение зачем; у предложения `id` нет ни в одном из 135 замеренных объектов. Вся платформенная сторона построена поверх этого `id`: сохранение банка ключует по нему, бампает ревизию книги, а исчезновение строки переводит книгу в сброс ревизии, «потому что исчезнувшую строку нельзя выразить дельтой». Контракт при этом отдаёт страницы с курсором и версией, а порядок предложений — **ранжирование**, которое между прогонами меняется. ⇒ «чем адресуется предложение в дельта-чтении» — настоящий вопрос, движок тебе править нельзя, и **пинг с обоснованием здесь полноценный исход пункта**, а не срыв. Выдумывать `id` на стороне платформы — пере-реализация закона движка, это запрещено. ⚠ **Проза контракта едет в исходник генерируемого клиента** — ратифицированная конструкция. Описания пишутся как код. ### 4.4. Хранилище — назови решение явно Секции сегодня хранить негде: таблица банка одна, миграций 35, и ни одна не знает ни предложений, ни консолидации. Решаешь сама, с аргументом: **хранить в базе** (тогда миграция — часть пака, и надо показать, что она не ломает дельта-чтение и ревизию) или **читать на лету** из артефакта (тогда назови, что происходит, когда артефакта нет или он с другой границы). ### 4.5. Чего НЕ делать - Не строить UI и не размораживать фронт; читатель сегодня — API. - Не трогать движок: проекцию пишет он, её формат — его зона. Расхождение формата — **пинг**, а не правка у себя. - ⛔ **Не подпирать заплаткой то, что просит перестройки.** Слово владельца 17.09 (`D39.258` п.3): чистый код, рефакторинг где нужен, техдолг не копить. Отрефакторила — **назови в отчёте, что и почему**. ## 5. Самопроверка ИСПОЛНЕНИЕМ Гейт зоны (`make check`) обязателен и самопроверкой не является. Сверх него — адверсариальный проход по своей готовой работе; **субагентов поднимать разрешаю явно**. Тебе разрешён **один** старший советчик (`model: "fable"` явно) для развилки, которую не закрывает своё суждение: досылай вопросы ему, а не поднимай новых. Он советчик, не источник истины — его посылки проверяются деревом. Четыре места, где этот пак мягок: 1. **Коллизия имени `proposed`** — проверь исполнением, что в одном ответе два смысла не смешались. 2. **Различение «нет» и «пусто»** — для секций И для опциональных полей; пин обязан краснеть, если их склеить. 3. **Полнота минора** — сверь, что каждое объявленное поле уходит на провод, а не только имеет тег. 4. **Ложный ноль на живом файле** — предъяви числа ДО и ПОСЛЕ на купленных проекциях: «было 0, стало 66» и есть доказательство. ## 6. Оси ревью Две-три, можешь заменить: **контрактная** (минор законен, полон, описания говорят правду о поведении) · **дисциплина ридера** (гарантии §4.2 перенесены, а не процитированы) · **человеческий узел** (достаточно ли отданного, чтобы человек принял решение; чего не хватает — назови, даже если не строишь). ## 7. Чем мерить — купленное сырьё, ТОЛЬКО на чтение - `/home/ubuntu/tm-coldrun-a/evidence/bankstop-paid/project.db.bank.json` - `/home/ubuntu/tm-coldrun-b/evidence/paid-bankstop/project.db.bank.json` ⛔ Это купленные улики: открывать только на чтение, ничего в этих каталогах не создавать. ⚠ Рядом с проекцией B лежит база прогона — **её не открывать вовсе**: движковый стор молча мигрирует старую схему и уничтожает улику (ряд **475**), а рядом с ней уже появился временный файл от чьего-то чтения без флага неизменности (ряд **472**). ## 8. Записка-план До первой правки кода — короткая записка в зонный журнал: что строишь, какой формой отдаёшь, что решила по коллизии имени, по идентичности предложения и по хранилищу. ## 9. Эхо-протокол старта **Первым действием** — десять строк **своими словами**: скоуп, инварианты, чего не делаешь. ## 10. Что не удалось — и где прибор слеп Секция обязательна, и вторая её половина тоже: **«где мой прибор слеп и я это знаю»** — что невидимо, почему не чинила, чем закрывается. В коде названо, в отчёте нет — значит для следующей смены не названо. ## 11. Канал вопросов и право отказа Конфликт промта с кодом — **пинг**, не интерпретация. Право сказать «этого делать не надо» с аргументом у тебя есть. Прямой канал — механизм в `CLAUDE.md` §«Связь между сессиями»: впиши свой блок первым делом, эхо отправь по адресу оркестратора оттуда же. ## 12. Критерий завершённости — проверяемый - у **каждого** пункта заказа исход: сделано · не делаю с доводом · пинг; - круги **сошлись**, прежние находки закрыты таблицей «находка → что сделано → **чем предъявлено**»; - **числа ДО и ПОСЛЕ на обоих купленных файлах** предъявлены командой; - ряды **224** и **253** закрыты либо названо, что именно от них осталось; - список «что отрефакторено и почему» либо явное «не потребовалось» с доводом; - гейт зоны зелёный **целиком**; всё живое — **в дереве**; - сказано явно: **«работа завершена, править не планирую»**. ## АДДЕНДУМ ВЛАДЕЛЬЦА 17.09 (передан сессии релеем; ратифицирован `D39.258` п.9) 1. **Тщательно проектируй решение** — замысел раньше кода, и он предъявляется запиской-планом. 2. **Комментарии только нужные, без странных гарантий.** Не пиши гарантию, которой не стережёт ни один пин; комментарий, несущий ВЫВОД, обязан назвать условие, при котором вывод перестаёт держаться. 3. **Прозы в коде нет.** Комментарий объясняет ПОЧЕМУ, а не пересказывает, что делает строка. 4. **Решение общее для книг и языков.** Go-логика не ветвится по паре или книге: пара-специфика — в данных и языковых пакетах, книжные каноны — в сиде и брифе. Ревью-вопрос по умолчанию: «заработает ли пара, которой в репозитории ещё НЕТ, без правки Go?» 5. **Советчиков разрешено ДО ДВУХ** (прежняя норма — один), с ПОСТОЯННЫМ контекстом; вопросы досылаются тем же агентам. Советоваться предписано на ПРОЕКТИРОВАНИИ и на ПРИЁМКЕ, а не только при затруднении. 6. **Грепать `docs/`, `research/`, `experiments/` можно в любое время** — карта чтения промта это МИНИМУМ, а не потолок. ⇒ приём аддендума эхо-подтверждается, и в отчёте он идёт ОТДЕЛЬНЫМ пунктом. --- ⭐ Приоритет №1 проекта — издательское качество перевода длинной книги: связные термины и голоса на всю книгу. Экран подписи — место, где человек этим управляет напрямую. Всё здесь меряется одним: **стало ли человеку видно, о чём его спрашивают.**