textmachine/docs/CONTRACT_MINOR_REPORT.md

41 KiB
Raw Blame History

Отчёт контрактной сессии: минор 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_version0.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 промта, заказ): 24 агента, мандат «дверь против словаря глагола» + оси §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. Раскладка полосы отказов. Ратифицированная полоса 1019 (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_waverefinement. Движковая константа несёт имя волны — запрещённый на проводе словарь (гейт §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 агента (в пределах веера 24, §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; false404) канон; прецеденты 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
§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 перед сдачей — см. финал сессии