# Промт сессии: ПЛАТФОРМА — «закрыть цикл: сквозной прогон и дверь выдачи» > **Роль:** платформа. **Зона записи:** `platform/`. Чужие зоны читаешь, не правишь; итоги и пинги — > ЗОННЫЙ журнал `platform/docs/platform-PROGRESS.md` (в `docs/PROGRESS.md` платформа НЕ пишет). > **Не коммитишь** и не трогаешь индекс и историю — запреты и причина: `CLAUDE.md`, > «Git-координация мультисессий». > **Обязателен к ссылке:** `platform/docs/ENGINEERING_STANDARDS.md`; отступление — пинг, не > самовольство. Направление зоны — `platform/docs/PLATFORM_DIRECTION.md`. ## Какая проблема и что изменит твой результат Цикл не замкнут: движок собирает книгу файлом с 30.08 (EPUB 3 + чистый txt), холодный прогон предъявил это живьём — собранный EPUB настоящего перевода прошёл `epubcheck` 0/0/0/0. **Пользователь этот файл получить не может:** канон обещает `createExport`/`getExport`, платформа их не монтирует. Долг числится с P8, и ни один пак после P7 его не взял. Вторая половина той же проблемы: **живой перевод книги насквозь через API не гонялся НИ РАЗУ.** Всё после «прогон стартовал и остановился» покрыто батареей против живого Postgres, но с движком-заглушкой. Настоящий манифест, сайдкар банка и карта причин флагов будут ПЕРВЫМИ данными, форму которых платформа не сочинила сама. После пака: книга доходит до пользователя файлом, и это предъявлено живым прогоном на настоящем движке, а не фикстурой. ## Карта чтения — пять позиций 1. `platform/README.md` — устройство зоны · `platform/docs/ENGINEERING_STANDARDS.md` (обязателен). 2. `platform/docs/platform-PROGRESS.md` — зонный журнал: пинги оркестратора и отчёты паков P12/P13. 3. **Состав и его доводы — здесь.** Разбор лежит в отработавшем плане `docs/archive/reports/NEXT_PACKS_PLAN_2026-09-03.md` §2 — ⚠ АРХИВ: читать как ДОВОД, инструкции оттуда не исполняются. Механизм потолка ратифицирован **эрратой 04.09-а к D39.189**, решения очереди — **D39.190**; оба грепом по номеру. 4. `docs/architecture/14-api-contract/` — канон; **зеркало фронта НЕ норматив**. Ряды регистра по номеру: `PD-424` · `PD-418` · `PD-438` · `PD-217` · `PD-246`. 5. Журнал решений грепом: **D39.189** и **эррата 04.09-а к нему** (механизм потолка) · **D39.176** п.3 (возобновление явным действием) · **D39.178** (дверь всегда строит файл) · **D39.175** п.2 (`BuildReport` — оператору) · **D39.85** (закон шва: импорта чужого модуля нет). ⚠ Ратифицированное вложено сюда; код-факты добываешь САМ. Числа — с командой получения. ## ⚠ ПРЕДУСЛОВИЕ: четыре условия хоста + ключи Условий батареи ЧЕТЫРЕ, и цель `make conditions` печатает их состояние сама — **начни с неё**, а не с догадки. На этом хосте: `~/go/bin` существует и держит `sqlc` (без `export PATH=$HOME/go/bin:$PATH` `make check` не стартует вовсе), сокет Postgres — `/tmp/.s.PGSQL.55433`, DSN — в `platform/docs/STACK_DECISIONS.md`. **Ключи провайдера для платного прогона.** Конвенционного `.env` нет ни у одной книги корпуса. Платформе нужен `TM_PLATFORM_ENGINE_KEYS_PATH` **абсолютным путём** на уже заполненный файл (`platform/internal/config/config.go`, греп `must be an absolute path`). ⛔ **Сам файл НЕ читать** — гардрейл `CLAUDE.md`. Проверять ПРОГОНОМ, а не чтением. ## Состав — четыре пункта ### 1. Строка 202 — живой сквозной прогон книги через API. ПЛАТНЫЙ **Санкция владельца ДАНА** (`D39.189`, 03.09: «разрешаю платные прогоны с ключами для тестов»). ⛔ **ПОТОЛОК — ЭТО ГРАНТ, А НЕ ФЛАГ. Читай внимательно, здесь легко сделать хак.** На пути через API `--ceiling-usd` руками не ставит никто: платформа выводит число сама — `bookCap = committed + increment` (`internal/runs/spawn.go`, греп `func (m meter) bookCap`), а `increment` считается по ставке `DefaultPerChapter = 30_000` ($0.03, `internal/pricing/pricing.go`), которая занижена ×4.47 (`D39.179` п.1). **Делай РОВНО так:** потолок пака = **грант тест-аккаунту ровно на $1.5** (`tmplatformctl grant --user --usd 1.5`) — холд делает перерасход невозможным по построению. ⛔ **`TM_PLATFORM_USD_PER_CHAPTER` НЕ КРУТИТЬ** — это подгонка окружения под тест, запрещённая каноном. Ставка занижена, и это известный ряд, а не твоя задача. **Путь до завершённой книги идёт цепочкой «покупка → пауза по потолку → пополнение → новый прогон», и это НЕ обход, а продуктовый путь** (`D39.176` п.3; `resume` прогона, остановленного потолком, отбивается — `internal/runs/runs.go`, греп `ErrCeilingReached`, и `PD-217` называет лечение: «новый прогон»). Тремя явными сценариями закрывается строка **216**: подпись банка · halt на потолке · резюм после пополнения. ⚠ **Стартовать в ДОЛИНУ:** у DeepSeek пиковые окна 01–04 и 06–10 UTC дают ×2 (строка 172а). Операционное правило дешевле любой правки Go. **Что сверить — то, что до сих пор не сверялось ни разу:** на шов реально вышло ОДНО значение `flag_reason` из пятнадцати, а манифест против `internal/ingest/manifest.go` не сверялся вовсе. ⚠ Четырнадцать причин флагов прогоном не вызвать — **так и напиши**, не выдавай непроверенное за проверенное. **Решаешь сам:** книга и её объём, порядок сценариев, форма фиксации артефактов. ### 2. Дверь выдачи — `createExport` / `getExport` Не построено: `grep -rn 'createExport\|getExport' platform/internal/ --include=*.go` → 0 (контроль: `listBankTerms` → есть). Смонтировано 15 маршрутов при 20 `operationId` канона. **Делай РОВНО так — слово владельца 30.08:** дверь **ВСЕГДА строит файл**. Отказ пользователю не отдаётся; неполная книга уходит **с пометкой**, то есть дверь зовёт `tmctl build --partial` (`D39.178`). Отказ по умолчанию остаётся операторской ручкой CLI. `BuildReport` — оператору в лог, не читателю (`D39.175` п.2). Денег на проводе нет (`D39.84`). ⚠ **Четыре факта кода, каждый меняет работу:** - `ExportFormats` захардкожен пустым (`cmd/tmplatformd/runner.go`, греп `ExportFormats`), а форматы движок публикует только Go-переменной `bookfile.Formats` — **импорт чужого модуля запрещён** (`D39.85`). Значит нужен КАНАЛ: переменная деплоя либо движок публикует данными. Это вопрос закона входной двери — **решаешь сам и аргументируешь, но если ответ требует правки движка — пинг, не правка**. - Декодера `tm-build-v1` / `BuildReport` в платформе НЕТ (ноль хитов при живых `DecodeExport`, `DecodeBank`). - `build` открывает стор read-only без flock ⇒ канонное «книгу можно экспортировать во время перевода» исполнимо. - `ExitBookIncomplete = 16` у платформы отсутствует (`internal/ingest/exit.go`). **Минор канона — состав назвать в отчёте, правку согласовать:** `Export.failure_code` становится enum с первым построенным форматом (`contract-10` строки 243, условие наступило) · механизм подписанной ссылки и её TTL плюс GC файлов · строка **241** (канон противоречит себе на дочитанной книге). ⚠ Прецедент есть: миноры 0.6.0/0.7.0/0.9.0 приезжали с паками зоны через ратификацию оркестратора. **Делай РОВНО так:** канон правится ТОЛЬКО через ратификацию, не своей рукой. ### 3. `PD-424` — терминальная ручка для живого прогона с заблокированной расплатой (`major`) Половина «невидим» вылечена P12; половина «ручки нет» стоит. `run abandon` ветвится по `runs.finished_at` (`internal/pgstore/runs.go`, греп `AbandonRun`) и на живом прогоне уходит в живую ветку, а `AbandonRun` отказывает над попыткой, ещё называющей юнит. ⚠ Это **НОВАЯ разрушительная операторская поверхность над деньгами**. **Делай РОВНО так:** её дизайн называется явно и целиком — кто вправе звать · чем доказывается отсутствие процесса · что происходит, если процесс вернётся (двойная расплата). **Решаешь сам:** форма ручки и глубина. ⚠ Дописать `PD-418`: та же ветвь по `finished_at`, долговечное лечение — «ветвить по НАЛИЧИЮ осиротевшей попытки». Либо входит в тот же дизайн, либо **явно объявляется вне его**. ### 4. Дофикс чужого пака + три райдера ⚠ **Почему это здесь.** По канону дофикс шёл бы той же сессии, но её больше нет (`ListAgents` 04.09). **Это чужая недоделка, а не новый заказ** — в отчёте называть отдельно от своей работы. - **Записка о предусловии хоста** (`platform-PROGRESS.md`) различает хосты **именем машины**, а имя у этого хоста то же самое (`DESKTOP-IN1MCEA`) при противоположных условиях: `~/go/bin` существует и держит `sqlc`, `make tools-check` на дефолтном PATH падает, сокет только 55433. Различает пользователь и `$HOME`, а не хост. **Делай РОВНО так:** ключевать записку пользователем/`$HOME`. - **Райдер `246`:** `internal/ingest/exit.go` обещает «nothing this process would have written was written», а движок это прямо отрицает. Остаток — комментарий плюс константа 16, которую дверь и так добавит. ⚠ Прежняя формулировка «разрушительно по полосе» ПЕРЕОЦЕНЕНА: интейк удаляет загрузку только на классе 11. - **Райдер `234`:** `internal/runs/bank.go` объясняет отказ снятой посылкой («status projects the STORED memory…»), опровергнутой `D39.170`. Одна правка комментария. - **Райдер `PD-438`-остаток:** лечение в дереве, но припаркованная попытка не видна ни в `runs`, ни гейджем, ни колонкой. **Решаешь сам:** закрывать сейчас или назвать отложенным — но НАЗВАТЬ обязан. ## Границы — что НЕ делать - ⛔ Не трогать форму манифеста · схему хранилища движка · `docs/scripts/counts.py`. - ⛔ Не править канон своей рукой — только через ратификацию. - ⛔ Не крутить `TM_PLATFORM_USD_PER_CHAPTER` и не обходить холд. - ⛔ Не решать `PD-439` и не переносить ряды между секциями регистра — статус есть акт лендинга. - ⛔ Не брать `PD-410` · `PD-412`/`413` · `PD-386`–`392`: первый архитектурный и крупнее двери, остальные — отдельный пак наблюдаемости. - ⛔ Не трогать бэкенд-половину, `.env`, соседний worktree. ## Свобода и её разметка **«Делай РОВНО так»:** грант как потолок и запрет крутить ставку · цепочка покупка→пауза→пополнение→ новый прогон · дверь всегда строит, `--partial`, `BuildReport` оператору · канон только через ратификацию · дизайн `PD-424` назван целиком · записка ключуется пользователем · все запреты границ. **«Решаешь сам и аргументируешь»:** книга и объём прогона · порядок сценариев · канал форматов (с пингом, если упирается в движок) · форма ручки `PD-424` · судьба `PD-438`-остатка · форма подписанной ссылки и GC. ⚠ Чего нет ни в одном списке — пинг, а не усмотрение. ## Мандат самопроверки — исполнением 1. **Живая проба каждого пункта поимённо**, с пометкой, нужен ли DSN. 2. **Собственные адверсариальные посадки ВНЕ списка** — на копии дерева (`cp -a platform /tmp/<имя>/`), каждая с командой и выходом; пережившие батарею — находки, и они объявляются. 3. **Отдельный проход по своей готовой работе** свежим контекстом. Субагенты разрешены явно, модель ИМЕНЕМ, число знай. 4. ⚠ «Прошла, находок нет» отчётом не является. ### Предметные оси ревью — под предмет этого пака 1. **Идемпотентность третьего создающего вызова** (`internal/pgstore/idempotency.go`, греп `beginIdempotent`): дверь — новая создающая поверхность. 2. **Жизнь и GC выданных файлов**: ссылка чеканится на ответ и владельца и истекает — что после. 3. **Экспорт ВО ВРЕМЯ живого прогона** (read-only без flock это разрешает — проверь, что не врёт). 4. **`PD-424`: возврат процесса после «признали отсутствующим»** — двойная расплата. 5. **Положительный контроль, без которого дверь не сдана:** `epubcheck` на ВЫДАННОМ файле и скачивание по чеканенной ссылке ВТОРЫМ клиентом. ⚠ Запрет подгонки тестов — `CLAUDE.md` (`D39.183`); заказанная смена поведения объявляется в отчёте. ## Отчёт **Записка-план ДО работы** (скоуп · инварианты · что НЕ делаю, ≤10 строк) — в `platform/docs/platform-PROGRESS.md`, и тем же текстом первым действием по каналу. **Пройди по четырём пунктам состава и таблице разметки и отчитайся ПО КАЖДОМУ.** **Каждое число — с командой получения**; приёмка пере-ранит. Гейты гнать ПОСЛЕДНИМ действием. **Обязательная секция «Что НЕ удалось и что НЕ проверено»** — третий исход законен; сюда обязательно попадают четырнадцать причин флагов, которые прогоном не вызвать. **Конфликт с кодом — пинг, не интерпретация.** Право сказать «этого делать не надо» с аргументом у тебя есть, включая состав и границы. ## Прямой канал Механизм — `CLAUDE.md`, «Связь между сессиями»: свой блок в `/tmp/textmachine-channel`, сверка с `ListAgents`, канала нет — нормальный случай. Эхо-записку отправь ПЕРВЫМ действием по адресу оркестратора — это и проверка канала.