textmachine/platform/docs/PLATFORM_P7_SESSION_PROMPT.md

18 KiB
Raw Blame History

Промт: платформа, пак P7 — читающая поверхность по контракту 0.3.0 + модель ошибок + форварды (П-17, строка 169 единого)

Выдан №17 16.08.2026, пересобран после лендинга батча 0.3.0 (D39.142144) и опровергателя промта. Запуск — по слову владельца.

0. Зачем

Платформа (control plane фронт↔движок) построена до потребительской половины шва: вход, кредиты, раннер, интейк, ингест событий движка в Postgres. Из 20 операций контракта 0.3.0 отвечает на 8: фронт не может читать главы/юниты/замечания/банк/поток — он на моках и ЗАМОРОЖЕН, экран подписи строить не на чем; отказы — английской фразой без машинного кода. Твой пак делает платформу читаемой и отказы машинными → разблокирует фронт. Контракт только что пере-согласован и сломан минором 0.3.0, чтобы ты строил СРАЗУ по правильной форме — не по памяти о старой.

1. Нормативный источник

Канон docs/architecture/14-api-contract/openapi.yaml, info.version: 0.3.0 (не та версия → стоп, пинг). Зеркало frontend/docs/api-contract/ ОТСТАЁТ намеренно (фриз фронта) — читать только канон. Форма каждой ручки решена там; расхождение промта с каноном → верь канону и пингуй.

2. Зона и git

Ты не коммитишь — лендит оркестратор. Пишешь только в platform/; отчёт/вопросы — только platform/docs/platform-PROGRESS.md. Чужие зоны read-only; живой полигон (eval/, docs/experiments/) не трогать; .env не читать; git не трогать вовсе (ни add, ни commit, ни reset/checkout), файлы застейдженными не оставлять. Путь Go-модуля не вкладывать под путь движка (D39.85).

3. Читать (≤5)

  1. Канон + компаньон (docs/architecture/14-api-contract/) целиком. В компаньоне: §3 таблица «чтение → источник» · приложение А-2 — готовая карта «твоя ветка v0.go → код ошибки» с file:line · §6б — почему формы такие.
  2. docs/research/28-contract-review.md §8а (классы отказов) · §5б (сеть) · §9 (находки твоей зоны)
    • D39.138 п.2 и D39.142144 (хвост docs/architecture/05-decisions-log.md).
  3. Свой журнал platform-PROGRESS.md: три пинга №17 + аддендумы (входы пака, file:line находок).
  4. Read-out движка — пинг №15 там же: <db>.manifest.json (tm-manifest-v2; unit.id = <chapterID>:<cutTag>:<firstChunkIdx>; ⚠ heading — ВРЕМЕННЫЙ рендер «Глава N», НЕ метка книги) · <db>.bank.json · <db>.bank-stop.json (conf: null ≠ 0); пишутся атомарно, читать можно при живом прогоне. Плюс своя unit_resolutions (миграция 00015).
  5. CLAUDE.md; жаргон — docs/glossary.md.

4. Состав. Пункты 05 — «РОВНО так» (состав ратифицирован; формы внутри — твои, где канон/промт

их не фиксируют). Пункт 6 — судишь сам. Отложенное — только явно, списком в отчёте.

0. Рантбук деплоя живым migrate, end-to-end, $0, первым шагом (предусловие первого выката; твой журнал: «живьём не гонялся»): прогнать свой deploy/README.md новым бинарём движка по книгам стенда (tmplatformctl books --migratabletmctl migrate). Попутно: deploy/README.md:131 — мёртвый текст ошибки (движок печатает schema_mismatch found=N expected=M, exit 13); cmd/tmplatformctl/runs.go:45 — комментарий зовёт голый tmctl из PATH (тихий no-op старым бинарём); якорь П-1 в BACKLOG обновить.

1. Форварды: (а) читать BookIntake.title — сегодня игнорируется (internal/httpapi/v0.go:369-376); по 0.3.0 обязателен, пустая строка = «назови по файлу»; (б) проецировать reject_reason — писатель pgstore/books.go:310, проекция projectBook (v0.go:470; обоснование-комментарий :497) — значениями словаря канона RejectReason (processing_failed, не имя внутренней ветки).

2. PD-104: SignupGrantMicroUSD дефолт → 0 + тест (слово владельца 16.08; возврат $5 — с суточным потолком при платежах). Ветка «0 при неверифицированном email» (login.go:306-308) уже есть — не баг. Протухшие «$5»: PLATFORM_DIRECTION.md §2, BACKLOG П-7, регистр.

3. Модель ошибок — ПЕРВОЙ из контрактной половины (от словаря зависят формы остальных ручек): Problem по канону (code 16 корневых + cause + request_id из internal/reqid + errors[]). Словарь НЕ выводить — реализуй карту А-2 компаньона; реальная ветка без кода → пинг, не изобретение. Класс 2 = один код content_refused, без вариации, лимит попыток — по канону (:2394). WWW-Authenticate на 401. Две причины 403 (нет X-TM-Client ≠ кросс-origin) — раздельно только в открытом cause.code, корневой forbidden один (канон), новых корневых не заводить.

4. Читающая поверхность (ядро): listChapters · listUnits (только пер-главно; ручку «вся книга юнитами» НЕ заводить — инвариант твоего же PLATFORM_DIRECTION.md:208-210 и §5б; 410 Gone на исчезнувшую главу; Unit.notes массивом) · listNotes (id+created_at+обязательный chapter_id; порядок created_at, тай-брейк серверный) · listBankTerms (проекция сайдкаров; агрегаты total/signed/pending_decisions/complete — первая страница, ИНФОРМАЦИОННЫЕ) · submitBankDecisions (approve/decline, накопительный, maxItems 1000; неизвестный term_id → 400 всей пачки, item-код unknown) · дельта-чтения ?after_version= на notes/bank (ВКЛЮЧИТЕЛЬНЫЕ; водяной знак = наименьшая ревизия обхода; устаревший → 400 version_too_old) · SSE streamBookEvents — все правила в каноне: id = позиция истории книги (служебные кадры несут id последнего кадра, 0 на пустой книге), кадр end + 204 по Last-Event-ID (кадра «конец разбора» НЕТ — конец интейка = смена статуса), склейка только state-кадрам, note не терять в пределах соединения, resync_required когда не можешь продолжить с предъявленного id · structure_version — в Book, во всех четырёх конвертах страниц и в КАЖДОМ кадре (EventBase); источник — манифест движка · gzip на JSON (НЕ на SSE) + ETag/If-None-Match → 304 на всех коллекциях, КАРТОЧКЕ книги и /capabilities; валидатор — ко всему запросу, query включая (:850 канона; «ETag = ревизия страницы» НЕДОСТАТОЧЕН — стр.2 и дельта той же ревизии обязаны отличаться). ⚠ Ловушки, каждая — канон против сегодняшнего кода:

  • heading: канон запрещает класть рендеренный порядковый (:1556-1566) — а heading манифеста ровно он; проецируй null до движковой строки 160. Прямая проекция сайдкара = нарушение.
  • Гейт полноты банка УЖЕ ПОСТРОЕН — ДЕМОНТИРУЙ: internal/runs/reconcile.go:934-938 (awaiting_bankErrNotResumable "glossary is not signed") ссылается на снятые D39.144 разделы. Подпись = ОДИН resume при любом состоянии решений; полноту не отливать ни в новый код, ни оставлять в старом. Границу паузы движка сверь чтением его кода (строка 191); расхождение — пинг.
  • Пофазность у главы НЕ строить (К-10 «НЕТ», D39.138 п.5): колонки units_draft_done/edit_done лежат готовыми и напрашиваются — глава отдаёт ОДИН счётчик прохода по канону.
  • Note.code: словарь НЕ ратифицирован (приложение А — заготовка ◆). Бери коды из ◆-карты как есть, новых не изобретай; причина движка мимо карты → пинг.

5. Конформность ПОСТРОЕННОГО. Правило: пофайловый дифф каждой построенной wire-структуры против required-списка канона; расхождение — чинить или в отчёт с причиной. Именованный минимум: Progress переезжает с книги на Run (одна полоса в ГЛАВАХ до остановки, знаменатель — купленный объём) · Book: +revision, +chapters_done (SQL уже считает — pgstore/books.go:677-681), progress, genre (v0.go:108 — нарушение allowlist-инварианта канона, строка 184) · Run: +book_id, +failure_reason (словарь канона из трёх значений — мапь полосу 1019 и ветки outcome()), verify_bankstop_for_signing (провод: v0.go:127,154) · Usage: paused_reasonhalt_reason со СВОИМ словарём AccountHaltReason (v0.go:159-163 сейчас несёт прогонный) · GET /capabilities — НОВАЯ ручка и зависимость всех чтений (дефолты страниц читаются из неё; все шесть полей канона, intake_enabled включая) · limit: подрезать до 1000, НЕ отвергать (pgstore/books.go:510-511 сейчас сбрасывает к дефолту; схемную валидацию параметра вывести из-под отказа — :886 канона) · трейлинг-части интейка → 400 (⚠ меняет узаконенное 0.2.3 «молча теряется» — по канону 0.3.0) · Location на 201 · Idempotency-Key на createBook И startRun — семантика целиком в §IdempotencyKey канона · blocked {code, book_id} на run-options и 409 (таблица reservations знает держателя) · отказ по неподдерживаемой паре кодом на интейке · finalizing — вон из словарей валидации (internal/runs/runs.go:229, pgstore/sink.go:435; CHECK-констрейнты — по канону, значение никем не пишется).

6. Свой регистр — судишь сам, кроме помеченного РОВНО: РОВНО — статусы PD-172/173/174/180 (исполнены 0.2.3) и PD-199 (закрыт D39.132 п.2а) привести; строку PD-201 обновить (движковая половина финальна — самолечение «exit 13 → migrate → повтор» можно строить); PD-241 исполнить — ратифицирован D39.132 п.2д «следующим касанием зоны», это касание — ты (намерение стопа выигрывает на статусе). Судишь: кандидаты PD-219/PD-217/PD-162; находки §9 research/28 — каждой диспозицию (берёшь / P8 / отклоняешь, с причиной): висящие расчёты без бюджета холда · флаг аккаунта сканом всех книг · ReadRunForSpawn O(живых) · /metrics без аутентификации · лимитер входа на процесс · сырой Go-текст в карантине. Протухшие тексты зоны: PLATFORM_DIRECTION.md §3-баннер (снят D39.132 п.2б), §4 п.5 (склейка сузилась), :199 «подписывает банк частями» — ложь после D39.144, §2 «$5». Инструменты: sqlc — привязан к паку (D39.132 п.2б; overrides на денежные типы; отступление = пинг); oapi-codegen — кандидат, реши и аргументируй.

Отложено в P8 (не тихо): updateBook/deleteBook/getRun · createExport/getExport (содержимое — S7; формы в каноне финальны) · эскроу П-18. Всё прочее невлезшее — списком с причинами.

5. Нормы

  • Самопроверка исполнением: make check + ОБА гейта (TM_PLATFORM_TEST_DSN, TM_PLATFORM_TEST_ENGINE_BIN/_BOOK_TEMPLATE), скипов 0 — гейт (неустранимый скип = obstacle с объяснением); дифф ^func Test исполнением; живые пробы новых ручек на дев-стенде (сид P6).
  • Заявление = команда: каждое число/категорика отчёта — с командой; приёмка пере-ранит.
  • Записка-план по §4 (пп. 06 + отложенные): «исполнено, где / отказ, почему» на каждый; сдача = все с диспозицией.
  • Шов: касаешься канала движка → сначала инвентарь ВСЕХ его каналов и кодов чтением чужого кода (урок D39.132).
  • Посадки мутаций — ENGINEERING_STANDARDS.md §3, списочный пункт «посадки» (~:67-69; заголовка «§3.3» в файле нет).
  • Предметная ось: индустриальный первоисточник прежде велосипеда — RFC 9457 · WHATWG SSE · RFC 9110/9111 (условные запросы, Vary при gzip). Право заменить ось — с аргументом.
  • Деньги: пак их не двигает (PD-104 — константа); коснулся — два независимых пути счёта из сырого леджера.
  • Адверсариальное селф-ревью финалом — механизмом (субагенты РАЗРЕШЕНЫ, спавнь): ≥2 независимых ревьюера по финальному диффу, author≠reviewer: (а) контракт-конформность — канон против твоих ручек, пере-раном живых проб; (б) деньги/шов — свой инвентарь каналов, не твой список. Плюс СВОИ посадки в новые гейты/ручки (не из ожидаемого тобой списка). Артефакт: таблица находок/посадок с диспозициями; ноль находок = не верить прогону.
  • Obstacle reporting — обязательная секция: что НЕ удалось / не проверено.
  • Канал вопросов: непонятно / промт против кода-спеки-доков → пинг через владельца, НЕ интерпретация. Право «этого делать не надо» — с аргументом.

6. Старт и сдача

Эхо-протокол: первым деливераблом ≤10 строк «скоуп / инварианты / не-делать». Сдача: отчёт в platform-PROGRESS.md (записка-план · команды · живые пробы · таблица селф-ревью · obstacle · диспозиции §4.6), дерево незакоммиченное, регистру — строки по находкам. Без саги.