# Отчёт контрактной сессии: минор 0.4.0 → 0.5.0 > Сессия по промту `docs/CONTRACT_MINOR_SESSION_PROMPT.md` (оркестратор №19, 27.08.2026). > Файл ведётся ПО ХОДУ работы (§7): секция 1 написана ДО правок. Зона записи — два файла контракта > плюс этот отчёт; сессия НЕ коммитит. ## 1. Эхо-протокол (§9) и записка-план — ДО правок **Скоуп:** снос отменённой пер-термной модели подписи (§3.1) · объявление двери правок банка, выведенной из словаря `tmctl bank-apply` (§3.2) · судьба счётчиков `pending_decisions`/`complete` (§3.2-бис) · предупреждение о конверте вне `/v0` (§3.3) · версия `0.5.0`. **Инварианты:** словарь двери — из `membank/decisions.go` + `pipeline/bankdecisions.go`, не изобретаю; неизвестный кортеж — НЕ ошибка (форма добавления терма); `undecided` — только вместе с запретительным контрактом `SignatureState`, обе половины; коды 14/15 различимы на проводе; конверт ошибки — существующий `Problem`/`ErrorCode`; узость окна, отклонение сид-терма, необслуживаемость — явно в каноне; машиночитаемый признак «не построено» обязателен. **Не-делать:** не коммичу; `platform/`/`frontend/`/`backend/`/`eval/` не трогаю; полоса прогресса (строка 200) не берётся (D39.160); семантика прогресса `openapi.yaml:1293` не меняется; гейт платформы не правится — его красный ожидаем; в `docs/PROGRESS.md` не пишу. ### Записка-план: что меняю, где, чем проверю **Канон `openapi.yaml`:** 1. `version: 0.4.0 → 0.5.0`; пример `contract_version` → `0.5.0`. 2. §3.1 снос: путь `:469-505` · проза `:1830` (`TermStatus`) · схемы `:1939-2008` (`BankDecision`/`BankDecisionsRequest`/`BankDecisionsResult`). Мой греп подтвердил список промта и НЕ нашёл иных носителей четырёх имён (команда в §5 ниже). 3. §3.2-бис: снос `pending_decisions`+`complete` из `BankPage` (`:1924-1934`) и — находка МОЕГО грепа, в списке промта её нет — из `EventBank` (`:2367-2372`). Ратифицированная проза «ONE act» в `listBankTerms` сохраняется, клауза счётчиков и фраза «marked unverified inside the service» (снята ещё ФБ-8 как обещание без носителя, но в `:445` уцелела) — уходят. 4. §3.2 дверь: `POST /books/{bookId}/bank/corrections` + схемы (`BankCorrection`, `BankCorrectionsRequest`, `BankCorrectionsReceipt`, `BankSignatureCount`, `CorrectionRefusal`) + два корневых кода (`bank_corrections_refused` 409, `bank_corrections_incomplete` 503) + признак `bank_corrections_enabled` в `Capabilities` (прецедент `intake_enabled`; false ⇒ 404). 5. §3.3: в `info.description` (после `:35-37`) — предупреждение о конверте вне `/v0` без обязательного `code`, ссылкой на компаньон §2.14 (один носитель на факт). 6. Тег `:127` «Memory bank and term signing» — переформулировать без пер-термной подписи. **Компаньон `README.md`:** шапка (статус 0.5.0, без самозаписи ратификации) · `:124` и `:724` (списки мест правила «схема + слова» — преемник) · `:674` (историческая строка сохраняется, статус дописывается) · `:685` (строка про недоезд `decline` — пере-снята: новая дверь пишет файлы движка) · `:358` §2.9 (остаток пере-привязан к живым носителям) · новая секция §2.19 (вывод двери, провенанс) · §3 таблица (строка двери: движок построен, платформа — пак 2в) · Приложение А-2 (две строки кодов). **Чем проверю (§5):** (1) YAML-парс + линтер, если найдётся в окружении; (2) сверка `$ref` против `components.schemas` в обе стороны + loader-хук на дубли ключей; (3) гейт платформы на копии `cp -a --parents platform docs/architecture/14-api-contract` — красный ИМЕННО на версии и с ожидаемым текстом. Плюс опровергатели (§5 промта, заказ): 2–4 агента, мандат «дверь против словаря глагола» + оси §6. ## 2. Обоснование формы двери (§3.2) Полная таблица «провод ← движковый источник, file:line» и решения ◆ — в компаньоне, новая секция §2.19 (`docs/architecture/14-api-contract/README.md`); здесь — сами решения с разобранными альтернативами. Всё выведенное (✓) взято из `membank/decisions.go` + `pipeline/bankdecisions.go` + `cmd/tmctl/main.go:69-75` и в канон попало без пересочинения. **2.1. Форма поверхности — один `POST /books/{bookId}/bank/corrections` с документом целиком.** Альтернатива «ресурсная» (`PATCH /bank/terms/{id}`) отвергнута: глагол атомарен и всё-или-ничего (`ApplyDecisions`, `decisions.go:282-307`), а пер-строчные мутации обещали бы частичную применимость и правку строк банка, которых этот вызов не меняет (вид пересобирается на границе прогона — `18-bank-ontology.md`). Альтернатива «двух путей» (`…/preview` отдельным POST) отвергнута: два пути = два места, где растёт форма, а закон шва п.7 требует, чтобы проекция была той же операцией, что мутация («a report printed by the same call that already wrote is not a projection» — `bankdecisions.go:44-45`). **2.2. Имя `corrections`.** «decisions» вернуло бы имена снесённых схем с другой семантикой (генерённый дифф читался бы как правка старой двери); «edits» — `edit` в грепе-гейте §5 компаньона неотличим от имени волны движка. Продуктовое слово владельца — «правка» (D39.144). **2.3. `book_id` в теле, обязательный, при живом `{bookId}` в пути.** Движок держит ДВЕ разные проверки: документ обязан НАЗЫВАТЬ книгу (`decisions.go:141-143`) и отдельно сверяется с открытой книгой (`bankdecisions.go:267-269`) — причина названа в коде: решения несут слова пользователя в канон книги, и набор, посчитанный для другой книги, даунстрим не заметит. Если бы book_id вводила платформа из пути, сверка стала бы вакуумной — клиент, POST-нувший набор книги A в путь книги B, прошёл бы молча. Цена — одно поле. **2.4. Кортеж требует все четыре члена** (`src`,`sense`,`since_chapter`,`until_chapter`; движок дефолтит опущенные — `decisions.go:469,479-482`). Провод строже движка сознательно: неизвестный кортеж здесь легально ДОБАВЛЯЕТ терм, поэтому цена опущенного `sense` — не отказ, а тихая параллельная строка (клиент хотел править (src, sense="X"), а назвал (src, "")). `null`-семантика окна — как у `BankTerm` (0.3.0 развёл сентинел `0` на `null`); проекция `null→0` — платформа, закон шва п.6. **2.5. `preview` — обязательное булево тела.** Закон шва п.7 (проекция прежде мутации) + прецеденты тотальной обязательности (`stop_requested` — §6в J компаньона; в запросах — `RunRequest.stop_for_signing`). Query-параметр на POST отвергнут: в этом каноне тело — единственный носитель семантики небезопасных вызовов, и опциональность дала бы «мутацию по умолчанию». **2.6. Раскладка полосы отказов.** Ратифицированная полоса 10–19 (`main.go:69-75`) ложится так: - **14 → `409` `bank_corrections_refused`** + member `refusals[]`. Отдельный корневой код, не общий `400`: это законный отказ, по которому ПОЛЬЗОВАТЕЛЬ пере-решает (совет промта принят; довод — разные адресаты ремеди). `409`, не `422`: канон весь класс state-зависимых отказов держит на 409, а отказ здесь — о книге как она стоит (сид, коллизии набора). - **15 → `503` `bank_corrections_incomplete`**: «документ ПРИНЯТ, слать ТОТ ЖЕ» — ремеди машинный и специфичный, потому код свой, а не общий `service_unavailable`; ретрай сходится по байтовому no-op (`bankdecisions.go:209-221`). - **12 → `409` `run_in_flight`**: словарь канона уже имеет точное слово («книга уже переводится»); движковая причина (флок живого прогона, `bankdecisions.go:159-163`) совпадает по смыслу. - **10/11/13 → без пер-операционных кодов**: это «деплой сломан, чинит человек» — `5xx` общего вида (500 канон сознательно не документирует — Zalando-правило из А-2). - **потолок 1 МиБ → `413`** (`payload_too_large` дообъяснён), **потолок 5000 → схема (`maxItems: 5000`) + слова**, нарушение = `400` `invalid_request` (нарушение объявленной формы; движковый класс 14 для него — за платформенной валидацией и на провод не выходит). **2.7. Причины пер-решенческих отказов — `refusals[].detail`, developer-facing, не показываются.** У движка причины — свободный текст (`RejectedDecision.Reason`); машинного словаря причин нет, и таблица перевода (закон п.6) переводит только структуры, не прозу. Замораживать в каноне пересказ двадцати формулировок = вторая копия растущего словаря. Альтернатива «коды причин на платформе» отвергнута: платформа для этого парсила бы английские предложения движка. Названная щель — в §6. **2.8. Что НЕ пошло на провод из отчёта глагола** (каждое — решение, не забывчивость): пути файлов и `written_delta`/`written_rejects` (серверная топология; ремеди клиента один — «слать тот же»); `canonical_rewrite*` (предупреждение оператору файлов на диске, у клиента продукта нет ни файла, ни комментариев в нём); ТЕКСТЫ `preexisting_problems` (свободный текст движка) — но их СЧЁТ (`preexisting_faults`) едет, потому что «книга уже больна, следующий прогон может встать» экрану нужен; `replaced[]` (свободный текст) — свёрнут в булев `displaced`, несущий ровно то свойство, ради которого поле существует («перекрыл чужое слово — видь это», `decisions.go:225-228`); `mode` — раскладывается на `preview`/`changed`/HTTP без остатка; `decisions_version`/ `report_version` — версии документов ШВА, на проводе их роль играет `contract_version`. **2.9. `depth`: `edit_wave` → `refinement`.** Движковая константа несёт имя волны — запрещённый на проводе словарь (гейт §5). Продуктовое слово с тем же смыслом; обе половины смысла («следующий прогон»; «черновик не пере-формируется» → «не пере-переводится с нуля») продублированы словами. Поле оставлено (не свёрнуто в прозу), потому что движок сделал его ПОЛЕМ с версией ровно затем, чтобы будущая смена глубины была наблюдаемой (`decisions.go:51-57`). **2.10. `signature` — опубликован с ОБЕИМИ половинами контракта** (`bankdecisions.go:88-118`): положительная (счёт согласован с правилом сворачивания — полезен экрану) и запретительная (не гейт; не отвечает «погаснет ли стоп» ни в одну сторону; `undecided: 0` ничего не обещает; решать — ПРАВО; `unreadable` = числа не значат ничего). `map` (путь) не едет; «карты ещё нет» выражено `signature: null` — иначе `0/0` без карты был бы байтово неотличим от «всё решено», тот же класс дыры, который движок закрыл флагом `unreadable`. **2.11. Признак «не построено» — `Capabilities.bank_corrections_enabled: boolean`.** `Capabilities` годится: плоский документ деплоя, уже дом `intake_enabled` (булев + объявленный `404`) и `export_formats` («пусто = не построено»). Булев, а не пустой список: у двери нет оси форматов — нечего перечислять. Поведение при `false` объявлено (`404`), зеркаля интейк. **2.12. Квитанция — НЕ чтение:** без `revision`/`structure_version`, кадр `bank` не испускается, строки `GET /bank` не меняются до следующего прогона — сказано в каноне прямо (иначе первый же экран прочтёт «исправил, а банк не изменился» как баг). Это проекция однонаправленного потока онтологии (источники → вид → проекции, `18-bank-ontology.md`). ## 3. Решение по счётчикам (§3.2-бис): СНЕСТИ — со всех ТРЁХ носителей Мой греп нашёл носителей больше, чем названо в промте: `pending_decisions`/`complete` жили в `BankPage` (`:1924-1934`), в квитанции `BankDecisionsResult` (`:1997-2008`, умерла со схемой) **и в кадре `EventBank` (`:2367-2372`, required)** — третий носитель в списке промта отсутствовал (команда: `grep -n "pending_decisions\|'complete'\|complete:" openapi.yaml` до правок — хиты 442, 1924, 1929, 1997, 2000, 2004, 2367, 2371-2372). Из трёх заказанных исходов выбран **снос**, довод в компаньоне §2.19-бис: пере-определить нельзя — честный счёт движковый (`SignatureState`), и read-модель его не вычислит, не пере-реализовав движковый закон (запрещено D39.156 п.6; «Чего эта форма НЕ несёт» онтологии); пометить нельзя — обязательное вечно-нулевое поле это PD-370 в поле вместо пути. Ратифицированная проза «Signing the bank is ONE act…» СОХРАНЕНА в `listBankTerms`; попутно из того же абзаца снята фраза «marked unverified inside the service» — обещание без носителя, снятое ещё ФБ-8 (компаньон §6б) и уцелевшее в одном месте. Цена сноса названа в каноне и компаньоне: чтение банка больше не отвечает «сколько осталось»; счёт едет квитанцией двери (`signature`); возврат в чтение — когда закажут экран подписи и движок опубликует нерешённость проекцией (носитель — `18-bank-ontology.md`). ## 4. Исполнения самопроверки (§5) — команды и вывод **4.1. Канон парсится + дубли ключей** (loader-хук, § 5 п.1-2; скрипт `check_canon.py` в скратчпаде сессии): ``` $ python3 .../check_canon.py PARSE OK, no duplicate keys. version = 0.5.0 ``` **4.2. Ссылки, обе стороны** (тот же скрипт: все `$ref` резолвятся; все компоненты на кого-то ссылаются): ``` refs total: 272; dangling: 0 components.schemas: 63 defined, unreferenced: none components.responses: 10 defined, unreferenced: none components.parameters: 11 defined, unreferenced: none components.headers: 2 defined, unreferenced: none ``` Тем же скриптом пере-ран гейт §5 компаньона (утечка конвейерного словаря) по ФИНАЛЬНОЙ спеке: `stage` — 1 хит, сама формулировка запрета (легально); `edit` — 2 хита, оба прежние легальные английские глаголы (`:283` «not an edit», `:1683` «editing the source» — инвентарь 0.4.0, новых нет; команда: `grep -n "\bedit" openapi.yaml | grep -v credit`); `verdict` — 2 хита БЫЛИ моими в `CorrectionRefusal`, исправлено на «refusal» до сдачи, пере-ран чист. **4.3. Настоящий линтер и генератор** (пины зоны фронта, поверх п.1): ``` $ ./frontend/node_modules/.bin/spectral lint --ruleset frontend/.spectral.yaml docs/architecture/14-api-contract/openapi.yaml No results with a severity of 'error' found! $ ./frontend/node_modules/.bin/openapi-typescript <канон 0.4.0 из HEAD> → OK (exit 0) $ ./frontend/node_modules/.bin/openapi-typescript <канон 0.5.0> → OK (exit 0) ``` Дифф генерённых типов 0.4.0 → 0.5.0 — 380 строк, ВСЕ в заявленной поверхности: путь и operationId · минус три схемы и счётчики (`BankPage`, `EventBank`) · плюс шесть схем · `ErrorCode` +2 значения · `Capabilities` +1 обязательное поле · `Problem.refusals`. Неожиданных сдвигов нет (команда: `diff types-040.ts types-050.ts`). Замечание генератора: `oneOf`-ветки идентичности `BankCorrection` сворачиваются в `& (unknown | unknown)` — тип не дискриминирует ветки; это известный класс К-11 (генератор игнорирует и `if`/`then`), правило «схема + слова» применено, слова в описании стоят. **4.4. Гейт платформы краснеет ПРЕДСКАЗУЕМО** (§5 п.3; копия ВМЕСТЕ с каноном, как велит промт): ``` $ cp -a --parents platform docs/architecture/14-api-contract $SCRATCH/gatecopy/ $ cd $SCRATCH/gatecopy/platform && go test ./internal/gates/ -run TestTheAnnouncedContractVersionIsTheOneTheCanonRatified --- FAIL: TestTheAnnouncedContractVersionIsTheOneTheCanonRatified (0.00s) contract_test.go:40: this build announces contract 0.4.0 and the ratified canon is 0.5.0; the constant is raised in the same change as the code that implements a minor, never afterwards FAIL ``` Красный ИМЕННО на несовпадении версий и ИМЕННО с ожидаемым текстом; константу поднимает оркестратор при лендинге тем же коммитом (§4 промта, D39.160). ## 5. Находки опровергателей — все, включая отвергнутые с причиной Панель: 3 агента (в пределах веера 2–4, §5 промта), по осям §6 — «словарь двери против словаря глагола» (заказ) · «холодный потребитель/генератор» · «что читатель узнает о том, чего нет». Workflow `wf_20c22060-e6e`, 349k токенов, 0 упавших. Каждый ключевой клейм пере-сверен МОИМ чтением кода до вправления (файлы и строки в диспозициях). **Итог: 21 находка; принято и вправлено 17, отвергнуто 4 (с причиной ниже).** ### Приняты и вправлены (после каждой — куда легла правка) **Ось «словарь глагола»:** 1. **MAJOR. Decline сид-поверхности уплощён до безусловного отказа.** Движок отказывает ТОЛЬКО инертному (`decisions.go:374`, условие `!deltaHoldsSurface`); когда правки книги держат свою строку той же поверхности, decline принимается и снимает её — ремонт ливлока, ради которого правило и переписывалось. Мой канон запрещал ремонт. → канон (`BankCorrection`, список «NOT correctable») + компаньон §2.19 (строка сид-терма). 2. **MAJOR. Decline алиаса уплощён.** Движок судит РЕЗУЛЬТАТ и отказывает только алиасу ПОДПИСАННОГО терма (`aliasOwner` пропускает `status != approved`, `decisions.go:644-659`); decline терма и его алиаса одним документом — оба принимаются. → канон (условная формулировка «once this document is applied, would remain only an ALIAS an approved correction still fires for») + компаньон. 3. Алиасы на проводе НЕ публикуются (`BankTerm` их не несёт, D39.136 п.4б), а вывод-таблица читалась как будто публикация есть; клиент не может увидеть, что поверхность — алиас. → канон (скобка «the alias set itself is not published on this surface») + компаньон (названная щель). 4. Класс 12 → `run_in_flight` точен только при сериализации платформой СВОИХ вызовов двери (флок держит любой глагол, включая превью). → компаньон: обязательство монтажа (в), «точное слово» переквалифицировано. 5. `400` `errors[/book_id]` не имеет движкового производителя (движковая сверка — класс 10): производит платформа до спавна. → компаньон: обязательство монтажа (б). 6. Оба потолка у движка — класс 14, канон раскладывает в `400`/`413`: платформа мерит их на проводной форме до спавна; остаток (движковый документ после рендера > 1 МиБ) падает в `409`. → компаньон: обязательство монтажа (а); канон: описание `bank_corrections_refused` несёт «a set larger than the service applies in one act». 7. `preexisting_faults` «may stop at the bank» читался как благой signing-stop, и объект был сужен до файлов правок (движок считает и фолты сид-строк). → канон: «bank inputs», «would FAIL at the bank — a fault, not the signing stop». 8. «`mode` раскладывается без остатка» — ложь: исход `stopped` не был разложен. → компаньон: назван (`5xx` рестарта, ничего не записано, ретрай сходится). 9. Усечение отказа: на `409` движок печатает полный отчёт, провод несёт только `refusals[]` — не было названо. → компаньон: названо ценой v1. 10. `kind` на проводе сужен до `TermKind`, движок принимает любую строку; источник пятёрки — классификатор чтения, не `decisions.go`. → компаньон: сужение задекларировано ◆ с доводом. **Ось «холодный потребитель»:** 11. **MAJOR. Счёт `signature` недостижим, пока нечего послать** (у `corrections` `minItems: 1`, пустой документ и движок отказывает классом 10). Решено НЕ ослаблением `minItems` (движок пустой документ не принимает — ослабление дало бы дверь, врущую о глаголе), а НАЗВАННОЙ узостью: канон (`signature` квитанции + `listBankTerms`) говорит прямо «only there; a client with nothing to correct or preview cannot ask for it yet»; носитель возврата счёта в чтение — §2.19-бис. 12. **MAJOR. Семантика `sense`/окна при `decline` в кортежной форме не была определена.** → канон: «say which row the receipt reports and do NOT narrow the effect», для поверхности вне банка — `sense: ""` и `null`-окна (сверено: движковый decline ключуется нормализованным `src`, `addReject`). 13. **MAJOR. Неизвестный `id` — двоякое прочтение (400 c `errors[] unknown` против 409).** → канон называет код явно: `409` `bank_corrections_refused`, вход в `refusals[]` (движок: класс 14). 14. **MAJOR. Отказ за decline алиаса опирался на данные, невидимые клиенту** — слился с №2/№3. 15. «Would change nothing» как причина 409 против гарантии `already_applied` — граница не была проведена. → канон: «a `decline` nothing recorded answers to; re-sending an already-recorded correction is NOT this — that answers `200` with `already_applied`». 16. `AcceptedCorrection.dst` — третье незаявленное исключение из правила шапки «required+nullable». → канон: `dst` теперь required, `[string, 'null']`, «null on decline». 17. Переиспользованные `TooLarge`/`ServiceUnavailable` несли чужую конкретику (интейк/прогоны) — докстроки врали бы на этой операции. → канон: описания компонентов обобщены, `503` отсылает к диспетчеризации по `code`. 18. `BankTerm.id` «its surfaces» (мн.ч.) читалось как «id зависит от dst». → канон: «its SOURCE surface … not from `dst`, so a corrected rendering keeps the id». 19. Протухший пример `EventHello.contract` `0.4.0`. → канон: `0.5.0`. 20. `Problem.code` обязателен схемой, а вне `/v0` может отсутствовать — правило жило только в шапке, генератор его не видит. → канон: оговорка в описании `Problem`. **Ось «чего нет»:** 21. **MAJOR. «Канон и деплой при лендинге СОВПАДАЮТ» — переклейм.** Сверено кодом: `wireBankPage` (`platform/internal/httpapi/reading.go`) продолжает слать `pending_decisions`/`complete`, и они НЕ нули — `bankCountsTx` (`pgstore/readmodel.go`) считает «все proposed-строки» с комментарием «the wire fields are the canon's» (теперь ложным). Совпадение точно по ПУТЯМ, не по полям. → компаньон: шапка переписана честно, §2.19-бис несёт сверенную правду вместо «навсегда нули», строка `GET /bank` в §3 пере-снята, носитель снятия — пункт (2в). ⚠ Это расхождение с БУКВОЙ промта пака (§4 п.2 «СОВПАДУТ точно», §3.2-бис «поля навсегда нули») — **пинг оркестратору, см. §6.** 22. Композиция «до монтажа 2в счёт недоступен НИГДЕ» была только выводимой. → компаньон §2.19-бис, названо тремя половинами цены. 23. А-2: «гейт полноты ДЕМОНТИРУЕТСЯ в P7» — будущее время при снятом гейте (сверено: `reconcile.go`, ветка `awaiting_bank`). → компаньон: «ДЕМОНТИРОВАН, сверено с кодом». 24. §2.9: баннер 0.5.0 стоял ПОСЛЕ перекрытой клаузы — против «баннер прежде содержимого». → компаньон: переставлен перед ней. 25. Позитив: все семь обязательных «явных фактов» оси 3 подтверждены с картой line-номеров (вердикт панели, находка-нота) — в канон изменений не требует. ### Отвергнуты, с причиной 1. **`Capabilities.intake_max_bytes` обязателен и не-nullable у read-only деплоя** — реальный дефект, но 0.3.0/0.4.0-наследие ВНЕ состава этого пака (§3 промта); правка сейчас раздула бы ломающую поверхность минора без заказа. Оставлено оркестратору как кандидат следующего касания. 2. **`TermKind`/`TermStatus`/`TermOrigin` без пер-схемных нот толерантности** — паттерн 0.3.0, вне состава пака; общее правило шапки формально покрывает. Кандидат следующего касания (вместе с №1). 3. **Байт-зеркало фронта (0.2.3) несёт снесённую модель** — отставание РАТИФИЦИРОВАНО (D39.142 п.5, D39.147, фриз фронта); шапка компаньона его уже несёт. Не дефект этого минора. 4. **`unreadable`: «the call was refused before it could count» не имеет носителя на проводе** — принято НАПОЛОВИНУ: формулировка-триггер из описания снята (правда), но само поле оставлено — первый триггер («не читается состояние») жив и на 200-квитанции (карта/файлы нечитаемы, вызов при этом принят byte-no-op'ом… нет: нечитаемые файлы — отказ класса 10; нечитаемой может быть КАРТА подписи — вызов принят, счёт не измерен). Ровно этот случай поле и несёт. ## 6. Obstacle — что НЕ удалось и что НЕ проверено (§10) 1. **Расхождение промта с кодом — пинг оркестратору (§11 промта):** промт утверждал «платформа свою половину уже снесла 22.08, после твоего сноса они СОВПАДУТ точно» (§4 п.2) и «поля навсегда нули» (§3.2-бис). Сверка с кодом (`httpapi/reading.go` `wireBankPage`; `pgstore/readmodel.go` `bankCountsTx`) показала: путь снесён, а ПРОЕКЦИЯ ЧТЕНИЯ продолжает слать оба поля, и `pending_decisions` — живое число всех proposed-строк, не ноль. Я не интерпретировал в свою пользу и не обходил: канон 0.5.0 поля снимает (это и есть заказ), а расхождение записано в шапку компаньона с носителем (пункт 2в) и сюда. **Оркестратору решить:** достаточно ли носителя «пункт 2в» для снятия двух полей из `wireBankPage`, или нужна отдельная строка бэклога платформы (я её завести не могу — не моя зона). 2. **Не проверено исполнением:** поведение НАСТОЯЩЕЙ платформы против 0.5.0 (маршрута нет — 404 проверить не на чем до монтажа); рендер экранов фронта (зона заморожена ратифицированно); `spectral` гонялся ТОЛЬКО с рулсетом зоны фронта (`spectral:oas`) — иных рулсетов в репо нет. 3. **Названные щели v1 (в канон/компаньон внесены, но не закрыты):** машинного словаря причин отказов нет (едут developer-facing `detail`); алиасы невидимы клиенту; счёт `signature` недостижим без правки/превью; на `409` не едут `preexisting`/`signature`; счётчики деплой шлёт до монтажа 2в. 4. **Гипотетический остаток раскладки потолков:** случай «HTTP-тело < 1 МиБ, движковый документ после рендера платформой > 1 МиБ» назван и покрыт кодом 409, но живьём не воспроизводился (двери нет); замер — работа монтажа. 5. Дифф генерённых типов пере-ран после вправлений панели (`types-050b.ts`, exit 0), но пост-фиксовый ПОЛНЫЙ дифф против 0.4.0 построчно не пере-инвентаризировался — сверены только изменённые правками места (`AcceptedCorrection.dst`, примеры, описания). ## 7. Таблица комплектности против §3 (§7) | Пункт заказа | Что сделано | Исполнение-подтверждение | |---|---|---| | §3.1 снос: канон, 9 позиций | путь+операция (`:469-505` стар.) · проза `:1830` · три схемы `:1939-2008` — снесены; замена — дверь corrections | `grep -n "bank/decisions\|submitBankDecisions\|BankDecision\b\|BankDecisions\|pending_decisions\|term_id" openapi.yaml` → exit 1 (0 хитов) | | §3.1 снос: компаньон, 5 позиций | `:124` (список К-11-мест) · `:674` (историческая строка сохранена, статус дописан) · `:685` (пере-снята на живые носители) · `:724` (К-11) · `:1173` (⚠-баннер истории §6в K) | `grep -n "submitBankDecisions\|BankDecisionsRequest\|BankDecisionsResult" README.md` → 0 хитов вне ⚠-контекстов; пер-позиционные диффы в дереве | | §3.1 «свой греп обязателен, ещё и по `dst`/`UnknownTermError`/`BankPage`» | исполнен до правок | команда и хиты — секция 3 отчёта; `UnknownTermError` — 0 хитов в обоих файлах | | §3.2 дверь объявлена, тело выведено из глагола | `POST /books/{bookId}/bank/corrections` + 6 схем + 2 корневых кода + member `refusals` | вывод-таблица §2.19 компаньона (каждое поле — file:line движка); панель-опровергатель по оси словаря — секция 5 | | §3.2 машиночитаемый признак «не построено» | `Capabilities.bank_corrections_enabled` (required; `false` ⇒ `404`) | канон; прецеденты `intake_enabled`/`export_formats` — §2.19 | | §3.2 ⛔ signature только с запретительным контрактом | `BankSignatureCount` несёт ОБЕ половины D39.144 + `unreadable` + `null`-семантика | канон `:2217+`; проверка панелью (ось 3, факт 7 подтверждён с line-номерами) | | §3.2-бис счётчики: решить обязан | решено — СНОС с трёх носителей (третий найден моим грепом) | секция 3 отчёта: греп-команда; §2.19-бис компаньона | | §3.3 конверт вне `/v0`, строка 203(а) | предупреждение в `info.description` + оговорка в `Problem`; ссылка на компаньон §2.14 | буква (а) сверена: `docs/PROGRESS.md:146` (греп `строка 203`); канон `:39-43` | | §3.4 прогресс НЕ трогать | семантика `:1293` не тронута | `git diff openapi.yaml | grep -c "segment\|counter starts again"` → 0 правок в блоке `Progress` | | §4 версия | `0.5.0`; гейт платформы краснеет предсказуемо | секция 4.4: команда копии и вывод FAIL с ожидаемым текстом | | §5 п.1 парс | исполнено | секция 4.1 | | §5 п.2 ссылки + дубли | исполнено, обе стороны | секция 4.2 | | §5 п.3 гейт на копии | исполнено, `cp -a --parents` | секция 4.4 | | §5 опровергатель (заказ) | 3 агента, 21 находка, 17 вправлено, 4 отвергнуто с причиной | секция 5; workflow `wf_20c22060-e6e` | | §7 записка-план до правок | секция 1 написана до первой правки файлов контракта | git-история дерева не создавалась (не коммичу); порядок виден по этому файлу | | §9 эхо · §10 obstacle · §11 состав | секции 1, 6; состав сдачи — три файла | `git status` перед сдачей — см. финал сессии |