textmachine/platform/docs/PLATFORM_P7_SESSION_PROMPT.md

161 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Промт: платформа, пак P7 — читающая поверхность по контракту 0.3.0 + модель ошибок + форварды (П-17, строка 169 единого)
> Выдан оркестратором №17 16.08.2026 (очередь D39.133; входы — D39.134 п.4 · D39.135 п.2в · D39.138 ·
> пинги №17 в зонном журнале). Запуск — по слову владельца, ПОСЛЕ лендинга батча 0.3.0 (§1).
## 0. Какую проблему ты решаешь и что решит твой результат
Платформа — control plane между веб-фронтом и движком перевода. К сегодняшнему дню построено всё
СТАТУСНОЕ и денежное: вход, кредиты с холдами, очередь и раннер, интейк книг, потребительская
половина шва с движком (события `events.jsonl` уже пишутся движком и материализуются в Postgres,
включая пер-юнитные разрешения). Чего нет — **читающей поверхности**: фронт не может прочитать ни
главы, ни юниты, ни замечания, ни банк, ни живой поток; из 16 операций контракта платформа отвечает
на 8. Из-за этого фронт живёт на моках и ЗАМОРОЖЕН, а центральный экран продукта (подпись банка) не
строится вовсе. Второе: причины отказов не существуют в машинном виде — сервер шлёт английскую фразу,
которую русский интерфейс печатает как есть.
Твой пак делает платформу ЧИТАЕМОЙ и её отказы — машинными. Результат разблокирует разморозку фронта
и экран подписи. Контракт только что пере-согласован целостным ревью (research/28, принят D39.138) и
сломан минором 0.3.0 ровно для того, чтобы ты строил новые ручки СРАЗУ по правильной форме — не строй
по памяти о старой.
## 1. ПРЕДУСЛОВИЕ — проверить до первой строки кода
Нормативная спека — **канон `docs/architecture/14-api-contract/openapi.yaml`**, `info.version`
обязана быть **0.3.0**. Если там 0.2.3 — батч ещё не заленден: исполни только пункты 02 состава
(§4 — они от батча не зависят), затем СТОП и пинг владельцу. ⚠ Зонное зеркало
`frontend/docs/api-contract/openapi.yaml` во фризе фронта может ОТСТАВАТЬ от канона — это известное
состояние; читать только канон.
## 2. Зона и git (канон — CLAUDE.md; здесь напоминание)
**Ты не коммитишь — лендит оркестратор.** Зона записи — только `platform/`. Прогресс, отчёт и
вопросы — ТОЛЬКО зонный журнал `platform/docs/platform-PROGRESS.md`. Чужие зоны read-only; чужие
незакоммиченные файлы (живой полигон: `eval/`, `docs/experiments/`) не трогать; `.env` не читать;
никаких `git add`/`git commit`/`reset`/`checkout`/переписывания истории — git не трогаешь вовсе,
файлы застейдженными не оставлять. Ревью-гард D39.85: путь Go-модуля платформы никогда не вкладывать
под путь движка.
## 3. Что читать (карта, ≤5 позиций)
1. **Канон 0.3.0 + компаньон** (`docs/architecture/14-api-contract/`) — целиком: форма каждой новой
ручки уже решена там, не изобретай параллельную.
2. **`docs/research/28-contract-review.md`** §5 (состав правок и зачем) · §8/§8а (решения владельца:
классы конкретности отказов) · §5б (сеть: что строить, чего НЕ строить) · §9 (находки по твоей
зоне) + **D39.138 п.2** (ратификация; при конфликте побеждает нота).
3. **Свой журнал `platform-PROGRESS.md`** — три пинга №17 (1516.08) и аддендум: там входы этого пака
(PD-104, форварды, протухшие тексты твоих доков) и попутные находки §9, которые ты судишь сам.
4. **Read-out поверхности движка** — пинг №15 в том же журнале (D39.122): манифест
`<db>.manifest.json` (`tm-manifest-v2`), банк `<db>.bank.json` + стоп-таблица `<db>.bank-stop.json`
(пишутся атомарно, читать можно во время прогона); плюс твоя же таблица `unit_resolutions`
(миграция 00015) — источник юнитов/замечаний.
5. `CLAUDE.md` — гардрейлы; `docs/glossary.md` — жаргон.
## 4. Состав пака — в этом порядке. **СОСТАВ пунктов 05 — «делай РОВНО так» (ратифицирован);
свобода — в ФОРМАХ исполнения внутри пунктов, где канон/промт форму не фиксируют. Пункт 6 — судишь
сам. ⚠ Пункты 02 от батча 0.3.0 не зависят — при запуске до батча исполняй их и стоп перед п.3.**
**0. Рантбук деплоя живым `migrate` — end-to-end на дев-стенде ($0, первым шагом).** Прогнать
собственный `deploy/README.md` настоящим новым бинарём движка по каждой книге стенда
(`tmplatformctl books --migratable``tmctl migrate`) — предусловие ПЕРВОГО выката (мнение
оркестратора из пинга 15.08; движковая половина финальна — D39.134; твой журнал честно фиксирует
«живьём не гонялся»). Попутно починить мёртвый текст ошибки схемы в
`deploy/README.md:131` (движок теперь печатает токен `schema_mismatch found=N expected=M`, exit 13)
и комментарий-образец `cmd/tmplatformctl/runs.go:45` (зовёт голый `tmctl` из PATH — воспроизводит
тихий no-op старым бинарём); якорь П-1 в своём BACKLOG обновить.
**1. Форварды 0.2.3 (РОВНО так, малые):** читать `BookIntake.title` (сегодня падает в «unknown field
is IGNORED» — `internal/httpapi/v0.go:369-376`, якорь-отправная точка, код первичен) · проецировать
`books.reject_reason` на провод (`v0.go:497` — «kept for an operator and never projected»).
**2. PD-104 (РОВНО так, слово владельца 16.08):** `SignupGrantMicroUSD` дефолт → **0** (бета:
начисление руками через админ-CLI; возврат $5 — вместе с суточным потолком при появлении платежей) +
тест; регистр и протухшие «$5» в `PLATFORM_DIRECTION.md` §2 / BACKLOG П-7 — поправить. ⚠ Ветка
«грант 0 при неверифицированном email» (`login.go:306-308`) УЖЕ существует — это не баг и не твоя
правка, не перепутай с ней.
**3. Модель ошибок (Б-1/§8а) — ПЕРВОЙ из контрактной половины,** от неё зависят формы остальных ручек:
структура `Problem` по 0.3.0 (машинный `code` двухуровневый + `request_id` — значение уже штампуется,
`internal/reqid`). ⚠ **Словарь кодов УЖЕ определён каноном** (батч вывел его из твоих же веток
`fail()`) — РЕАЛИЗУЙ словарь канона, не выводи свой заново: не хватает причины для реальной ветки —
пинг, не изобретение (два независимых вывода из одного источника гарантированно разойдутся именами).
Класс 2 (прескрин/провайдер/фильтр) — ОДИН грубый код, без вариации между попытками.
`WWW-Authenticate` на 401; две причины 403 развести (нет `X-TM-Client` ≠ кросс-origin).
**4. Читающая поверхность по 0.3.0 (ядро пака):** главы / юниты / замечания (с `id` и `created_at`
форма 0.3.0) / банк (проекция сайдкаров движка + снимок стопа подписи `pending/complete`) /
`POST /bank/decisions` / **SSE-поток** в форме 0.3.0 (канал КНИГИ, кадры конца разбора и конца
прогона, `204` переподключению к завершённому, склейка ТОЛЬКО снимкам — `note`-класс не склеивать).
**Пофазность у главы НЕ строить** (К-10 отвечен «НЕТ», D39.138 п.5): колонки `units_draft_done`/
`units_edit_done` лежат в read-модели готовыми и «бесплатная проекция» напрашивается — фазы на провод
не выходят НИ у книги, ни у главы; глава отдаёт один счётчик по канону.
Сюда же сеть, шаги 12 §5б (строка 186): **gzip на текстовых ответах (НЕ на SSE)** и
`ETag`/`If-None-Match` → 304 на списочных GET. Совет-приор: ревизия у тебя уже читается одной
транзакцией со страницей (PD-163) — ETag из неё.
**5. Правки построенного под 0.3.0:** `wireProgress` → один счётчик до остановки (Б-0; ⚠ колонки БД
и словарь шва с движком НЕ трогать — фазы остаются внутренним делом); `GET /capabilities` (Б-2: пары
из конфигурации · порог интейка · форматы · размеры страниц · версия контракта); подрезка `limit` до
максимума вместо сброса к дефолту (Б-10); трейлинг-части интейка → 400 вместо тихой потери + `Location`
на 201 + `Idempotency-Key` (Б-3); `blocked: {code, book_id}` на run-options/409 (В-6); отказ по
неподдерживаемой паре кодом на интейке (сегодня ja/en-книга умирает `failed`-ом на валидации движка
в конце пути); `Run.failure_reason` (Б-8 — словарь исхода у движка уже есть); переименование
`verify_bank``stop_for_signing` на проводе (живёт в построенном: `v0.go:127,154`) и сворачивание
`finalizing` из словарей валидации (`runs.go:229`, `sink.go:435`; судьбу CHECK-констрейнтов
read-модели реши по канону — значение никем не пишется).
**6. Свой регистр — судишь сам (кроме помеченного):** PD-201 (самолечение «поймал exit 13 → migrate →
повтор» — движковая половина ФИНАЛЬНА, можно строить); кандидаты PD-219 / PD-217 / PD-162;
**обновить протухшие статусы (РОВНО так):** PD-172/PD-173/PD-174/PD-180 — диспозиция «спек-правка»
ИСПОЛНЕНА ещё 0.2.3 · PD-199 — ратифицирован закрытым D39.132 п.2а, в регистре до сих пор open;
находки §9 research/28 — каждой явную диспозицию (берёшь / P8 с причиной / отклоняешь с причиной):
незакрываемые расчёты (бюджет висения холда) · флаг аккаунта сканом всех книг (после PD-203) ·
`ReadRunForSpawn` O(живых) · **`/metrics` без аутентификации (защита — только 127.0.0.1)** · лимитер
входа на процесс · сырой Go-текст в карантине. Протухшие тексты зоны: баннер §3
`PLATFORM_DIRECTION.md` привести к D39.132 п.2б и §4 п.5 (склейка сузилась — только снимкам).
Инструменты: **sqlc — ПРИВЯЗАН к этому паку (D39.132 п.2б, ратифицировано):** внедряй на читающей
поверхности с `overrides` на денежные типы, отступление = пинг; oapi-codegen — кандидат, реши сам
и аргументируй.
**Явно отложено в P8 (не тихо):** `PATCH /books/{id}` (title-only) + `DELETE` + `GET /runs/{id}` ·
эскроу П-18 (денежный промт) · всё, что не влезло, — списком с причинами в отчёте.
## 5. Нормы исполнения
- **Самопроверка исполнением:** батарея `make check` + ОБА гейта (`TM_PLATFORM_TEST_DSN` +
`TM_PLATFORM_TEST_ENGINE_BIN`/`_BOOK_TEMPLATE`) — **скипов 0 это гейт**; физически неустранимый
скип = obstacle, объяви и объясни; дифф `^func Test` — исполнением, не памятью; живые пробы новых
ручек против дев-стенда (сид P6).
- **Заявление = команда:** каждое число/категорическое утверждение отчёта — с командой; приёмка
пере-ранит.
- **Записка-план по §4** (D39.121): каждый пункт (06 и отложенные) — строка «исполнено, где /
отказ, почему»; сдача = все с диспозицией, комплектность против заказа механически.
- **Шов:** если касаешься ЛЮБОГО канала движка — сначала инвентарь ВСЕХ его каналов и кодов чтением
чужого кода, не по памяти (урок D39.132: `status --json` упустили все, кроме панели приёмки).
- Посадки мутаций — дисциплина `ENGINEERING_STANDARDS.md` §3, пункт «посадки» (списочный пункт 3,
~:67-69; ⚠ нумерации «§3.3» в файле нет — не ищи заголовок).
- **Предметная ось зоны:** индустриальный первоисточник прежде велосипеда — RFC 9457 (problem+json),
WHATWG SSE (204/переподключение), RFC 9110/9111 (условные запросы, `Vary` при gzip); stdlib/устоявшаяся
библиотека прежде своего. Право добавить свою ось или снять эту — с аргументом.
- **Деньги:** пак денег не двигает (PD-104 — константа гранта); если что-то денежное всё же затронул —
два независимых пути счёта из сырого леджера.
- **Адверсариальное селф-ревью финалом вехи — МЕХАНИЗМОМ, не стилем чтения (субагенты РАЗРЕШЕНЫ
явно, спавнь их; норма CLAUDE.md 12.07 + урок 14.08 «author≠reviewer ≠ перечитал сам»):** ≥2
независимых ревьюера-субагента по финальному диффу, author≠reviewer, разные линзы — (а)
контракт-конформность: ревьюер получает канон 0.3.0 и твои ручки, мандат «найди расхождение формы
провода со спекой» (пере-раном живых проб, не чтением); (б) деньги/шов: мандат «найди путь, где
холд/расчёт/канал движка ведёт себя не так, как записано» — с инвентарём каналов, не по списку
автора. Плюс **СВОИ посадки мутаций** в новые гейты/ручки (дисциплина посадок `ENGINEERING_STANDARDS.md` §3:
свойство считается запиненным, когда посадка роняет тест — посадки НЕ из списка, который ты сам
ожидаешь). Проверяемый артефакт: таблица находок и посадок в отчёте, каждая с диспозицией
(исправлено / отклонено-с-причиной); ноль находок = повод не верить прогону.
- **Obstacle reporting** — обязательная секция отчёта: что НЕ удалось, что не проверено.
- **Канал вопросов:** непонятно / промт конфликтует с кодом, спекой или доками → пинг оркестратору
через владельца, НЕ интерпретация. Право сказать «этого делать не надо» — с аргументом.
## 6. Эхо-протокол и сдача
Первый деливерабл — ≤10 строк «что я понял: скоуп / инварианты / не-делать». Сдача: отчёт в
`platform-PROGRESS.md` (записка-план · команды батареи · живые пробы · таблица находок и посадок
адверсариального селф-ревью с диспозициями · obstacle reporting · диспозиции §4.6), дерево
незакоммиченное, регистру дефектов — новые строки по находкам. Без саги.