19 KiB
⚠ ОТРАБОТАН. Исход: пак ИСПОЛНЕН (пять актов, 16–20.08) и ПРИНЯТ С ФИКС-ЛИСТОМ, заленден оркестратором №18 20.08 — D39.153. Сессия закрыта владельцем.
Что изменилось против этого текста: §1 велел строить по канону 0.3.0, а зона по ходу пака получила ответ контрактной сессии и построила по 0.4.0 (ратифицирован тем же лендингом, D39.152) — против 0.3.0 расходятся четыре места, все благословлены 0.4.0. §4.6: sqlc НЕ взят (отступление от D39.132 п.2б), решение владельца 20.08 — брать следующим паком. Отложено в P8 явно:
updateBook/deleteBook/getRun, экспорт, эскроу П-18.Фикс-лист приёмки, дыры и то, что ушло в единый бэклог (строки 198–203), — пинг оркестратора №18 в
platform/docs/platform-PROGRESS.md. Инструкции ниже НЕ исполнять: документ историчен.
Промт: платформа, пак P7 — читающая поверхность по контракту 0.3.0 + модель ошибок + форварды (П-17, строка 169 единого)
Выдан №17 16.08.2026, пересобран после лендинга батча 0.3.0 (D39.142–144) и опровергателя промта. Запуск — по слову владельца.
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)
- Канон + компаньон (
docs/architecture/14-api-contract/) целиком. В компаньоне: §3 таблица «чтение → источник» · приложение А-2 — готовая карта «твоя веткаv0.go→ код ошибки» сfile:line· §6б — почему формы такие. docs/research/28-contract-review.md§8а (классы отказов) · §5б (сеть) · §9 (находки твоей зоны)- D39.138 п.2 и D39.142–144 (хвост
docs/architecture/05-decisions-log.md).
- D39.138 п.2 и D39.142–144 (хвост
- Свой журнал
platform-PROGRESS.md: три пинга №17 + аддендумы (входы пака,file:lineнаходок). - 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). CLAUDE.md; жаргон —docs/glossary.md.
4. Состав. Пункты 0–5 — «РОВНО так» (состав ратифицирован; формы внутри — твои, где канон/промт
их не фиксируют). Пункт 6 — судишь сам. Отложенное — только явно, списком в отчёте.
0. Рантбук деплоя живым migrate, end-to-end, $0, первым шагом (предусловие первого выката;
твой журнал: «живьём не гонялся»): прогнать свой deploy/README.md новым бинарём движка по книгам
стенда (tmplatformctl books --migratable → tmctl 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_bank→ErrNotResumable "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 (словарь канона из трёх значений — мапь полосу 10–19 и ветки
outcome()), verify_bank→stop_for_signing (провод: v0.go:127,154) · Usage:
paused_reason→halt_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 (пп. 0–6 + отложенные): «исполнено, где / отказ, почему» на каждый; сдача = все с диспозицией.
- Шов: касаешься канала движка → сначала инвентарь ВСЕХ его каналов и кодов чтением чужого кода (урок 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), дерево незакоммиченное, регистру — строки по находкам. Без саги.