From b206e1cef2ae2a881515f0680db215f8be5aad46 Mon Sep 17 00:00:00 2001 From: heaven Date: Sun, 6 Sep 2026 02:35:44 +0300 Subject: [PATCH] Withdraw an erratum whose measurement asked the wrong manager, correct two numbers their own author disproved, and take a literal out of a working line that outlived it --- docs/PROGRESS.md | 6 +++--- docs/architecture/05-decisions-log.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index a990d76c..e01ed723 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -112,7 +112,7 @@ **10. НЕ ОПИСАНО, А НАДО:** пакет `internal/langscreen` (новый, на денежном пути вердиктов) в README не упомянут вовсе · карта пакетов не называет ~20 несущих файлов `internal/pipeline` (`volume.go`, `rebill.go`, `reprice.go`, `refusal.go`, `terminologist.go`, `bookbuild.go`…) и пять в `internal/store` · -`cmd/tmmutate` (каталог 141 посадки, объявленный ГЕЙТОМ) и `cmd/tmvet` не названы · цена закона +`cmd/tmmutate` (каталог посадок, объявленный ГЕЙТОМ; ⚠ **число из этой строки снято 06.09 — стояло «141», в дереве 211**: литерал в рабочей строке живёт дольше предмета, поэтому здесь его больше нет — счёт берётся из `cmd/tmmutate/mutations.json`) и `cmd/tmvet` не названы · цена закона раскрытия («загейчен на 40 %», Г1/Г2 не построены) в статус-борде 09 не оговорена. ⚠ **Что оркестратор поправил СВОЕЙ рукой в свою зону тем же заходом:** статус-борд @@ -349,7 +349,7 @@ | 296 | **ТОЧЕЧНАЯ ПЕРЕГЕНЕРАЦИЯ ПО ПРОМАХУ ГЛОССАРИЯ — направление владельца 05.09 («или флагать, или перегенерировать проблемный участок»), работы сегодня НЕТ.** Актуаторы ремонта — только `RepairLatinResidue` и `RepairBrokenWord` (`backend/internal/pipeline/repair.go`, греп `defaultRepairClasses`); `glossary_miss` нет ни там, ни в `knownRepairClasses`. Сегодняшние лекарства не точечные и обе дороги: удержать ВЕСЬ фрагмент (гейт) либо править глоссарий с `--resnapshot`, то есть ПЕРЕ-ОПЛАТИТЬ книгу. ⇒ заказ: `glossary_miss` как класс-актуатор — перегенерация участка с подписанной формой. ⚠ Гейтится строкой **295**: без замера точности перегенерация по ложному срабатыванию перепишет верный текст | бэкенд | когда-нибудь (после 295) | новый класс актуатора + пост-инвариант | **D39.205** | | 297 | ⛔ **СЛОВАРЬ ПРОВЕНАНСА СТРУКТУРЫ КОРОЧЕ НА ОДНО ЗНАЧЕНИЕ, И ПЛАТФОРМА ЖИВЁТ НА ВРЕМЕННОМ ПРАВИЛЕ.** Для EPUB-spine ложны ВСЕ ТРИ значения `Document.Structure` (`backend/internal/chunk/ingest.go:70-113`): `declared` = «ФОРМАТ назвал границу», а spine называет ПОРЯДОК ЧТЕНИЯ, и «документ = глава» — догадка движка, не слово формата; `detected` определено МЕХАНИЗМОМ «header-shaped lines in the prose» (`splitTextChapters`), которого здесь не было; `none` = «одна глава». ⚠ Само поле спроектировано ВЕРНО — оно отвечает на «КАКОЙ ПУТЬ провёл границы» (`:94-95`); неверна его же первая строка (`:70`), рекламирующая «how much the chapter cut can be trusted». Прибор отвечает на свой вопрос, а читают его как ответ на другой, и здесь неверное чтение НАПЕЧАТАНО ВНУТРИ прибора, двумя строками выше верного. Пока значения нет, платформа исполняет потребительское решение, прописанное в самом комментарии (`:93-94`, «decline to offer an order in chapters»): `declared` ведётся как `none` для целей ползунка заказа. **Правило ВРЕМЕННОЕ, и снятие его — уборка, а НЕ сцепленный деплой.** Добавить значение можно АДДИТИВНО: `manifestVersion` версионирует ФОРМУ ДОКУМЕНТА (`backend/internal/pipeline/manifest.go:40-46`), а новое значение строкового поля формы не меняет — так же приехали сами `Structure` и `Price`. Стоп-мир возник бы только из CHECK-ограничения схемы платформы (`platform/internal/pgstore/migrations/00033_order_and_price.sql:28`), которое противоречит её же обещанию «unknown → not recognised» и снимается ДО лендинга. ⇒ как только движок пошлёт новое значение для spine, платформа прочтёт неизвестное как `none` своим `StructureTrusted`, и для SPINE-книг ползунок станет верным САМ. ⚠ **Испр. 05.09: «без правки на её стороне» — НЕВЕРНО и снято.** Правка нужна, и снятие правила ОБЯЗАТЕЛЬНО: после пака `declared` станет означать ТОЛЬКО настоящую структуру глав из `nav`/NCX, и временное правило начнёт ОТНИМАТЬ у таких книг заслуженный ползунок глав. Отказ безопасен по направлению (продаём по знакам там, где могли по главам — консервативно, не опасно), но он МОЛЧА недодаёт продукт, и потому это не уборка, а обязательный шаг. Носитель довода зона положила в комментарий `ingest.ChapterOrdersOffered`, чтобы снимающий нашёл его по коду. ⚠ По тому же правилу под недостающее значение попадает и `\f` в txt — form feed есть разрыв СТРАНИЦЫ, а не утверждение о главе, и сегодня он тоже `declared`; решает структурный пак | бэкенд+платформа | скоро (структурный пак) | недостающее значение на проводе, и `declared` означает ТОЛЬКО объявленную форматом структуру глав | **D39.202**, D39.205 | | 298 | ⛔ **`unit_resolutions` КЛЮЧЕВАНЫ ПОЗИЦИЕЙ, И ЛЮБОЙ ПЕРЕКРОЙ ИХ СНОСИТ ЦЕЛИКОМ.** Ключ `(book_id, chapter, unit, wave)` позиционен по построению, и миграция это прямо объявляет: «keyed by the ENGINE's own ordinals» (`platform/internal/pgstore/migrations/00015_seam_ceiling_and_units.sql:50-56`); событие `unit_done` несёт номер главы и ординал юнита, синк пишет их как есть (`platform/internal/pgstore/sink.go:249`). Потому при перекрое платформа ОБЯЗАНА удалять решения — иначе они перевесятся на чужую главу. Сегодня цена нулевая: решения есть только у стенд-книги, и это окно закрывается с каждой новой платной книгой. ⇒ разрешать `(chapter, unit)` в идентификатор ПРИ ПРИЁМЕ события, пока дерево у платформы на руках, и хранить идентификатор. Платформенная половина структурного пака: миграция плюс синк. ⚠ Этой строкой НЕ закрывается одноразовая перечеканка всех id при смене смысла `cutTag` — это другой предмет и другая цена | бэкенд+платформа | скоро (структурный пак) | решения переживают перекрой, не переклеиваясь на чужую главу | **D39.202** | -| 299 | ⛔ **ИМЯ В GO-КОММЕНТАРИИ, КОТОРОЕ НИ ВО ЧТО НЕ РАЗРЕШАЕТСЯ, — И НИЧТО ЭТОГО НЕ ЛОВИТ.** ⭐ **ЗАМЕР 05.09, полностью меняющий форму ДОРОГОЙ половины (той, что сверяет имя с каталогом мутаций): она обязана писать ФАЙЛ, а не читать `stdout`.** Полный прогон каталога дал: несущих верхнеуровневых тестов **194** из 1213 тест-функций движка (**16,0 %** батареи), и **139 записей из 197 пинятся РОВНО ОДНИМ тестом** — то есть краснота атрибутируется однозначно, и долговременная запись «какие тесты несущие» реально получается. ⛔ **Но тул обрезает список имён на четырёх и печатает `+N more` — так усечены 9 записей из 197, и механизм, читающий `stdout`, насчитал бы 178 вместо 194 И НЕ УЗНАЛ БЫ ОБ ЭТОМ.** Это тот же класс «прибор ответил на свой вопрос»: величина ВЫЧИСЛЯЕТСЯ сегодня, но в поток приезжает УСЕЧЁННОЙ. ⇒ вход механизма — `-logs`, не вывод. Точный список имён воспроизводится пере-прогоном каталога с `-logs`; сохранять его отдельным артефактом не нужно. Два живых носителя, найдены верификацией 05.09 (`D39.207` п.3): **(а)** `backend/internal/runevents/runevents.go:187`=`not to a screen` цитирует **СТАРЫЙ** путь — `docs/BACKEND_MONEYSTOP_SESSION_PROMPT.md`, строка 78 (записано БЕЗ формы якоря намеренно: это УЛИКА мёртвой ссылки, а не ссылка; в форме якоря линт вечно краснел бы на предмете самой записи) — и удалён именно он (промт уведён в архив коммитом `f71c4dc`, тем же, что писал акт), а цитируемая фраза ЖИВА в архивной копии и стоит там на строке **82**. ⚠ **Испр. 06.09: клауза была заландена ПЕРЕВЁРНУТОЙ** — называла удалённым архивный файл, который цел, и приписывала комментарию цитату, которой в нём нет. Механика ошибки записана отдельно, она повторяемая: сплошная замена строки якоря при пере-наведении попала в ОПИСАНИЕ дефекта, где тот же путь был УЛИКОЙ, а не ссылкой, и превратила описание поломки в описание её отсутствия. Нашёл верификатор `textmachine-main-e6` контролем закрытия своих же находок; ⚠ приёмочный столбец строки при этом сформулирован ВЕРНО и поймал бы дефект независимо от прозы — то есть major в описании, не в гейте; **(б)** `backend/internal/config/internal_call.go:11`=`builds a Stage outside the loader` и `backend/internal/pipeline/live_reprobe_test.go:14`=`the single-egress guard` называют сторожами тесты `TestSyntheticStageSeamIsSingle` и `TestProviderEgressSeamIsSingle`, которых в дереве НЕТ — инварианты при этом реально сторожатся вет-анализаторами `StageSeam`/`EgressSeam` (`backend/internal/archguard/archguard.go:80,377`=`StageSeam, RequestSeam, EgressSeam`), то есть гарантия цела, а назначенный ей сторож ВЫДУМАН. Замер верификатора: из 2026 упомянутых в Go имён `Test…` определены 2012; из восьми неразрешающихся четыре — не дефекты (надгробия и иллюстрация), два — мелочь, два — эти. ⇒ **дешёвая половина открытого вопроса `D39.202` п.9: не «доказал ли каталог, что названный тест умеет падать» (дорого, требует интеграции с `tmmutate`), а «РАЗРЕШАЕТСЯ ли названное имя вообще» — это греп, и сегодня он находит два дефекта.** ⚠ `counts.py --lint` этого класса не видит по построению: он читает доки, а не код. ⚠⚠ **ДВА ПРАВИЛА, БЕЗ КОТОРЫХ ГЕЙТ ВЫКЛЮЧАТ НА ВТОРОЙ ДЕНЬ** (принесены верификатором вместе с находкой): **(1)** разрешением считается и ПРЕФИКС — доки и комментарии цитируют имя усечённым, как греп-цель; **(2)** НАДГРОБИЯ не дефект — комментарий, прямым текстом говорящий «удалён/заменён», законен, как и иллюстративное имя в примере. Замер, обосновывающий оба: из восьми неразрешающихся имён СЕГОДНЯ четыре — надгробия и иллюстрация, два — усечение в шапке над функцией, и лишь два — настоящие выдуманные сторожа. Гейт без этих правил краснеет 8 из 8, то есть врёт вчетверо, и его погасят — а гейт умирает не отключением, а вытеснением из привычки (`D39.202` п.3-бис) | бэкенд | скоро | грепом: имя `Test…` и `<док>.md:<строка>` в Go разрешаются, иначе красно | **D39.207**, D39.202 | +| 299 | ⛔ **ИМЯ В GO-КОММЕНТАРИИ, КОТОРОЕ НИ ВО ЧТО НЕ РАЗРЕШАЕТСЯ, — И НИЧТО ЭТОГО НЕ ЛОВИТ.** ⭐ **ЗАМЕР 05.09, полностью меняющий форму ДОРОГОЙ половины (той, что сверяет имя с каталогом мутаций): она обязана писать ФАЙЛ, а не читать `stdout`.** Полный прогон каталога дал: несущих верхнеуровневых тестов **189** из 1213 тест-функций движка (**15,5 %** батареи; ⚠ испр. 06.09 автором замера: было «194 / 16,0 %» — его парсер резал вывод по запятой, а пять подтестов несут запятую В ИМЕНИ, и круглые «16,0 %» получились именно из пяти фантомов. ⚠ Числитель и знаменатель разной природы: 1213 считает только `^func Test`, а один из 189 — `Fuzz`; честно 188/1213 либо 189/1219, но не 189/1213), и **139 записей из 197 пинятся РОВНО ОДНИМ тестом** — то есть краснота атрибутируется однозначно, и долговременная запись «какие тесты несущие» реально получается. ⛔ **Но тул обрезает список имён на четырёх и печатает `+N more` — так усечены 9 записей из 197, и механизм, читающий `stdout`, насчитал бы 178 вместо 194 И НЕ УЗНАЛ БЫ ОБ ЭТОМ.** Это тот же класс «прибор ответил на свой вопрос»: величина ВЫЧИСЛЯЕТСЯ сегодня, но в поток приезжает УСЕЧЁННОЙ. ⇒ вход механизма — `-logs`, не вывод. Точный список имён воспроизводится пере-прогоном каталога с `-logs`; сохранять его отдельным артефактом не нужно. Два живых носителя, найдены верификацией 05.09 (`D39.207` п.3): **(а)** `backend/internal/runevents/runevents.go:187`=`not to a screen` цитирует **СТАРЫЙ** путь — `docs/BACKEND_MONEYSTOP_SESSION_PROMPT.md`, строка 78 (записано БЕЗ формы якоря намеренно: это УЛИКА мёртвой ссылки, а не ссылка; в форме якоря линт вечно краснел бы на предмете самой записи) — и удалён именно он (промт уведён в архив коммитом `f71c4dc`, тем же, что писал акт), а цитируемая фраза ЖИВА в архивной копии и стоит там на строке **82**. ⚠ **Испр. 06.09: клауза была заландена ПЕРЕВЁРНУТОЙ** — называла удалённым архивный файл, который цел, и приписывала комментарию цитату, которой в нём нет. Механика ошибки записана отдельно, она повторяемая: сплошная замена строки якоря при пере-наведении попала в ОПИСАНИЕ дефекта, где тот же путь был УЛИКОЙ, а не ссылкой, и превратила описание поломки в описание её отсутствия. Нашёл верификатор `textmachine-main-e6` контролем закрытия своих же находок; ⚠ приёмочный столбец строки при этом сформулирован ВЕРНО и поймал бы дефект независимо от прозы — то есть major в описании, не в гейте; **(б)** `backend/internal/config/internal_call.go:11`=`builds a Stage outside the loader` и `backend/internal/pipeline/live_reprobe_test.go:14`=`the single-egress guard` называют сторожами тесты `TestSyntheticStageSeamIsSingle` и `TestProviderEgressSeamIsSingle`, которых в дереве НЕТ — инварианты при этом реально сторожатся вет-анализаторами `StageSeam`/`EgressSeam` (`backend/internal/archguard/archguard.go:80,377`=`StageSeam, RequestSeam, EgressSeam`), то есть гарантия цела, а назначенный ей сторож ВЫДУМАН. Замер верификатора: из 2026 упомянутых в Go имён `Test…` определены 2012; из восьми неразрешающихся четыре — не дефекты (надгробия и иллюстрация), два — мелочь, два — эти. ⇒ **дешёвая половина открытого вопроса `D39.202` п.9: не «доказал ли каталог, что названный тест умеет падать» (дорого, требует интеграции с `tmmutate`), а «РАЗРЕШАЕТСЯ ли названное имя вообще» — это греп, и сегодня он находит два дефекта.** ⚠ `counts.py --lint` этого класса не видит по построению: он читает доки, а не код. ⚠⚠ **ДВА ПРАВИЛА, БЕЗ КОТОРЫХ ГЕЙТ ВЫКЛЮЧАТ НА ВТОРОЙ ДЕНЬ** (принесены верификатором вместе с находкой): **(1)** разрешением считается и ПРЕФИКС — доки и комментарии цитируют имя усечённым, как греп-цель; **(2)** НАДГРОБИЯ не дефект — комментарий, прямым текстом говорящий «удалён/заменён», законен, как и иллюстративное имя в примере. Замер, обосновывающий оба: из восьми неразрешающихся имён СЕГОДНЯ четыре — надгробия и иллюстрация, два — усечение в шапке над функцией, и лишь два — настоящие выдуманные сторожа. Гейт без этих правил краснеет 8 из 8, то есть врёт вчетверо, и его погасят — а гейт умирает не отключением, а вытеснением из привычки (`D39.202` п.3-бис) | бэкенд | скоро | грепом: имя `Test…` и `<док>.md:<строка>` в Go разрешаются, иначе красно | **D39.207**, D39.202 | | 300 | ⛔ **РЕПО-ШИРОКИЙ СТОРОЖ НЕ ДОТЯГИВАЕТСЯ ДО СОСЕДНЕГО ВОРКРИ НА ДРУГОЙ ВЕТКЕ — и стенд от этого УЖЕ СГНИЛ.** ⚠ Замер 05.09, вторая половина: снять пин манифеста стенд-конфигами удалось для **ОДНОГО исходника из восьми**; семь падают, и ни одно падение не про структурный пак. Причины — ретированные в `main` вещи, живые в дереве `polygon`: плейсхолдер `{{genre}}` (ретирован `D39.138` п.2в) — в моём дереве `grep -rln '{{genre}}' backend/prompts/` ПУСТ, в соседнем живёт в ШЕСТИ файлах промтов, и падают на нём 6 конфигов из 8; поля `stm_depth`/`overlap_tokens`, которых больше нет в `config.ContextAssembly` — 1 из 8; ключи `mined_delta:`/`mined_rejects:` (ретированы `D39.156` п.3) — **17 конфигов из 31**. ⭐ **Тест `genre_retired_test.go:46` предсказал этот случай дословно** («should be caught by the repository that retired it, not by a paid run») — и поймали его действительно бесплатно, но **сторож не дотянулся до соседней ветки**, где ретированное живо. ⇒ общая форма дефекта: ретирование, проведённое репо-широким гейтом, НЕ распространяется на воркри другой ветки, и стенд тихо остаётся в прошлом. **ЧАСТНЫЙ СЛУЧАЙ ТОГО ЖЕ КОРНЯ — ДАННЫЕ ПАР-ПАКА В ДВУХ ВЕТКАХ.** Замер бэкенд-сессии 05.09 по 31 конфигу `book.yaml` стенда 蛊真人: у **20** `langpack_root` указывает в СОСЕДНЕЕ РАБОЧЕЕ ДЕРЕВО `/home/ubuntu/projects/textmachine` — а оно на ветке **`polygon`**; у 9 — в `main`; 2 не объявляют его вовсе. Пока каждая ветка собирается из своего дерева, расхождения не видно. ⚠ **Структурный пак (`CHAPTER_STRUCTURE_SESSION_PROMPT.md`) выносит `marker`/`units` из `zh-ru/heading.txt` в данные ИСТОЧНИКА и учит `parseHeading` ОТВЕРГАТЬ эти ключи с переходным сообщением** ⇒ старый файл, оставшийся на `polygon`, станет невалидным, и двадцать конфигов не загрузятся вовсе (загрузка пар-пака FAIL-LOUD). **Выстрелит НЕ при лендинге в `main`, а в момент, когда полигон вольёт `main` в свою ветку** — то есть цена назначена чужой зоне и в чужой момент. ⇒ заказ: перед мержем полигон либо снимает `marker`/`units` из своего `heading.txt`, либо переводит `langpack_root` своих конфигов на `main`. ⚠ Второе дешевле и, возможно, правильнее по существу: **каталоги `configs/langpacks` в обоих деревьях сегодня БАЙТ-В-БАЙТ идентичны** (`diff -rq` пуст, sha256 `heading.txt` совпадают), а комментарии в конфигах, утверждающие «`ru/` есть только здесь», ПРОТУХЛИ — класс строки 299. То есть двадцать конфигов смотрят в чужую ветку по причине, которой больше нет | полигон | скоро (до мержа main в polygon) | конфиги грузятся после мержа, либо `langpack_root` переведён | **D39.207** | | 301 | ⛔ **`--max-units` НЕ УМЕЕТ СКАЗАТЬ «ДОРАБОТАЙ ПЕРЕНЕСЁННОЕ И НЕ НАЧИНАЙ НОВОГО», И ЧЕЛОВЕК ЗА СВОИ ДЕНЬГИ ПОЛУЧАЕТ НЕ ТУ РАБОТУ.** Флаг бюджетирует N НОВЫХ стартов, а carried-юниты (задрафченные прошлым прогоном и не отгруженные) движок допускает СВЕРХ гранта, до N штук: `granted()` их не считает (`backend/internal/pipeline/volume.go:396-407`), и собственный тест движка это фиксирует — под `--max-units 1` при одном carried выходит `Delivered=2, Carried=1` (`volume_test.go:721`). ⇒ прогон, оборвавшийся МЕЖДУ волнами (стоп на подпись банка, деплой, краш), при респауне получает `--max-units = заказ − доставлено`, и движок оплачивает ЧЕРНОВИКИ глав, которых человек НЕ ЗАКАЗЫВАЛ, раньше редактуры заказанных. ⚠ **Это НЕ перерасход** — `--ceiling-usd` держит сумму; ломается ровно обещание «вы купили N»: за те же деньги приходит другая работа. Выразить нужное платформа не может по построению: вычесть carried значит обнулить грант, а ноль для движка = «без границы» (`planVolume` при `MaxUnits <= 0` возвращает `nil`, `volume.go:321`). ⇒ заказ: словарь скоупа обязан различать «сколько НОВЫХ начинать» и «сколько всего допускать». Живая половина **эрраты 03.09-а** (перенос юнита вне гранта, семантика НЕ ратифицирована, слово владельца «подумаем»), но со следствием более острым, чем записано в ноте: там был перерасход единиц, здесь — подмена предмета покупки | бэкенд+платформа | скоро | флагом выражается «ничего нового не начинать»; пин на респауне между волнами | **D39.207** | | 302 | **РЕЗКА xhtml ПО ЯКОРЯМ `nav`: текст цел, ГРАНУЛЯРНОСТЬ ТЕРЯЕТСЯ.** Массовая форма EPUB — несколько глав в ОДНОМ документе, разделённых якорями, и `nav` объявляет на них отдельные цели. Структурный пак 1 такие цели СХЛОПЫВАЕТ: одна глава вместо трёх, текст не теряется (формулировка бэкенд-сессии 05.09: «текст цел, гранулярность потеряна»). ⚠ **Ложь при этом уже не едет** — тем же паком ратифицировано: схлопнулась хоть одна цель ⇒ книга НЕ `declared`, а `delimited`, плюс счёт `targets collapsed: N` в WARN. То есть провенанс честен, а разрез груб. ⇒ заказ: резать документ по якорям целей. ⛔ **Почему НЕ сделано паком 1 и почему это дорого:** это единственное место, трогающее `extractXHTML`, у которого **четыре пина байт-паритета** (`ingest_test.go:323, 359, 423, 467` — void-теги, несбалансированный ruby, raw-text-элементы, голый амперсанд), и ошибка там ТИХАЯ. Заходить в него в конце пака, ради гранулярности, при живом гейте разреза — плохой размен. ⚠ Строкой закрывается ГРАНУЛЯРНОСТЬ, а не провенанс: продать такую книгу по главам платформа и так не предложит | бэкенд | когда-нибудь (после пака 2) | книга с тремя якорями в одном документе даёт три главы; четыре пина байт-паритета целы | **D39.207** | @@ -1011,7 +1011,7 @@ bidi-переопределений (Trojan Source), при этом ZWJ/ZWNJ/LR ни одна существующая не удалена и не переименована, два протухших починены внутри тела. Каталог мутаций **158 → 191**. Батарея: `MAKE_EXIT=0`, 19 пакетов, 0 упавших, 0 issues (шестой прогон — первые пять красны или остановлены). Каталог ЦЕЛИКОМ: **191 запись, 187 RED, 0 SURVIVED, 0 NOTHING, 0 ROTTED, 0 неожиданных исходов** — второй полный прогон; ПЕРВЫЙ не сошёлся и нашёл четыре дефекта в моих же артефактах, включая named-артефакт приёмки (§6.5 отчёта) (и `go vet -vettool` собственного анализатора зоны — чисто; он поймал у меня один хенд-билд `config.Stage`, см. отчёт). -⚠⚠ **ПОПРАВКА 05.09 (замер верификатора по дереву на `d766007`; числа выше НЕ переписаны — они были верны в свою минуту).** Абзац заленджен коммитом `ba4fd34` через **девять секунд** после пака `81a89e9` и за **три с лишним часа ДО** дофикса `616a8e4`, который добавил ещё +5 тест-функций и +10 записей каталога. Сообщение коммита подписало их «final counts», и после дофикса их никто не тронул. Верно на сегодня: тестовых функций **1172 → 1213 (+41)** · каталог мутаций **158 → 201** · каталог целиком — **201 запись, 197 RED, ЧЕТЫРЕ аргументированных выживших, 0 неожиданных исходов**. ⛔ **Переворачивается именно последнее: «0 SURVIVED» против четырёх записанных выживших** — а это то самое различение из `D39.202` п.3 (`SURVIVED` как СООБЩЕНИЕ О НЕДОСТИЖИМОСТИ, а не как провал), и следующая движковая смена открывает этот журнал РАНЬШЕ акта. Акт `D39.206` всё это время нёс верные числа — разошлись НОСИТЕЛИ, а не факт: класс «поправил читателя, оставил писателя» (`D39.202` п.1). +⚠⚠ **ПОПРАВКА 05.09 (замер верификатора по дереву на `d766007`; числа выше НЕ переписаны — они были верны в свою минуту).** Абзац заленджен коммитом `ba4fd34` через **девять секунд** после пака `81a89e9` и за **три с лишним часа ДО** дофикса `616a8e4`, который добавил ещё +5 тест-функций и +10 записей каталога. Сообщение коммита подписало их «final counts», и после дофикса их никто не тронул. Верно на сегодня: тестовых функций **1172 → 1213 (+41)** · каталог мутаций **158 → 201** · каталог целиком — **201 запись, 197 RED, ЧЕТЫРЕ аргументированных выживших, 0 неожиданных исходов**. ⛔ **⚠ **Испр. 06.09 автором находки: ПРОТУХЛИ ДВА числа, не три, и „0 SURVIVED" НЕ протухло.** У инструмента ДВА ведра: `SURVIVED` — **неожиданный** выживший (настоящая дыра), `survives` строчными — записанный и аргументированный. На ревизии, которую абзац описывает, каталог был 191 = 187 red + 4 survives, то есть все три числа верны ДЛЯ СВОЕЙ РЕВИЗИИ; четыре аргументированных были четырьмя уже тогда. Протухли 191→201 и 187→197. Третье — не протухание, а НЕПОЛНОЕ ПЕРЕЧИСЛЕНИЕ: 187+0+0+0 = 187 при собственном итоге 191, потому что ведро аргументированных не названо. Дефект другой природы и слабее. Прежняя редакция: **Переворачивается именно последнее: «0 SURVIVED» против четырёх записанных выживших** — а это то самое различение из `D39.202` п.3 (`SURVIVED` как СООБЩЕНИЕ О НЕДОСТИЖИМОСТИ, а не как провал), и следующая движковая смена открывает этот журнал РАНЬШЕ акта. Акт `D39.206` всё это время нёс верные числа — разошлись НОСИТЕЛИ, а не факт: класс «поправил читателя, оставил писателя» (`D39.202` п.1). ⛔ **ТРИ ВЕЩИ, КОТОРЫЕ ОРКЕСТРАТОРУ НАДО ЗНАТЬ ДЛЯ ЛЕНДИНГА:** 1. **Наружу едет НЕ то число, что назвал промт, и это согласовано.** §4(3) назвал `denied estimate` и diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 2308e6bb..95830a86 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -43,7 +43,7 @@ > ⚠ **Эррата 06.09-а (D39.208 п.7) — НОТА УТВЕРЖДАЛА ТО, ЧЕГО ФАЙЛ НЕ ДЕРЖАЛ.** Пункт 7 писал, что «`getRunOptions` приобрёл 409, **внесён в состав минора**». В каноне у операции стояли только `200/401/404`: я бампнул `info.version` до 0.11.0 и правку ответа НЕ внёс, то есть версия объявляла поведение, которого канон не описывал. **Класс строки 299 ВНУТРИ D-ноты** — нашёл коллега-Fable сверкой ноты с файлом. Исправлено 06.09: `'409'` с описанием причины `not_priced` и прямой оговоркой, что операция ВПЕРВЫЕ научилась отказывать, а клиент по 0.10.0 встретит код, которого нет в его заглушках. Тем же заходом сняты зеркала эры шкалы в `15-money-path.md` (`CeilingBounds` ретирован, шкалы в главах больше нет — абзацы оставлены историей под баннером). ⚠ Урок в свою сторону: **акт приёмки — тоже носитель, и он врёт ровно так же, как код**; «внесено в состав минора» я написал о собственном намерении, а не о состоянии файла. > ⚠ **Эррата 05.09-к (D39.200, разбор «`git add docs/` унёс чужой отчёт») — ТА ЖЕ ЛОВУШКА СРАБОТАЛА ВТОРОЙ РАЗ ЗА СМЕНУ, И ПЕРВАЯ ЗАПИСЬ ЕЁ НЕ ПРЕДОТВРАТИЛА.** Утром корень был записан верно («`docs/PROGRESS.md` — единственный файл зоны `docs/`, в который пишут чужие зоны») и вывод сделан правильный (коммитить pathspec-формой). Вечером коммит `e8ec901` — строка бэклога 302, pathspec-форма, индекс чист — **всё равно унёс секцию отчёта бэкенд-зоны** (пак структуры глав), потому что **pathspec берёт рабочее состояние ФАЙЛА ЦЕЛИКОМ и от чужого ВНУТРИ файла не защищает вовсе**. Содержимое цело, потеряна атрибуция; историю не переписывал, зона уведомлена, нашла это сама. ⇒ **Первая запись назвала ФАКТ и не назвала ДЕЙСТВИЯ, и потому не сработала.** Исполнимый шаг внесён в ролевой промт оркестратора: перед каждым коммитом `docs/PROGRESS.md` смотреть `git diff -- docs/PROGRESS.md` и опознавать чужие секции. ⚠ Урок шире случая: **знание, записанное как факт, а не как шаг, не мешает повторению** — и это тот же класс, что `D39.202` п.3-бис (гейт умирает не отключением, а вытеснением из привычки). > ⚠ **Эррата 05.09-и (D39.207 п.6, «каталог мутаций целиком не перегонял») — ДЫРА ЗАКРЫТА ПРОГОНОМ.** Пункт честно записывал, что верификатор проверил СОСТАВ каталога статически и тем повторил дыру приёмки, а не закрыл её. Прогон состоялся: **201/201 записей получили вердикт, каждая РОВНО ОДИН раз** (сверено программно по id) — **197 RED · 4 `survives` · 0 SURVIVED · 0 `RED!` · 0 NOTHING · 0 ROTTED · 0 неожиданных исходов**, baseline зелен во всех десяти пакетах в каждом вызове. ⭐ **Множество фактически выживших ТОЧНО РАВНО множеству записанных `expect: survives`** — сверено как МНОЖЕСТВА: `G-byte-gate`, `WB62-innocent-const-must-not-be-accused`, `MS-reserve-under-the-gate`, `MS-reservation-released-on-marshal-failure`. ⇒ «197 RED» из `D39.206` §2 больше не держится на счёте записей в JSON. ⚠ **ФОРМА: это СКЛЕЙКА ВОСЬМИ вызовов (2 ч 29 мин против калиброванных ~50), шесть убиты нехваткой памяти; ОДНИМ ПРОГОНОМ НЕ ЯВЛЯЕТСЯ.** Законность предъявлена механически: покрытие 201/201 без пересечений, дерево между вызовами — `diff -r --brief`, побайтно идентично, 334 файла, проверено ПЯТЬ раз. ⚠ В двух убитых вызовах тул НЕ напечатал `restored on terminated`, и чистота там держится на побайтном сравнении, а не на самоотчёте инструмента. ⚠ Флагов было ТРИ варианта (`-p` снижался дважды), а не два, как я полагал, — объявил верификатор сам; `-parallel`/`GOMAXPROCS` не трогались, семантика тестов одна. ⚠ И моя оговорка «неожиданный исход перегнать под флагами первого вызова» **исполнена ВХОЛОСТУЮ**: неожиданных исходов не было ни одного, то есть правило осталось НЕИСПОЛЬЗОВАННЫМ, а не соблюдённым — формулировка верификатора, и она точнее моей. ⚠ Форма улики пере-проверена по объединённому корпусу логов: строк `RED`, не называющих ни одного упавшего теста, — **0** из 197; маркеров `INCONCLUSIVE`/`signal: killed`/`out of memory` — **0**. Нехватка памяти не превратила ни одной зелени в ложную красноту. -> ⚠ **Эррата 05.09-ж (D39.201 §2в) — ПРИЧИНА НЕПРОВЕРКИ ПРИПИСАНА НЕВЕРНО.** Пункт объясняет непроверку тем, что стенд зоны неисполним («Failed to connect to bus») и «проверит только боевой хост». Замерено верификатором на ЭТОЙ машине: пользовательский systemd ДОСТУПЕН — `make conditions` в `platform/` печатает `systemctl --user reachable`, пробник `systemd-run --user --collect --unit=… /bin/true` вернул 0. ⇒ блокер был свойством ОКРУЖЕНИЯ той сессии, а не свойством непроизводственного хоста, и сценарий здесь ИСПОЛНИМ. Сама находка не портится — неверна приписанная ей причина; разбор и норма, из неё выросшая, — `D39.207` п.5. +> ⛔⛔ **ЭРРАТА 05.09-ж ОТОЗВАНА 06.09 ЕЁ ЖЕ АВТОРОМ — ЗАМЕР БЫЛ НЕ О ТОМ МЕНЕДЖЕРЕ, И АКТ БЫЛ ПРАВ.** Верификатор прогнал `systemctl --user` под `ubuntu` и прочёл ответ как ответ про менеджер пользователя ДЕМОНА — а его на хосте нет вовсе (`id tmplatform` → `no such user`). Репозиторий предупреждает ровно об этой ошибке отдельным абзацем (`platform/deploy/README.md:488`: «это НЕ ТОТ systemd… `systemctl --user` отвечает про менеджер ТОГО, КТО СПРАШИВАЕТ»), и он правил рядом, не прочитав. ⇒ **PLAUSIBLE в `D39.201` §2(в) был квалифицирован ВЕРНО**, и демонтирован без основания. ⚠ Следствие для `D39.207`: п.3 F4 снят, а обоснование нормы п.5 пересчитано — находок «про ПРИЧИНЫ, приписанные без прогона» остаётся ДВЕ, не три; норма от этого не рушится, но её счёт обязан быть честным, иначе она сама станет примером своего нарушения. Ниже — отозванный текст. ⚠ **Эррата 05.09-ж (D39.201 §2в) — ПРИЧИНА НЕПРОВЕРКИ ПРИПИСАНА НЕВЕРНО.** Пункт объясняет непроверку тем, что стенд зоны неисполним («Failed to connect to bus») и «проверит только боевой хост». Замерено верификатором на ЭТОЙ машине: пользовательский systemd ДОСТУПЕН — `make conditions` в `platform/` печатает `systemctl --user reachable`, пробник `systemd-run --user --collect --unit=… /bin/true` вернул 0. ⇒ блокер был свойством ОКРУЖЕНИЯ той сессии, а не свойством непроизводственного хоста, и сценарий здесь ИСПОЛНИМ. Сама находка не портится — неверна приписанная ей причина; разбор и норма, из неё выросшая, — `D39.207` п.5. > ⚠ **Эррата 05.09-з (D39.206 §1) — ПЕРЕЧЕНЬ ЛЕНДИНГОВ ПАКА НЕПОЛОН.** Названы `81a89e9`, `616a8e4` и `ba4fd34`; НЕ назван **`e7d6b3f`**, правящий доки того же пака — и именно он пере-навёл шесть якорей, оставив без внимания соседний указатель в Go-комментарии (`D39.207` п.3, F2). Полный состав пака — четыре коммита. > ⚠ **Эррата 05.09-е (D39.190 п.2) — «ПОТЕРЯННЫЙ ЗАГОЛОВОК У ШЕСТИ ГЛАВ ИЗ СЕМНАДЦАТИ» НЕ ИМЕЕТ НОСИТЕЛЯ.** Пункт 2 обосновывает вес структурной строки «свежей уликой полигона» — вычиткой семнадцати глав боевого перевода, нашедшей потерянный заголовок у шести глав из семнадцати (≈800 на книге). **Число подано без единой ссылки на файл**, и поиск первоисточника не дал его ни мне, ни независимо коллеге-Fable 05.09: в `eval/dovodka/` находится план на семнадцать глав, но не счёт потерянных заголовков. ⇒ Число НЕ отзывается — оно может быть верным, — но **опирать на него скоуп ЗАПРЕЩЕНО**: механизм потери не установлен (роняет модель? теряется на экспорте? не показывает читалка?), а лечение зависит от механизма. Титульная работа структурного пака стоит на СОБСТВЕННОМ основании — заголовок, не едущий по проводу, невозможно отрендерить, — а не на этой улике. Кто найдёт первоисточник, впишет адрес сюда. > ⚠⚠ **Эррата 05.09-г — НОРМА «ДЕРЕВО МОРОЗИТСЯ ЛИБО РЕВЬЮЕРУ НАЗЫВАЕТСЯ КОММИТ» ПРИПИСАНА `D39.172` ОШИБОЧНО; в её теле этого НЕТ.** Проверено: тело `D39.172` (пак `sqlc`) не содержит ни «морозится», ни «КОНКРЕТНОЕ дерево», ни «ревьюер» — оно про то, что чужие застейдженные правки уехали в чужой коммит под чужой подписью, то есть про гигиену коммита, а не про суждение о названном дереве. ⚠⚠ **ИСПР. в тот же час: первая редакция ЭТОЙ ЭРРАТЫ САМА ОВЕР-АТРИБУТИРОВАЛА ДВАЖДЫ** — назвала `D39.201` (её тело `D39.172` не цитирует ВОВСЕ) и пропустила `D39.180` и `D39.202` п.8, которые цитируют; плюс перевернула исток. **Замер:** `grep -n 'D39\.172' 05-decisions-log.md` → тела `D39.174` (×2) · `D39.180` · `D39.199` · `D39.202` · `D39.206`; `git log -S'судит КОНКРЕТНОЕ дерево'` → `0393e7a` (30.08, ПРОМТ) старше `8977001` (`D39.174`). ⇒ **норма родилась в `docs/ORCHESTRATOR_SESSION_PROMPT.md`, а ноты её унаследовали**, и ложную атрибуцию несут: `D39.174` · `D39.180` · `D39.199` · `D39.202` п.8 · `D39.206` + сам промт. ⚠ Поймано внешним ревьюером через час после написания: **эррата про овер-атрибуцию, написанная небрежно, — четвёртый случай того же класса за смену и худший из них, потому что стоит в шапке журнала, куда следующая сессия идёт первой.** ⚠ **Сама норма ВЕРНА и остаётся в силе** — операгивный носитель `ORCHESTRATOR_SESSION_PROMPT.md`, греп `судит КОНКРЕТНОЕ дерево`; ложна только атрибуция. Тела нот не переписываются (D23.3) — читать их через эту эррату. **Класс — ОВЕР-АТРИБУЦИЯ: ссылка на ноту, которая цитируемого не содержит; оркестратор допустил её сегодня ТРЕТИЙ раз** (прежние два: фраза «деньги покидают движок только внутри `spend`», которой в журнале нет, и подномер `D2.3`, оказавшийся про другое). Поймано сплошной вычиткой корпуса.