# Промт: дофикс P6 — фикс-лист приёмки (шов status-канала · деплой-порядок · пины гейта миграции) > Выдан оркестратором №16 15.08.2026 по приёмке пака P6 (панель 5 верификаторов + посадки > оркестратора). Запуск — по слову владельца. Средний вес: полный DoD `ENGINEERING_STANDARDS` §3, > но скоуп — ровно фикс-лист ниже, не новый пак. ## 0. Какую проблему решаем Пак P6 (потребительская половина шва эмиттера · интейк формы Б · дев-сид) принят УСЛОВНО. Ядро устояло под адверсариальной панелью — денежные гонки, дев-вход, фолд юнитов, аддендум деплоя проверены исполнением и держат. Но приёмка нашла находки, из-за которых лендить без дофикса нельзя: самая тяжёлая — платформа не переживёт первый прогон с помеченными юнитами (см. ФП-1). Твой результат = закрытый фикс-лист, после которого оркестратор лендит P6+дофикс одним пакетом. **Мандат владельца (15.08, дословно по смыслу): каждая находка ниже — ПРИОР приёмки, а не истина. ПЕРЕПРОВЕРЬ каждую, пройдясь по коду, прежде чем чинить; где находка не подтверждается — не чини, а опровергни в отчёте с уликой. Рефакторинг разрешён и приветствуется там, где чинить точечно получается грязно, — на месте разберись сам и аргументируй.** Промт — твой единственный контекст. Улики приёмки даны как file:line — код первичен. ⚠ Если ты — та же сессия, что строила P6, после компакта контекста: своей памяти о деталях кода НЕ доверяй — компакт теряет именно детали. Каждую правку начинай с чтения актуального кода, а не с воспоминания о нём; свои прежние решения перепроверяй так же адверсариально, как чужие. «Аддендум», упоминаемый ниже, — аддендум оркестратора 14.08 о деплое; его текст — раздел «Аддендум оркестратора» в записи P6 журнала `platform-PROGRESS.md`. ## 1. Онбординг (коротко — ты зона `platform/`, правила прежние) `CLAUDE.md` (гардрейлы: зона записи ТОЛЬКО `platform/`, НЕ коммитишь, `.env` не читать, чужие незакоммиченные файлы в `backend/`/`frontend/`/`docs/`/`eval/` не трогать — там живые параллельные сессии; свой tmctl для проб — из КОПИИ `backend/` вне репозитория) → `platform/docs/ENGINEERING_STANDARDS.md` §3 (DoD) → раздел «P6» в `platform/docs/platform-PROGRESS.md` (что построено) → этот фикс-лист. Движок read-only; ⚠ в `backend/` лежит незакоммиченная работа параллельной migrate-сессии — HEAD и дерево различай `git diff -- backend/`. **Эхо-протокол:** ≤10 строк «что я понял: скоуп / инварианты / не-делать» ДО работы. ## 2. Фикс-лист (по каждой: перепроверить → чинить или опровергнуть → пин + посадка) ### ФП-1 [HIGH, деньги, несущий путь] `status --json` с exit 2 читается как отказ Движок с D39.131 выходит кодом 2 из `status --json`, когда в книге есть flagged-юниты (симметрия с человеческим режимом, «minor 1d»; `backend/cmd/tmctl/render.go:548-554`, запинено его же `TestRenderStatusJSONSchemaAndSentinel`). Платформенный `runner.Status` (`internal/runner/engine.go:157`) любой ненулевой код читает как ошибку и выбрасывает валидный JSON со stdout. Следствия: settle каждого flagged-прогона откладывается вечно (холд висит, PD-162-класс на ОБЫЧНОМ пути), `bookMeter` перед спавном отказывает каждому новому прогону такой книги, резюнк мёртв. Дев-путь `ingest/supervisor.go` (`cmd.Output()`) — тот же класс. Чинить: exit 2 при валидном JSON = валидный отчёт. **Перепроверь по коду движка, какие ещё $0-команды, которые зовёт платформа, могут выйти 2** (`render.go:639`, `:691` — там тоже `CompletedWithFlags`; `manifest`?) — и накрой каждую осознанно, а не только status. Exit 2 с НЕвалидным stdout остаётся отказом. Пины: фейк движка, выходящий 2 с валидным JSON → settle проходит и деньги считаются, спавн допускается; посадка «вернуть err-на-любой-ненулевой» падает. ### ФП-2 [доки, несущий документ] Деплой-порядок апгрейда движка гоняет `migrate` СТАРЫМ бинарём `deploy/README.md:136-148`: шаг 2 зовёт голый `tmctl migrate` ДО установки нового бинаря (шаг 3) — это no-op старым бинарём, деадлок v15 остаётся. Движковый `backend/cmd/tmctl/migrate.go` (заголовок; ⚠ незакоммичен, параллельная сессия) требует обратного: «стоп прогонов → НОВЫЙ бинарь на место → migrate ИМ по книгам → прогоны обратно». Поправь порядок: новый бинарь на ВЕРСИОНИРОВАННЫЙ путь (это безопасно — попытки запинены к своим путям) → `migrate` явным путём нового бинаря → только затем перевести `TM_PLATFORM_ENGINE_BIN`. Там же: комментарий шага 1 говорит «ДВА факта», а код и аддендум — ТРИ (незакрытый холд — `README:153` называет его только прозой ниже) — приведи к трём. Там же реши (запиши выбор): окно между списком `--migratable` и прогоном migrate ничем не заморожено — либо шаг «остановить демон/приём прогонов» в порядок, либо названный остаток строкой. ### ФП-3 [DoD] Гейт миграции книг не запинен Посадка приёмки «убрать блокер незакрытого холда из `BooksForMigration`» (`internal/pgstore/books.go:399-413`) пережила ВСЮ батарею. Это денежный гейт аддендума. Пин: тест, где каждый из ТРЁХ блокеров (живой прогон · резюмируемый · незакрытый холд) по отдельности переводит вердикт книги в «нельзя», и книга без всех трёх — в «можно»; посадка на каждый блокер падает. (Сам запрос приёмка проверила живым PG — он верен; не хватает именно пина.) ### ФП-4 [minor] Ветка нечитаемого маркера хоронит потолочную паузу как `failed` `internal/runs/reconcile.go:139-146` — единственная из трёх веток конца попытки, которая НЕ перечитывает `freshPausedReason` после дрейна: потолок, приехавший событием в этот же свип при испорченном маркере, закрывается `failed` с пустой причиной (воспроизведено приёмкой на живом PG: журнал `ceiling{scope:day}` + маркер `{not json` → `failed`/`""`, хотел `paused`/`daily_ceiling`). Чини (кандидат — поднять перечит выше switch, реши сам) + пин на этот сценарий. ### ФП-5 [hardening] `TM_PLATFORM_INSECURE_COOKIES` не отвергается рядом с боевым OIDC `config.Load` (`internal/config/config.go:252`) отказывает связке DEV_LOGIN+OIDC, но НЕ связке INSECURE_COOKIES+OIDC — а дев-рецепт `deploy/README.md` экспортирует обе переменные соседними строками, так что «оператор скопировал стендовое окружение в прод» ловится только наполовину: демон стартует с боевым Google-логином и куками без Secure/__Host (проверено приёмкой живым демоном). Приор — тот же отказ на буте; перепроверь, нет ли легитимного сценария (OIDC по http на стенде?) — если есть, реши форму сам (явный override?) и аргументируй. Пин + посадка; рецепт поправить, если изменится. ### ФП-6 [однострочники — перепроверить и взять либо опровергнуть] - **Незнакомый scope потолка** → `PausedCreditExhausted` (`internal/pgstore/books.go` `CeilingPause`): зажигает аккаунтный halted-флаг на аккаунте с деньгами — тогда как `ceiling_unknown` этот же пак завёл ровно для «потолок был, чей — не установлено». Приор: unknown scope → `ceiling_unknown`. - **Сид не тримит `--subject`** (`cmd/tmplatformctl/seed.go:42` читает сырую переменную, `Load` тримит): падённое значение создаёт аккаунт, сжигает одноразовый грант и обрывает сид (воспроизведено). Выровнять. - **Комментарий `sink.go` при `at >=`-гарде** утверждает «переанонс несёт СТАРОЕ время события» — по коду движка неверно (`pipeline/events.go:357` штампует время анонсирующего процесса, `ForgetEvents` стирает старую строку); гард всё равно корректен, но довод ложен — привести к факту. - **Комментарий Resume про book-ceiling** («remaining ноль и резюм ничего не меняет») — по арифметике остаток до одного зарезервированного вызова положителен, резюм даёт короткий холд-спавн-паузу цикл за клик. Комментарий привести к факту; сам чурн — чини или строкой, реши. - **exit 5 + стоп, записанный ПОЗЖЕ маркера** → сегодня `failed` (воспроизведено): намерение снимает «прерывание», а `stoppedOnRequest` отвергает по времени. Приор: намерение стопа при exit 5 = `stopped` независимо от того, кто был первым (пользователь ХОЧЕТ стоп — не перезапускать и не хоронить); перепроверь, не ломает ли это гард «чистый финиш перебивает стоп» (0/2/3 — он должен остаться), реши и запини. ### ФП-7 [строки регистра — не чинить, завести честно] Новые находки приёмки, которые НЕ чинятся этим касанием, — строками, **нумерация с PD-217** (⚠ PD-198/PD-199 НЕ трогать вовсе — их коллизию правит оркестратор при лендинге; открытый daily_ceiling-вопрос остаётся под номером PD-199): книга на `daily_ceiling`/вечно-незакрытом холде навсегда блокирует апгрейд движка без выхода для оператора · down-путь миграции 00015 падает на данных с новыми причинами паузы · рестарт при упавшем дрейне навсегда теряет непримененный хвост журнала (`unit_resolutions` для P7) · резерв имени `dev` сравнивается байт-в-байт («Dev» проходит; сегодня инертно — Postgres сравнивает байт-в-байт) · TM_TRACE_ID переиспользуется на ре-спавне попытки, движок отвергает и чеканит свой (деградация в резюнк, свежесть) · сид-променад не имеет теста (или добавь тест — реши по цене). Что из этого возьмёшь чинить сверх строк — твоё право, но класс PD-83 помни: не расширяться молча. ### ФП-8 [журнал] Базис «396 → 403» в шапке P6 не воспроизводится В HEAD 359 `^func Test`, в дереве 401 (+2 fuzz) — прирост +42, не +7; откуда 396 — неизвестно. Поправь запись P6 в журнале на воспроизводимые числа С КОМАНДОЙ счёта. ## 3. Чего НЕ делать Контракт (`openapi.yaml` и зеркало) не трогать (PD-199-вопрос ждёт слова владельца; правит S4). Читающую поверхность (P7), эскроу, брокер — нет. Чужие зоны и чужие незакоммиченные файлы — нет. `PD-198`/`PD-199` в регистре — нет (см. ФП-7). Тесты/гейты под зелень не подгонять — несогласие с пином = пинг. ## 4. Самопроверка и сдача (DoD = `ENGINEERING_STANDARDS` §3) Батарея `make check` с живым PG (`~/.local/pgsql`, порт 55433) под `-race`, скипов 0 — включая второй гейт (`TM_PLATFORM_TEST_ENGINE_BIN` + `_BOOK_TEMPLATE`, tmctl из копии backend/ вне репо). ФП-1 — «тяжёлый» класс: живая проба на фейке, умеющем выйти 2 с валидным JSON И с мусором. Каждый фикс — пин + посадка, списки посадок В ЖУРНАЛ; дифф `^func Test` исполнением, не памятью. Адверсариальное ревью диффа ДО сдачи механизмом (author≠reviewer, субагенты разрешены явно; ≥1 опровергатель другой модели на оценочной линзе); **артефакт — таблица «находка → диспозиция» в журнале**. Предметные оси этого дофикса (вправе добавить/аргументированно снять): (1) шов против РЕАЛЬНОГО движка — перечень команд, способных выйти 2, снимается чтением/пробой настоящего tmctl из копии, не догадкой; (2) деньги: settle flagged-прогона пересчитать из сырого леджера двумя путями; (3) конфиг-отказы (ФП-5) — атаковать обходы связки, как security-ось P6 атаковала дев-вход. Записка-план ID (ФП-N) → статус (закрыт/опровергнут/строкой) → улика; «заявление = команда». Сдача: раздел «Дофикс P6» в `platform-PROGRESS.md`, регистр строками тем же деревом, `python3 docs/scripts/counts.py --check` зелёный от корня, дерево НЕ коммитить. ## 5. Канал вопросов Непонятно / находка не подтверждается кодом / фикс тянет за границы зоны → пинг оркестратору через владельца, НЕ интерпретация.