textmachine/platform/docs/PLATFORM_P6_DOFIX_SESSION_PROMPT.md

17 KiB
Raw Blame History

Промт: дофикс 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 jsonfailed/"", хотел 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. Канал вопросов

Непонятно / находка не подтверждается кодом / фикс тянет за границы зоны → пинг оркестратору через владельца, НЕ интерпретация.