39 KiB
Промт: контрактная сессия, минор 0.4.0 → 0.5.0 — снос отменённой модели и дверь, выведенная из глагола
⚠⚠ ОТРАБОТАН И ЗАКРЫТ. Инструкции отсюда НЕ исполнять — файл сохранён как заказ, по которому судить исполнение.
Исход: пак исполнен и ПРИНЯТ 27.08, ратификация D39.161. Канон 0.5.0 и компаньон заленджены, отчёт —
docs/CONTRACT_MINOR_REPORT.md.⚠ ДВА МЕСТА, ГДЕ ЭТОТ ПРОМТ БЫЛ НЕВЕРЕН, и это нашёл исполнитель, а не автор. §4 п.2 обещал, что после сноса «канон и деплой СОВПАДУТ точно», а §3.2-бис — что счётчики
pending_decisions/complete«навсегда нули». Верно по ПУТЯМ, неверно по ПОЛЯМ: проекцияGET /bankпродолжает их слать, и это живой счётproposed-строк (platform/internal/pgstore/readmodel.go:330). Носитель —PD-399, эррата — 27.08-ж в шапке журнала решений. Сессия принесла расхождение ПИНГОМ, а не подогнала работу под неверную посылку.⚠ Список носителей §3.1 был НЕПОЛОН: третий носитель счётчиков (
EventBank) сессия нашла своим грепом. Промт предупреждал, что его шаблон мог что-то не поймать, — предупреждение оправдалось.
Выдан оркестратором №19, 27.08.2026. Порядок работ по шву ратифицирован D39.156; этот пак — пункт (2б) очереди, и он идёт ПОСЛЕ движкового пака, который закончен и заленджен 27.08 (D39.158, коммит
d1eb8a9). Это существенно: тело новой двери больше не сочиняется — оно ВЫВОДИТСЯ из словаря уже работающего глагола.
§0. Какая проблема и что решит твой результат
Контракт docs/architecture/14-api-contract/ — единственный ратифицированный договор между фронтом и
платформой. Сегодня он лжёт в двух местах и молчит в одном, и цена лжи не абстрактная.
1. Канон описывает дверь, которой нет и не будет. 16.08 владелец отменил пер-термную модель
подписи банка памяти: подписывается ВЕСЬ банк одним «ОК», а пер-термно существует не подпись, а
ПРАВКА термина. Зона платформы снесла свою половину 22.08 — маршрут, хендлер, wire-типы. Канон свою
половину не снёс: путь POST /books/{bookId}/bank/decisions, глагол submitBankDecisions и три
схемы стоят в 0.4.0 как действующие. Следствие сегодня: клиент, сгенерированный по канону, получит
404 на ручке, которую канон объявляет обязательной, а деплой обслуживает на одну ручку меньше, чем
декларирует. Носитель — PD-370, вес major, зонная половина закрыта, контрактная открыта.
2. Канон не предупреждает о конверте вне /v0. Он говорит только «Signing in is not part of this
surface» (openapi.yaml:35-36), а компаньон описывает поверхность /auth в §2.14. Отказ оттуда может
прийти БЕЗ обязательного поля code, и сгенерированный по канону клиент об это спотыкается. Носитель
— строка бэклога 203, пункт (а) — ⚠ проверь букву своим грепом, в первой редакции этого промта стояла «(е)», и это была моя ошибка чтения. У строки открыт ещё пункт (к) (владение project_db в book.yaml) — он в этот пак НЕ входит.
3. Двери для правок банка в контракте нет вовсе. Движок её теперь имеет: tmctl bank-apply —
$0-глагол со своим словарём, кодами отказа и отчётом. Платформе нечего объявлять фронту, потому что в
каноне такой поверхности не существует.
Что решит твой результат. После пака канон перестаёт обещать несуществующее, начинает предупреждать о конверте и объявляет дверь правок банка в форме, выведенной из глагола движка, — так что платформенный пак (пункт 2в очереди) реализует объявленное, а не изобретает своё.
§1. Зона записи и git
Твоя зона — РОВНО два файла: docs/architecture/14-api-contract/openapi.yaml (канон) и
docs/architecture/14-api-contract/README.md (компаньон). Плюс отчёт — docs/CONTRACT_MINOR_REPORT.md, его состав в §11.
- Ты НЕ коммитишь. Дерево готовишь и сдаёшь; лендит оркестратор. Канон —
CLAUDE.md. platform/иfrontend/не трогать ничем, даже одной строкой. Почему это названо отдельно — §4: там лежит ровно одна строка, которую хочется поправить, и правит её оркестратор при лендинге.frontend/src/api/— зеркало контракта, оно отстаёт РАТИФИЦИРОВАННО (зона заморожена D39.147, сверкаcmpпри разморозке). Версию оно не хардкодит — проверено грепом; трогать нечего.- В дереве живёт незакоммиченная работа зоны полигона (20 позиций,
eval/+START_PROMT.MD) и возможны другие параллельные сессии. Чужих файлов не касаться,git add -Aне существует.
§2. Карта чтения — ≤5 позиций, и она ЗАКОН
Дальше — только по ссылкам отсюда. README проекта, CURRENT-STATE и голову журнала решений читать НЕ нужно: ратифицированное вложено в тело этого промта.
docs/architecture/14-api-contract/README.md— компаньон, 1414 строк. Он и есть карта канона: читается целиком, объясняет, ЗАЧЕМ канон устроен так. Начни с него, не с YAML.openapi.yaml, только нужные места — 2592 строки, целиком НЕ читать. Отправные точки в §3.- Словарь глагола — в КОДЕ, и он первичен:
backend/internal/membank/decisions.go, строки 51–117 — это НЕ только комментарий к типуDecision(он начинается на:65). Читай с:51, потому что тамDecisionDepth, и он сделан ПОЛЕМ, а не комментарием, ровно потому, что ответ не тот, какой пользователь предполагает: принятое решение доезжает до РЕДАКТОРА, а не пере-формирует черновик (дельта —Source:"mined"и в БАЗОВЫЙ банк черновой волны не входит). Комментарий кDecisionнаписан развёрнуто НАРОЧНО и прямо предупреждает, что короткий лозунг «входной словарь = выходной» про него НЕВЕРЕН. Это твой источник тела двери. backend/internal/pipeline/bankdecisions.go— форма отчёта (BankDecisionsReport) и шесть исходов;backend/cmd/tmctl/main.go:69-75— полоса отказов 10–19.- Две ратифицированные НОРМЫ — читать обе, они короткие и обе про твой предмет:
docs/architecture/18-bank-ontology.md(69 строк, ратифицирована D39.158) — три роли носителей, единственные писатели и дисциплина проекции;docs/README.mdназывает её обязательным пре-чтением перед всем, что трогает банк или его артефакты, и твоя дверь — ровно это. Из неё же растут §3.2 (машиночитаемый признак «не построено») и §6 ось 3.docs/architecture/17-seam-inbound-law.md(ратифицирован D39.156) — закон входной двери шва, семь пунктов дисциплины; на его п.4 ссылается §3.2, когда говорит про громкий отказ на неизвестное поле, и на п.6 — §3.0.
⚠ Прочее ратифицированное вложено в §3.0 — грепать журнал решений не требуется.
§3. Состав пака
§3.0. Ратифицированное, из чего исходишь (не пере-открывать, конфликт — пингом)
- D39.144 (16.08, слово владельца): подписывается ВЕСЬ банк ОДНИМ «ОК». «Пер-термная подпись — сотни кликов — НЕ модель продукта». Пер-термно существует ПРАВКА термина.
- D39.158 (27.08): стоп банка — ФЛАЖОК, который движок чтит сам; «ОК» = возобновление. Дверь
правок —
tmctl bank-apply: проекция--dry-run, всё-или-ничего, байтовый no-op идемпотентен. - D39.156 п.6: платформа НЕ пере-реализует движковый закон у себя.
- Полоса отказов [10,19] — ратифицированная: 10 конфиг · 11 источник · 12 лок · 13 схема · 14 решения отклонены (законный отказ, пользователь ПЕРЕ-решает) · 15 write_incomplete (документ принят, запись не довершена — слать ТОТ ЖЕ документ) · 19 без имени.
- Версионирование канона: semver; пока мажор
0, различающийся МИНОР несёт ломающие изменения по замыслу. Клиент обязан игнорировать неизвестные поля и терпеть неизвестные enum-значения.
§3.1. Снести отменённую модель — делай РОВНО так
Носители пере-сняты мной грепом 27.08, числа в строке PD-370 («~17 мест + ~8») — ОЦЕНКА, не замер;
доверяй своему грепу, не строке. Канон, 9 позиций: 469 (путь) · 474 (operationId) · 495
(запрос) · 501 (ответ) · 1830 (проза, ссылающаяся на путь) · 1939 (BankDecision) · 1980
(BankDecisionsRequest) · 1990 (ссылка на элемент) · 1992 (BankDecisionsResult).
Компаньон, 5 позиций: 124 · 674 · 685 · 724 · 1173.
⚠ 674 — уже зачёркнутая строка таблицы («»), а не действующее
описание: прочти её целиком прежде, чем править, — там может стоять запись, которую снос обязан
СОХРАНИТЬ как историю, а не стереть.POST /bank/decisions
Свой греп обязателен: мой шаблон ловил четыре имени, и позиция, названная иначе, в него не попала
бы. Пере-проверь ещё и по dst, UnknownTermError, BankPage.
§3.2. Объявить дверь правок банка — реши САМ, аргументируй
Тело выводится из словаря глагола (позиция 3 карты чтения). Что словарь говорит буквально:
- Два действия:
approveиdecline. Больше нет. - Идентичность термина — ЛИБО стабильный
idиз читаемого банка, ЛИБО кортежsrc/sense/since_chapter/until_chapter, из которого id выводится. Взаимоисключающе, и причина названа в коде: принять оба значит позволить назвать два разных термина одним решением. - ⛔ Кортеж — это НЕ второй способ назвать существующее. Это форма, которой терм ДОБАВЛЯЕТСЯ
(
decisions.go:94-96: «the form in which a term the bank does not have yet is added»). Неизвестный кортеж — НЕ ошибка. Канон 0.4.0 делал ровно наоборот — отвечалunknown(openapi.yaml:486), — и дверь, спроектированная по той же логике, убьёт добавление терма, то есть половину продуктовой правки. Это место, где ошибиться легче всего; ошибка стоит целой ветки. dst— ОБЯЗАТЕЛЕН приapproveи ЗАПРЕЩЁН приdecline.kind— отсутствие значит «не решено», а не «сбросить».note— принимается и НЕ публикуется; отсутствие значит «не решено». Опустошить его дверью нельзя, только заменить другими словами — узость названа в коде, не прячь её.aliases— публикуются и НЕ принимаются, намеренно.gender/speech/decl— ни то, ни другое: сид-онли, производителя нет (строка 210), и дверь на них была бы дверью на неработающую ось.- ⚠ Названная узость v1, и у неё ДВЕ половины — обе в канон: ОКНО ГЛАВ термина одним решением не
правится.
approveнового кортежа добавляет вторую строку и оставляет старую стоять, аdeclineснимает ВСЕ окна поверхности (decisions.go:85-87). Расширение или сдвиг окна — операция в два вызова. Это ратифицированное свойство, а не дефект: предупреждением, не умолчанием. - Конверт документа — тоже словарь, и его нельзя изобретать заново:
decisions_versionсо значениемtm-bank-decisions-v1(decisions.go:47) ·book_idобязателен (decisions.go:142, «names no book_id») и отдельно СВЕРЯЕТСЯ с книгой (pipeline/bankdecisions.go:267,openDecisionRequest:doc.BookID != book.BookID— отказ). Два разных места и две разные проверки; путать их не надо. Причина сверки: решения — единственный вход, несущий слова пользователя в чужую книгу незаметно для даунстрима · неизвестное поле — громкий отказ (DisallowUnknownFields,:133) — зеркало п.4 закона входной двери шва (docs/architecture/17-seam-inbound-law.md, позиция 5 карты). depth— поле ОТЧЁТА, и оно обязано доехать до фронта с правильным смыслом.edit_wave: принятое решение доезжает до редакторской волны и НЕ пере-формирует черновик (bankdecisions.go:49-52говорит это прямо: «what it must not do is assume the corrected term re-forms the draft»). Это первое, о чём экран соврёт пользователю, если канон промолчит.- Два потолка, оба объявляются: 1 МиБ на чтение документа и 5000 решений на один акт
(
bankdecisions.go:647,maxDecisions; за ним — отказ КЛАССОМ 14 с текстом «split it», потому что дальше вызов перестаёт влезать в таймаут вызывающего и умирает на каждом ретрае). Опубликованная дверь без объявленных лимитов — это сгенерированный клиент, шлющий двадцать тысяч решений вслепую. - Правка СИД-терма этой дверью ОТКЛОНЯЕТСЯ по имени (
decisions.go:359): это перенос базового снапшота и пере-оплата черновой волны — другая дверь, ещё не спроектированная (строка 192).
⛔ Если отчёт публикуется на проводе — поле signature едет ТОЛЬКО со своим контрактом, и контракт
этот запретительный. SignatureState (bankdecisions.go:88-118) — ИНФОРМАЦИОННОЕ, ровно как его
понизил D39.144: «it counts, it does not gate». Код говорит прямо: оно НЕ отвечает на вопрос
«погаснет ли стоп» ни в одну сторону, undecided: 0 ничего не обещает о поведении следующего
прогона, а «решать поверхности — ПРАВО владельца, а не требование стопа». Есть и четвёртое поле,
unreadable, которое означает «эти два числа для этого вызова не значат НИЧЕГО».
Почему это в промте отдельным знаком: опубликуй undecided без контракта — и экран подписи при
разморозке фронта выучит из канона, что его работа — довести число до нуля. Это и есть отменённая
пер-термная модель, вернувшаяся через чёрный ход тем же минором, который её сносит. Публикуешь
поле — публикуешь и запрет; не готов опубликовать запрет — не публикуй поле.
⚠ И неси ОБЕ половины контракта. У него есть положительная (bankdecisions.go:101-104), и без
неё блок кренит к «проще не публиковать», а поле экрану полезно: числа отвечают на вопрос «из
поверхностей, которые предложил последний стоп, о скольких владелец ещё не высказался», и считаются
ТЕМ ЖЕ правилом, каким прогон сворачивает решения в банк, — поэтому счёт согласован с тем, что
следующий прогон сочтёт решённым содержанием.
Отправные точки модели ошибки — держи их под рукой прежде, чем раскладывать коды: конверт отказа
— схема Problem (openapi.yaml:2395, RFC 9457 плюс расширения); машинный идентификатор — code
(:2432), его словарь — ErrorCode (:2462); errors[] (:2444) несёт, ЧТО именно в запросе не так,
и его несёт invalid_request. Согласовывать дверь надо с ЭТИМ конвертом — §6 ось 1 будет судить
именно по нему.
Твоя свобода и твой аргумент: форма HTTP-поверхности (один POST с документом целиком против
чего-либо иного), имена схем, как ложатся коды 10–19 на статусы HTTP, как выражается --dry-run.
Решай сам и обоснуй в отчёте. Совет, опровергаемый аргументом: код 14 — это НЕ ошибка сервера,
а законный отказ, по которому ПОЛЬЗОВАТЕЛЬ пере-решает; код 15 несёт указание «слать тот же
документ», и оба заслуживают различимости на проводе, а не общего 400.
⚠ Дверь объявляется, но платформой ещё НЕ обслуживается — её смонтирует пак (2в). Прецедент того,
как контракт честно объявляет непостроенное, в каноне уже есть: export_formats в Capabilities
(openapi.yaml:1222 и :1250 — ⚠ в каноне поле именно в snake_case; греп по Go-имени ExportFormats
даёт там ноль), пустой список = «здесь не построено», и это названо честным ответом. Машиночитаемый признак «здесь не построено» ОБЯЗАТЕЛЕН — свободна только его ФОРМА. Без него
пак объявит голую необслуживаемую дверь и воспроизведёт PD-370 тем же коммитом, которым его
закрывает: «канон объявляет — деплой не обслуживает» и есть содержание той строки. Разберись, годится
ли Capabilities для двери; если нет — назови почему и предложи замену, но не отсутствие.
§3.2-бис. Счётчики упразднённой модели — реши САМ, но решить ОБЯЗАН
Канон объявляет pending_decisions и complete — «how much of the bank a person has touched»
(openapi.yaml:442-447). Это счётчики платформенной таблицы bank_decisions, у которой write-путь
снесён 22.08: колонки были write-only, кормившая их дверь мертва, а новая (§3.2) пишет ДВИЖКОВЫЕ
файлы, не эту таблицу. Значит поля навсегда нули.
⚠ Мой греп §3.1 их НЕ ловит — имена другие, — и твой по тем же четырём именам не поймает тоже.
Греп-форма, которая их вытаскивает: bank_decisions (с подчёркиванием). Ею же находится носитель
компаньона :358 («решение живёт отдельной таблицей bank_decisions») и тег openapi.yaml:127
(«Memory bank and term signing»).
Заказ: реши судьбу обоих полей — снести · пере-определить на новую дверь · пометить — и обоснуй.
⚠ Проза рядом (:442-447) при этом УЖЕ несёт ратифицированную модель («Signing the bank is ONE act
over the whole of it»): она правильная, и сносить её вместе со счётчиками было бы потерей.
§3.3. Предупредить о конверте вне /v0 — делай РОВНО так
Строка 203, пункт (а) (не (е) — см. §0). Канон (openapi.yaml:35-36) говорит только «Signing in is not part of this
surface». Допиши предупреждение: отказ от поверхности вне версионного префикса может прийти БЕЗ
обязательного code, и клиент, сгенерированный по канону, обязан это терпеть. Поверхность описана в
компаньоне §2.14 — сошлись, не пересказывай (один носитель на факт).
§3.4. Чего в этом паке НЕТ
Сквозная полоса прогресса (строка 200) в этот минор НЕ входит — РАТИФИЦИРОВАНО ВЛАДЕЛЬЦЕМ 27.08 (D39.160), едет с платформенным паком (2в). Причина механическая, и её надо знать: см. §4. Вопрос закрыт — аддендума не будет, сам не бери и не предлагай вернуть.
§4. Развилка версии — прочти ДО того, как поднимешь номер
Гейт платформы TestTheAnnouncedContractVersionIsTheOneTheCanonRatified
(platform/internal/gates/contract_test.go:14) читает ТВОЙ канон и требует, чтобы константа
platform/internal/httpapi/capabilities.go:13 (ContractVersion = "0.4.0") ему равнялась. Гейт
заведён не зря: однажды деплой обслуживал 0.3.0, когда каноном был 0.4.0.
Следствия, каждое проверено мной командой:
- В ту секунду, когда ты напишешь
version: 0.5.0, батарея зоны платформы КРАСНЕЕТ. Это ожидаемо и это не твоя ошибка. Константу правит оркестратор при лендинге, одной строкой, тем же коммитом. Ты вplatform/не пишешь. - Поэтому канон и деплой обязаны совпадать В МОМЕНТ ЛЕНДИНГА. Снос двери этому не мешает: платформа свою половину уже снесла 22.08, после твоего сноса они СОВПАДУТ точно. Объявление необслуживаемой двери — тоже, если оно честное (§3.2).
- А смена семантики ПРОГРЕССА — мешает. Канон сегодня говорит: «When a stop is cleared the
counter starts again from zero» (
openapi.yaml:1293). Владелец 20.08 назвал это дефектом и потребовал ОДНУ долю на весь прогон, считаемую СЕРВЕРОМ. Но сервер её не считает и не будет считать до пака (2в). Написать новую семантику в канон и поднять константу значит объявить0.5.0у деплоя, который обслуживает прогресс по-старому, — ровно та ложь, против которой гейт и стоит.
Разбор, ратифицированный владельцем 27.08 (D39.160): прежнее «одним куском» покупалось тем, что иначе фронт перегенерируется дважды. Фронт ЗАМОРОЖЕН, и его зеркало отстаёт ратифицированно — при разморозке он перегенерируется ОДИН раз независимо от того, сколько миноров прошло. Значит цена разделения сегодня равна нулю, а цена объединения — деплой, врущий о своей версии. Поэтому прогресс едет с паком (2в) отдельным минором.
⚠ Разбор ратифицирован владельцем 27.08 (D39.160): прогресс едет с паком (2в). Он приведён здесь не для пере-решения, а потому что ты обязан понимать, ПОЧЕМУ версия поднимается именно так, — иначе первая же красная батарея платформы будет прочитана как твоя ошибка. Если найдёшь, что разбор неверен по МЕХАНИКЕ (а не по вкусу), — это пинг, а не молчаливое отступление.
§5. Самопроверка ИСПОЛНЕНИЕМ — обязательна, и «перечитал сам» её не удовлетворяет
Сессии регулярно ошибаются, и самоотчёт «проверено» без исполнения регулярно оказывается ложным. Названный механизм, три пункта, каждый даёт проверяемый артефакт:
- Канон обязан парситься. Прогони валидатор OpenAPI (любой доступный:
python3 -c "import yaml, sys; yaml.safe_load(open('...'))"— минимум; если в окружении есть настоящий линтер схемы — лучше). Артефакт: команда и её вывод в отчёте. YAML, который не грузится, — это канон, который не читает никто. - Ни одной висячей ссылки после сноса. Схема, на которую больше никто не ссылается, и ссылка на
снесённую схему — оба дефекта. Собери проверку сам (греп
$refпротив спискаcomponents.schemasгодится) и приложи её вывод, а не утверждение. ⚠ Туда же — ДУБЛИ КЛЮЧЕЙ:yaml.safe_loadсхлопывает их молча по правилу last-wins (проверено:a: 1\na: 2даёт{'a': 2}без единого слова), а это реальный класс дефекта канона после правок — пятистрочный loader-хук их ловит. - Гейт платформы обязан покраснеть ПРЕДСКАЗУЕМО. Прогони его на копии дерева и покажи, что он
краснеет ИМЕННО на несовпадении версий и ИМЕННО с ожидаемым текстом. ⚠ Копию снимай ВМЕСТЕ с
каноном:
cp -a --parents platform docs/architecture/14-api-contract <куда>/. Голаяcp -a platformдаёт постоянный красный того же теста по другой причине, и вердикт будет ложным — норма зоны платформы,ENGINEERING_STANDARDS§3 п.3.
Опровергатель на §3.2 — ЗАКАЗ, а не право (разметка исправлена 27.08: прежняя редакция писала «разрешены», а §11 требует его находок в отчёте — без него отчёт некомплектен, и это был заказ, размеченный как разрешение). Субагенты тебе РАЗРЕШЕНЫ явно — харнесс по умолчанию их не берёт, и без явного разрешения запрет тихо побеждает. Опровергатель получает твоё предложение двери и словарь из кода, мандат — «найди, где предложенное тело расходится со словарём глагола». Его находки — в отчёт, включая те, что ты отверг, и с причиной.
⚠ Соразмеряй веер заранее: 2–4 агента, не больше. Панель на полтора десятка агентов на этой машине убивает сама себя, и это уже стоило проекту находок.
§6. Оси ревью — 1–3, сессия вправе заменить с аргументом
- Ось «клиент, сгенерированный по канону». Пройди канон глазами генератора: обязательные поля,
которых сервер не шлёт; enum, который вырастет; ссылки в никуда. Это ось, на которой канон уже
ловили дважды (
0.3.0/0.4.0и конверт/auth). - Ось «словарь двери против словаря глагола». Каждое поле твоей схемы — с ответом, откуда оно в
decisions.goи почему принимается/публикуется именно так. Поле без ответа — либо изобретение, либо находка. - Ось «что читатель канона узнает о том, чего нет». Необслуживаемая дверь, узость окна глав, отклонение сид-терма — все три обязаны быть В КАНОНЕ явными, а не выводимыми.
§7. Записка-план и комплектность
До правок СОЗДАЙ файл отчёта docs/CONTRACT_MINOR_REPORT.md и первой же секцией положи в него
записку-план: что меняешь, где, чем проверишь. Файл ведёшь по ходу работы, а не собираешь в конце —
так оркестратор видит план ДО правок, и так секции §9/§10 не пишутся задним числом по памяти. В конце — механическая сверка
комплектности против §3 таблицей: пункт заказа → что сделано → каким исполнением подтверждено. Пункт,
по которому в колонке «исполнение» стоит слово, а не команда, считается НЕ сделанным.
§8. «Заявление = команда»
Любое число и любая категорика в отчёте — с командой, которой они получены. «Снёс девять мест» без
grep -c — не факт. Приёмка пере-считает выборочно, и расхождение будет стоить дороже, чем честное
«не мерил».
§9. Эхо-протокол старта
ДО работы — ≤10 строк: скоуп (что делаешь) · инварианты (что не сдвинется) · не-делать (что явно вне пака). Если эхо расходится с этим промтом — расхождение и есть первый вопрос.
§10. Obstacle — обязательная секция отчёта
«Что НЕ удалось и что НЕ проверено» — отдельной секцией, не россыпью. Названный пробел стоит дёшево; необъявленная ошибка автора — это находка, которой нет, и она всплывёт у приёмки дороже.
§11. Канал вопросов
Конфликт промта с кодом или доками — пинг оркестратору через владельца, НЕ интерпретация в свою
пользу и НЕ обход. Где твой отчёт. У контрактной сессии зонного журнала НЕТ, и в docs/PROGRESS.md ты не пишешь —
это зона оркестратора. Отчёт кладёшь ОТДЕЛЬНЫМ новым файлом docs/CONTRACT_MINOR_REPORT.md;
существенное из него в журнал и в ноту переносит оркестратор при лендинге.
Что ты сдаёшь — состав дерева на лендинг:
docs/architecture/14-api-contract/openapi.yaml— правленый канон, версия0.5.0.docs/architecture/14-api-contract/README.md— правленый компаньон.docs/CONTRACT_MINOR_REPORT.md— новый: эхо-протокол (§9) · записка-план и таблица комплектности (§7) · обоснование формы двери и её схем (§3.2) · решение по счётчикам (§3.2-бис) · выводы всех трёх исполнений самопроверки С КОМАНДАМИ (§5) · находки опровергателя, включая отвергнутые с причиной · секция obstacle (§10).- Ничего больше. Ни одного файла в
platform/,frontend/,backend/илиeval/.
Сдача = сказать оркестратору «готово» и назвать этот состав. Коммитит он; git status перед сдачей
прогони и убедись, что в дереве нет твоих файлов вне списка.
⚠ Тесты и гейты не подгонять под зелень. Гейт платформы обязан покраснеть — это ожидаемое поведение, описанное в §4, а не повод его править. Несогласие с гейтом — вопрос, не правка.